Skip to content

Commit b9a3883

Browse files
Update README.md
1 parent fa55171 commit b9a3883

File tree

1 file changed

+187
-4
lines changed
  • APIJSON-Java-Server/APIJSONDemo-Script

1 file changed

+187
-4
lines changed
Lines changed: 187 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,190 @@
1-
# APIJSONDemo
1+
1、目前支持脚步引擎 <br/>
2+
jdk默认实现 Nashorn 引擎<br/>
3+
Nashorn(--global-per-engine)<br/>
4+
graalvm<br/>
5+
lua<br/>
6+
其他脚步引擎,业务侧可以扩展<br/>
7+
2、扩展脚步引擎,支持更多脚步执行器<br/>
8+
![image](https://user-images.githubusercontent.com/12228225/212584805-12f7c2d0-4b67-4c9e-b4c7-4259e2c7cb04.png)
9+
![image](https://user-images.githubusercontent.com/12228225/212584868-3893f192-8f7c-4612-ac72-d022ff0550ed.png)
10+
3、脚本 线程安全问题<br/>
11+
业务侧按照需求,进行锁颗粒度控制<br/>
12+
目前测试, lua Bindings无法保证线程安全 需要通过外部锁,比如 lock、synchronized、redis 分布式锁,防止并发问题<br/>
13+
建议锁颗粒度: 脚本名.<br/>
14+
举例:<br/>
15+
脚本: length, testArray_lua<br/>
16+
锁: length<br/>
17+
锁: testArray_lua<br/>
18+
ConcurrentHashMap 写key实现原理差不多<br/>
19+
![image](https://user-images.githubusercontent.com/12228225/212581538-a68d677b-bb3f-487b-8e4a-b7415e03666a.png)
220

3-
APIJSON + SpringBoot 初级使用的最简单 Demo
21+
![image](https://user-images.githubusercontent.com/12228225/212581560-5304baf4-fd80-4809-80cc-168767199986.png)
22+
4、支持传递 apijson元数据 参数:<br/>
23+
version、tag、args<br/>
24+
5、支持业务侧扩展参数<br/>
25+
extParam<br/>
26+
![image](https://user-images.githubusercontent.com/12228225/212581889-edbe0d99-1a0e-401f-ba14-73d81e244382.png)
27+
![image](https://user-images.githubusercontent.com/12228225/212582389-f5de9267-893e-4db1-beae-39f5a3cbdcc7.png)
28+
6、脚本编写规范<br/>
29+
案例一:<br/>
430

5-
### 运行
31+
```
32+
function getType() {
33+
var curObj = _meta.args[0];
34+
var val = _meta.args[1];
35+
var index = _meta.args[2];
36+
return curObj[val] instanceof Array ? 'array' : typeof curObj[val];
37+
}
38+
getType()
639
7-
右键 DemoApplication > Run As > Java Application
40+
```
41+
案例二:<br/>
42+
43+
```
44+
function getType(curObj, val, index) {
45+
return curObj[val] instanceof Array ? 'array' : typeof curObj[val];
46+
}
47+
getType(_meta.args[0], _meta.args[1], _meta.args[2])
48+
49+
```
50+
7、支持二次处理脚步<br/>
51+
格式化等<br/>
52+
![image](https://user-images.githubusercontent.com/12228225/212583376-52081fee-7c1a-40c2-8a40-3ec04cb6c5f9.png)
53+
8、数据库测试脚本<br/>
54+
55+
```
56+
DROP TABLE IF EXISTS `function`;
57+
CREATE TABLE `function` (
58+
`id` bigint(20) NOT NULL AUTO_INCREMENT,
59+
`debug` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否为 DEBUG 调试数据,只允许在开发环境使用,测试和线上环境禁用:0-否,1-是。',
60+
`userId` varchar(36) NOT NULL COMMENT '管理员用户Id',
61+
`type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '''0'' COMMENT ''类型:0-远程函数;1- SQL 函数''',
62+
`name` varchar(50) NOT NULL COMMENT '方法名',
63+
`returnType` varchar(50) NOT NULL DEFAULT 'Object' COMMENT '返回值类型。TODO RemoteFunction 校验 type 和 back',
64+
`arguments` varchar(100) DEFAULT NULL COMMENT '参数列表,每个参数的类型都是 String。\n用 , 分割的字符串 比 [JSONArray] 更好,例如 array,item ,更直观,还方便拼接函数。',
65+
`demo` json NOT NULL COMMENT '可用的示例。\nTODO 改成 call,和返回值示例 back 对应。',
66+
`detail` varchar(1000) NOT NULL COMMENT '详细描述',
67+
`version` tinyint(4) NOT NULL DEFAULT '0' COMMENT '允许的最低版本号,只限于GET,HEAD外的操作方法。\nTODO 使用 requestIdList 替代 version,tag,methods',
68+
`tag` varchar(20) DEFAULT NULL COMMENT '允许的标签.\nnull - 允许全部\nTODO 使用 requestIdList 替代 version,tag,methods',
69+
`methods` varchar(50) DEFAULT NULL COMMENT '允许的操作方法。\nnull - 允许全部\nTODO 使用 requestIdList 替代 version,tag,methods',
70+
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
71+
`appId` varchar(36) DEFAULT NULL COMMENT '应用编号',
72+
`return` varchar(45) DEFAULT NULL COMMENT '返回值示例',
73+
`language` varchar(255) DEFAULT NULL COMMENT '语言:Java(java), JavaScript(js), Lua(lua), Python(py), Ruby(ruby), PHP(php) 等,NULL 默认为 Java,JDK 1.6-11 默认支持 JavaScript,JDK 12+ 需要额外依赖 Nashron/Rhiro 等 js 引擎库,其它的语言需要依赖对应的引擎库,并在 ScriptEngineManager 中注册',
74+
PRIMARY KEY (`id`) USING BTREE,
75+
UNIQUE KEY `name_UNIQUE` (`name`) USING BTREE
76+
) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=utf8 COMMENT='远程函数。强制在启动时校验所有demo是否能正常运行通过';
77+
78+
-- ----------------------------
79+
-- Records of function
80+
-- ----------------------------
81+
BEGIN;
82+
INSERT INTO `function` (`id`, `debug`, `userId`, `type`, `name`, `returnType`, `arguments`, `demo`, `detail`, `version`, `tag`, `methods`, `date`, `appId`, `return`, `language`) VALUES (18, 0, '0', 1, 'getType', 'String', 'var,index', '{\"var\": [1, 2, 3], \"index\": 0}', '系统', 0, NULL, NULL, '2022-12-13 14:17:43', NULL, NULL, 'js');
83+
INSERT INTO `function` (`id`, `debug`, `userId`, `type`, `name`, `returnType`, `arguments`, `demo`, `detail`, `version`, `tag`, `methods`, `date`, `appId`, `return`, `language`) VALUES (28, 0, '0', 0, 'testArray', 'Object', 'var,index', '{\"var\": [1, 2, 3], \"index\": 0}', '测试', 0, NULL, NULL, '2022-12-20 18:42:39', NULL, NULL, 'js');
84+
INSERT INTO `function` (`id`, `debug`, `userId`, `type`, `name`, `returnType`, `arguments`, `demo`, `detail`, `version`, `tag`, `methods`, `date`, `appId`, `return`, `language`) VALUES (31, 0, '0', 0, 'isContainJs', 'Object', 'var,valKey', '{\"var\": \"a, b,c\", \"valKey\": \"1\"}', '测试', 0, NULL, NULL, '2023-01-12 14:29:11', NULL, NULL, 'nashornJS');
85+
INSERT INTO `function` (`id`, `debug`, `userId`, `type`, `name`, `returnType`, `arguments`, `demo`, `detail`, `version`, `tag`, `methods`, `date`, `appId`, `return`, `language`) VALUES (32, 0, '0', 0, 'length', 'Object', 'var', '{\"var\": [1, 2, 3]}', '测试', 0, NULL, NULL, '2023-01-12 17:28:47', NULL, NULL, 'js');
86+
INSERT INTO `function` (`id`, `debug`, `userId`, `type`, `name`, `returnType`, `arguments`, `demo`, `detail`, `version`, `tag`, `methods`, `date`, `appId`, `return`, `language`) VALUES (33, 0, '0', 0, 'lengthExtendParameter', 'Object', 'var', '{\"var\": [1, 2, 3]}', '测试', 0, NULL, NULL, '2023-01-12 18:18:31', NULL, NULL, 'nashornJS');
87+
INSERT INTO `function` (`id`, `debug`, `userId`, `type`, `name`, `returnType`, `arguments`, `demo`, `detail`, `version`, `tag`, `methods`, `date`, `appId`, `return`, `language`) VALUES (34, 0, '0', 0, 'length_lua', 'Object', 'var', '{\"var\": [1, 2, 3]}', '测试', 0, NULL, NULL, '2023-01-13 15:59:47', NULL, NULL, 'luaj');
88+
INSERT INTO `function` (`id`, `debug`, `userId`, `type`, `name`, `returnType`, `arguments`, `demo`, `detail`, `version`, `tag`, `methods`, `date`, `appId`, `return`, `language`) VALUES (35, 0, '0', 0, 'testArray_lua', 'Object', 'var,index', '{\"var\": [1, 2, 3], \"index\": 0}', '测试', 0, NULL, NULL, '2023-01-13 16:02:00', NULL, NULL, 'luaj');
89+
INSERT INTO `function` (`id`, `debug`, `userId`, `type`, `name`, `returnType`, `arguments`, `demo`, `detail`, `version`, `tag`, `methods`, `date`, `appId`, `return`, `language`) VALUES (36, 0, '0', 0, 'length_graalJS', 'Object', 'var', '{\"var\": [1, 2, 3]}', '测试', 0, NULL, NULL, '2023-01-13 18:03:25', NULL, NULL, 'graalJS');
90+
COMMIT;
91+
92+
SET FOREIGN_KEY_CHECKS = 1;
93+
94+
```
95+
```
96+
SET NAMES utf8mb4;
97+
SET FOREIGN_KEY_CHECKS = 0;
98+
99+
-- ----------------------------
100+
-- Table structure for script
101+
-- ----------------------------
102+
DROP TABLE IF EXISTS `script`;
103+
CREATE TABLE `script` (
104+
`id` bigint(20) NOT NULL AUTO_INCREMENT,
105+
`documentId` bigint(20) NOT NULL,
106+
`randomId` bigint(20) NOT NULL,
107+
`simple` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否为可直接执行的简单代码段:0-否 1-是',
108+
`name` varchar(100) NOT NULL,
109+
`script` text NOT NULL,
110+
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
111+
`ahead` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否为前置脚本',
112+
PRIMARY KEY (`id`) USING BTREE,
113+
UNIQUE KEY `id_UNIQUE` (`id`) USING BTREE
114+
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT='脚本,前置预处理脚本、后置断言和恢复脚本等';
115+
116+
-- ----------------------------
117+
-- Records of script
118+
-- ----------------------------
119+
BEGIN;
120+
INSERT INTO `script` (`id`, `documentId`, `randomId`, `simple`, `name`, `script`, `date`, `ahead`) VALUES (1, 0, 0, 0, 'getType', 'function getType() {\n var curObj = _meta.args[0];\n var val = _meta.args[1];\n var index = _meta.args[2];\n return curObj[val] instanceof Array ? \'array\' : typeof curObj[val];\n}\ngetType()', '2022-11-16 16:01:23', 0);
121+
INSERT INTO `script` (`id`, `documentId`, `randomId`, `simple`, `name`, `script`, `date`, `ahead`) VALUES (2, 0, 0, 0, 'isContainJs', 'function isContainJs() {\n var curObj = _meta.args[0];\n var key = _meta.args[1];\n var valKey = _meta.args[2];\n var arr = curObj == null ? null : curObj[key];\n var val = curObj == null ? null : curObj[valKey];\n return arr != null && arr.indexOf(val) >=0;\n}\nisContainJs()\n', '2022-11-16 16:02:48', 0);
122+
INSERT INTO `script` (`id`, `documentId`, `randomId`, `simple`, `name`, `script`, `date`, `ahead`) VALUES (3, 0, 0, 1, 'init', 'var i = 1;\n\"init done \" + i;', '2022-11-16 16:41:35', 0);
123+
INSERT INTO `script` (`id`, `documentId`, `randomId`, `simple`, `name`, `script`, `date`, `ahead`) VALUES (4, 0, 0, 0, 'length', 'function length() {\n var curObj = _meta.args[0];\n var key = _meta.args[1];\n var val = curObj == null ? null : curObj[key];\n return val == null ? 0 : val.length;\n}\nlength()', '2022-11-16 17:18:43', 0);
124+
INSERT INTO `script` (`id`, `documentId`, `randomId`, `simple`, `name`, `script`, `date`, `ahead`) VALUES (5, 0, 0, 0, 'testArray', 'function testArray() {\n var curObj = _meta.args[0];\n var key = _meta.args[1];\n var index = _meta.args[2];\n var val = curObj == null ? null : curObj[key][curObj[index]];\n return val;\n}\ntestArray()', '2022-12-20 18:44:09', 0);
125+
INSERT INTO `script` (`id`, `documentId`, `randomId`, `simple`, `name`, `script`, `date`, `ahead`) VALUES (6, 0, 0, 0, 'lengthExtendParameter', 'function lengthExtendParameter() {\n var data = extParam.data;\n print(\'data:\'+data);\n var curObj = _meta.args[0];\n var key = _meta.args[1];\n var val = curObj == null ? null : curObj[key];\n return val == null ? 0 : val.length;\n}\nlengthExtendParameter()', '2023-01-12 18:23:45', 0);
126+
INSERT INTO `script` (`id`, `documentId`, `randomId`, `simple`, `name`, `script`, `date`, `ahead`) VALUES (7, 0, 0, 0, 'length_lua', 'function length_lua()\n local extParam = extParam:getUsername()\n local version = _meta:get(\'version\')\n local args = _meta:get(\'args\')\n local curObj = args[1];\n local key = args[2]\n print(\'curObj:get(key):\'..tostring(curObj:get(key)))\n print(\'ret type:\'..type(curObj:get(key)))\n print(\'ret:\'..tostring(curObj:get(key):size()))\n return curObj:get(key):size()\nend\nreturn length_lua()', '2023-01-13 16:00:34', 0);
127+
INSERT INTO `script` (`id`, `documentId`, `randomId`, `simple`, `name`, `script`, `date`, `ahead`) VALUES (8, 0, 0, 0, 'testArray_lua', 'function testArray_lua()\n local args = _meta:get(\'args\')\n local curObj = args[1];\n print(\'curObj:\'..tostring(curObj)) \n local key = args[2];\n local index = args[3];\n local valIndex = curObj:get(index)\n print(\'valIndex:\'..tostring(valIndex)) \n print(\'ret:\'..tostring(curObj:get(key)))\n return curObj:get(key):get(valIndex)\nend\nreturn testArray_lua()', '2023-01-13 16:01:35', 0);
128+
INSERT INTO `script` (`id`, `documentId`, `randomId`, `simple`, `name`, `script`, `date`, `ahead`) VALUES (9, 0, 0, 0, 'length_graalJS', 'function length() {\n var curObj = _meta.args[0];\n var key = _meta.args[1];\n var val = curObj == null ? null : curObj[key];\n return val == null ? 0 : val.length;\n}\nlength()', '2023-01-13 18:04:25', 0);
129+
COMMIT;
130+
131+
SET FOREIGN_KEY_CHECKS = 1;
132+
133+
```
134+
9、apijson 测试json<br/>
135+
```
136+
#js
137+
{
138+
"func": {
139+
"var": [1,2,3],
140+
"index": 0,
141+
"id()": "getType(var,index)"
142+
}
143+
}
144+
145+
{
146+
"func": {
147+
"var": "a,b,c",
148+
"valKey": "a1",
149+
"id()": "isContainJs(var,valKey)"
150+
}
151+
}
152+
153+
{
154+
"func": {
155+
"var": [1,2,3],
156+
"length()": "length(var)"
157+
}
158+
}
159+
160+
{
161+
"func": {
162+
"var": [1,2,3],
163+
"index": 1,
164+
"testArray()": "testArray(var,index)"
165+
}
166+
}
167+
#lua
168+
{
169+
"func": {
170+
"var": [1,2,3,'dd'],
171+
"length_lua()": "length_lua(var)"
172+
}
173+
}
174+
175+
{
176+
"func": {
177+
"var": [1,2,3],
178+
"index": 2,
179+
"testArray_lua()": "testArray_lua(var,index)"
180+
}
181+
}
182+
183+
# graalJS
184+
{
185+
"func": {
186+
"var": [1,2,3],
187+
"length_graalJS()": "length_graalJS(var)"
188+
}
189+
}
190+
```

0 commit comments

Comments
 (0)