Pre Merge pull request !1 from Alex家的兔子/lyh_dev

This commit is contained in:
Alex家的兔子 2023-03-15 07:39:11 +00:00 committed by Gitee
commit 60ad3fa368
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
11 changed files with 284 additions and 117 deletions

View File

@ -63,7 +63,9 @@ public class DebugMain {
= new ResultCallback() { = new ResultCallback() {
@Override @Override
public void onResult(String str) { public void onResult(String str) {
if(str.contains("Error")) {
LOGGER.error("Some error happens: " + str);
}
LOGGER.info("[PrintCB] " + str); LOGGER.info("[PrintCB] " + str);
} }
}; };

View File

@ -16,6 +16,7 @@ import org.bdware.analysis.gas.PPCount;
import org.bdware.analysis.taint.TaintBB; import org.bdware.analysis.taint.TaintBB;
import org.bdware.analysis.taint.TaintCFG; import org.bdware.analysis.taint.TaintCFG;
import org.bdware.analysis.taint.TaintResult; import org.bdware.analysis.taint.TaintResult;
import org.bdware.doip.audit.EndpointConfig;
import org.bdware.sc.ContractResult.Status; import org.bdware.sc.ContractResult.Status;
import org.bdware.sc.bean.*; import org.bdware.sc.bean.*;
import org.bdware.sc.boundry.JavaScriptEntry; import org.bdware.sc.boundry.JavaScriptEntry;
@ -49,6 +50,7 @@ import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
public class ContractProcess { public class ContractProcess {
@ -522,10 +524,7 @@ public class ContractProcess {
// doipModule的话拉起DoipServer服务端口 // doipModule的话拉起DoipServer服务端口
if(cn.getYjsType() == YjsType.DoipModule) { if(cn.getYjsType() == YjsType.DoipModule) {
// 只有一台机器去更新Router中的repoInfo就可以了 // 只有一台机器去更新Router中的repoInfo就可以了
if(JavaScriptEntry.shardingID == 0) { updateRepoInfo(contract.getCreateParam());
DoipClusterServer server = DoipClusterServer.getDOOPServerInstance();
server.updateRepoInfo(contract, cn);
}
invokeOnStartingDoipServer(cn, contract.getCreateParam()); invokeOnStartingDoipServer(cn, contract.getCreateParam());
} }
@ -570,10 +569,6 @@ public class ContractProcess {
fun.appendBeforeInvokeHandler(argSchemaHandler); fun.appendBeforeInvokeHandler(argSchemaHandler);
} }
if (fun.isDoipOperation()) {
fun.appendBeforeInvokeHandler(DOOPHandler.createDOOPHandler());
}
if (fun.isExport()) { if (fun.isExport()) {
//if(fun.annotations...) //if(fun.annotations...)
AccessHandler accessHandler = createHandlerIfExist(fun,fun.annotations,AccessHandler.class); AccessHandler accessHandler = createHandlerIfExist(fun,fun.annotations,AccessHandler.class);
@ -600,6 +595,10 @@ public class ContractProcess {
fun.appendAfterInvokeHandler(new HomomorphicDecryptHandler(fun)); fun.appendAfterInvokeHandler(new HomomorphicDecryptHandler(fun));
} }
if (fun.isDoipOperation()) {
fun.appendBeforeInvokeHandler(DOOPBeforeExecHandler.createDOOPHandler());
fun.appendAfterInvokeHandler(DOOPAfterExecHandler.createDOOPHandler());
}
} }
} }
@ -665,11 +664,7 @@ public class ContractProcess {
// doipModule的话拉起DoipServer服务端口 // doipModule的话拉起DoipServer服务端口
if(cn.getYjsType() == YjsType.DoipModule) { if(cn.getYjsType() == YjsType.DoipModule) {
// 只有一台机器去更新Router中的repoInfo就可以了 updateRepoInfo(contract.getCreateParam());
if(JavaScriptEntry.shardingID == 0) {
DoipClusterServer server = DoipClusterServer.getDOOPServerInstance();
server.updateRepoInfo(contract, cn);
}
invokeOnStartingDoipServer(cn, contract.getCreateParam()); invokeOnStartingDoipServer(cn, contract.getCreateParam());
} }
@ -682,9 +677,35 @@ public class ContractProcess {
} }
} }
public void updateRepoInfo(JsonElement arg) throws Exception {
// 只有0号节点需要初始化IRP连接去updateRepoInfo
if(JavaScriptEntry.shardingID == 0) {
// DOOP relevant logic
DoipClusterServer server = DoipClusterServer.getDOOPServerInstance();
if(server == null) {
JsonObject createParams = arg.getAsJsonObject();
if(createParams.has("router")) {
JsonElement routerInfo = createParams.get("router");
if(!routerInfo.isJsonObject()) throw new Exception("Provide wrong router info in create params to DoipModule");
else {
EndpointConfig endpointConfig = JsonUtil.GSON.fromJson(routerInfo.getAsJsonObject(), EndpointConfig.class);
DoipClusterServer.createDOOPServerInstance(endpointConfig);
}
} else {
throw new Exception("DoipModule should provide router info in create params");
}
server = DoipClusterServer.getDOOPServerInstance();
}
// 只有一台机器去更新Router中的repoInfo就可以了
server.updateRepoInfo(contract, cn);
}
}
public void invokeOnStartingDoipServer(ContractNode cn, JsonElement arg) { public void invokeOnStartingDoipServer(ContractNode cn, JsonElement arg) {
ContractRequest onStartingDoipServer = new ContractRequest(); ContractRequest onStartingDoipServer = new ContractRequest();
onStartingDoipServer.setAction("invokeOnStartingDoipServer"); onStartingDoipServer.setAction("onServerStart");
if (arg == null) { if (arg == null) {
if (engine != null && engine.getManifest() != null && engine.getManifest().createParam != null) if (engine != null && engine.getManifest() != null && engine.getManifest().createParam != null)
arg = engine.getManifest().createParam; arg = engine.getManifest().createParam;
@ -699,7 +720,7 @@ public class ContractProcess {
} else { } else {
onStartingDoipServer.setRequesterDOI("empty"); onStartingDoipServer.setRequesterDOI("empty");
} }
FunctionNode funNode = cn.getFunction("invokeOnStartingDoipServer"); FunctionNode funNode = cn.getFunction("onServerStart");
try { try {
JsonElement onStartingDoipServerRes = invoke(onStartingDoipServer, funNode).result; JsonElement onStartingDoipServerRes = invoke(onStartingDoipServer, funNode).result;
@ -724,7 +745,7 @@ public class ContractProcess {
} }
} catch (Exception e) { } catch (Exception e) {
LOGGER.error("DoipLocalSingleton cannot starts properly, plz check the invokeOnStartingDoipServer function"); LOGGER.error("DoipLocalSingleton cannot starts properly, plz check the onServerStart function");
e.printStackTrace(); e.printStackTrace();
} }
} }
@ -738,7 +759,7 @@ public class ContractProcess {
} else { } else {
funcArgs[2] = "empty"; funcArgs[2] = "empty";
} }
Object result = engine.invokeFunction("invokeOnStartingDoipServer", funcArgs); Object result = engine.invokeFunction("onServerStart", funcArgs);
Map<String, String> resMap = (Map<String, String>) result; Map<String, String> resMap = (Map<String, String>) result;
try { try {
if (!resMap.containsKey("doipAddr")) { if (!resMap.containsKey("doipAddr")) {
@ -747,7 +768,7 @@ public class ContractProcess {
DoipClusterServer.startDoipServer(resMap.get("doipAddr")); DoipClusterServer.startDoipServer(resMap.get("doipAddr"));
} }
} catch (Exception e) { } catch (Exception e) {
LOGGER.error("DoipLocalSingleton cannot starts properly, plz check the invokeOnStartingDoipServer function"); LOGGER.error("DoipLocalSingleton cannot starts properly, plz check the onServerStart function");
e.printStackTrace(); e.printStackTrace();
} }
} }

View File

@ -10,7 +10,7 @@ public abstract class AnnotationProcessor {
} }
public void processFunction( public void processFunction(
AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) { AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) throws Exception {
return; return;
} }
} }

View File

@ -119,18 +119,6 @@ public class YJSCompiler {
ContractManifest cm = ContractManifest cm =
JsonUtil.GSON.fromJson( JsonUtil.GSON.fromJson(
new InputStreamReader(manifestInput), ContractManifest.class); new InputStreamReader(manifestInput), ContractManifest.class);
// DOOP relevant logic
ZipEntry routerConfig = zf.getEntry("/router.json");
if (null == routerConfig) {
routerConfig = zf.getEntry("router.json");
}
if(null != routerConfig) {
InputStream routerInput = zf.getInputStream(routerConfig);
EndpointConfig endpointConfig = JsonUtil.GSON.fromJson(new InputStreamReader(routerInput), EndpointConfig.class);
DoipClusterServer.createDOOPServerInstance(endpointConfig);
}
// 如果没有就不限制根据gas进行插装 // 如果没有就不限制根据gas进行插装
if (0L != cm.getInsnLimit()) { if (0L != cm.getInsnLimit()) {
LOGGER.info("++++++++++++++++++++++true"); LOGGER.info("++++++++++++++++++++++true");
@ -189,7 +177,7 @@ public class YJSCompiler {
return czb; return czb;
} }
public ContractNode compile(InputStream input, String fileName) throws IOException { public ContractNode compile(InputStream input, String fileName) throws Exception {
// 词法分析 // 词法分析
JavaScriptLexer lexer = new JavaScriptLexer(new ANTLRInputStream(input)); JavaScriptLexer lexer = new JavaScriptLexer(new ANTLRInputStream(input));
lexer.setUseStrictDefault(true); lexer.setUseStrictDefault(true);
@ -209,7 +197,7 @@ public class YJSCompiler {
return contract; return contract;
} }
private void handleAnnotation(ContractNode contractNode) { private void handleAnnotation(ContractNode contractNode) throws Exception {
for (AnnotationNode node : contract.annotations) { for (AnnotationNode node : contract.annotations) {
AnnotationProcessor processor = findProcessor(node); AnnotationProcessor processor = findProcessor(node);
if (processor != null) { if (processor != null) {

View File

@ -2,7 +2,8 @@ package org.bdware.sc.compiler.ap;
import org.bdware.sc.bean.DoipOperationInfo; import org.bdware.sc.bean.DoipOperationInfo;
import org.bdware.sc.compiler.AnnotationProcessor; import org.bdware.sc.compiler.AnnotationProcessor;
import org.bdware.sc.engine.hook.DOOPHandler; import org.bdware.sc.engine.hook.DOOPAfterExecHandler;
import org.bdware.sc.engine.hook.DOOPBeforeExecHandler;
import org.bdware.sc.handler.DOOPRequestHandler; import org.bdware.sc.handler.DOOPRequestHandler;
import org.bdware.sc.node.AnnotationNode; import org.bdware.sc.node.AnnotationNode;
import org.bdware.sc.node.ContractNode; import org.bdware.sc.node.ContractNode;
@ -12,7 +13,7 @@ import org.bdware.sc.node.FunctionNode;
// DOOP is designed for DoipModule which contains specific functions for RepositoryHandler // DOOP is designed for DoipModule which contains specific functions for RepositoryHandler
public class DOOP extends AnnotationProcessor { public class DOOP extends AnnotationProcessor {
@Override @Override
public void processFunction(AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) { public void processFunction(AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) throws Exception {
// 通过DOOP注解解析对应的值并放进对应的FunctionNode中 // 通过DOOP注解解析对应的值并放进对应的FunctionNode中
// 注解必须暴露出来昂 // 注解必须暴露出来昂
functionNode.setIsExport(true); functionNode.setIsExport(true);
@ -25,8 +26,10 @@ public class DOOP extends AnnotationProcessor {
DOOPRequestHandler.instance.addDoipOperation(functionNode); DOOPRequestHandler.instance.addDoipOperation(functionNode);
// 维护DOOPHandler // 维护DOOPHandler
DOOPHandler.createDOOPHandler(); DOOPBeforeExecHandler.createDOOPHandler();
DOOPHandler.instance.putFuncNameAndDoipOperationsMapping(functionNode); DOOPBeforeExecHandler.instance.putFuncNameAndDoipOperationsMapping(functionNode);
DOOPAfterExecHandler.createDOOPHandler();
DOOPAfterExecHandler.instance.putFuncNameAndDoipOperationsMapping(functionNode);
// 维护ContractNodefunctionName is useless, use BasicOperation to map the corresponding functionNode // 维护ContractNodefunctionName is useless, use BasicOperation to map the corresponding functionNode
// contractNode.updateFunctionMap(functionNode.functionName, functionNode.getDoipOperationInfo().operationName); // contractNode.updateFunctionMap(functionNode.functionName, functionNode.getDoipOperationInfo().operationName);

View File

@ -1,6 +1,8 @@
package org.bdware.sc.engine; package org.bdware.sc.engine;
import com.google.gson.*; import com.google.gson.*;
import org.bdware.doip.codec.doipMessage.DoipMessage;
import org.bdware.sc.util.JsonUtil;
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror; import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
import wrp.jdk.nashorn.internal.objects.NativeArray; import wrp.jdk.nashorn.internal.objects.NativeArray;
import wrp.jdk.nashorn.internal.runtime.PropertyMap; import wrp.jdk.nashorn.internal.runtime.PropertyMap;
@ -147,7 +149,9 @@ public class JSONTool {
return jsonObject; return jsonObject;
} else if (obj.getClass() == jdk.internal.dynalink.beans.StaticClass.class) { } else if (obj.getClass() == jdk.internal.dynalink.beans.StaticClass.class) {
return JsonNull.INSTANCE; return JsonNull.INSTANCE;
} else if (obj instanceof Number) { } else if (obj.getClass() == DoipMessage.class) {
return JsonUtil.fromJson(JsonUtil.toJson(obj), JsonObject.class);
}else if (obj instanceof Number) {
return new JsonPrimitive((Number) obj); return new JsonPrimitive((Number) obj);
} else if (obj instanceof String) { } else if (obj instanceof String) {
return new JsonPrimitive((String) obj); return new JsonPrimitive((String) obj);

View File

@ -0,0 +1,157 @@
package org.bdware.sc.engine.hook;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.bdware.doip.codec.doipMessage.*;
import org.bdware.doip.codec.operations.BasicOperations;
import org.bdware.sc.JSEngine;
import org.bdware.sc.bean.ContractRequest;
import org.bdware.sc.boundry.ScriptReturnException;
import org.bdware.sc.engine.JSONTool;
import org.bdware.sc.entity.DoipMessagePacker;
import org.bdware.sc.node.AnnotationHook;
import org.bdware.sc.node.ArgPacks;
import org.bdware.sc.node.FunctionNode;
import org.bdware.sc.util.JsonUtil;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class DOOPAfterExecHandler implements AnnotationHook {
public static Map<String, BasicOperations> funcNameToDoipOperations;
public static DOOPAfterExecHandler instance;
public DOOPAfterExecHandler() {
funcNameToDoipOperations = new HashMap<>();
}
public static DOOPAfterExecHandler createDOOPHandler() {
if(instance == null) {
instance = new DOOPAfterExecHandler();
}
return instance;
}
public void putFuncNameAndDoipOperationsMapping(FunctionNode fn) {
String basicOperationsString = fn.getDoipOperationInfo().operationType;
BasicOperations operation = BasicOperations.Unknown;
for(BasicOperations basicOperation : BasicOperations.values()) {
if(basicOperation.toString().equals(basicOperationsString)) {
operation = basicOperation;
}
}
funcNameToDoipOperations.put(fn.getFunctionName(), operation);
}
@Override
public ArgPacks handle(JSEngine desktopEngine, ArgPacks argPacks) {
BasicOperations curOp = funcNameToDoipOperations.get(argPacks.request.getAction());
Object originDoipMsgPacker = argPacks.arg;
DoipMessage originDoipMsg = null;
if (originDoipMsgPacker instanceof DoipMessagePacker) {
DoipMessagePacker doipMessagePacker = (DoipMessagePacker) originDoipMsgPacker;
originDoipMsg = doipMessagePacker.rawDoipMsg;
// if http, directly return
if (doipMessagePacker.source.equals("http")) {
return argPacks;
} else {
// pack
JsonObject jsonObjectRes = JSONTool.convertMirrorToJson(argPacks.ret).getAsJsonObject();
// validate json response
JsonElement jsonResponseRules = getRulesForJsonResponse(curOp);
ArgSchemaVisitor visitor = new ArgSchemaVisitor(jsonObjectRes);
validateJsonElementRulesByArgSchemaVisitor(jsonResponseRules, visitor);
JsonObject header = jsonObjectRes.get("header") != null ? jsonObjectRes.get("header").getAsJsonObject() : null;
String body = jsonObjectRes.get("body") != null ? jsonObjectRes.get("body").getAsString() : null;
// 和HTTP一样所有需要的字段自己封装校验规则也比较简单这里只做简单的包装返回即可
if(header != null) {
originDoipMsg.header = JsonUtil.fromJson(header, MessageHeader.class);
// response字段根据白皮书上的规定处于header下人为包装到parameters的response中
String headerRespCode = header.get("response") != null ? header.get("response").getAsString() : null;
if(headerRespCode != null) {
if (originDoipMsg.header.parameters == null) originDoipMsg.header.parameters = new HeaderParameter(null, null);
originDoipMsg.header.parameters.response = DoipResponseCode.valueOf(headerRespCode);
}
}
if(body != null) {
originDoipMsg.body.encodedData = body.getBytes(StandardCharsets.UTF_8);
}
argPacks.ret = originDoipMsg;
return argPacks;
}
} else {
return argPacks;
}
}
public static JsonElement getRulesForJsonResponse(BasicOperations basicOperations) {
switch (basicOperations) {
case Hello:
case Retrieve:
case Create:
case Update:
case Search:
case ListOps:
return JsonParser.parseString("{\"!header\":{\"!response\":\"string\"}, \"!body\":\"string\"}");
case Delete:
return JsonParser.parseString("{\"!header\":{\"!response\":\"string\"}, \"body\":\"string\"}");
case Extension:
case Unknown:
default:
return null;
}
}
// old convert jsonResponse from argPack's ret to Doip response in doip chain logic
public static DoipMessage convertJsonResponseToDoipMessage(FunctionNode fn, JsonElement jsonResponse, DoipMessage msg) {
BasicOperations curOp = funcNameToDoipOperations.get(fn.getFunctionName());
JsonObject jsonParams = jsonResponse.getAsJsonObject();
// validate json response
JsonElement jsonResponseRules = getRulesForJsonResponse(curOp);
ArgSchemaVisitor visitor = new ArgSchemaVisitor(jsonResponse);
validateJsonElementRulesByArgSchemaVisitor(jsonResponseRules, visitor);
JsonObject header = jsonParams.get("header") != null ? jsonParams.get("header").getAsJsonObject() : null;
String body = jsonParams.get("body") != null ? jsonParams.get("body").getAsString() : null;
if(header != null) {
String headerRespCode = header.get("response") != null ? header.get("response").getAsString() : null;
if(headerRespCode != null) {
for (DoipResponseCode responseCode : DoipResponseCode.values()) {
if(responseCode.toString().equals(headerRespCode)) {
msg.header.parameters.response = responseCode;
break;
}
}
}
}
if(body != null) {
msg.body.encodedData = body.getBytes(StandardCharsets.UTF_8);
}
return msg;
}
public static void validateJsonElementRulesByArgSchemaVisitor(JsonElement jsonElement, ArgSchemaVisitor visitor) {
visitor.visit(jsonElement);
if (!visitor.getStatus()) {
JsonObject jo = new JsonObject();
jo.addProperty("msg", visitor.getException());
jo.addProperty("code", visitor.errorCode);
throw new ScriptReturnException(jo);
}
}
}

View File

@ -5,7 +5,6 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import org.bdware.doip.codec.doipMessage.DoipMessage; import org.bdware.doip.codec.doipMessage.DoipMessage;
import org.bdware.doip.codec.doipMessage.DoipMessageFactory; import org.bdware.doip.codec.doipMessage.DoipMessageFactory;
import org.bdware.doip.codec.doipMessage.DoipResponseCode;
import org.bdware.doip.codec.operations.BasicOperations; import org.bdware.doip.codec.operations.BasicOperations;
import org.bdware.sc.JSEngine; import org.bdware.sc.JSEngine;
import org.bdware.sc.bean.ContractRequest; import org.bdware.sc.bean.ContractRequest;
@ -20,16 +19,16 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
public class DOOPHandler implements AnnotationHook { public class DOOPBeforeExecHandler implements AnnotationHook {
public static Map<String, BasicOperations> funcNameToDoipOperations; public static Map<String, BasicOperations> funcNameToDoipOperations;
public static DOOPHandler instance; public static DOOPBeforeExecHandler instance;
public DOOPHandler() { public DOOPBeforeExecHandler() {
funcNameToDoipOperations = new HashMap<>(); funcNameToDoipOperations = new HashMap<>();
} }
public static DOOPHandler createDOOPHandler() { public static DOOPBeforeExecHandler createDOOPHandler() {
if(instance == null) { if(instance == null) {
instance = new DOOPHandler(); instance = new DOOPBeforeExecHandler();
} }
return instance; return instance;
@ -98,30 +97,12 @@ public class DOOPHandler implements AnnotationHook {
} }
} }
public static JsonElement getRulesForJsonResponse(BasicOperations basicOperations) {
switch (basicOperations) {
case Hello:
case Retrieve:
case Create:
case Update:
case Search:
case ListOps:
return JsonParser.parseString("{\"!header\":{\"!response\":\"string\"}, \"!body\":\"string\"}");
case Delete:
return JsonParser.parseString("{\"!header\":{\"!response\":\"string\"}, \"body\":\"string\"}");
case Extension:
case Unknown:
default:
return null;
}
}
public static DoipMessage convertHttpRequestToDoipMessage(ContractRequest httpReq) { public static DoipMessage convertHttpRequestToDoipMessage(ContractRequest httpReq) {
BasicOperations httpOperation = funcNameToDoipOperations.get(httpReq.getAction()); BasicOperations httpOperation = funcNameToDoipOperations.get(httpReq.getAction());
JsonObject jsonParams = JsonParser.parseString(httpReq.getArg().getAsString()).getAsJsonObject(); JsonObject jsonParams = JsonParser.parseString(httpReq.getArg().getAsString()).getAsJsonObject();
// taking Extension into consideration // taking Extension into consideration
JsonObject header = jsonParams.get("header") != null ? jsonParams.get("header").getAsJsonObject() : null; JsonObject header = jsonParams.get("header") != null ? jsonParams.get("header").getAsJsonObject() : null;
JsonObject body = jsonParams.get("body") != null ? jsonParams.get("body").getAsJsonObject() : null; String body = jsonParams.get("body") != null ? jsonParams.get("body").getAsString() : null;
DoipMessage doipMessage = null; DoipMessage doipMessage = null;
switch(httpOperation) { switch(httpOperation) {
case Hello: case Hello:
@ -133,7 +114,7 @@ public class DOOPHandler implements AnnotationHook {
case Update: case Update:
doipMessage = new DoipMessageFactory.DoipMessageBuilder() doipMessage = new DoipMessageFactory.DoipMessageBuilder()
.createRequest(header.get("identifier").getAsString(), httpOperation.getName()) .createRequest(header.get("identifier").getAsString(), httpOperation.getName())
.setBody(body.getAsString().getBytes(StandardCharsets.UTF_8)) .setBody(body.getBytes(StandardCharsets.UTF_8))
.create(); .create();
break; break;
case Search: case Search:
@ -172,7 +153,7 @@ public class DOOPHandler implements AnnotationHook {
} }
if(body != null) { if(body != null) {
extensionBuilder.setBody(body.getAsString().getBytes(StandardCharsets.UTF_8)); extensionBuilder.setBody(body.getBytes(StandardCharsets.UTF_8));
} }
doipMessage = extensionBuilder.create(); doipMessage = extensionBuilder.create();
@ -185,36 +166,6 @@ public class DOOPHandler implements AnnotationHook {
return doipMessage; return doipMessage;
} }
public static DoipMessage convertJsonResponseToDoipMessage(FunctionNode fn, JsonElement jsonResponse, DoipMessage msg) {
BasicOperations curOp = funcNameToDoipOperations.get(fn.getFunctionName());
JsonObject jsonParams = jsonResponse.getAsJsonObject();
// validate json response
JsonElement jsonResponseRules = getRulesForJsonResponse(curOp);
ArgSchemaVisitor visitor = new ArgSchemaVisitor(jsonResponse);
validateJsonElementRulesByArgSchemaVisitor(jsonResponseRules, visitor);
JsonObject header = jsonParams.get("header") != null ? jsonParams.get("header").getAsJsonObject() : null;
String body = jsonParams.get("body") != null ? jsonParams.get("body").getAsString() : null;
if(header != null) {
String headerRespCode = header.get("response") != null ? header.get("response").getAsString() : null;
if(headerRespCode != null) {
for (DoipResponseCode responseCode : DoipResponseCode.values()) {
if(responseCode.toString().equals(headerRespCode)) {
msg.header.parameters.response = responseCode;
break;
}
}
}
}
if(body != null) {
msg.body.encodedData = body.getBytes(StandardCharsets.UTF_8);
}
return msg;
}
public static void validateJsonElementRulesByArgSchemaVisitor(JsonElement jsonElement, ArgSchemaVisitor visitor) { public static void validateJsonElementRulesByArgSchemaVisitor(JsonElement jsonElement, ArgSchemaVisitor visitor) {
visitor.visit(jsonElement); visitor.visit(jsonElement);

View File

@ -1,18 +1,19 @@
package org.bdware.sc.handler; package org.bdware.sc.handler;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonElement; import com.google.gson.JsonObject;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.bdware.doip.codec.doipMessage.DoipMessage; import org.bdware.doip.codec.doipMessage.DoipMessage;
import org.bdware.doip.codec.doipMessage.HeaderParameter;
import org.bdware.doip.codec.operations.BasicOperations; import org.bdware.doip.codec.operations.BasicOperations;
import org.bdware.doip.endpoint.server.DoipRequestHandler; import org.bdware.doip.endpoint.server.DoipRequestHandler;
import org.bdware.doip.endpoint.server.NettyServerHandler; import org.bdware.doip.endpoint.server.NettyServerHandler;
import org.bdware.doip.endpoint.server.RepositoryHandler; import org.bdware.doip.endpoint.server.RepositoryHandler;
import org.bdware.sc.ContractProcess; import org.bdware.sc.ContractProcess;
import org.bdware.sc.bean.ContractRequest; import org.bdware.sc.bean.ContractRequest;
import org.bdware.sc.engine.hook.DOOPHandler; import org.bdware.sc.boundry.JavaScriptEntry;
import org.bdware.sc.entity.DoipMessagePacker; import org.bdware.sc.entity.DoipMessagePacker;
import org.bdware.sc.node.FunctionNode; import org.bdware.sc.node.FunctionNode;
@ -39,8 +40,12 @@ public class DOOPRequestHandler implements DoipRequestHandler, RepositoryHandler
return instance; return instance;
} }
public void addDoipOperation(FunctionNode function) { public void addDoipOperation(FunctionNode function) throws Exception {
doipFunctionNodeMap.put(function.getDoipOperationInfo().operationName, function); String operationName = function.getDoipOperationInfo().operationName;
if (doipFunctionNodeMap.containsKey(operationName)) {
throw new Exception("Contract is wrong: One DO operation maps multiple functions");
}
doipFunctionNodeMap.put(operationName, function);
} }
@Override @Override
@ -139,7 +144,16 @@ public class DOOPRequestHandler implements DoipRequestHandler, RepositoryHandler
try { try {
// 改变调用的函数 + 构造DoipMessagePacker // 改变调用的函数 + 构造DoipMessagePacker
Object ret = ContractProcess.instance.engine.executeWithoutLock(fn, contractRequest, arg); Object ret = ContractProcess.instance.engine.executeWithoutLock(fn, contractRequest, arg);
return DOOPHandler.convertJsonResponseToDoipMessage(fn, (JsonElement) ret, msg); DoipMessage finalDoipMsg = (DoipMessage) ret;
finalDoipMsg.requestID = msg.requestID;
if(finalDoipMsg.header.parameters == null) {
finalDoipMsg.header.parameters = new HeaderParameter("", "");
}
if(finalDoipMsg.header.parameters.attributes == null) {
finalDoipMsg.header.parameters.attributes = new JsonObject();
}
finalDoipMsg.header.parameters.attributes.addProperty("nodeID", String.valueOf(JavaScriptEntry.shardingID));
return finalDoipMsg;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
logger.error("buildRequestAndInvokeEngine has something wrong, executeWithoutLock err or validateJsonElementRulesByArgSchemaVisitor err"); logger.error("buildRequestAndInvokeEngine has something wrong, executeWithoutLock err or validateJsonElementRulesByArgSchemaVisitor err");

View File

@ -15,6 +15,7 @@ import org.bdware.irp.exception.IrpClientException;
import org.bdware.irp.stateinfo.StateInfoBase; import org.bdware.irp.stateinfo.StateInfoBase;
import org.bdware.sc.ContractProcess; import org.bdware.sc.ContractProcess;
import org.bdware.sc.bean.Contract; import org.bdware.sc.bean.Contract;
import org.bdware.sc.bean.JoinInfo;
import org.bdware.sc.bean.RouteInfo; import org.bdware.sc.bean.RouteInfo;
import org.bdware.sc.handler.DOOPRequestHandler; import org.bdware.sc.handler.DOOPRequestHandler;
import org.bdware.sc.node.ContractNode; import org.bdware.sc.node.ContractNode;
@ -96,15 +97,19 @@ public class DoipClusterServer extends DoipServerImpl {
// doipOperationName和对应的routeFunctionName的对应关系存储方式为doipOperationName: routeFunctionName // doipOperationName和对应的routeFunctionName的对应关系存储方式为doipOperationName: routeFunctionName
JsonObject methodRouteInfoMap = new JsonObject(); JsonObject methodRouteInfoMap = new JsonObject();
// doipOperationName和对应的routeFunctionName的对应关系存储方式为doipOperationName: routeFunctionName
JsonObject methodJoinInfoMap = new JsonObject();
// 所有Router中用得到的函数例如Route函数和Route函数依赖的相关函数 // 所有Router中用得到的函数例如Route函数和Route函数依赖的相关函数
JsonObject functions = new JsonObject(); JsonObject functions = new JsonObject();
// 维护RouteInfo将RouteInfo和doipOperationName的映射关系以及所有Router中用得到的函数都维护好 // 维护RouteInfo将RouteInfo和doipOperationName的映射关系以及所有Router中用得到的函数都维护好
maintainRouteInfo(cn, methodRouteInfoMap, functions); maintainRouteJoinInfo(cn, methodRouteInfoMap, methodJoinInfoMap, functions);
if(clusterInfo != null) repoHandleValues.add("clusterInfo", clusterInfo); if(clusterInfo != null) repoHandleValues.add("clusterInfo", clusterInfo);
if(!functions.equals(new JsonObject())) repoHandleValues.add("functions", functions); if(!functions.equals(new JsonObject())) repoHandleValues.add("functions", functions);
if(!methodRouteInfoMap.equals(new JsonObject())) repoHandleValues.add("routeInfo", methodRouteInfoMap); if(!methodRouteInfoMap.equals(new JsonObject())) repoHandleValues.add("routeInfo", methodRouteInfoMap);
if(!methodJoinInfoMap.equals(new JsonObject())) repoHandleValues.add("joinInfo", methodJoinInfoMap);
repoInfo.handleValues.addProperty("cluster", repoHandleValues.toString()); repoInfo.handleValues.addProperty("cluster", repoHandleValues.toString());
String updateRepoInfoRes = repoIrpClient.reRegister(repoInfo); String updateRepoInfoRes = repoIrpClient.reRegister(repoInfo);
@ -117,7 +122,7 @@ public class DoipClusterServer extends DoipServerImpl {
} }
} }
public void maintainRouteInfo(ContractNode cn, JsonObject methodRouteInfoMap, JsonObject functions) { public void maintainRouteJoinInfo(ContractNode cn, JsonObject methodRouteInfoMap, JsonObject methodJoinInfoMap, JsonObject functions) {
// all functions存了ContractNode中所有的FunctionNode // all functions存了ContractNode中所有的FunctionNode
List<FunctionNode> allFunctions = cn.getFunctions(); List<FunctionNode> allFunctions = cn.getFunctions();
// gson是Gson工具类昂 // gson是Gson工具类昂
@ -128,25 +133,47 @@ public class DoipClusterServer extends DoipServerImpl {
String doipOperationName = doipFunctionNodes.getKey(); String doipOperationName = doipFunctionNodes.getKey();
FunctionNode doipFunctionNode = doipFunctionNodes.getValue(); FunctionNode doipFunctionNode = doipFunctionNodes.getValue();
RouteInfo doipFunctionRouteInfo = doipFunctionNode.getRouteInfo(); RouteInfo doipFunctionRouteInfo = doipFunctionNode.getRouteInfo();
JoinInfo doipFunctionJoinInfo = doipFunctionNode.getJoinInfo();
// 对于routerInfo进行处理对于routeInfo进行维护 // 对于RouterInfo进行维护
if(doipFunctionRouteInfo != null) { if(doipFunctionRouteInfo != null) {
// 建立method和RouteInfo的映射
methodRouteInfoMap.addProperty(doipOperationName, gson.toJson(doipFunctionRouteInfo)); methodRouteInfoMap.addProperty(doipOperationName, gson.toJson(doipFunctionRouteInfo));
if(doipFunctionRouteInfo.funcName != null) { if(doipFunctionRouteInfo.funcName != null) {
String routeFunctionName = doipFunctionRouteInfo.funcName; String routeFunctionName = doipFunctionRouteInfo.funcName;
for(FunctionNode functionNode : allFunctions) { packSourceFunctionAndDependentFunctions(allFunctions, routeFunctionName, functions);
// find Route Function }
if(functionNode.functionName.equals(routeFunctionName)) { }
functions.addProperty(functionNode.functionName, functionNode.plainText());
// add all dependentFunction to the "functions" struct // 对于JoinInfo进行维护
for (String dependentFunctionName : functionNode.getDependentFunctions()) { if(doipFunctionJoinInfo != null) {
for (FunctionNode f : cn.getFunctions()) { // 建立method和JoinInfo的映射
if(f.functionName.equals(dependentFunctionName) && !functions.has(dependentFunctionName)) { methodJoinInfoMap.addProperty(doipOperationName, gson.toJson(doipFunctionJoinInfo));
functions.addProperty(dependentFunctionName, f.plainText()); // 包装JoinInfo中用到的JoinFunction
} if(doipFunctionJoinInfo.joinFuncName != null) {
} String joinFunctionName = doipFunctionJoinInfo.joinFuncName;
} packSourceFunctionAndDependentFunctions(allFunctions, joinFunctionName, functions);
}
// 包装JoinInfo中用到的JoinCountFunction
if(doipFunctionJoinInfo.joinCountFuncName != null) {
String joinFunctionCountName = doipFunctionJoinInfo.joinCountFuncName;
packSourceFunctionAndDependentFunctions(allFunctions, joinFunctionCountName, functions);
}
}
}
}
public void packSourceFunctionAndDependentFunctions(List<FunctionNode> allFunctions, String sourceFunctionName, JsonObject functions) {
for(FunctionNode functionNode : allFunctions) {
// add sourceFunction
if(functionNode.functionName.equals(sourceFunctionName)) {
functions.addProperty(functionNode.functionName, functionNode.plainText());
// find all dependent functions to the "functions" struct
for (String dependentFunctionName : functionNode.getDependentFunctions()) {
for (FunctionNode f : allFunctions) {
if(f.functionName.equals(dependentFunctionName) && !functions.has(dependentFunctionName)) {
functions.addProperty(dependentFunctionName, f.plainText());
} }
} }
} }

View File

@ -67,7 +67,7 @@ public class YJSParserTest {
ContractNode cn = compiler.compile(resource, "rrr.yjs"); ContractNode cn = compiler.compile(resource, "rrr.yjs");
new DesktopEngine(); new DesktopEngine();
System.out.println(new Gson().toJson(cn)); System.out.println(new Gson().toJson(cn));
} catch (IOException e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }