finish the draft version

This commit is contained in:
haoeliu@foxmail.com 2022-11-27 18:54:50 +08:00
parent 9686de6ba9
commit 24c0673b9b
9 changed files with 256 additions and 104 deletions

View File

@ -32,6 +32,7 @@ import org.bdware.sc.engine.hook.*;
import org.bdware.sc.handler.ContractHandler; import org.bdware.sc.handler.ContractHandler;
import org.bdware.sc.index.TimeSerialIndex; import org.bdware.sc.index.TimeSerialIndex;
import org.bdware.sc.node.*; import org.bdware.sc.node.*;
import org.bdware.sc.server.DoipServerTest;
import org.bdware.sc.trace.ProgramPointCounter; import org.bdware.sc.trace.ProgramPointCounter;
import org.bdware.sc.util.FileUtil; import org.bdware.sc.util.FileUtil;
import org.bdware.sc.util.HashUtil; import org.bdware.sc.util.HashUtil;
@ -559,6 +560,10 @@ public class ContractProcess {
fun.appendBeforeInvokeHandler(argSchemaHandler); fun.appendBeforeInvokeHandler(argSchemaHandler);
} }
if (fun.isDoipOperation()) {
fun.appendBeforeInvokeHandler(new DOOPHandler());
}
if (fun.isExport()) { if (fun.isExport()) {
//if(fun.annotations...) //if(fun.annotations...)
fun.appendAfterInvokeHandler(new ObjToJsonHandler()); fun.appendAfterInvokeHandler(new ObjToJsonHandler());
@ -643,6 +648,12 @@ public class ContractProcess {
jo.add("loadContract", JsonUtil.parseObject(ret)); jo.add("loadContract", JsonUtil.parseObject(ret));
jo.addProperty("status", ret.status.merge(onCreate.status).toString()); jo.addProperty("status", ret.status.merge(onCreate.status).toString());
LOGGER.debug("result: " + jo.toString()); LOGGER.debug("result: " + jo.toString());
// doipModule的话拉起DoipServer服务端口
if(cn.getYjsType() == YjsType.DoipModule) {
DoipServerTest.main(new String[]{"8080"});
}
return jo.toString(); return jo.toString();
} catch (Exception e) { } catch (Exception e) {
ByteArrayOutputStream bo = new ByteArrayOutputStream(); ByteArrayOutputStream bo = new ByteArrayOutputStream();

View File

@ -18,6 +18,7 @@ public class DOOP extends AnnotationProcessor {
// 通过DOOP注解解析对应的值并放进对应的FunctionNode中 // 通过DOOP注解解析对应的值并放进对应的FunctionNode中
// 注解必须暴露出来昂 // 注解必须暴露出来昂
functionNode.setIsExport(true); functionNode.setIsExport(true);
functionNode.setIsDoipOperation(true);
functionNode.setDoipOperationInfo(DoipOperationInfo.create(anno, contractNode)); functionNode.setDoipOperationInfo(DoipOperationInfo.create(anno, contractNode));
// 维护DOOPRequestHandler // 维护DOOPRequestHandler
@ -27,6 +28,6 @@ public class DOOP extends AnnotationProcessor {
DOOPRequestHandler.instance.addDoipOperation(functionNode); DOOPRequestHandler.instance.addDoipOperation(functionNode);
// 维护ContractNodefunctionName is useless, use BasicOperation to map the corresponding functionNode // 维护ContractNodefunctionName is useless, use BasicOperation to map the corresponding functionNode
contractNode.updateFunctionMap(functionNode.functionName, functionNode.getDoipOperationInfo().operationType.toString()); contractNode.updateFunctionMap(functionNode.functionName, functionNode.getDoipOperationInfo().operationName);
} }
} }

View File

@ -518,10 +518,10 @@ public class DesktopEngine extends JSEngine {
input.getRequester().startsWith("event"))) { input.getRequester().startsWith("event"))) {
Object ret; Object ret;
if (fun.isView()) { if (fun.isView()) {
ret = executeWithoutLock(fun, input); ret = executeWithoutLock(fun, input, null);
} else { } else {
synchronized (this) { 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 { public Object executeWithoutLock(FunctionNode fun, ContractRequest input, Object injectedArg) throws ScriptException, NoSuchMethodException {
Object ret = null;
// long start = System.currentTimeMillis(); // long start = System.currentTimeMillis();
ArgPacks argPack = new ArgPacks(input, input.getArg(), null);
for (AnnotationHook handler : fun.beforeExecutionAnnotations()) { if(injectedArg != null) {
ret = handler.handle(this, new ArgPacks(input, input.getArg(), ret)); argPack.arg = injectedArg;
} }
for (AnnotationHook handler : fun.beforeExecutionAnnotations()) {
argPack = handler.handle(this, argPack);
}
// actually invoke! // actually invoke!
if (ret == null) { // todo 这里invoke应该如何调用改了一行代码正确吗input.getArg() -> argPack.arg
ret = if (argPack.ret == null) {
argPack.ret =
engine.invokeFunction( engine.invokeFunction(
input.getAction(), input.getAction(),
(fun.isHandler() (fun.isHandler()
? JsonUtil.fromJson(input.getArg(), Event.class) ? JsonUtil.fromJson(input.getArg(), Event.class)
: JSONTool.convertJsonElementToMirror(input.getArg())), : JSONTool.convertJsonElementToMirror(argPack.arg)),
input.getRequester(), input.getRequester(),
input.getRequesterDOI()); input.getRequesterDOI());
} }
@ -628,9 +632,9 @@ public class DesktopEngine extends JSEngine {
//Mask在after裏面 //Mask在after裏面
//System.out.println("afterHook"+contract.Mask); //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<String> stack) { private String extractException(String msg, List<String> stack) {

View File

@ -40,6 +40,14 @@ public class JSONTool {
return null; 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<Object> recorded) { private static JsonElement convertMirrorToJsonInternal(Object obj, Set<Object> recorded) {
if (recorded.contains(obj)) return JsonNull.INSTANCE; if (recorded.contains(obj)) return JsonNull.INSTANCE;
if (obj == null) return JsonNull.INSTANCE; if (obj == null) return JsonNull.INSTANCE;

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -11,11 +11,11 @@ import org.bdware.doip.endpoint.server.DoipRequestHandler;
import org.bdware.doip.endpoint.server.NettyServerHandler; import org.bdware.doip.endpoint.server.NettyServerHandler;
import org.bdware.doip.endpoint.server.RepositoryHandler; import org.bdware.doip.endpoint.server.RepositoryHandler;
import org.bdware.sc.ContractProcess; import org.bdware.sc.ContractProcess;
import org.bdware.sc.ContractResult;
import org.bdware.sc.bean.ContractRequest; 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 org.bdware.sc.node.FunctionNode;
import java.lang.reflect.Method;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -35,7 +35,7 @@ public class DOOPRequestHandler implements DoipRequestHandler, RepositoryHandler
} }
public void addDoipOperation(FunctionNode function) { public void addDoipOperation(FunctionNode function) {
doipOperationsMap.put(function.getDoipOperationInfo().operationType.getName(), function); doipOperationsMap.put(function.getDoipOperationInfo().operationName, function);
} }
@Override @Override
@ -47,13 +47,7 @@ public class DOOPRequestHandler implements DoipRequestHandler, RepositoryHandler
fn = doipOperationsMap.get(str); fn = doipOperationsMap.get(str);
if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName()); if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName());
if (fn != null) { if (fn != null) {
try { return buildRequestAndInvokeEngine(fn, 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();
}
} }
} }
return null; return null;
@ -62,57 +56,82 @@ public class DOOPRequestHandler implements DoipRequestHandler, RepositoryHandler
@Override @Override
public DoipMessage handleHello(DoipMessage request) { public DoipMessage handleHello(DoipMessage request) {
FunctionNode fn = doipOperationsMap.get(BasicOperations.Hello.getName()); FunctionNode fn = doipOperationsMap.get(BasicOperations.Hello.getName());
ContractRequest cr = constructContractRequest(fn, request); if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName());
JsonElement res = ContractProcess.instance.engine.executeContract(cr).result; if (fn != null) {
return gson.fromJson(res.toString(), DoipMessage.class); return buildRequestAndInvokeEngine(fn, request);
}
return null;
} }
@Override @Override
public DoipMessage handleListOps(DoipMessage request) { public DoipMessage handleListOps(DoipMessage request) {
FunctionNode fn = doipOperationsMap.get(BasicOperations.ListOps.getName()); FunctionNode fn = doipOperationsMap.get(BasicOperations.ListOps.getName());
ContractRequest cr = constructContractRequest(fn, request); if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName());
JsonElement res = ContractProcess.instance.engine.executeContract(cr).result; if (fn != null) {
return gson.fromJson(res.toString(), DoipMessage.class); return buildRequestAndInvokeEngine(fn, request);
}
return null;
} }
@Override @Override
public DoipMessage handleCreate(DoipMessage request) { public DoipMessage handleCreate(DoipMessage request) {
FunctionNode fn = doipOperationsMap.get(BasicOperations.Create.getName()); FunctionNode fn = doipOperationsMap.get(BasicOperations.Create.getName());
ContractRequest cr = constructContractRequest(fn, request); if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName());
JsonElement res = ContractProcess.instance.engine.executeContract(cr).result; if (fn != null) {
return gson.fromJson(res.toString(), DoipMessage.class); return buildRequestAndInvokeEngine(fn, request);
}
return null;
} }
@Override @Override
public DoipMessage handleUpdate(DoipMessage request) { public DoipMessage handleUpdate(DoipMessage request) {
FunctionNode fn = doipOperationsMap.get(BasicOperations.Update.getName()); FunctionNode fn = doipOperationsMap.get(BasicOperations.Update.getName());
ContractRequest cr = constructContractRequest(fn, request); if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName());
JsonElement res = ContractProcess.instance.engine.executeContract(cr).result; if (fn != null) {
return gson.fromJson(res.toString(), DoipMessage.class); return buildRequestAndInvokeEngine(fn, request);
}
return null;
} }
@Override @Override
public DoipMessage handleDelete(DoipMessage request) { public DoipMessage handleDelete(DoipMessage request) {
FunctionNode fn = doipOperationsMap.get(BasicOperations.Delete.getName()); FunctionNode fn = doipOperationsMap.get(BasicOperations.Delete.getName());
ContractRequest cr = constructContractRequest(fn, request); if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName());
JsonElement res = ContractProcess.instance.engine.executeContract(cr).result; if (fn != null) {
return gson.fromJson(res.toString(), DoipMessage.class); return buildRequestAndInvokeEngine(fn, request);
}
return null;
} }
@Override @Override
public DoipMessage handleRetrieve(DoipMessage request) { public DoipMessage handleRetrieve(DoipMessage request) {
FunctionNode fn = doipOperationsMap.get(BasicOperations.Retrieve.getName()); FunctionNode fn = doipOperationsMap.get(BasicOperations.Retrieve.getName());
ContractRequest cr = constructContractRequest(fn, request); if (fn == null) fn = doipOperationsMap.get(BasicOperations.Unknown.getName());
JsonElement res = ContractProcess.instance.engine.executeContract(cr).result; if (fn != null) {
return gson.fromJson(res.toString(), DoipMessage.class); 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) { public ContractRequest constructContractRequest(FunctionNode fn, DoipMessage request) {
ContractRequest cr = new ContractRequest(); ContractRequest cr = new ContractRequest();
cr.setContractID(""); cr.setContractID("");
cr.setRequester(""); cr.setRequester(request.credential.getSigner());
cr.setAction(""); cr.setAction(fn.functionName);
cr.setArg("");
return cr; return cr;
} }
} }

View File

@ -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<DoipListenerConfig> 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();
}
}
}

View File

@ -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<DoipListenerConfig> 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);
}
}
}