|
| 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 | + |
| 9 | + |
| 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 | + |
| 20 | + |
| 21 | + |
| 22 | +4、支持传递 apijson元数据 参数:<br/> |
| 23 | +version、tag、args<br/> |
| 24 | +5、支持业务侧扩展参数<br/> |
| 25 | +extParam<br/> |
| 26 | + |
| 27 | + |
| 28 | +6、脚本编写规范<br/> |
| 29 | +案例一:<br/> |
| 30 | + |
| 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() |
| 39 | +
|
| 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 | + |
| 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