QLExpress requests 设计

参考文档:https://github.com/alibaba/QLExpress

要达到的目标

使用QLExpress技术构建服务编排逻辑,用户可以通过简单的 QLExpress 脚本实现复杂的服务编排逻辑。

QL脚本使用示例如下

  • QLExpress 脚本标识用 code: 前缀,也就是只认此段字符串前缀有 code: 开头就代表是QL脚本。如果不是QL脚本,那么则是标准的requestInfo json 内容,执行的逻辑将分支到标准的request执行。
  • request(requestInfo, vars) 函数支持QL脚本嵌套,其中由 requestInfo参数来承接,标识用 code: 前缀,也就是当 requestInfo是字符串时,并且此字符串片段的前缀开头是 code: 那么我们将走内嵌 QLExpress 脚本执行逻辑。
  • xmlcode::: 开始到结束都标注为画代码的描述信息配置,这些配置在执行QL脚本时要进行截取剔除不要。
  • 自定义的 request(requestInfo, vars) 函数可支持两个参数也可支持一个参数——》request(requestInfo)
code:
// 导入的包必须放到顶部
import org.apache.commons.lang.StringUtils;
import com.justep.util.net.ServiceUrlUtil;

//========== 标准类型的request使用示例
requestInfo =
'{
    "request": [{
        "body": {
            "classSize": 2,
            "teacher": "陈chensc",
            "student": [{
                "number": 1,
                "name": "${schedulingJobId}",
                "age": 40
            }, {
                "number": 8,
                "name": "${schedulingJobId}",
                "age": 30
            }],
            "describe": "附中..."
        },
        "formCommit": false,
        "headers": {},
        "method": "POST",
        "responseHeader": false,
        "url": "http://jobswork/main/resultHandleSchool"
    }, {
        "body": {
            "jobId": "${schedulingJobId}",
            "feedbackUrl": "${schedulingFeedbackUrl}",
            "executeNumber": "${schedulingExecuteNumber}",
            "requestCounts": "${schedulingRequestCounts}",
            "content": "${$.student[0]}|json"
        },
        "formCommit": false,
        "headers": {},
        "method": "POST",
        "responseHeader": false,
        "url": "http://jobswork/main/workHandleStr",
        "timeoutSeconds": 300
    }],
    "timeoutSeconds": 60,
    ""
}';

vars =
'{
    "schedulingJobId": "jobid",
    "schedulingFeedbackUrl": "http://dfdf.newdoa.com",
    "schedulingExecuteNumber": 12,
    "schedulingRequestCounts": 1
}';

// 这里执行request函数逻辑
result = request(requestInfo,vars);
logger("响应body: " + result.responseBody);
logger("响应headers: " + result.responseHeaders);


//========== 根据request结果result来执行自己的逻辑
list = new ArrayList<>();
for (int i = 0; i < 1; i++) {
  item = result.responseBody.message;
  list.add(item);
}
logger("最后list: " + list);


//========== OpenAPI类型的request使用示例
requests_OpenAPI =
{
    "request": [{
        "kind": "OpenAPI",
        "docUrl": "https://petstore3.swagger.io/api/v3/openapi.json",
        "docContent": "",
        "path": "/pet/login",
        "method": "GET",
        "label": "Finds Pets by status.",
        "parameters": {
            "status": "${status}"
        }
    }, {
        "kind": "OpenAPI",
        "docUrl": "https://petstore3.swagger.io/api/v3/openapi.json",
        "path": "/pet/saveBody",
        "method": "POST",
        "label": "Update an existing pet by Id.",
        "body": "${body}"
    }],
    "timeoutSeconds": 60
};
vars_OpenAPI =
{
    "body": "body内容",
    "status": 1
};
// 这里执行request函数逻辑,根据上方的requestInfo_OpenAPI配置,此逻辑将执行OpenAPI类型request
result_OpenAPI = request(requests_OpenAPI, vars_OpenAPI);


//========== request(requests, var) 函数支持QL嵌套
requests_QLCode =
'code:
logger("=== QLExpress脚本开始执行 ===");
// 定义变量
requestInfo = {
    "request": [{
        "method": "POST",
        "url": "https://jobclient/main/workHandleStr",
        "body": {
            "teacher": "陈八",
            "student": [{"name": "张三"}, {"name": "李四"}]
        }
    }]
};
result = request(requestInfo);
';
result_QLCode = request(requests_QLCode);

// ========== import 导包测试,导入 StringUtils和ServiceUrlUtil
url = "service://{serviceName}/main/api";
logger(url);
if (StringUtils.isNotBlank(url)) {
    logger("进入了=========");
    newurl = ServiceUrlUtil.format(url);
}


//========== 画代码xml描述信息
xmlcode:::
<service filepath="service/main/message.service.m">
    <label language="zh_CN">消息服务</label>
    <uses/>
</service>

实现QL request

  • 实现一个自定义的 request 函数
// 自定义 request 函数实现
public class RequestFunction implements CustomFunction {
    @Override
    public Object call(QContext qContext, Parameters parameters) throws Throwable {
        // TODO
    }
}
// request 函数在QL脚本中的使用
requestInfo = {};
vars = {};
request(requestInfo, vars)
  • RequestUtil 中添加request QL对外的使用工具方法
// RequestUtil 工具类中添加如下方法为外界提供使用
public class RequestUtil {
    /**
     * 标准 request 和 ql_script 统一使用入口
     *
     * @param requestInfo requestInfo、requests、ql_script 等三种(必填),如果该文本前缀有 code: 开头的标识时,则是QL脚本,否则是requestInfo(JSON)、request(JSONArray)
     * @param staticVar   静态变量(可选)
     * @param extHeaders  request请求透传头,只作用于requestInfo不作用于QL code(可选)
     * @param options     扩展选项(可选):自定义函数在此处设置注入{"ql_custom_function":[{"functionName":"hello","functionClass":"com.justep.util.request.ql.HelloFunction"}]}
     * @return
     * @throws RequestException
     */
    public static HttpInvokeResult<JSONObject> invokeRequest(String requestInfo, Map<String, Object> staticVar, Map<String, String> extHeaders, Map<String, Object> options) throws RequestException {
        // TODO
    }
}
// 该工具方法使用示例

// 传入的文档内容可以有三种组成,ql_script(QL脚本)、requestInfo(请求JSON信息)、requests(请求JSON数组)
String context = "";
String ql_script = "ql_script"; context = ql_script;
String requestInfo = "{}"; context = requestInfo;
String requests = "[]"; context = requests;

// 添加用户自定义函数 hello()
Map<String, Object> options = new HashMap<>();
List<QLCustomFunctionManager> qlCustomFunctionManagers = new ArrayList<>();
qlCustomFunctionManagers.add(new QLCustomFunctionManager("hello", "com.justep.cloud.HelloFunction"));
options.put("ql_custom_function", qlCustomFunctionManagers);

// 配置静态变量
Map<String, Object> staticVar = new HashMap<>();
staticVar.put("hello","world");

HttpInvokeResult<JSONObject> res = RequestUtil.invokeRequest(context, staticVar, null,options);
System.out.println("执行invokeQLRequest得到结果: " + JSON.toJSONString(res));
  • 扩展自定义函数:如上方工具类代码所示,用options参数承载
// invokeRequest() 方法中options参数承载,传入内容示例如下:
{
    "ql_custom_function": [{
        "functionName": "hello",
        "functionClass": "com.justep.util.request.ql.HelloFunction"
    }]
}
  • 为了方便调试,内置定义了一个logger 函数,实现方式与上方的 request 函数类似
// 可在 QL 脚本中这样使用
logger("=== QLExpress脚本开始执行 ===");
logger("=== QLExpress脚本开始执行 ===", 3, 2, 1);

results matching ""

    No results matching ""