From a35ca147e3d3a2d8280738fa669920240206fb6a Mon Sep 17 00:00:00 2001 From: "haoeliu@foxmail.com" Date: Wed, 9 Nov 2022 19:17:35 +0800 Subject: [PATCH 01/10] resolve merging conflicts --- build.gradle | 16 ++++++++-------- .../java/org/bdware/sc/compiler/ap/DOOP.java | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 src/main/java/org/bdware/sc/compiler/ap/DOOP.java diff --git a/build.gradle b/build.gradle index f8c490a..0f61c2d 100644 --- a/build.gradle +++ b/build.gradle @@ -172,18 +172,18 @@ publishing { maven { name 'bdwareSnapshotRepository' url 'https://oss.sonatype.org/content/repositories/snapshots' - credentials { - username = "${NEXUS_USERNAME}" - password = "${NEXUS_PASSWORD}" - } +// credentials { +// username = "${NEXUS_USERNAME}" +// password = "${NEXUS_PASSWORD}" +// } } maven { name 'bdwareRepository' url 'https://oss.sonatype.org/service/local/staging/deploy/maven2' - credentials { - username = "${NEXUS_USERNAME}" - password = "${NEXUS_PASSWORD}" - } +// credentials { +// username = "${NEXUS_USERNAME}" +// password = "${NEXUS_PASSWORD}" +// } } } } diff --git a/src/main/java/org/bdware/sc/compiler/ap/DOOP.java b/src/main/java/org/bdware/sc/compiler/ap/DOOP.java new file mode 100644 index 0000000..d0d546d --- /dev/null +++ b/src/main/java/org/bdware/sc/compiler/ap/DOOP.java @@ -0,0 +1,18 @@ +package org.bdware.sc.compiler.ap; + +import org.bdware.doip.codec.operations.BasicOperations; +import org.bdware.sc.compiler.AnnotationProcessor; +import org.bdware.sc.node.AnnotationNode; +import org.bdware.sc.node.ContractNode; +import org.bdware.sc.node.FunctionNode; + +import java.util.HashMap; +import java.util.Map; + +// DOOP is designed for DoipModule which contains specific functions for RepositoryHandler +public class DOOP extends AnnotationProcessor { + @Override + public void processFunction(AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) { + + } +} From 65aa9fd78dcd60155a3b303f77777b0a22b85499 Mon Sep 17 00:00:00 2001 From: "haoeliu@foxmail.com" Date: Tue, 15 Nov 2022 11:47:26 +0800 Subject: [PATCH 02/10] add first version DOOPRequestHandler --- .../java/org/bdware/sc/compiler/ap/DOOP.java | 9 ++- .../sc/handler/DOOPRepositoryHandler.java | 71 ++++++++++++++++ .../bdware/sc/handler/DOOPRequestHandler.java | 81 +++++++++++++++++++ .../org/bdware/sc/server/DOOPDoipServer.java | 65 +++++++++++++++ 4 files changed, 222 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/bdware/sc/handler/DOOPRepositoryHandler.java create mode 100644 src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java create mode 100644 src/main/java/org/bdware/sc/server/DOOPDoipServer.java diff --git a/src/main/java/org/bdware/sc/compiler/ap/DOOP.java b/src/main/java/org/bdware/sc/compiler/ap/DOOP.java index d0d546d..806a2f7 100644 --- a/src/main/java/org/bdware/sc/compiler/ap/DOOP.java +++ b/src/main/java/org/bdware/sc/compiler/ap/DOOP.java @@ -1,18 +1,19 @@ package org.bdware.sc.compiler.ap; -import org.bdware.doip.codec.operations.BasicOperations; +import org.bdware.sc.bean.DoipOperationInfo; import org.bdware.sc.compiler.AnnotationProcessor; import org.bdware.sc.node.AnnotationNode; import org.bdware.sc.node.ContractNode; import org.bdware.sc.node.FunctionNode; -import java.util.HashMap; -import java.util.Map; // DOOP is designed for DoipModule which contains specific functions for RepositoryHandler public class DOOP extends AnnotationProcessor { @Override public void processFunction(AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) { - + // 通过DOOP注解,解析对应的值,并放进对应的FunctionNode中 + functionNode.setDoipOperationInfo(DoipOperationInfo.create(anno, contractNode)); + // 维护DoipOperation维 + contractNode.addDoipOperation(functionNode); } } diff --git a/src/main/java/org/bdware/sc/handler/DOOPRepositoryHandler.java b/src/main/java/org/bdware/sc/handler/DOOPRepositoryHandler.java new file mode 100644 index 0000000..f67df99 --- /dev/null +++ b/src/main/java/org/bdware/sc/handler/DOOPRepositoryHandler.java @@ -0,0 +1,71 @@ +package org.bdware.sc.handler; + +import com.google.gson.JsonPrimitive; +import org.bdware.doip.codec.doipMessage.DoipMessage; +import org.bdware.doip.codec.operations.BasicOperations; +import org.bdware.doip.endpoint.server.RepositoryHandler; +import org.bdware.sc.ContractProcess; +import org.bdware.sc.ContractResult; +import org.bdware.sc.node.ContractNode; +import org.bdware.sc.node.FunctionNode; +import org.bdware.sc.node.YjsType; + +public class DOOPRepositoryHandler implements RepositoryHandler { + private ContractNode cn; + private boolean isDoipModule; + + public DOOPRepositoryHandler(ContractNode cn) { + if(cn.getYjsType() == YjsType.DoipModule) { + isDoipModule = true; + this.cn = cn; + } + } + + @Override + public DoipMessage handleHello(DoipMessage request) { + FunctionNode fn = cn.getDoipOperation(BasicOperations.Hello); + ContractProcess.instance.executeContract(""); + return null; + } + + @Override + public DoipMessage handleListOps(DoipMessage request) { + FunctionNode fn = cn.getDoipOperation(BasicOperations.ListOps); + + return null; + } + + @Override + public DoipMessage handleCreate(DoipMessage request) { + FunctionNode fn = cn.getDoipOperation(BasicOperations.Create); + return null; + } + + @Override + public DoipMessage handleUpdate(DoipMessage request) { + FunctionNode fn = cn.getDoipOperation(BasicOperations.Update); + return null; + } + + @Override + public DoipMessage handleDelete(DoipMessage request) { + FunctionNode fn = cn.getDoipOperation(BasicOperations.Delete); + return null; + } + + @Override + public DoipMessage handleRetrieve(DoipMessage request) { + FunctionNode fn = cn.getDoipOperation(BasicOperations.Retrieve); + return null; + } + + private ContractResult invokeFunction(FunctionNode fun, BasicOperations basicOperation) { + if (fun == null) { + return new ContractResult( + ContractResult.Status.Exception, + new JsonPrimitive("DoipOperation " + basicOperation + " is not exists")); + } + + return null; + } +} diff --git a/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java b/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java new file mode 100644 index 0000000..3130380 --- /dev/null +++ b/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java @@ -0,0 +1,81 @@ +package org.bdware.sc.handler; + +import io.netty.channel.ChannelHandlerContext; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bdware.doip.codec.doipMessage.DoipMessage; +import org.bdware.doip.codec.operations.BasicOperations; +import org.bdware.doip.endpoint.server.DoipRequestHandler; +import org.bdware.doip.endpoint.server.NettyServerHandler; +import org.bdware.doip.endpoint.server.Op; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +public class DOOPRequestHandler implements DoipRequestHandler { + Map handlers; + static Logger logger = LogManager.getLogger(NettyServerHandler.class); + protected DOOPRepositoryHandler doopRepoHandler; + + public DOOPRequestHandler(DOOPRepositoryHandler doopRepoHandler) { + handlers = new HashMap<>(); + this.doopRepoHandler = doopRepoHandler; + Class handlerClass = doopRepoHandler.getClass(); + + // 建立doopRepoHandler这个类中,方法名和对应的Method的对应关系 + while (handlerClass != Object.class) { + putDoipHandlerMethod(handlerClass); + Class[] interfaces = handlerClass.getInterfaces(); + for (Class clz : interfaces) { + putDoipHandlerMethod(clz); + } + handlerClass = handlerClass.getSuperclass(); + } + } + + private void putDoipHandlerMethod(Class handlerClass) { + Method[] methods = handlerClass.getDeclaredMethods(); + for (Method m : methods) { + Op a = m.getAnnotation(Op.class); + if (a != null) { +// logger.debug("method annotation: " + a.op().getName()); +// logger.debug("method annotation: " + a.name()); + if (a.op() != BasicOperations.Extension) { + putHandler(a.op().getName(), m); + } else { + putHandler(a.name(), m); + } + } + } + } + + private void putHandler(String name, Method m) { + if (handlers.containsKey(name)) { +// logger.error("Duplicated operation handler:" + name + " methodName:" + m.getName()); + return; + } + logger.debug("[Register operation] name: " + name); + m.setAccessible(true); + handlers.put(name, m); + } + + @Override + public DoipMessage onRequest(ChannelHandlerContext ctx, DoipMessage msg) { + String str = msg.header.parameters.operation; + logger.debug("[Call operation] name: " + str); + if (str != null) { + Method m; + m = handlers.get(str); + if (m == null) m = handlers.get(BasicOperations.Unknown.getName()); + if (m != null) { + try { + return (DoipMessage) m.invoke(doopRepoHandler, msg); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return null; + } +} diff --git a/src/main/java/org/bdware/sc/server/DOOPDoipServer.java b/src/main/java/org/bdware/sc/server/DOOPDoipServer.java new file mode 100644 index 0000000..fe0db45 --- /dev/null +++ b/src/main/java/org/bdware/sc/server/DOOPDoipServer.java @@ -0,0 +1,65 @@ +package org.bdware.sc.server; + +import org.bdware.doip.audit.EndpointConfig; +import org.bdware.doip.audit.EndpointInfo; +import org.bdware.doip.audit.client.AuditIrpClient; +import org.bdware.doip.audit.server.AuditRequestHandler; +import org.bdware.doip.audit.writer.ConfigurableAuditConfig; +import org.bdware.doip.endpoint.server.DoipListenerConfig; +import org.bdware.doip.endpoint.server.DoipServerImpl; +import org.bdware.doip.endpoint.server.DoipServiceInfo; +import org.bdware.doip.endpoint.server.RepositoryHandler; +import org.bdware.sc.ContractProcess; +import org.bdware.sc.handler.DOOPRepositoryHandler; +import org.bdware.sc.handler.DOOPRequestHandler; +import org.bdware.sc.node.ContractNode; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +import static org.bdware.doip.audit.EndpointConfig.defaultDOIPServerPort; +import static org.bdware.doip.audit.EndpointConfig.defaultRepoType; + +public class DOOPDoipServer extends DoipServerImpl { + private final ConfigurableAuditConfig auditConfig; + EndpointConfig config; + static AuditIrpClient irpClient; + + + public DOOPDoipServer(EndpointConfig config) { + super(resolveInfo(config)); + this.config = config; + this.auditConfig = irpClient.getAuditConfig(); + } + + private static DoipServiceInfo resolveInfo(EndpointConfig config) { + irpClient = new AuditIrpClient(config); + EndpointInfo info = irpClient.getEndpointInfo(); + if (info == null) { + String content = "{\"date\":\"2022-1-13\",\"name\":\"testrepoforaibd\",\"doId\":\"bdware.test.local/Repo\",\"address\":\"tcp://127.0.0.1:" + defaultDOIPServerPort + "\",\"status\":\"已审核\",\"protocol\":\"DOIP\",\"pubKey\":\"empty\",\"version\":\"2.1\"}"; + info = EndpointInfo.fromJson(content); + } + List infos = new ArrayList<>(); + try { + infos.add(new DoipListenerConfig(info.getURI(), info.getVersion())); + } catch (Exception e) { + e.printStackTrace(); + } + DoipServiceInfo ret = new DoipServiceInfo(info.getDoId(), info.getPubKey(), defaultRepoType, infos); + return ret; + } + + @Override + public void setRepositoryHandler(RepositoryHandler handler) { + Class clz = DoipServerImpl.class; + Field f = null; + try { + f = clz.getDeclaredField("requestCallback"); + f.setAccessible(true); +// f.set(this, new DOOPRequestHandler(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} From 9686de6ba9a48a4e412af65ce637558b435efa88 Mon Sep 17 00:00:00 2001 From: "haoeliu@foxmail.com" Date: Wed, 16 Nov 2022 14:58:26 +0800 Subject: [PATCH 03/10] add doipOperationMap in DOOPRequestHandler and merge DOOPRepoHandler --- .../java/org/bdware/sc/compiler/ap/DOOP.java | 17 ++- .../sc/handler/DOOPRepositoryHandler.java | 71 ---------- .../bdware/sc/handler/DOOPRequestHandler.java | 127 +++++++++++------- .../org/bdware/sc/server/DOOPDoipServer.java | 5 - 4 files changed, 97 insertions(+), 123 deletions(-) delete mode 100644 src/main/java/org/bdware/sc/handler/DOOPRepositoryHandler.java diff --git a/src/main/java/org/bdware/sc/compiler/ap/DOOP.java b/src/main/java/org/bdware/sc/compiler/ap/DOOP.java index 806a2f7..6529401 100644 --- a/src/main/java/org/bdware/sc/compiler/ap/DOOP.java +++ b/src/main/java/org/bdware/sc/compiler/ap/DOOP.java @@ -1,19 +1,32 @@ package org.bdware.sc.compiler.ap; +import org.bdware.doip.codec.operations.BasicOperations; import org.bdware.sc.bean.DoipOperationInfo; import org.bdware.sc.compiler.AnnotationProcessor; +import org.bdware.sc.handler.DOOPRequestHandler; import org.bdware.sc.node.AnnotationNode; import org.bdware.sc.node.ContractNode; import org.bdware.sc.node.FunctionNode; +import java.util.List; + // DOOP is designed for DoipModule which contains specific functions for RepositoryHandler public class DOOP extends AnnotationProcessor { @Override public void processFunction(AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) { // 通过DOOP注解,解析对应的值,并放进对应的FunctionNode中 + // 注解必须暴露出来昂!!! + functionNode.setIsExport(true); functionNode.setDoipOperationInfo(DoipOperationInfo.create(anno, contractNode)); - // 维护DoipOperation维 - contractNode.addDoipOperation(functionNode); + + // 维护DOOPRequestHandler + if(DOOPRequestHandler.instance == null) { + new DOOPRequestHandler(); + } + DOOPRequestHandler.instance.addDoipOperation(functionNode); + + // 维护ContractNode,functionName is useless, use BasicOperation to map the corresponding functionNode + contractNode.updateFunctionMap(functionNode.functionName, functionNode.getDoipOperationInfo().operationType.toString()); } } diff --git a/src/main/java/org/bdware/sc/handler/DOOPRepositoryHandler.java b/src/main/java/org/bdware/sc/handler/DOOPRepositoryHandler.java deleted file mode 100644 index f67df99..0000000 --- a/src/main/java/org/bdware/sc/handler/DOOPRepositoryHandler.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.bdware.sc.handler; - -import com.google.gson.JsonPrimitive; -import org.bdware.doip.codec.doipMessage.DoipMessage; -import org.bdware.doip.codec.operations.BasicOperations; -import org.bdware.doip.endpoint.server.RepositoryHandler; -import org.bdware.sc.ContractProcess; -import org.bdware.sc.ContractResult; -import org.bdware.sc.node.ContractNode; -import org.bdware.sc.node.FunctionNode; -import org.bdware.sc.node.YjsType; - -public class DOOPRepositoryHandler implements RepositoryHandler { - private ContractNode cn; - private boolean isDoipModule; - - public DOOPRepositoryHandler(ContractNode cn) { - if(cn.getYjsType() == YjsType.DoipModule) { - isDoipModule = true; - this.cn = cn; - } - } - - @Override - public DoipMessage handleHello(DoipMessage request) { - FunctionNode fn = cn.getDoipOperation(BasicOperations.Hello); - ContractProcess.instance.executeContract(""); - return null; - } - - @Override - public DoipMessage handleListOps(DoipMessage request) { - FunctionNode fn = cn.getDoipOperation(BasicOperations.ListOps); - - return null; - } - - @Override - public DoipMessage handleCreate(DoipMessage request) { - FunctionNode fn = cn.getDoipOperation(BasicOperations.Create); - return null; - } - - @Override - public DoipMessage handleUpdate(DoipMessage request) { - FunctionNode fn = cn.getDoipOperation(BasicOperations.Update); - return null; - } - - @Override - public DoipMessage handleDelete(DoipMessage request) { - FunctionNode fn = cn.getDoipOperation(BasicOperations.Delete); - return null; - } - - @Override - public DoipMessage handleRetrieve(DoipMessage request) { - FunctionNode fn = cn.getDoipOperation(BasicOperations.Retrieve); - return null; - } - - private ContractResult invokeFunction(FunctionNode fun, BasicOperations basicOperation) { - if (fun == null) { - return new ContractResult( - ContractResult.Status.Exception, - new JsonPrimitive("DoipOperation " + basicOperation + " is not exists")); - } - - return null; - } -} diff --git a/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java b/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java index 3130380..a40af26 100644 --- a/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java +++ b/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java @@ -1,5 +1,7 @@ package org.bdware.sc.handler; +import com.google.gson.Gson; +import com.google.gson.JsonElement; import io.netty.channel.ChannelHandlerContext; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -7,57 +9,33 @@ import org.bdware.doip.codec.doipMessage.DoipMessage; import org.bdware.doip.codec.operations.BasicOperations; import org.bdware.doip.endpoint.server.DoipRequestHandler; import org.bdware.doip.endpoint.server.NettyServerHandler; -import org.bdware.doip.endpoint.server.Op; +import org.bdware.doip.endpoint.server.RepositoryHandler; +import org.bdware.sc.ContractProcess; +import org.bdware.sc.ContractResult; +import org.bdware.sc.bean.ContractRequest; +import org.bdware.sc.node.FunctionNode; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; -public class DOOPRequestHandler implements DoipRequestHandler { - Map handlers; +public class DOOPRequestHandler implements DoipRequestHandler, RepositoryHandler { + public Map doipOperationsMap; static Logger logger = LogManager.getLogger(NettyServerHandler.class); - protected DOOPRepositoryHandler doopRepoHandler; + Gson gson; - public DOOPRequestHandler(DOOPRepositoryHandler doopRepoHandler) { - handlers = new HashMap<>(); - this.doopRepoHandler = doopRepoHandler; - Class handlerClass = doopRepoHandler.getClass(); + public static DOOPRequestHandler instance; - // 建立doopRepoHandler这个类中,方法名和对应的Method的对应关系 - while (handlerClass != Object.class) { - putDoipHandlerMethod(handlerClass); - Class[] interfaces = handlerClass.getInterfaces(); - for (Class clz : interfaces) { - putDoipHandlerMethod(clz); - } - handlerClass = handlerClass.getSuperclass(); + public DOOPRequestHandler() { + if(instance == null) { + instance = new DOOPRequestHandler(); + instance.doipOperationsMap = new HashMap<>(); + gson = new Gson(); } } - private void putDoipHandlerMethod(Class handlerClass) { - Method[] methods = handlerClass.getDeclaredMethods(); - for (Method m : methods) { - Op a = m.getAnnotation(Op.class); - if (a != null) { -// logger.debug("method annotation: " + a.op().getName()); -// logger.debug("method annotation: " + a.name()); - if (a.op() != BasicOperations.Extension) { - putHandler(a.op().getName(), m); - } else { - putHandler(a.name(), m); - } - } - } - } - - private void putHandler(String name, Method m) { - if (handlers.containsKey(name)) { -// logger.error("Duplicated operation handler:" + name + " methodName:" + m.getName()); - return; - } - logger.debug("[Register operation] name: " + name); - m.setAccessible(true); - handlers.put(name, m); + public void addDoipOperation(FunctionNode function) { + doipOperationsMap.put(function.getDoipOperationInfo().operationType.getName(), function); } @Override @@ -65,12 +43,14 @@ public class DOOPRequestHandler implements DoipRequestHandler { String str = msg.header.parameters.operation; logger.debug("[Call operation] name: " + str); if (str != null) { - Method m; - m = handlers.get(str); - if (m == null) m = handlers.get(BasicOperations.Unknown.getName()); - if (m != null) { + FunctionNode fn; + fn = doipOperationsMap.get(str); + if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName()); + if (fn != null) { try { - return (DoipMessage) m.invoke(doopRepoHandler, msg); + ContractRequest contractRequest = constructContractRequest(fn, msg); + ContractResult res = ContractProcess.instance.engine.executeContract(contractRequest); + return gson.fromJson(res.toString(), DoipMessage.class); } catch (Exception e) { e.printStackTrace(); } @@ -78,4 +58,61 @@ public class DOOPRequestHandler implements DoipRequestHandler { } return null; } + + @Override + public DoipMessage handleHello(DoipMessage request) { + FunctionNode fn = doipOperationsMap.get(BasicOperations.Hello.getName()); + ContractRequest cr = constructContractRequest(fn, request); + JsonElement res = ContractProcess.instance.engine.executeContract(cr).result; + return gson.fromJson(res.toString(), DoipMessage.class); + } + + @Override + public DoipMessage handleListOps(DoipMessage request) { + FunctionNode fn = doipOperationsMap.get(BasicOperations.ListOps.getName()); + ContractRequest cr = constructContractRequest(fn, request); + JsonElement res = ContractProcess.instance.engine.executeContract(cr).result; + return gson.fromJson(res.toString(), DoipMessage.class); + } + + @Override + public DoipMessage handleCreate(DoipMessage request) { + FunctionNode fn = doipOperationsMap.get(BasicOperations.Create.getName()); + ContractRequest cr = constructContractRequest(fn, request); + JsonElement res = ContractProcess.instance.engine.executeContract(cr).result; + return gson.fromJson(res.toString(), DoipMessage.class); + } + + @Override + public DoipMessage handleUpdate(DoipMessage request) { + FunctionNode fn = doipOperationsMap.get(BasicOperations.Update.getName()); + ContractRequest cr = constructContractRequest(fn, request); + JsonElement res = ContractProcess.instance.engine.executeContract(cr).result; + return gson.fromJson(res.toString(), DoipMessage.class); + } + + @Override + public DoipMessage handleDelete(DoipMessage request) { + FunctionNode fn = doipOperationsMap.get(BasicOperations.Delete.getName()); + ContractRequest cr = constructContractRequest(fn, request); + JsonElement res = ContractProcess.instance.engine.executeContract(cr).result; + return gson.fromJson(res.toString(), DoipMessage.class); + } + + @Override + public DoipMessage handleRetrieve(DoipMessage request) { + FunctionNode fn = doipOperationsMap.get(BasicOperations.Retrieve.getName()); + ContractRequest cr = constructContractRequest(fn, request); + JsonElement res = ContractProcess.instance.engine.executeContract(cr).result; + return gson.fromJson(res.toString(), DoipMessage.class); + } + + public ContractRequest constructContractRequest(FunctionNode fn, DoipMessage request) { + ContractRequest cr = new ContractRequest(); + cr.setContractID(""); + cr.setRequester(""); + cr.setAction(""); + cr.setArg(""); + return cr; + } } diff --git a/src/main/java/org/bdware/sc/server/DOOPDoipServer.java b/src/main/java/org/bdware/sc/server/DOOPDoipServer.java index fe0db45..b509bc3 100644 --- a/src/main/java/org/bdware/sc/server/DOOPDoipServer.java +++ b/src/main/java/org/bdware/sc/server/DOOPDoipServer.java @@ -3,16 +3,11 @@ package org.bdware.sc.server; import org.bdware.doip.audit.EndpointConfig; import org.bdware.doip.audit.EndpointInfo; import org.bdware.doip.audit.client.AuditIrpClient; -import org.bdware.doip.audit.server.AuditRequestHandler; import org.bdware.doip.audit.writer.ConfigurableAuditConfig; import org.bdware.doip.endpoint.server.DoipListenerConfig; import org.bdware.doip.endpoint.server.DoipServerImpl; import org.bdware.doip.endpoint.server.DoipServiceInfo; import org.bdware.doip.endpoint.server.RepositoryHandler; -import org.bdware.sc.ContractProcess; -import org.bdware.sc.handler.DOOPRepositoryHandler; -import org.bdware.sc.handler.DOOPRequestHandler; -import org.bdware.sc.node.ContractNode; import java.lang.reflect.Field; import java.util.ArrayList; From 24c0673b9b7bc1537ad5457f6fbabccc5e8dc427 Mon Sep 17 00:00:00 2001 From: "haoeliu@foxmail.com" Date: Sun, 27 Nov 2022 18:54:50 +0800 Subject: [PATCH 04/10] finish the draft version --- .../java/org/bdware/sc/ContractProcess.java | 11 ++ .../java/org/bdware/sc/compiler/ap/DOOP.java | 3 +- .../org/bdware/sc/engine/DesktopEngine.java | 28 ++--- .../java/org/bdware/sc/engine/JSONTool.java | 8 ++ .../bdware/sc/engine/hook/DOOPHandler.java | 101 ++++++++++++++++++ .../bdware/sc/entity/DoipMessagePacker.java | 25 +++++ .../bdware/sc/handler/DOOPRequestHandler.java | 81 ++++++++------ .../org/bdware/sc/server/DOOPDoipServer.java | 60 ----------- .../org/bdware/sc/server/DoipServerTest.java | 43 ++++++++ 9 files changed, 256 insertions(+), 104 deletions(-) create mode 100644 src/main/java/org/bdware/sc/engine/hook/DOOPHandler.java create mode 100644 src/main/java/org/bdware/sc/entity/DoipMessagePacker.java delete mode 100644 src/main/java/org/bdware/sc/server/DOOPDoipServer.java create mode 100644 src/main/java/org/bdware/sc/server/DoipServerTest.java diff --git a/src/main/java/org/bdware/sc/ContractProcess.java b/src/main/java/org/bdware/sc/ContractProcess.java index ac3eea1..a9875d4 100644 --- a/src/main/java/org/bdware/sc/ContractProcess.java +++ b/src/main/java/org/bdware/sc/ContractProcess.java @@ -32,6 +32,7 @@ import org.bdware.sc.engine.hook.*; import org.bdware.sc.handler.ContractHandler; import org.bdware.sc.index.TimeSerialIndex; import org.bdware.sc.node.*; +import org.bdware.sc.server.DoipServerTest; import org.bdware.sc.trace.ProgramPointCounter; import org.bdware.sc.util.FileUtil; import org.bdware.sc.util.HashUtil; @@ -559,6 +560,10 @@ public class ContractProcess { fun.appendBeforeInvokeHandler(argSchemaHandler); } + if (fun.isDoipOperation()) { + fun.appendBeforeInvokeHandler(new DOOPHandler()); + } + if (fun.isExport()) { //if(fun.annotations...) fun.appendAfterInvokeHandler(new ObjToJsonHandler()); @@ -643,6 +648,12 @@ public class ContractProcess { jo.add("loadContract", JsonUtil.parseObject(ret)); jo.addProperty("status", ret.status.merge(onCreate.status).toString()); LOGGER.debug("result: " + jo.toString()); + + // doipModule的话,拉起DoipServer服务端口 + if(cn.getYjsType() == YjsType.DoipModule) { + DoipServerTest.main(new String[]{"8080"}); + } + return jo.toString(); } catch (Exception e) { ByteArrayOutputStream bo = new ByteArrayOutputStream(); diff --git a/src/main/java/org/bdware/sc/compiler/ap/DOOP.java b/src/main/java/org/bdware/sc/compiler/ap/DOOP.java index 6529401..a24446d 100644 --- a/src/main/java/org/bdware/sc/compiler/ap/DOOP.java +++ b/src/main/java/org/bdware/sc/compiler/ap/DOOP.java @@ -18,6 +18,7 @@ public class DOOP extends AnnotationProcessor { // 通过DOOP注解,解析对应的值,并放进对应的FunctionNode中 // 注解必须暴露出来昂!!! functionNode.setIsExport(true); + functionNode.setIsDoipOperation(true); functionNode.setDoipOperationInfo(DoipOperationInfo.create(anno, contractNode)); // 维护DOOPRequestHandler @@ -27,6 +28,6 @@ public class DOOP extends AnnotationProcessor { DOOPRequestHandler.instance.addDoipOperation(functionNode); // 维护ContractNode,functionName is useless, use BasicOperation to map the corresponding functionNode - contractNode.updateFunctionMap(functionNode.functionName, functionNode.getDoipOperationInfo().operationType.toString()); + contractNode.updateFunctionMap(functionNode.functionName, functionNode.getDoipOperationInfo().operationName); } } diff --git a/src/main/java/org/bdware/sc/engine/DesktopEngine.java b/src/main/java/org/bdware/sc/engine/DesktopEngine.java index 080b50a..7d7fe5d 100644 --- a/src/main/java/org/bdware/sc/engine/DesktopEngine.java +++ b/src/main/java/org/bdware/sc/engine/DesktopEngine.java @@ -518,10 +518,10 @@ public class DesktopEngine extends JSEngine { input.getRequester().startsWith("event"))) { Object ret; if (fun.isView()) { - ret = executeWithoutLock(fun, input); + ret = executeWithoutLock(fun, input, null); } else { synchronized (this) { - ret = executeWithoutLock(fun, input); + ret = executeWithoutLock(fun, input, null); } } @@ -606,21 +606,25 @@ public class DesktopEngine extends JSEngine { } - private Object executeWithoutLock(FunctionNode fun, ContractRequest input) throws ScriptException, NoSuchMethodException { - Object ret = null; + public Object executeWithoutLock(FunctionNode fun, ContractRequest input, Object injectedArg) throws ScriptException, NoSuchMethodException { // long start = System.currentTimeMillis(); - - for (AnnotationHook handler : fun.beforeExecutionAnnotations()) { - ret = handler.handle(this, new ArgPacks(input, input.getArg(), ret)); + ArgPacks argPack = new ArgPacks(input, input.getArg(), null); + if(injectedArg != null) { + argPack.arg = injectedArg; } + for (AnnotationHook handler : fun.beforeExecutionAnnotations()) { + argPack = handler.handle(this, argPack); + } + // actually invoke! - if (ret == null) { - ret = + // todo 这里invoke应该如何调用,改了一行代码正确吗?input.getArg() -> argPack.arg + if (argPack.ret == null) { + argPack.ret = engine.invokeFunction( input.getAction(), (fun.isHandler() ? JsonUtil.fromJson(input.getArg(), Event.class) - : JSONTool.convertJsonElementToMirror(input.getArg())), + : JSONTool.convertJsonElementToMirror(argPack.arg)), input.getRequester(), input.getRequesterDOI()); } @@ -628,9 +632,9 @@ public class DesktopEngine extends JSEngine { //Mask在after裏面 //System.out.println("afterHook"+contract.Mask); - ret = handler.handle(this, new ArgPacks(input, input.getArg(), ret)); + argPack = handler.handle(this, argPack); } - return ret; + return argPack.ret; } private String extractException(String msg, List stack) { diff --git a/src/main/java/org/bdware/sc/engine/JSONTool.java b/src/main/java/org/bdware/sc/engine/JSONTool.java index cccf9f9..5577b7d 100644 --- a/src/main/java/org/bdware/sc/engine/JSONTool.java +++ b/src/main/java/org/bdware/sc/engine/JSONTool.java @@ -40,6 +40,14 @@ public class JSONTool { return null; } + public static Object convertJsonElementToMirror(Object input) { + if(input instanceof JsonElement) { + return convertJsonElementToMirror((JsonElement) input); + } else { + return input; + } + } + private static JsonElement convertMirrorToJsonInternal(Object obj, Set recorded) { if (recorded.contains(obj)) return JsonNull.INSTANCE; if (obj == null) return JsonNull.INSTANCE; diff --git a/src/main/java/org/bdware/sc/engine/hook/DOOPHandler.java b/src/main/java/org/bdware/sc/engine/hook/DOOPHandler.java new file mode 100644 index 0000000..3d0addb --- /dev/null +++ b/src/main/java/org/bdware/sc/engine/hook/DOOPHandler.java @@ -0,0 +1,101 @@ +package org.bdware.sc.engine.hook; + +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import org.bdware.doip.codec.doipMessage.DoipMessage; +import org.bdware.doip.codec.doipMessage.DoipMessageFactory; +import org.bdware.doip.codec.doipMessage.DoipResponseCode; +import org.bdware.doip.codec.operations.BasicOperations; +import org.bdware.sc.JSEngine; +import org.bdware.sc.bean.ContractRequest; +import org.bdware.sc.entity.DoipMessagePacker; +import org.bdware.sc.node.AnnotationHook; +import org.bdware.sc.node.AnnotationNode; +import org.bdware.sc.node.ArgPacks; +import org.bdware.sc.node.FunctionNode; + +import java.nio.charset.StandardCharsets; + +public class DOOPHandler implements AnnotationHook { + public DOOPHandler() { + + } + + public static DOOPHandler fromAnnotationNode(FunctionNode funNode, AnnotationNode annoNode) { + return new DOOPHandler(); + } + + @Override + public ArgPacks handle(JSEngine desktopEngine, ArgPacks argPacks) { + Object arg = argPacks.arg; + DoipMessagePacker doipMsgPackerArg = new DoipMessagePacker(); + + if (arg instanceof DoipMessagePacker){ + doipMsgPackerArg = (DoipMessagePacker)arg; + } else { + // validate http request's params + ContractRequest httpReq = argPacks.request; + validateHTTPRequestArgs(httpReq); + + // set doipMsgPackerArg struct's params + doipMsgPackerArg.setSource("http"); + doipMsgPackerArg.rawDoipMsg = convertContractRequestToDoipMessage(httpReq); + } + + argPacks.arg = doipMsgPackerArg; + return argPacks; + } + + public static void validateHTTPRequestArgs(ContractRequest httpReq) { + JsonElement httpArgs = httpReq.getArg(); + BasicOperations curOp = BasicOperations.getDoOp(httpReq.getAction()); + + // get args rules and validate http args + JsonElement httpArgsRules = getRulesForBasicOperation(curOp); + ArgSchemaVisitor visitor = new ArgSchemaVisitor(httpArgs); + visitor.visit(httpArgsRules); + } + + public static JsonElement getRulesForBasicOperation(BasicOperations basicOperation) { + + switch(basicOperation) { + case Hello: + return JsonParser.parseString("{\"!doid\":\"string\"}"); + case Retrieve: + return JsonParser.parseString("{\"!doid\":\"string\", \"!element\":\"boolean\"}"); + default: + return null; + } + } + + public static DoipMessage convertContractRequestToDoipMessage(ContractRequest httpReq) { + BasicOperations httpOperation = BasicOperations.getDoOp(httpReq.getAction()); + DoipMessage doipMessage = new DoipMessageFactory.DoipMessageBuilder().createRequest("", httpReq.getAction()).create(); + switch(httpOperation) { + case Hello: + doipMessage = new DoipMessageFactory.DoipMessageBuilder().createRequest(httpReq.getArg().getAsJsonObject().get("doid").getAsString(), httpReq.getAction()).create(); + break; + case Retrieve: + DoipMessageFactory.DoipMessageBuilder msgBuilder = new DoipMessageFactory.DoipMessageBuilder().createRequest(httpReq.getArg().getAsJsonObject().get("doid").getAsString(), httpReq.getAction()); + msgBuilder = msgBuilder.addAttributes("element", httpReq.getArg().getAsJsonObject().get("element").getAsString()); + doipMessage = msgBuilder.create(); + break; + } + + return doipMessage; + } + + public static DoipMessage convertJsonElementToDoipMessage(JsonElement jsonElementRet, DoipMessage msg) { + DoipMessageFactory.DoipMessageBuilder builder = new DoipMessageFactory.DoipMessageBuilder(); + + String responseCodeStr = jsonElementRet.getAsJsonObject().get("doipResponseCode").getAsString(); + DoipResponseCode responseCode = DoipResponseCode.UnKnownError; + for (DoipResponseCode resp : DoipResponseCode.values()) { + if (resp.toString().equals(responseCodeStr)) responseCode = resp; + } + + DoipMessage doipRet = builder.createResponse(responseCode, msg).create();; + doipRet.body.encodedData = jsonElementRet.getAsJsonObject().get("body").getAsJsonObject().get("encodedData").getAsString().getBytes(StandardCharsets.UTF_8); + return doipRet; + } +} diff --git a/src/main/java/org/bdware/sc/entity/DoipMessagePacker.java b/src/main/java/org/bdware/sc/entity/DoipMessagePacker.java new file mode 100644 index 0000000..691f970 --- /dev/null +++ b/src/main/java/org/bdware/sc/entity/DoipMessagePacker.java @@ -0,0 +1,25 @@ +package org.bdware.sc.entity; + +import org.bdware.doip.codec.doipMessage.DoipMessage; + +public class DoipMessagePacker { + // the DoipMessagePacker is raised by http/doip + public String source; + // the well-composed DoipMessage + public DoipMessage rawDoipMsg; + + public DoipMessagePacker() {} + + public DoipMessagePacker(String source, DoipMessage rawMsg) { + this.source = source; + this.rawDoipMsg = rawMsg; + } + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } +} diff --git a/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java b/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java index a40af26..72f0f97 100644 --- a/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java +++ b/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java @@ -11,11 +11,11 @@ import org.bdware.doip.endpoint.server.DoipRequestHandler; import org.bdware.doip.endpoint.server.NettyServerHandler; import org.bdware.doip.endpoint.server.RepositoryHandler; import org.bdware.sc.ContractProcess; -import org.bdware.sc.ContractResult; import org.bdware.sc.bean.ContractRequest; +import org.bdware.sc.engine.hook.DOOPHandler; +import org.bdware.sc.entity.DoipMessagePacker; import org.bdware.sc.node.FunctionNode; -import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; @@ -35,7 +35,7 @@ public class DOOPRequestHandler implements DoipRequestHandler, RepositoryHandler } public void addDoipOperation(FunctionNode function) { - doipOperationsMap.put(function.getDoipOperationInfo().operationType.getName(), function); + doipOperationsMap.put(function.getDoipOperationInfo().operationName, function); } @Override @@ -47,13 +47,7 @@ public class DOOPRequestHandler implements DoipRequestHandler, RepositoryHandler fn = doipOperationsMap.get(str); if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName()); if (fn != null) { - try { - ContractRequest contractRequest = constructContractRequest(fn, msg); - ContractResult res = ContractProcess.instance.engine.executeContract(contractRequest); - return gson.fromJson(res.toString(), DoipMessage.class); - } catch (Exception e) { - e.printStackTrace(); - } + return buildRequestAndInvokeEngine(fn, msg); } } return null; @@ -62,57 +56,82 @@ public class DOOPRequestHandler implements DoipRequestHandler, RepositoryHandler @Override public DoipMessage handleHello(DoipMessage request) { FunctionNode fn = doipOperationsMap.get(BasicOperations.Hello.getName()); - ContractRequest cr = constructContractRequest(fn, request); - JsonElement res = ContractProcess.instance.engine.executeContract(cr).result; - return gson.fromJson(res.toString(), DoipMessage.class); + if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName()); + if (fn != null) { + return buildRequestAndInvokeEngine(fn, request); + } + return null; } @Override public DoipMessage handleListOps(DoipMessage request) { FunctionNode fn = doipOperationsMap.get(BasicOperations.ListOps.getName()); - ContractRequest cr = constructContractRequest(fn, request); - JsonElement res = ContractProcess.instance.engine.executeContract(cr).result; - return gson.fromJson(res.toString(), DoipMessage.class); + if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName()); + if (fn != null) { + return buildRequestAndInvokeEngine(fn, request); + } + return null; } @Override public DoipMessage handleCreate(DoipMessage request) { FunctionNode fn = doipOperationsMap.get(BasicOperations.Create.getName()); - ContractRequest cr = constructContractRequest(fn, request); - JsonElement res = ContractProcess.instance.engine.executeContract(cr).result; - return gson.fromJson(res.toString(), DoipMessage.class); + if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName()); + if (fn != null) { + return buildRequestAndInvokeEngine(fn, request); + } + return null; } @Override public DoipMessage handleUpdate(DoipMessage request) { FunctionNode fn = doipOperationsMap.get(BasicOperations.Update.getName()); - ContractRequest cr = constructContractRequest(fn, request); - JsonElement res = ContractProcess.instance.engine.executeContract(cr).result; - return gson.fromJson(res.toString(), DoipMessage.class); + if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName()); + if (fn != null) { + return buildRequestAndInvokeEngine(fn, request); + } + return null; } @Override public DoipMessage handleDelete(DoipMessage request) { FunctionNode fn = doipOperationsMap.get(BasicOperations.Delete.getName()); - ContractRequest cr = constructContractRequest(fn, request); - JsonElement res = ContractProcess.instance.engine.executeContract(cr).result; - return gson.fromJson(res.toString(), DoipMessage.class); + if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName()); + if (fn != null) { + return buildRequestAndInvokeEngine(fn, request); + } + return null; } @Override public DoipMessage handleRetrieve(DoipMessage request) { FunctionNode fn = doipOperationsMap.get(BasicOperations.Retrieve.getName()); - ContractRequest cr = constructContractRequest(fn, request); - JsonElement res = ContractProcess.instance.engine.executeContract(cr).result; - return gson.fromJson(res.toString(), DoipMessage.class); + if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName()); + if (fn != null) { + return buildRequestAndInvokeEngine(fn, request); + } + return null; + } + + public DoipMessage buildRequestAndInvokeEngine(FunctionNode fn, DoipMessage msg) { + ContractRequest contractRequest = constructContractRequest(fn, msg); + DoipMessagePacker arg = new DoipMessagePacker("doip", msg); + try { + // 改变调用的函数 + 构造DoipMessagePacker + Object ret = ContractProcess.instance.engine.executeWithoutLock(fn, contractRequest, arg); + return DOOPHandler.convertJsonElementToDoipMessage((JsonElement) ret, msg); + } catch (Exception e) { + e.printStackTrace(); + } + + return null; } public ContractRequest constructContractRequest(FunctionNode fn, DoipMessage request) { ContractRequest cr = new ContractRequest(); cr.setContractID(""); - cr.setRequester(""); - cr.setAction(""); - cr.setArg(""); + cr.setRequester(request.credential.getSigner()); + cr.setAction(fn.functionName); return cr; } } diff --git a/src/main/java/org/bdware/sc/server/DOOPDoipServer.java b/src/main/java/org/bdware/sc/server/DOOPDoipServer.java deleted file mode 100644 index b509bc3..0000000 --- a/src/main/java/org/bdware/sc/server/DOOPDoipServer.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.bdware.sc.server; - -import org.bdware.doip.audit.EndpointConfig; -import org.bdware.doip.audit.EndpointInfo; -import org.bdware.doip.audit.client.AuditIrpClient; -import org.bdware.doip.audit.writer.ConfigurableAuditConfig; -import org.bdware.doip.endpoint.server.DoipListenerConfig; -import org.bdware.doip.endpoint.server.DoipServerImpl; -import org.bdware.doip.endpoint.server.DoipServiceInfo; -import org.bdware.doip.endpoint.server.RepositoryHandler; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; - -import static org.bdware.doip.audit.EndpointConfig.defaultDOIPServerPort; -import static org.bdware.doip.audit.EndpointConfig.defaultRepoType; - -public class DOOPDoipServer extends DoipServerImpl { - private final ConfigurableAuditConfig auditConfig; - EndpointConfig config; - static AuditIrpClient irpClient; - - - public DOOPDoipServer(EndpointConfig config) { - super(resolveInfo(config)); - this.config = config; - this.auditConfig = irpClient.getAuditConfig(); - } - - private static DoipServiceInfo resolveInfo(EndpointConfig config) { - irpClient = new AuditIrpClient(config); - EndpointInfo info = irpClient.getEndpointInfo(); - if (info == null) { - String content = "{\"date\":\"2022-1-13\",\"name\":\"testrepoforaibd\",\"doId\":\"bdware.test.local/Repo\",\"address\":\"tcp://127.0.0.1:" + defaultDOIPServerPort + "\",\"status\":\"已审核\",\"protocol\":\"DOIP\",\"pubKey\":\"empty\",\"version\":\"2.1\"}"; - info = EndpointInfo.fromJson(content); - } - List infos = new ArrayList<>(); - try { - infos.add(new DoipListenerConfig(info.getURI(), info.getVersion())); - } catch (Exception e) { - e.printStackTrace(); - } - DoipServiceInfo ret = new DoipServiceInfo(info.getDoId(), info.getPubKey(), defaultRepoType, infos); - return ret; - } - - @Override - public void setRepositoryHandler(RepositoryHandler handler) { - Class clz = DoipServerImpl.class; - Field f = null; - try { - f = clz.getDeclaredField("requestCallback"); - f.setAccessible(true); -// f.set(this, new DOOPRequestHandler(); - } catch (Exception e) { - e.printStackTrace(); - } - } -} diff --git a/src/main/java/org/bdware/sc/server/DoipServerTest.java b/src/main/java/org/bdware/sc/server/DoipServerTest.java new file mode 100644 index 0000000..ff56911 --- /dev/null +++ b/src/main/java/org/bdware/sc/server/DoipServerTest.java @@ -0,0 +1,43 @@ +package org.bdware.sc.server; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bdware.doip.endpoint.server.DoipListenerConfig; +import org.bdware.doip.endpoint.server.DoipServerImpl; +import org.bdware.doip.endpoint.server.DoipServiceInfo; +import org.bdware.sc.handler.DOOPRequestHandler; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +public class DoipServerTest { + static Logger LOGGER = LogManager.getLogger(DoipServerTest.class); + + public static void main(String[] arg) throws InterruptedException { + int port = 21042; + if (arg != null && arg.length > 0) { + port = Integer.parseInt(arg[0]); + } + run(port); + } + + public static void run(int port) throws InterruptedException { + List infos = new ArrayList<>(); + try { + infos.add(new DoipListenerConfig("tcp://127.0.0.1:" + port, "2.1")); + } catch (Exception e) { + e.printStackTrace(); + } + DoipServiceInfo info = new DoipServiceInfo("aibd.govdata.tj/do.3f9c41e6-9f8e-48a0-9220-53f438d40e43", "ownerDEF", "gateRepo", infos); + DoipServerImpl server = new DoipServerImpl(info); + final AtomicInteger count = new AtomicInteger(0); + DOOPRequestHandler handler = new DOOPRequestHandler(); + server.setRepositoryHandler(handler); + server.start(); + for (; ; ) { + LOGGER.info("Count:" + count.get()); + Thread.sleep(10000); + } + } +} From 9477ff8a31c4b5e7674f695cac0978cc20d2b37d Mon Sep 17 00:00:00 2001 From: "haoeliu@foxmail.com" Date: Tue, 29 Nov 2022 15:17:57 +0800 Subject: [PATCH 05/10] update test version --- build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 1aa5e24..94f3268 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ plugins { } group = "org.bdware.sc" -version = "1.7.1" +version = "2.0.0" repositories { mavenCentral() mavenLocal() @@ -61,8 +61,8 @@ jar { // uncomment this when publish, //while develop at local use "false" configurations.runtimeClasspath.filter { - it.getAbsolutePath().contains("/lib/") - // false +// it.getAbsolutePath().contains("/lib/") + false }.collect { it.isDirectory() ? it : zipTree(it) } From 76a8e3ca58e987df40fc0c265d1f7c867c131454 Mon Sep 17 00:00:00 2001 From: "haoeliu@foxmail.com" Date: Tue, 29 Nov 2022 15:22:44 +0800 Subject: [PATCH 06/10] fix the conflicts in build.gradle --- build.gradle | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 9f9a47c..952ae7d 100644 --- a/build.gradle +++ b/build.gradle @@ -6,11 +6,8 @@ plugins { } group = "org.bdware.sc" -<<<<<<< HEAD version = "2.0.0" -======= -version = "1.7.2" ->>>>>>> origin/master + repositories { mavenCentral() mavenLocal() From a1b59cfbfdd771242fa0e8d899e822a7a92fd23f Mon Sep 17 00:00:00 2001 From: "haoeliu@foxmail.com" Date: Fri, 2 Dec 2022 16:39:11 +0800 Subject: [PATCH 07/10] finish the local version --- .../java/org/bdware/sc/ContractProcess.java | 10 +++- .../java/org/bdware/sc/compiler/ap/DOOP.java | 12 +++-- .../bdware/sc/engine/hook/DOOPHandler.java | 48 +++++++++++++---- .../bdware/sc/handler/DOOPRequestHandler.java | 17 ++++-- .../org/bdware/sc/server/DoipServerTest.java | 21 +++++--- .../java/org/bdware/doip/DoipClientTest.java | 52 +++++++++++++++++++ 6 files changed, 135 insertions(+), 25 deletions(-) create mode 100644 src/test/java/org/bdware/doip/DoipClientTest.java diff --git a/src/main/java/org/bdware/sc/ContractProcess.java b/src/main/java/org/bdware/sc/ContractProcess.java index c58cbbf..b0a8703 100644 --- a/src/main/java/org/bdware/sc/ContractProcess.java +++ b/src/main/java/org/bdware/sc/ContractProcess.java @@ -3,6 +3,7 @@ package org.bdware.sc; import com.google.gson.*; import com.google.gson.reflect.TypeToken; import com.google.gson.stream.MalformedJsonException; +import groovy.util.logging.Log; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.config.Configurator; import org.bdware.analysis.BasicBlock; @@ -518,6 +519,12 @@ public class ContractProcess { jo.add("loadContract", JsonUtil.parseObject(result)); jo.addProperty("status", result.status.merge(onCreate.status).toString()); LOGGER.debug("result: " + jo.toString()); + + if(cn.getYjsType() == YjsType.DoipModule) { + LOGGER.info("the doipServer has started"); + DoipServerTest.main(new String[]{"8080"}); + } + return jo.toString(); } else { contract.setScript(FileUtil.getFileContent(zipPath)); @@ -560,7 +567,7 @@ public class ContractProcess { } if (fun.isDoipOperation()) { - fun.appendBeforeInvokeHandler(new DOOPHandler()); + fun.appendBeforeInvokeHandler(DOOPHandler.createDOOPHandler()); } if (fun.isExport()) { @@ -654,6 +661,7 @@ public class ContractProcess { // doipModule的话,拉起DoipServer服务端口 if(cn.getYjsType() == YjsType.DoipModule) { + LOGGER.info("the doipServer has started"); DoipServerTest.main(new String[]{"8080"}); } diff --git a/src/main/java/org/bdware/sc/compiler/ap/DOOP.java b/src/main/java/org/bdware/sc/compiler/ap/DOOP.java index a24446d..d5e5037 100644 --- a/src/main/java/org/bdware/sc/compiler/ap/DOOP.java +++ b/src/main/java/org/bdware/sc/compiler/ap/DOOP.java @@ -3,6 +3,7 @@ package org.bdware.sc.compiler.ap; import org.bdware.doip.codec.operations.BasicOperations; import org.bdware.sc.bean.DoipOperationInfo; import org.bdware.sc.compiler.AnnotationProcessor; +import org.bdware.sc.engine.hook.DOOPHandler; import org.bdware.sc.handler.DOOPRequestHandler; import org.bdware.sc.node.AnnotationNode; import org.bdware.sc.node.ContractNode; @@ -20,14 +21,17 @@ public class DOOP extends AnnotationProcessor { functionNode.setIsExport(true); functionNode.setIsDoipOperation(true); functionNode.setDoipOperationInfo(DoipOperationInfo.create(anno, contractNode)); + // functionNode.setFunctionName(functionNode.getDoipOperationInfo().operationName); // 维护DOOPRequestHandler - if(DOOPRequestHandler.instance == null) { - new DOOPRequestHandler(); - } + DOOPRequestHandler.createHandler(); DOOPRequestHandler.instance.addDoipOperation(functionNode); + // 维护DOOPHandler + DOOPHandler.createDOOPHandler(); + DOOPHandler.instance.putFuncNameAndDoipOperationsMapping(functionNode); + // 维护ContractNode,functionName is useless, use BasicOperation to map the corresponding functionNode - contractNode.updateFunctionMap(functionNode.functionName, functionNode.getDoipOperationInfo().operationName); + // contractNode.updateFunctionMap(functionNode.functionName, functionNode.getDoipOperationInfo().operationName); } } diff --git a/src/main/java/org/bdware/sc/engine/hook/DOOPHandler.java b/src/main/java/org/bdware/sc/engine/hook/DOOPHandler.java index 3d0addb..b9fbb70 100644 --- a/src/main/java/org/bdware/sc/engine/hook/DOOPHandler.java +++ b/src/main/java/org/bdware/sc/engine/hook/DOOPHandler.java @@ -1,6 +1,7 @@ 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.DoipMessage; import org.bdware.doip.codec.doipMessage.DoipMessageFactory; @@ -8,21 +9,40 @@ import org.bdware.doip.codec.doipMessage.DoipResponseCode; 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.entity.DoipMessagePacker; import org.bdware.sc.node.AnnotationHook; -import org.bdware.sc.node.AnnotationNode; import org.bdware.sc.node.ArgPacks; import org.bdware.sc.node.FunctionNode; import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; public class DOOPHandler implements AnnotationHook { + public static Map funcNameToDoipOperations; + public static DOOPHandler instance; public DOOPHandler() { - + funcNameToDoipOperations = new HashMap<>(); } - public static DOOPHandler fromAnnotationNode(FunctionNode funNode, AnnotationNode annoNode) { - return new DOOPHandler(); + public static DOOPHandler createDOOPHandler() { + if(instance == null) { + instance = new DOOPHandler(); + } + + 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 @@ -47,13 +67,20 @@ public class DOOPHandler implements AnnotationHook { } public static void validateHTTPRequestArgs(ContractRequest httpReq) { - JsonElement httpArgs = httpReq.getArg(); - BasicOperations curOp = BasicOperations.getDoOp(httpReq.getAction()); + JsonElement originArgs = httpReq.getArg(); + JsonElement httpArgs = JsonParser.parseString(originArgs.getAsString()); + BasicOperations curOp = funcNameToDoipOperations.get(httpReq.getAction()); // get args rules and validate http args JsonElement httpArgsRules = getRulesForBasicOperation(curOp); ArgSchemaVisitor visitor = new ArgSchemaVisitor(httpArgs); visitor.visit(httpArgsRules); + if (!visitor.getStatus()) { + JsonObject jo = new JsonObject(); + jo.addProperty("msg", visitor.getException()); + jo.addProperty("code", visitor.errorCode); + throw new ScriptReturnException(jo); + } } public static JsonElement getRulesForBasicOperation(BasicOperations basicOperation) { @@ -69,15 +96,16 @@ public class DOOPHandler implements AnnotationHook { } public static DoipMessage convertContractRequestToDoipMessage(ContractRequest httpReq) { - BasicOperations httpOperation = BasicOperations.getDoOp(httpReq.getAction()); + BasicOperations httpOperation = funcNameToDoipOperations.get(httpReq.getAction()); + JsonObject jsonParams = JsonParser.parseString(httpReq.getArg().getAsString()).getAsJsonObject(); DoipMessage doipMessage = new DoipMessageFactory.DoipMessageBuilder().createRequest("", httpReq.getAction()).create(); switch(httpOperation) { case Hello: - doipMessage = new DoipMessageFactory.DoipMessageBuilder().createRequest(httpReq.getArg().getAsJsonObject().get("doid").getAsString(), httpReq.getAction()).create(); + doipMessage = new DoipMessageFactory.DoipMessageBuilder().createRequest(jsonParams.get("doid").getAsString(), httpReq.getAction()).create(); break; case Retrieve: - DoipMessageFactory.DoipMessageBuilder msgBuilder = new DoipMessageFactory.DoipMessageBuilder().createRequest(httpReq.getArg().getAsJsonObject().get("doid").getAsString(), httpReq.getAction()); - msgBuilder = msgBuilder.addAttributes("element", httpReq.getArg().getAsJsonObject().get("element").getAsString()); + DoipMessageFactory.DoipMessageBuilder msgBuilder = new DoipMessageFactory.DoipMessageBuilder().createRequest(jsonParams.get("doid").getAsString(), httpReq.getAction()); + msgBuilder = msgBuilder.addAttributes("element", jsonParams.get("element").getAsString()); doipMessage = msgBuilder.create(); break; } diff --git a/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java b/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java index 72f0f97..bb00c37 100644 --- a/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java +++ b/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java @@ -22,16 +22,21 @@ import java.util.Map; public class DOOPRequestHandler implements DoipRequestHandler, RepositoryHandler { public Map doipOperationsMap; static Logger logger = LogManager.getLogger(NettyServerHandler.class); - Gson gson; + static Gson gson; public static DOOPRequestHandler instance; public DOOPRequestHandler() { + doipOperationsMap = new HashMap<>(); + gson = new Gson(); + } + + public static DOOPRequestHandler createHandler() { if(instance == null) { instance = new DOOPRequestHandler(); - instance.doipOperationsMap = new HashMap<>(); - gson = new Gson(); } + + return instance; } public void addDoipOperation(FunctionNode function) { @@ -130,7 +135,11 @@ public class DOOPRequestHandler implements DoipRequestHandler, RepositoryHandler public ContractRequest constructContractRequest(FunctionNode fn, DoipMessage request) { ContractRequest cr = new ContractRequest(); cr.setContractID(""); - cr.setRequester(request.credential.getSigner()); + if(request.credential == null) { + cr.setRequester(null); + } else { + cr.setRequester(request.credential.getSigner()); + } cr.setAction(fn.functionName); return cr; } diff --git a/src/main/java/org/bdware/sc/server/DoipServerTest.java b/src/main/java/org/bdware/sc/server/DoipServerTest.java index ff56911..b14ebbc 100644 --- a/src/main/java/org/bdware/sc/server/DoipServerTest.java +++ b/src/main/java/org/bdware/sc/server/DoipServerTest.java @@ -15,11 +15,20 @@ public class DoipServerTest { static Logger LOGGER = LogManager.getLogger(DoipServerTest.class); public static void main(String[] arg) throws InterruptedException { - int port = 21042; - if (arg != null && arg.length > 0) { - port = Integer.parseInt(arg[0]); - } - run(port); + final int port = (arg.length == 0 ? 21042 : Integer.parseInt(arg[0])); + + Thread doipServerThread = new Thread(){ + @Override + public void run() { + try { + DoipServerTest.run(port); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }; + + doipServerThread.start(); } public static void run(int port) throws InterruptedException { @@ -32,7 +41,7 @@ public class DoipServerTest { DoipServiceInfo info = new DoipServiceInfo("aibd.govdata.tj/do.3f9c41e6-9f8e-48a0-9220-53f438d40e43", "ownerDEF", "gateRepo", infos); DoipServerImpl server = new DoipServerImpl(info); final AtomicInteger count = new AtomicInteger(0); - DOOPRequestHandler handler = new DOOPRequestHandler(); + DOOPRequestHandler handler = DOOPRequestHandler.createHandler(); server.setRepositoryHandler(handler); server.start(); for (; ; ) { diff --git a/src/test/java/org/bdware/doip/DoipClientTest.java b/src/test/java/org/bdware/doip/DoipClientTest.java new file mode 100644 index 0000000..da9ae56 --- /dev/null +++ b/src/test/java/org/bdware/doip/DoipClientTest.java @@ -0,0 +1,52 @@ +package org.bdware.doip; + +import org.bdware.doip.codec.doipMessage.DoipMessage; +import org.bdware.doip.endpoint.client.ClientConfig; +import org.bdware.doip.endpoint.client.DoipClientImpl; +import org.bdware.doip.endpoint.client.DoipMessageCallback; +import org.junit.Test; + +import java.util.concurrent.atomic.AtomicInteger; + + +public class DoipClientTest { + long start = System.currentTimeMillis(); + final AtomicInteger total = new AtomicInteger(0); + final AtomicInteger correct = new AtomicInteger(0); + int totalCount = 10000; + + @Test + public void doipClientTest(){ + long start = System.currentTimeMillis(); + final AtomicInteger total = new AtomicInteger(0); + final AtomicInteger correct = new AtomicInteger(0); + int totalCount = 1; + for (int i = 0; i < totalCount; i++) { + final DoipClientImpl doipClient = new DoipClientImpl(); + doipClient.connect(ClientConfig.fromUrl("tcp://127.0.0.1:8080")); + doipClient.retrieve("aibd/do.e626924a-3b1c-492f-9a41-59179bfe0361", null, true, new DoipMessageCallback() { + @Override + public void onResult(DoipMessage msg) { + String str = new String(msg.body.encodedData); + System.out.println("Result is " + str); + //LOGGER.info("Retrieved:" + str + //+ " respCode:" + msg.header.parameters.response); + total.incrementAndGet(); + if (str.contains("aaa")) + correct.incrementAndGet(); + if (doipClient != null) doipClient.close(); + } + }); + } + int circle = 0; + for (; total.get() < totalCount; ) { + if (++circle % 100 == 0) { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } +} From 51ee18928b2ffeb2daf1e8fd0758c9d3b6420151 Mon Sep 17 00:00:00 2001 From: "haoeliu@foxmail.com" Date: Tue, 6 Dec 2022 21:31:08 +0800 Subject: [PATCH 08/10] finish the http input validation --- .../java/org/bdware/sc/ContractProcess.java | 1 - .../java/org/bdware/sc/compiler/ap/DOOP.java | 3 - .../bdware/sc/engine/hook/DOOPHandler.java | 92 ++++++++++++++++--- .../bdware/sc/handler/DOOPRequestHandler.java | 2 +- .../java/org/bdware/doip/DoipClientTest.java | 42 +++++++-- 5 files changed, 115 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/bdware/sc/ContractProcess.java b/src/main/java/org/bdware/sc/ContractProcess.java index b0a8703..4aeb587 100644 --- a/src/main/java/org/bdware/sc/ContractProcess.java +++ b/src/main/java/org/bdware/sc/ContractProcess.java @@ -3,7 +3,6 @@ package org.bdware.sc; import com.google.gson.*; import com.google.gson.reflect.TypeToken; import com.google.gson.stream.MalformedJsonException; -import groovy.util.logging.Log; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.config.Configurator; import org.bdware.analysis.BasicBlock; diff --git a/src/main/java/org/bdware/sc/compiler/ap/DOOP.java b/src/main/java/org/bdware/sc/compiler/ap/DOOP.java index d5e5037..4f67f9c 100644 --- a/src/main/java/org/bdware/sc/compiler/ap/DOOP.java +++ b/src/main/java/org/bdware/sc/compiler/ap/DOOP.java @@ -1,6 +1,5 @@ package org.bdware.sc.compiler.ap; -import org.bdware.doip.codec.operations.BasicOperations; import org.bdware.sc.bean.DoipOperationInfo; import org.bdware.sc.compiler.AnnotationProcessor; import org.bdware.sc.engine.hook.DOOPHandler; @@ -9,8 +8,6 @@ import org.bdware.sc.node.AnnotationNode; import org.bdware.sc.node.ContractNode; import org.bdware.sc.node.FunctionNode; -import java.util.List; - // DOOP is designed for DoipModule which contains specific functions for RepositoryHandler public class DOOP extends AnnotationProcessor { diff --git a/src/main/java/org/bdware/sc/engine/hook/DOOPHandler.java b/src/main/java/org/bdware/sc/engine/hook/DOOPHandler.java index b9fbb70..4064e95 100644 --- a/src/main/java/org/bdware/sc/engine/hook/DOOPHandler.java +++ b/src/main/java/org/bdware/sc/engine/hook/DOOPHandler.java @@ -18,6 +18,7 @@ import org.bdware.sc.node.FunctionNode; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; +import java.util.Set; public class DOOPHandler implements AnnotationHook { public static Map funcNameToDoipOperations; @@ -59,7 +60,7 @@ public class DOOPHandler implements AnnotationHook { // set doipMsgPackerArg struct's params doipMsgPackerArg.setSource("http"); - doipMsgPackerArg.rawDoipMsg = convertContractRequestToDoipMessage(httpReq); + doipMsgPackerArg.rawDoipMsg = httpInputConvertContractRequestToDoipMessage(httpReq); } argPacks.arg = doipMsgPackerArg; @@ -72,7 +73,7 @@ public class DOOPHandler implements AnnotationHook { BasicOperations curOp = funcNameToDoipOperations.get(httpReq.getAction()); // get args rules and validate http args - JsonElement httpArgsRules = getRulesForBasicOperation(curOp); + JsonElement httpArgsRules = getRulesForHTTPRequest(curOp); ArgSchemaVisitor visitor = new ArgSchemaVisitor(httpArgs); visitor.visit(httpArgsRules); if (!visitor.getStatus()) { @@ -83,37 +84,102 @@ public class DOOPHandler implements AnnotationHook { } } - public static JsonElement getRulesForBasicOperation(BasicOperations basicOperation) { - + public static JsonElement getRulesForHTTPRequest(BasicOperations basicOperation) { switch(basicOperation) { case Hello: - return JsonParser.parseString("{\"!doid\":\"string\"}"); + case Delete: + case ListOps: + return JsonParser.parseString("{\"!header\":{{\"!identifier\":\"string\"}}}"); case Retrieve: - return JsonParser.parseString("{\"!doid\":\"string\", \"!element\":\"boolean\"}"); + return JsonParser.parseString("{\"!header\":{\"!identifier\":\"string\", \"attributes\":{\"element\":\"string\", \"includeElementData\":\"boolean\"}}}"); + case Create: + return JsonParser.parseString("{\"!header\":{\"!identifier\":\"string\", \"attributes\":{\"element\":\"string\", \"includeElementData\":\"boolean\"}}, \"!body\":\"string\"}"); + case Update: + return JsonParser.parseString("{\"!header\":{{\"!identifier\":\"string\"}}, \"!body\":\"string\"}"); + case Search: + return JsonParser.parseString("{\"!header\":{\"!identifier\":\"string\", \"attributes\":{\"query\":\"string\", \"pageNum\":\"int\", \"pageSize\":\"int\", \"type\":\"string\"}}}"); + case Extension: + case Unknown: default: return null; } } - public static DoipMessage convertContractRequestToDoipMessage(ContractRequest httpReq) { + public static DoipMessage httpInputConvertContractRequestToDoipMessage(ContractRequest httpReq) { BasicOperations httpOperation = funcNameToDoipOperations.get(httpReq.getAction()); JsonObject jsonParams = JsonParser.parseString(httpReq.getArg().getAsString()).getAsJsonObject(); - DoipMessage doipMessage = new DoipMessageFactory.DoipMessageBuilder().createRequest("", httpReq.getAction()).create(); + // taking Extension into consideration + JsonObject header = jsonParams.get("header") != null ? jsonParams.get("header").getAsJsonObject() : null; + JsonObject body = jsonParams.get("body") != null ? jsonParams.get("body").getAsJsonObject() : null; + DoipMessage doipMessage = null; switch(httpOperation) { case Hello: - doipMessage = new DoipMessageFactory.DoipMessageBuilder().createRequest(jsonParams.get("doid").getAsString(), httpReq.getAction()).create(); + case Delete: + case ListOps: + doipMessage = new DoipMessageFactory.DoipMessageBuilder().createRequest(header.get("identifier").getAsString(), httpReq.getAction()).create(); break; case Retrieve: - DoipMessageFactory.DoipMessageBuilder msgBuilder = new DoipMessageFactory.DoipMessageBuilder().createRequest(jsonParams.get("doid").getAsString(), httpReq.getAction()); - msgBuilder = msgBuilder.addAttributes("element", jsonParams.get("element").getAsString()); - doipMessage = msgBuilder.create(); + doipMessage = new DoipMessageFactory.DoipMessageBuilder().createRequest(header.get("identifier").getAsString(), httpReq.getAction()).create(); + JsonElement element = header.get("element"); + JsonElement includeElementData = header.get("includeElementData"); + if(element != null) doipMessage.header.parameters.addAttribute("element", element.getAsString()); + if(includeElementData != null) doipMessage.header.parameters.addAttribute("includeElementData", includeElementData.getAsBoolean()); + break; + case Create: + doipMessage = new DoipMessageFactory.DoipMessageBuilder() + .createRequest(header.get("identifier").getAsString(), BasicOperations.Create.getName()) + .setBody(body.getAsString().getBytes(StandardCharsets.UTF_8)) + .create(); + break; + case Update: + doipMessage = new DoipMessageFactory.DoipMessageBuilder() + .createRequest(header.get("identifier").getAsString(), BasicOperations.Update.getName()) + .setBody(body.getAsString().getBytes(StandardCharsets.UTF_8)) + .create(); + break; + case Search: + DoipMessageFactory.DoipMessageBuilder searchBuilder = new DoipMessageFactory.DoipMessageBuilder() + .createRequest(header.get("identifier").getAsString(), BasicOperations.Search.getName()); + JsonElement query = header.get("query"); + if(query != null) searchBuilder.addAttributes("query", query.getAsString()); + JsonElement pageNum = header.get("pageNum"); + if(pageNum != null) searchBuilder.addAttributes("pageNum", pageNum.getAsInt()); + JsonElement pageSize = header.get("pageSize"); + if(pageSize != null) searchBuilder.addAttributes("pageSize", pageSize.getAsInt()); + JsonElement type = header.get("type"); + if(type != null) searchBuilder.addAttributes("type", type.getAsString()); + + doipMessage = searchBuilder.create(); + break; + case Extension: + DoipMessageFactory.DoipMessageBuilder extensionBuilder = new DoipMessageFactory.DoipMessageBuilder(); + if(header != null) { + if(header.get("identifier") != null) { + extensionBuilder = extensionBuilder + .createRequest(header.get("identifier").getAsString(), BasicOperations.Extension.getName()); + } + + Set> entries = header.entrySet(); + for (Map.Entry entry : entries) { + extensionBuilder.addAttributes(entry.getKey(), entry.getValue()); + } + } + + if(body != null) { + extensionBuilder.setBody(body.getAsString().getBytes(StandardCharsets.UTF_8)); + } + + doipMessage = extensionBuilder.create(); + break; + case Unknown: + default: break; } return doipMessage; } - public static DoipMessage convertJsonElementToDoipMessage(JsonElement jsonElementRet, DoipMessage msg) { + public static DoipMessage doipOuputConvertJsonElementToDoipMessage(JsonElement jsonElementRet, DoipMessage msg) { DoipMessageFactory.DoipMessageBuilder builder = new DoipMessageFactory.DoipMessageBuilder(); String responseCodeStr = jsonElementRet.getAsJsonObject().get("doipResponseCode").getAsString(); diff --git a/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java b/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java index bb00c37..59096de 100644 --- a/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java +++ b/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java @@ -124,7 +124,7 @@ public class DOOPRequestHandler implements DoipRequestHandler, RepositoryHandler try { // 改变调用的函数 + 构造DoipMessagePacker Object ret = ContractProcess.instance.engine.executeWithoutLock(fn, contractRequest, arg); - return DOOPHandler.convertJsonElementToDoipMessage((JsonElement) ret, msg); + return DOOPHandler.doipOuputConvertJsonElementToDoipMessage((JsonElement) ret, msg); } catch (Exception e) { e.printStackTrace(); } diff --git a/src/test/java/org/bdware/doip/DoipClientTest.java b/src/test/java/org/bdware/doip/DoipClientTest.java index da9ae56..0e9ed0f 100644 --- a/src/test/java/org/bdware/doip/DoipClientTest.java +++ b/src/test/java/org/bdware/doip/DoipClientTest.java @@ -10,14 +10,8 @@ import java.util.concurrent.atomic.AtomicInteger; public class DoipClientTest { - long start = System.currentTimeMillis(); - final AtomicInteger total = new AtomicInteger(0); - final AtomicInteger correct = new AtomicInteger(0); - int totalCount = 10000; - @Test - public void doipClientTest(){ - long start = System.currentTimeMillis(); + public void doipClientRetrieveTest(){ final AtomicInteger total = new AtomicInteger(0); final AtomicInteger correct = new AtomicInteger(0); int totalCount = 1; @@ -49,4 +43,38 @@ public class DoipClientTest { } } } + + @Test + public void doipClientHelloTest(){ + final AtomicInteger total = new AtomicInteger(0); + final AtomicInteger correct = new AtomicInteger(0); + int totalCount = 1; + for (int i = 0; i < totalCount; i++) { + final DoipClientImpl doipClient = new DoipClientImpl(); + doipClient.connect(ClientConfig.fromUrl("tcp://127.0.0.1:8080")); + doipClient.hello("aibd/do.e626924a-3b1c-492f-9a41-59179bfe0361", new DoipMessageCallback() { + @Override + public void onResult(DoipMessage msg) { + String str = new String(msg.body.encodedData); + System.out.println("Result is " + str); + //LOGGER.info("Retrieved:" + str + //+ " respCode:" + msg.header.parameters.response); + total.incrementAndGet(); + if (str.contains("aaa")) + correct.incrementAndGet(); + if (doipClient != null) doipClient.close(); + } + }); + } + int circle = 0; + for (; total.get() < totalCount; ) { + if (++circle % 100 == 0) { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } } From 1a4bf502bba7416e9af850b72f336208fa1a9c04 Mon Sep 17 00:00:00 2001 From: "haoeliu@foxmail.com" Date: Sun, 11 Dec 2022 12:02:27 +0800 Subject: [PATCH 09/10] fix the wrapperException bug in DesktopEngine's executeContract and finish the reponse check --- .../org/bdware/sc/engine/DesktopEngine.java | 4 +- .../bdware/sc/engine/hook/DOOPHandler.java | 81 ++++++++++++++----- .../bdware/sc/handler/DOOPRequestHandler.java | 2 +- 3 files changed, 63 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/bdware/sc/engine/DesktopEngine.java b/src/main/java/org/bdware/sc/engine/DesktopEngine.java index 12e82d9..416add6 100644 --- a/src/main/java/org/bdware/sc/engine/DesktopEngine.java +++ b/src/main/java/org/bdware/sc/engine/DesktopEngine.java @@ -581,9 +581,7 @@ public class DesktopEngine extends JSEngine { } catch (ScriptException e) { Throwable cause = e.getCause(); e.printStackTrace(); - return new ContractResult( - Status.Exception, - new JsonPrimitive(extractException(e.getMessage(), extract(cn, cause)))); + return wrapperException(e, fun); } catch (Throwable e) { ByteArrayOutputStream bo1 = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(bo1); diff --git a/src/main/java/org/bdware/sc/engine/hook/DOOPHandler.java b/src/main/java/org/bdware/sc/engine/hook/DOOPHandler.java index 4064e95..b7f1090 100644 --- a/src/main/java/org/bdware/sc/engine/hook/DOOPHandler.java +++ b/src/main/java/org/bdware/sc/engine/hook/DOOPHandler.java @@ -60,7 +60,7 @@ public class DOOPHandler implements AnnotationHook { // set doipMsgPackerArg struct's params doipMsgPackerArg.setSource("http"); - doipMsgPackerArg.rawDoipMsg = httpInputConvertContractRequestToDoipMessage(httpReq); + doipMsgPackerArg.rawDoipMsg = convertHttpRequestToDoipMessage(httpReq); } argPacks.arg = doipMsgPackerArg; @@ -75,13 +75,7 @@ public class DOOPHandler implements AnnotationHook { // get args rules and validate http args JsonElement httpArgsRules = getRulesForHTTPRequest(curOp); ArgSchemaVisitor visitor = new ArgSchemaVisitor(httpArgs); - visitor.visit(httpArgsRules); - if (!visitor.getStatus()) { - JsonObject jo = new JsonObject(); - jo.addProperty("msg", visitor.getException()); - jo.addProperty("code", visitor.errorCode); - throw new ScriptReturnException(jo); - } + validateJsonElementRulesByArgSchemaVisitor(httpArgsRules, visitor); } public static JsonElement getRulesForHTTPRequest(BasicOperations basicOperation) { @@ -89,13 +83,13 @@ public class DOOPHandler implements AnnotationHook { case Hello: case Delete: case ListOps: - return JsonParser.parseString("{\"!header\":{{\"!identifier\":\"string\"}}}"); + return JsonParser.parseString("{\"!header\":{\"!identifier\":\"string\"}}"); case Retrieve: return JsonParser.parseString("{\"!header\":{\"!identifier\":\"string\", \"attributes\":{\"element\":\"string\", \"includeElementData\":\"boolean\"}}}"); case Create: return JsonParser.parseString("{\"!header\":{\"!identifier\":\"string\", \"attributes\":{\"element\":\"string\", \"includeElementData\":\"boolean\"}}, \"!body\":\"string\"}"); case Update: - return JsonParser.parseString("{\"!header\":{{\"!identifier\":\"string\"}}, \"!body\":\"string\"}"); + return JsonParser.parseString("{\"!header\":{\"!identifier\":\"string\"}, \"!body\":\"string\"}"); case Search: return JsonParser.parseString("{\"!header\":{\"!identifier\":\"string\", \"attributes\":{\"query\":\"string\", \"pageNum\":\"int\", \"pageSize\":\"int\", \"type\":\"string\"}}}"); case Extension: @@ -105,7 +99,25 @@ public class DOOPHandler implements AnnotationHook { } } - public static DoipMessage httpInputConvertContractRequestToDoipMessage(ContractRequest httpReq) { + 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) { BasicOperations httpOperation = funcNameToDoipOperations.get(httpReq.getAction()); JsonObject jsonParams = JsonParser.parseString(httpReq.getArg().getAsString()).getAsJsonObject(); // taking Extension into consideration @@ -179,17 +191,46 @@ public class DOOPHandler implements AnnotationHook { return doipMessage; } - public static DoipMessage doipOuputConvertJsonElementToDoipMessage(JsonElement jsonElementRet, DoipMessage msg) { - DoipMessageFactory.DoipMessageBuilder builder = new DoipMessageFactory.DoipMessageBuilder(); + public static DoipMessage convertJsonResponseToDoipMessage(FunctionNode fn, JsonElement jsonResponse, DoipMessage msg) { + BasicOperations curOp = funcNameToDoipOperations.get(fn.getFunctionName()); + JsonObject jsonParams = jsonResponse.getAsJsonObject(); - String responseCodeStr = jsonElementRet.getAsJsonObject().get("doipResponseCode").getAsString(); - DoipResponseCode responseCode = DoipResponseCode.UnKnownError; - for (DoipResponseCode resp : DoipResponseCode.values()) { - if (resp.toString().equals(responseCodeStr)) responseCode = resp; + // 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; + JsonObject body = jsonParams.get("body") != null ? jsonParams.get("body").getAsJsonObject() : null; + + if(header != null) { + JsonObject respCodeJson = header.get("response") != null ? header.get("response").getAsJsonObject() : null; + DoipResponseCode respCode = null; + if(respCodeJson != null) { + for (DoipResponseCode responseCode : DoipResponseCode.values()) { + if(responseCode.toString().equals(respCodeJson.toString())) { + respCode = responseCode; + } + } + + if(respCode != null) msg.header.parameters.response = respCode; + } } - DoipMessage doipRet = builder.createResponse(responseCode, msg).create();; - doipRet.body.encodedData = jsonElementRet.getAsJsonObject().get("body").getAsJsonObject().get("encodedData").getAsString().getBytes(StandardCharsets.UTF_8); - return doipRet; + if(body != null) { + msg.body.encodedData = body.getAsString().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); + } } } diff --git a/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java b/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java index 59096de..421f4f2 100644 --- a/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java +++ b/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java @@ -124,7 +124,7 @@ public class DOOPRequestHandler implements DoipRequestHandler, RepositoryHandler try { // 改变调用的函数 + 构造DoipMessagePacker Object ret = ContractProcess.instance.engine.executeWithoutLock(fn, contractRequest, arg); - return DOOPHandler.doipOuputConvertJsonElementToDoipMessage((JsonElement) ret, msg); + return DOOPHandler.convertJsonResponseToDoipMessage(fn, (JsonElement) ret, msg); } catch (Exception e) { e.printStackTrace(); } From 6e25abbef0bf0a552ca33236b6d927120fd4e1ed Mon Sep 17 00:00:00 2001 From: "haoeliu@foxmail.com" Date: Wed, 25 Jan 2023 21:01:19 +0800 Subject: [PATCH 10/10] add doip cluster server logic --- .../java/org/bdware/sc/ContractProcess.java | 89 +++++++++- .../bdware/sc/boundry/utils/ClusterUtil.java | 14 -- .../org/bdware/sc/compiler/YJSCompiler.java | 13 ++ .../java/org/bdware/sc/compiler/ap/DOOP.java | 2 +- .../org/bdware/sc/engine/DesktopEngine.java | 2 +- .../bdware/sc/engine/hook/DOOPHandler.java | 50 +++--- .../bdware/sc/handler/DOOPRequestHandler.java | 50 ++++-- .../bdware/sc/server/DoipClusterServer.java | 156 ++++++++++++++++++ ...erverTest.java => DoipLocalSingleton.java} | 25 ++- .../java/org/bdware/doip/DoipClientTest.java | 80 --------- 10 files changed, 331 insertions(+), 150 deletions(-) create mode 100644 src/main/java/org/bdware/sc/server/DoipClusterServer.java rename src/main/java/org/bdware/sc/server/{DoipServerTest.java => DoipLocalSingleton.java} (63%) delete mode 100644 src/test/java/org/bdware/doip/DoipClientTest.java diff --git a/src/main/java/org/bdware/sc/ContractProcess.java b/src/main/java/org/bdware/sc/ContractProcess.java index 4aeb587..51be291 100644 --- a/src/main/java/org/bdware/sc/ContractProcess.java +++ b/src/main/java/org/bdware/sc/ContractProcess.java @@ -32,7 +32,7 @@ import org.bdware.sc.engine.hook.*; import org.bdware.sc.handler.ContractHandler; import org.bdware.sc.index.TimeSerialIndex; import org.bdware.sc.node.*; -import org.bdware.sc.server.DoipServerTest; +import org.bdware.sc.server.DoipClusterServer; import org.bdware.sc.trace.ProgramPointCounter; import org.bdware.sc.util.FileUtil; import org.bdware.sc.util.HashUtil; @@ -519,9 +519,14 @@ public class ContractProcess { jo.addProperty("status", result.status.merge(onCreate.status).toString()); LOGGER.debug("result: " + jo.toString()); + // doipModule的话,拉起DoipServer服务端口 if(cn.getYjsType() == YjsType.DoipModule) { - LOGGER.info("the doipServer has started"); - DoipServerTest.main(new String[]{"8080"}); + // 只有一台机器去更新Router中的repoInfo就可以了 + if(JavaScriptEntry.shardingID == 0) { + DoipClusterServer server = DoipClusterServer.getDOOPServerInstance(); + server.updateRepoInfo(contract, cn); + } + invokeOnStartingDoipServer(cn, contract.getCreateParam()); } return jo.toString(); @@ -660,8 +665,12 @@ public class ContractProcess { // doipModule的话,拉起DoipServer服务端口 if(cn.getYjsType() == YjsType.DoipModule) { - LOGGER.info("the doipServer has started"); - DoipServerTest.main(new String[]{"8080"}); + // 只有一台机器去更新Router中的repoInfo就可以了 + if(JavaScriptEntry.shardingID == 0) { + DoipClusterServer server = DoipClusterServer.getDOOPServerInstance(); + server.updateRepoInfo(contract, cn); + } + invokeOnStartingDoipServer(cn, contract.getCreateParam()); } return jo.toString(); @@ -673,6 +682,76 @@ public class ContractProcess { } } + public void invokeOnStartingDoipServer(ContractNode cn, JsonElement arg) { + ContractRequest onStartingDoipServer = new ContractRequest(); + onStartingDoipServer.setAction("invokeOnStartingDoipServer"); + if (arg == null) { + if (engine != null && engine.getManifest() != null && engine.getManifest().createParam != null) + arg = engine.getManifest().createParam; + else + arg = new JsonPrimitive(""); + } + onStartingDoipServer.setArg(arg); + LOGGER.debug("invoke onStartingDoipServer, param:" + onStartingDoipServer.getArg().toString()); + onStartingDoipServer.setRequester(contract.getOwner()); + if (contract.getDoipFlag() && null != contract.getDOI() && !contract.getDOI().isEmpty()) { + onStartingDoipServer.setRequesterDOI(contract.getDOI()); + } else { + onStartingDoipServer.setRequesterDOI("empty"); + } + FunctionNode funNode = cn.getFunction("invokeOnStartingDoipServer"); + + try { + JsonElement onStartingDoipServerRes = invoke(onStartingDoipServer, funNode).result; + LOGGER.info("Fetch the onStartingDoipServerRes from router successfully, the result is " + onStartingDoipServerRes); + if(onStartingDoipServerRes.isJsonObject()) { + JsonObject onStartingDoipServerJO = onStartingDoipServerRes.getAsJsonObject(); + if (!onStartingDoipServerJO.has("doipAddr")) { + throw new Exception("the doipAddr is improper"); + } else { + JsonElement doipAddrJE = onStartingDoipServerJO.get("doipAddr"); + if(doipAddrJE.isJsonArray()) { + JsonArray doipAddrJA = doipAddrJE.getAsJsonArray(); + for(int i = 0 ; i < doipAddrJA.size() ; i++) { + DoipClusterServer.startDoipServer(doipAddrJA.get(i).getAsString()); + } + } else { + DoipClusterServer.startDoipServer(doipAddrJE.getAsString()); + } + } + } else { + throw new Exception("the onStartingDoipServerRes doesn't return the correct json result"); + } + + } catch (Exception e) { + LOGGER.error("DoipLocalSingleton cannot starts properly, plz check the invokeOnStartingDoipServer function"); + e.printStackTrace(); + } + } + + public void invokeOnStartingDoipServer2(JsonElement arg) { + Object[] funcArgs = new Object[3]; + funcArgs[0] = JSONTool.convertJsonElementToMirror(arg); + funcArgs[1] = contract.getOwner(); + if (contract.getDoipFlag() && null != contract.getDOI() && !contract.getDOI().isEmpty()) { + funcArgs[2] = contract.getDOI(); + } else { + funcArgs[2] = "empty"; + } + Object result = engine.invokeFunction("invokeOnStartingDoipServer", funcArgs); + Map resMap = (Map) result; + try { + if (!resMap.containsKey("doipAddr")) { + throw new Exception("the doipAddr is improper"); + } else { + DoipClusterServer.startDoipServer(resMap.get("doipAddr")); + } + } catch (Exception e) { + LOGGER.error("DoipLocalSingleton cannot starts properly, plz check the invokeOnStartingDoipServer function"); + e.printStackTrace(); + } + } + private void handleLog() { for (FunctionNode fun : cn.getFunctions()) { StringBuilder detail = new StringBuilder(); diff --git a/src/main/java/org/bdware/sc/boundry/utils/ClusterUtil.java b/src/main/java/org/bdware/sc/boundry/utils/ClusterUtil.java index f6b01b4..7154e24 100644 --- a/src/main/java/org/bdware/sc/boundry/utils/ClusterUtil.java +++ b/src/main/java/org/bdware/sc/boundry/utils/ClusterUtil.java @@ -1,23 +1,9 @@ package org.bdware.sc.boundry.utils; -import com.google.gson.JsonArray; import org.bdware.sc.boundry.JavaScriptEntry; import org.bdware.sc.compiler.PermissionStub; -import org.bdware.sc.engine.JSONTool; import org.bdware.sc.node.Permission; -import org.bdware.sc.util.JsonUtil; import wrp.jdk.nashorn.internal.objects.NativeArray; -import wrp.jdk.nashorn.internal.runtime.PropertyMap; -import wrp.jdk.nashorn.internal.runtime.ScriptObject; -import wrp.jdk.nashorn.internal.scripts.JO; - -import javax.crypto.*; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; -import javax.xml.bind.DatatypeConverter; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; @PermissionStub(permission = Permission.Cluster) public class ClusterUtil { diff --git a/src/main/java/org/bdware/sc/compiler/YJSCompiler.java b/src/main/java/org/bdware/sc/compiler/YJSCompiler.java index 82c203b..11cd2c6 100644 --- a/src/main/java/org/bdware/sc/compiler/YJSCompiler.java +++ b/src/main/java/org/bdware/sc/compiler/YJSCompiler.java @@ -5,11 +5,13 @@ import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.DiagnosticErrorListener; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.bdware.doip.audit.EndpointConfig; import org.bdware.sc.engine.YJSFilter; import org.bdware.sc.node.*; import org.bdware.sc.parser.JavaScriptLexer; import org.bdware.sc.parser.YJSParser; import org.bdware.sc.parser.YJSParser.ProgramContext; +import org.bdware.sc.server.DoipClusterServer; import org.bdware.sc.util.JsonUtil; import org.bdware.sc.visitor.ContractReader; import wrp.jdk.nashorn.internal.objects.Global; @@ -118,6 +120,17 @@ public class YJSCompiler { JsonUtil.GSON.fromJson( 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进行插装 if (0L != cm.getInsnLimit()) { LOGGER.info("++++++++++++++++++++++true"); diff --git a/src/main/java/org/bdware/sc/compiler/ap/DOOP.java b/src/main/java/org/bdware/sc/compiler/ap/DOOP.java index 4f67f9c..630c19a 100644 --- a/src/main/java/org/bdware/sc/compiler/ap/DOOP.java +++ b/src/main/java/org/bdware/sc/compiler/ap/DOOP.java @@ -29,6 +29,6 @@ public class DOOP extends AnnotationProcessor { DOOPHandler.instance.putFuncNameAndDoipOperationsMapping(functionNode); // 维护ContractNode,functionName is useless, use BasicOperation to map the corresponding functionNode - // contractNode.updateFunctionMap(functionNode.functionName, functionNode.getDoipOperationInfo().operationName); + // contractNode.updateFunctionMap(functionNode.functionName, functionNode.getDoipOperationInfo().operationName); } } diff --git a/src/main/java/org/bdware/sc/engine/DesktopEngine.java b/src/main/java/org/bdware/sc/engine/DesktopEngine.java index 416add6..20a9636 100644 --- a/src/main/java/org/bdware/sc/engine/DesktopEngine.java +++ b/src/main/java/org/bdware/sc/engine/DesktopEngine.java @@ -526,7 +526,7 @@ public class DesktopEngine extends JSEngine { } } //System.out.println("[DesktopEngine MaskConfig]"+ContractProcess.instance.getProjectConfig().getMaskConfig().config.toString()); - ContractResult contractRes = new ContractResult(Status.Success, (JsonElement) ret); + ContractResult contractRes = new ContractResult(Status.Success, JSONTool.convertMirrorToJson(ret)); if (ppc != null) { contractRes.extraGas = ppc.extraGas; contractRes.executionGas = ppc.cost; diff --git a/src/main/java/org/bdware/sc/engine/hook/DOOPHandler.java b/src/main/java/org/bdware/sc/engine/hook/DOOPHandler.java index b7f1090..bbed912 100644 --- a/src/main/java/org/bdware/sc/engine/hook/DOOPHandler.java +++ b/src/main/java/org/bdware/sc/engine/hook/DOOPHandler.java @@ -84,14 +84,13 @@ public class DOOPHandler implements AnnotationHook { case Delete: case ListOps: return JsonParser.parseString("{\"!header\":{\"!identifier\":\"string\"}}"); - case Retrieve: - return JsonParser.parseString("{\"!header\":{\"!identifier\":\"string\", \"attributes\":{\"element\":\"string\", \"includeElementData\":\"boolean\"}}}"); case Create: - return JsonParser.parseString("{\"!header\":{\"!identifier\":\"string\", \"attributes\":{\"element\":\"string\", \"includeElementData\":\"boolean\"}}, \"!body\":\"string\"}"); case Update: return JsonParser.parseString("{\"!header\":{\"!identifier\":\"string\"}, \"!body\":\"string\"}"); case Search: - return JsonParser.parseString("{\"!header\":{\"!identifier\":\"string\", \"attributes\":{\"query\":\"string\", \"pageNum\":\"int\", \"pageSize\":\"int\", \"type\":\"string\"}}}"); + return JsonParser.parseString("{\"!header\":{\"!identifier\":\"string\", \"!attributes\":{\"!query\":\"string\", \"!pageNum\":\"int\", \"!pageSize\":\"int\", \"!type\":\"string\"}}}"); + case Retrieve: + return JsonParser.parseString("{\"!header\":{\"!identifier\":\"string\", \"attributes\":{\"element\":\"string\", \"includeElementData\":\"boolean\"}}}"); case Extension: case Unknown: default: @@ -128,30 +127,18 @@ public class DOOPHandler implements AnnotationHook { case Hello: case Delete: case ListOps: - doipMessage = new DoipMessageFactory.DoipMessageBuilder().createRequest(header.get("identifier").getAsString(), httpReq.getAction()).create(); - break; - case Retrieve: - doipMessage = new DoipMessageFactory.DoipMessageBuilder().createRequest(header.get("identifier").getAsString(), httpReq.getAction()).create(); - JsonElement element = header.get("element"); - JsonElement includeElementData = header.get("includeElementData"); - if(element != null) doipMessage.header.parameters.addAttribute("element", element.getAsString()); - if(includeElementData != null) doipMessage.header.parameters.addAttribute("includeElementData", includeElementData.getAsBoolean()); + doipMessage = new DoipMessageFactory.DoipMessageBuilder().createRequest(header.get("identifier").getAsString(), httpOperation.getName()).create(); break; case Create: - doipMessage = new DoipMessageFactory.DoipMessageBuilder() - .createRequest(header.get("identifier").getAsString(), BasicOperations.Create.getName()) - .setBody(body.getAsString().getBytes(StandardCharsets.UTF_8)) - .create(); - break; case Update: doipMessage = new DoipMessageFactory.DoipMessageBuilder() - .createRequest(header.get("identifier").getAsString(), BasicOperations.Update.getName()) + .createRequest(header.get("identifier").getAsString(), httpOperation.getName()) .setBody(body.getAsString().getBytes(StandardCharsets.UTF_8)) .create(); break; case Search: DoipMessageFactory.DoipMessageBuilder searchBuilder = new DoipMessageFactory.DoipMessageBuilder() - .createRequest(header.get("identifier").getAsString(), BasicOperations.Search.getName()); + .createRequest(header.get("identifier").getAsString(), httpOperation.getName()); JsonElement query = header.get("query"); if(query != null) searchBuilder.addAttributes("query", query.getAsString()); JsonElement pageNum = header.get("pageNum"); @@ -163,12 +150,19 @@ public class DOOPHandler implements AnnotationHook { doipMessage = searchBuilder.create(); break; + case Retrieve: + doipMessage = new DoipMessageFactory.DoipMessageBuilder().createRequest(header.get("identifier").getAsString(), httpOperation.getName()).create(); + JsonElement element = header.get("element"); + JsonElement includeElementData = header.get("includeElementData"); + if(element != null) doipMessage.header.parameters.addAttribute("element", element.getAsString()); + if(includeElementData != null && includeElementData.getAsBoolean()) doipMessage.header.parameters.addAttribute("includeElementData", "true"); + break; case Extension: DoipMessageFactory.DoipMessageBuilder extensionBuilder = new DoipMessageFactory.DoipMessageBuilder(); if(header != null) { if(header.get("identifier") != null) { extensionBuilder = extensionBuilder - .createRequest(header.get("identifier").getAsString(), BasicOperations.Extension.getName()); + .createRequest(header.get("identifier").getAsString(), httpOperation.getName()); } Set> entries = header.entrySet(); @@ -201,24 +195,22 @@ public class DOOPHandler implements AnnotationHook { validateJsonElementRulesByArgSchemaVisitor(jsonResponseRules, visitor); 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; if(header != null) { - JsonObject respCodeJson = header.get("response") != null ? header.get("response").getAsJsonObject() : null; - DoipResponseCode respCode = null; - if(respCodeJson != null) { + String headerRespCode = header.get("response") != null ? header.get("response").getAsString() : null; + if(headerRespCode != null) { for (DoipResponseCode responseCode : DoipResponseCode.values()) { - if(responseCode.toString().equals(respCodeJson.toString())) { - respCode = responseCode; + if(responseCode.toString().equals(headerRespCode)) { + msg.header.parameters.response = responseCode; + break; } } - - if(respCode != null) msg.header.parameters.response = respCode; } } if(body != null) { - msg.body.encodedData = body.getAsString().getBytes(StandardCharsets.UTF_8); + msg.body.encodedData = body.getBytes(StandardCharsets.UTF_8); } return msg; diff --git a/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java b/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java index 421f4f2..c0c1c38 100644 --- a/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java +++ b/src/main/java/org/bdware/sc/handler/DOOPRequestHandler.java @@ -20,14 +20,14 @@ import java.util.HashMap; import java.util.Map; public class DOOPRequestHandler implements DoipRequestHandler, RepositoryHandler { - public Map doipOperationsMap; + public Map doipFunctionNodeMap; static Logger logger = LogManager.getLogger(NettyServerHandler.class); static Gson gson; public static DOOPRequestHandler instance; public DOOPRequestHandler() { - doipOperationsMap = new HashMap<>(); + doipFunctionNodeMap = new HashMap<>(); gson = new Gson(); } @@ -40,7 +40,7 @@ public class DOOPRequestHandler implements DoipRequestHandler, RepositoryHandler } public void addDoipOperation(FunctionNode function) { - doipOperationsMap.put(function.getDoipOperationInfo().operationName, function); + doipFunctionNodeMap.put(function.getDoipOperationInfo().operationName, function); } @Override @@ -49,8 +49,8 @@ public class DOOPRequestHandler implements DoipRequestHandler, RepositoryHandler logger.debug("[Call operation] name: " + str); if (str != null) { FunctionNode fn; - fn = doipOperationsMap.get(str); - if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName()); + fn = doipFunctionNodeMap.get(str); + if (fn == null) fn = doipFunctionNodeMap.get(BasicOperations.Unknown.getName()); if (fn != null) { return buildRequestAndInvokeEngine(fn, msg); } @@ -60,61 +60,76 @@ public class DOOPRequestHandler implements DoipRequestHandler, RepositoryHandler @Override public DoipMessage handleHello(DoipMessage request) { - FunctionNode fn = doipOperationsMap.get(BasicOperations.Hello.getName()); - if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName()); + FunctionNode fn = doipFunctionNodeMap.get(BasicOperations.Hello.getName()); + if (fn == null) fn = doipFunctionNodeMap.get(BasicOperations.Unknown.getName()); if (fn != null) { return buildRequestAndInvokeEngine(fn, request); + } else { + logger.error("DoipOperation Hello is not provided"); } return null; } @Override public DoipMessage handleListOps(DoipMessage request) { - FunctionNode fn = doipOperationsMap.get(BasicOperations.ListOps.getName()); - if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName()); + FunctionNode fn = doipFunctionNodeMap.get(BasicOperations.ListOps.getName()); + if (fn == null) fn = doipFunctionNodeMap.get(BasicOperations.Unknown.getName()); if (fn != null) { return buildRequestAndInvokeEngine(fn, request); + } else { + logger.error("DoipOperation ListOps is not provided"); } + return null; } @Override public DoipMessage handleCreate(DoipMessage request) { - FunctionNode fn = doipOperationsMap.get(BasicOperations.Create.getName()); - if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName()); + FunctionNode fn = doipFunctionNodeMap.get(BasicOperations.Create.getName()); + if (fn == null) fn = doipFunctionNodeMap.get(BasicOperations.Unknown.getName()); if (fn != null) { return buildRequestAndInvokeEngine(fn, request); + } else { + logger.error("DoipOperation Create is not provided"); } return null; } @Override public DoipMessage handleUpdate(DoipMessage request) { - FunctionNode fn = doipOperationsMap.get(BasicOperations.Update.getName()); - if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName()); + FunctionNode fn = doipFunctionNodeMap.get(BasicOperations.Update.getName()); + if (fn == null) fn = doipFunctionNodeMap.get(BasicOperations.Unknown.getName()); if (fn != null) { return buildRequestAndInvokeEngine(fn, request); + } else { + logger.error("DoipOperation Update is not provided"); } + return null; } @Override public DoipMessage handleDelete(DoipMessage request) { - FunctionNode fn = doipOperationsMap.get(BasicOperations.Delete.getName()); - if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName()); + FunctionNode fn = doipFunctionNodeMap.get(BasicOperations.Delete.getName()); + if (fn == null) fn = doipFunctionNodeMap.get(BasicOperations.Unknown.getName()); if (fn != null) { return buildRequestAndInvokeEngine(fn, request); + } else { + logger.error("DoipOperation Delete is not provided"); } return null; } @Override public DoipMessage handleRetrieve(DoipMessage request) { - FunctionNode fn = doipOperationsMap.get(BasicOperations.Retrieve.getName()); - if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName()); + FunctionNode fn = doipFunctionNodeMap.get(BasicOperations.Retrieve.getName()); + if (fn == null) fn = doipFunctionNodeMap.get(BasicOperations.Unknown.getName()); if (fn != null) { return buildRequestAndInvokeEngine(fn, request); + } else { + logger.error("DoipOperation Retrieve is not provided"); } + return null; } @@ -127,6 +142,7 @@ public class DOOPRequestHandler implements DoipRequestHandler, RepositoryHandler return DOOPHandler.convertJsonResponseToDoipMessage(fn, (JsonElement) ret, msg); } catch (Exception e) { e.printStackTrace(); + logger.error("buildRequestAndInvokeEngine has something wrong, executeWithoutLock err or validateJsonElementRulesByArgSchemaVisitor err"); } return null; diff --git a/src/main/java/org/bdware/sc/server/DoipClusterServer.java b/src/main/java/org/bdware/sc/server/DoipClusterServer.java new file mode 100644 index 0000000..e202388 --- /dev/null +++ b/src/main/java/org/bdware/sc/server/DoipClusterServer.java @@ -0,0 +1,156 @@ +package org.bdware.sc.server; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bdware.doip.audit.EndpointConfig; +import org.bdware.doip.audit.EndpointInfo; +import org.bdware.doip.audit.client.AuditIrpClient; +import org.bdware.doip.endpoint.server.DoipListenerConfig; +import org.bdware.doip.endpoint.server.DoipServerImpl; +import org.bdware.doip.endpoint.server.DoipServiceInfo; +import org.bdware.irp.exception.IrpClientException; +import org.bdware.irp.stateinfo.StateInfoBase; +import org.bdware.sc.ContractProcess; +import org.bdware.sc.bean.Contract; +import org.bdware.sc.bean.RouteInfo; +import org.bdware.sc.handler.DOOPRequestHandler; +import org.bdware.sc.node.ContractNode; +import org.bdware.sc.node.FunctionNode; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.bdware.doip.audit.EndpointConfig.defaultDOIPServerPort; +import static org.bdware.doip.audit.EndpointConfig.defaultRepoType; + +public class DoipClusterServer extends DoipServerImpl { + static EndpointConfig config; + static AuditIrpClient repoIrpClient; + static DoipClusterServer instance; + // LOGGER + private static final Logger LOGGER = LogManager.getLogger(ContractProcess.class); + + public DoipClusterServer(EndpointConfig config) { + super(resolveInfo(config)); + DoipClusterServer.config = config; + } + + public static void createDOOPServerInstance(EndpointConfig config) { + instance = new DoipClusterServer(config); + } + + public static DoipClusterServer getDOOPServerInstance() { + return instance; + } + + public static void startDoipServer(String arg) throws InterruptedException { + final String doipAddr = arg; + + Thread doipServerThread = new Thread(){ + @Override + public void run() { + try { + DoipLocalSingleton.run(doipAddr); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }; + + doipServerThread.start(); + } + + private static DoipServiceInfo resolveInfo(EndpointConfig config) { + repoIrpClient = new AuditIrpClient(config); + EndpointInfo info = repoIrpClient.getEndpointInfo(); + if (info == null) { + String content = "{\"date\":\"2022-1-13\",\"name\":\"testrepoforaibd\",\"doId\":\"bdware.test.local/Repo\",\"address\":\"tcp://127.0.0.1:" + defaultDOIPServerPort + "\",\"status\":\"已审核\",\"protocol\":\"DOIP\",\"pubKey\":\"empty\",\"version\":\"2.1\"}"; + info = EndpointInfo.fromJson(content); + } + List infos = new ArrayList<>(); + try { + infos.add(new DoipListenerConfig(info.getURI(), info.getVersion())); + } catch (Exception e) { + e.printStackTrace(); + } + DoipServiceInfo ret = new DoipServiceInfo(info.getDoId(), info.getPubKey(), defaultRepoType, infos); + return ret; + } + + public void updateRepoInfo(Contract contract, ContractNode cn) throws IrpClientException { + String repoIdentifier = "bdtest/" + config.repoName; + StateInfoBase repoInfo = new StateInfoBase(); + + repoInfo.identifier = repoIdentifier; + repoInfo.handleValues = new JsonObject(); + + JsonObject repoHandleValues = new JsonObject(); + + JsonObject createParams = contract.getCreateParam().getAsJsonObject(); + // 放置集群信息 + JsonElement clusterInfo = createParams.get("clusterInfo"); + + // doipOperationName和对应的routeFunctionName的对应关系,存储方式为doipOperationName: routeFunctionName + JsonObject methodRouteInfoMap = new JsonObject(); + // 所有Router中用得到的函数(例如Route函数和Route函数依赖的相关函数) + JsonObject functions = new JsonObject(); + + // 维护RouteInfo,将RouteInfo和doipOperationName的映射关系,以及所有Router中用得到的函数都维护好 + maintainRouteInfo(cn, methodRouteInfoMap, functions); + + if(clusterInfo != null) repoHandleValues.add("clusterInfo", clusterInfo); + if(!functions.equals(new JsonObject())) repoHandleValues.add("functions", functions); + if(!methodRouteInfoMap.equals(new JsonObject())) repoHandleValues.add("routeInfo", methodRouteInfoMap); + repoInfo.handleValues.addProperty("cluster", repoHandleValues.toString()); + + String updateRepoInfoRes = repoIrpClient.reRegister(repoInfo); + if (updateRepoInfoRes.equals("success")) { + LOGGER.info("Update cluster info to router successfully"); + } else if (updateRepoInfoRes.equals("failed")) { + LOGGER.error("Failed to update cluster info to router"); + } else { + LOGGER.warn("Oops...The result of updating clusterInfo to the router is " + updateRepoInfoRes); + } + } + + public void maintainRouteInfo(ContractNode cn, JsonObject methodRouteInfoMap, JsonObject functions) { + // all functions存了ContractNode中,所有的FunctionNode + List allFunctions = cn.getFunctions(); + // gson是Gson工具类昂!!! + Gson gson = new Gson(); + + // 遍历所有的 doipOperationName 和其对应的 doipFunctionNode + for (Map.Entry doipFunctionNodes : DOOPRequestHandler.instance.doipFunctionNodeMap.entrySet()) { + String doipOperationName = doipFunctionNodes.getKey(); + FunctionNode doipFunctionNode = doipFunctionNodes.getValue(); + RouteInfo doipFunctionRouteInfo = doipFunctionNode.getRouteInfo(); + + // 对于routerInfo进行处理,对于routeInfo进行维护 + if(doipFunctionRouteInfo != null) { + methodRouteInfoMap.addProperty(doipOperationName, gson.toJson(doipFunctionRouteInfo)); + if(doipFunctionRouteInfo.funcName != null) { + String routeFunctionName = doipFunctionRouteInfo.funcName; + for(FunctionNode functionNode : allFunctions) { + // find Route Function + if(functionNode.functionName.equals(routeFunctionName)) { + functions.addProperty(functionNode.functionName, functionNode.plainText()); + + // add all dependentFunction to the "functions" struct + for (String dependentFunctionName : functionNode.getDependentFunctions()) { + for (FunctionNode f : cn.getFunctions()) { + if(f.functionName.equals(dependentFunctionName) && !functions.has(dependentFunctionName)) { + functions.addProperty(dependentFunctionName, f.plainText()); + } + } + } + } + } + } + } + } + } +} diff --git a/src/main/java/org/bdware/sc/server/DoipServerTest.java b/src/main/java/org/bdware/sc/server/DoipLocalSingleton.java similarity index 63% rename from src/main/java/org/bdware/sc/server/DoipServerTest.java rename to src/main/java/org/bdware/sc/server/DoipLocalSingleton.java index b14ebbc..1993032 100644 --- a/src/main/java/org/bdware/sc/server/DoipServerTest.java +++ b/src/main/java/org/bdware/sc/server/DoipLocalSingleton.java @@ -11,8 +11,8 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; -public class DoipServerTest { - static Logger LOGGER = LogManager.getLogger(DoipServerTest.class); +public class DoipLocalSingleton { + static Logger LOGGER = LogManager.getLogger(DoipLocalSingleton.class); public static void main(String[] arg) throws InterruptedException { final int port = (arg.length == 0 ? 21042 : Integer.parseInt(arg[0])); @@ -21,7 +21,7 @@ public class DoipServerTest { @Override public void run() { try { - DoipServerTest.run(port); + DoipLocalSingleton.run(port); } catch (InterruptedException e) { e.printStackTrace(); } @@ -49,4 +49,23 @@ public class DoipServerTest { Thread.sleep(10000); } } + + public static void run(String doipAddr) throws InterruptedException { + List infos = new ArrayList<>(); + try { + infos.add(new DoipListenerConfig(doipAddr, "2.1")); + } catch (Exception e) { + e.printStackTrace(); + } + DoipServiceInfo info = new DoipServiceInfo("aibd.govdata.tj/do.3f9c41e6-9f8e-48a0-9220-53f438d40e43", "ownerDEF", "gateRepo", infos); + DoipServerImpl server = new DoipServerImpl(info); + final AtomicInteger count = new AtomicInteger(0); + DOOPRequestHandler handler = DOOPRequestHandler.createHandler(); + server.setRepositoryHandler(handler); + server.start(); + for (; ; ) { + LOGGER.info("Count:" + count.get()); + Thread.sleep(10000); + } + } } diff --git a/src/test/java/org/bdware/doip/DoipClientTest.java b/src/test/java/org/bdware/doip/DoipClientTest.java deleted file mode 100644 index 0e9ed0f..0000000 --- a/src/test/java/org/bdware/doip/DoipClientTest.java +++ /dev/null @@ -1,80 +0,0 @@ -package org.bdware.doip; - -import org.bdware.doip.codec.doipMessage.DoipMessage; -import org.bdware.doip.endpoint.client.ClientConfig; -import org.bdware.doip.endpoint.client.DoipClientImpl; -import org.bdware.doip.endpoint.client.DoipMessageCallback; -import org.junit.Test; - -import java.util.concurrent.atomic.AtomicInteger; - - -public class DoipClientTest { - @Test - public void doipClientRetrieveTest(){ - final AtomicInteger total = new AtomicInteger(0); - final AtomicInteger correct = new AtomicInteger(0); - int totalCount = 1; - for (int i = 0; i < totalCount; i++) { - final DoipClientImpl doipClient = new DoipClientImpl(); - doipClient.connect(ClientConfig.fromUrl("tcp://127.0.0.1:8080")); - doipClient.retrieve("aibd/do.e626924a-3b1c-492f-9a41-59179bfe0361", null, true, new DoipMessageCallback() { - @Override - public void onResult(DoipMessage msg) { - String str = new String(msg.body.encodedData); - System.out.println("Result is " + str); - //LOGGER.info("Retrieved:" + str - //+ " respCode:" + msg.header.parameters.response); - total.incrementAndGet(); - if (str.contains("aaa")) - correct.incrementAndGet(); - if (doipClient != null) doipClient.close(); - } - }); - } - int circle = 0; - for (; total.get() < totalCount; ) { - if (++circle % 100 == 0) { - try { - Thread.sleep(10); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - } - - @Test - public void doipClientHelloTest(){ - final AtomicInteger total = new AtomicInteger(0); - final AtomicInteger correct = new AtomicInteger(0); - int totalCount = 1; - for (int i = 0; i < totalCount; i++) { - final DoipClientImpl doipClient = new DoipClientImpl(); - doipClient.connect(ClientConfig.fromUrl("tcp://127.0.0.1:8080")); - doipClient.hello("aibd/do.e626924a-3b1c-492f-9a41-59179bfe0361", new DoipMessageCallback() { - @Override - public void onResult(DoipMessage msg) { - String str = new String(msg.body.encodedData); - System.out.println("Result is " + str); - //LOGGER.info("Retrieved:" + str - //+ " respCode:" + msg.header.parameters.response); - total.incrementAndGet(); - if (str.contains("aaa")) - correct.incrementAndGet(); - if (doipClient != null) doipClient.close(); - } - }); - } - int circle = 0; - for (; total.get() < totalCount; ) { - if (++circle % 100 == 0) { - try { - Thread.sleep(10); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - } -}