From f29e4fca1478b1a553574f5a3dde6dd42915aa5f Mon Sep 17 00:00:00 2001 From: clay <20932067@zju.edu.cn> Date: Tue, 23 Apr 2024 09:25:38 +0800 Subject: [PATCH 01/10] =?UTF-8?q?feat:=20=E4=B8=8A=E7=BA=BF=E7=9B=91?= =?UTF-8?q?=E6=8E=A7=E5=92=8C=E9=99=90=E6=B5=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- visual/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/visual/pom.xml b/visual/pom.xml index fdb2ec2..e4b1e6b 100644 --- a/visual/pom.xml +++ b/visual/pom.xml @@ -16,10 +16,10 @@ true - + monitor - + sentinel-dashboard From 450ed63e606df00971102937b607c7246c5904f4 Mon Sep 17 00:00:00 2001 From: clay <20932067@zju.edu.cn> Date: Tue, 23 Apr 2024 11:32:55 +0800 Subject: [PATCH 02/10] =?UTF-8?q?feat:=20java=E6=89=A7=E8=A1=8C=E5=BC=95?= =?UTF-8?q?=E6=93=8E=E5=92=8Cjs=E6=89=A7=E8=A1=8C=E5=BC=95=E6=93=8E?= =?UTF-8?q?=E8=B0=83=E8=AF=95=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/common-code/pom.xml | 10 ++ .../code/console/MultiThreadedCapture.java | 45 ++++++ .../common/code/engine/JavaCodeEngine.java | 38 +++-- .../common/code/engine/JavaScriptEngine.java | 77 +++++++--- .../common/code/model/EngineResult.java | 25 ++++ .../common/decrypt/annotation/Encrypt.java | 19 +++ .../decrypt/annotation/EncryptField.java | 8 ++ .../common/decrypt/aspect/EncryptAspect.java | 136 +++++++++++++----- custom-query/custom-query-biz/pom.xml | 4 + .../query/config/RestTemplateConfig.java | 53 +++++++ .../query/constant/QueryConstant.java | 22 ++- .../controller/DataAdapterController.java | 6 +- .../query/controller/PortalController.java | 62 +++++++- .../fateverse/query/entity/DataAdapter.java | 3 + .../cn/fateverse/query/entity/Portal.java | 9 +- .../fateverse/query/entity/PortalMapping.java | 13 +- .../fateverse/query/entity/bo/PortalBo.java | 4 + .../fateverse/query/entity/dto/MockParam.java | 33 +++++ .../fateverse/query/entity/dto/PortalDto.java | 8 +- .../query/entity/query/PortalQuery.java | 4 +- .../fateverse/query/entity/vo/PortalVo.java | 21 +++ .../query/entity/vo/SimplePortalVo.java | 14 +- .../adapter/AbstractDataAdapterHandler.java | 73 ++++++++++ .../handler/adapter/DataAdapterHandler.java | 24 +++- .../impl/ExternalDataAdapterHandler.java | 73 ++++++++++ .../adapter/impl/LocalDataAdapterHandler.java | 84 +++++++---- .../handler/engine/EngineExecuteHandler.java | 4 +- .../engine/impl/JavaEngineExecuteHandler.java | 5 +- .../impl/JavaScriptEngineExecuteHandler.java | 27 +++- .../reader/DataAdapterHandlerReader.java | 21 ++- .../reader/EngineExecuteHandlerReader.java | 5 +- .../query/mapper/DataAdapterMapper.java | 8 ++ .../fateverse/query/mapper/PortalMapper.java | 24 ++++ .../query/portal/PortalDispatchServlet.java | 31 +--- .../portal/service/DispatchSyncService.java | 1 + .../service/DynamicDataSearchService.java | 4 +- .../query/service/PortalService.java | 41 ++++++ .../query/service/impl/PortalServiceImpl.java | 123 ++++++++++------ .../resources/mapper/DataAdapterMapper.xml | 25 +++- .../main/resources/mapper/PortalMapper.xml | 38 ++++- .../resources/mapper/PortalMappingMapper.xml | 7 +- .../cn/fateverse/query/ConsoleCapture.java | 32 +++++ .../java/cn/fateverse/query/DataAdapter.java | 14 -- .../cn/fateverse/query/DataAdapter1100.java | 16 +++ .../fateverse/query/JavaScriptParamTest.java | 77 ++++++++++ .../cn/fateverse/query/JavaScriptTest.java | 122 ++++++++++++++++ .../test/java/cn/fateverse/query/Main.java | 38 +++++ .../java/cn/fateverse/query/SystemOut.java | 45 ++++++ visual/pom.xml | 4 +- .../workflow/process/TriggerService.java | 8 +- 50 files changed, 1353 insertions(+), 235 deletions(-) create mode 100644 common/common-code/src/main/java/cn/fateverse/common/code/console/MultiThreadedCapture.java create mode 100644 common/common-code/src/main/java/cn/fateverse/common/code/model/EngineResult.java create mode 100644 custom-query/custom-query-biz/src/main/java/cn/fateverse/query/config/RestTemplateConfig.java create mode 100644 custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/MockParam.java create mode 100644 custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/AbstractDataAdapterHandler.java create mode 100644 custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/impl/ExternalDataAdapterHandler.java create mode 100644 custom-query/custom-query-biz/src/test/java/cn/fateverse/query/ConsoleCapture.java delete mode 100644 custom-query/custom-query-biz/src/test/java/cn/fateverse/query/DataAdapter.java create mode 100644 custom-query/custom-query-biz/src/test/java/cn/fateverse/query/DataAdapter1100.java create mode 100644 custom-query/custom-query-biz/src/test/java/cn/fateverse/query/JavaScriptParamTest.java create mode 100644 custom-query/custom-query-biz/src/test/java/cn/fateverse/query/JavaScriptTest.java create mode 100644 custom-query/custom-query-biz/src/test/java/cn/fateverse/query/Main.java create mode 100644 custom-query/custom-query-biz/src/test/java/cn/fateverse/query/SystemOut.java diff --git a/common/common-code/pom.xml b/common/common-code/pom.xml index 9dea91f..6daff0a 100644 --- a/common/common-code/pom.xml +++ b/common/common-code/pom.xml @@ -21,6 +21,16 @@ cn.fateverse common-core + + org.graalvm.js + js-scriptengine + 22.1.0 + + + org.graalvm.js + js + 22.1.0 + \ No newline at end of file diff --git a/common/common-code/src/main/java/cn/fateverse/common/code/console/MultiThreadedCapture.java b/common/common-code/src/main/java/cn/fateverse/common/code/console/MultiThreadedCapture.java new file mode 100644 index 0000000..a0f4ddf --- /dev/null +++ b/common/common-code/src/main/java/cn/fateverse/common/code/console/MultiThreadedCapture.java @@ -0,0 +1,45 @@ +package cn.fateverse.common.code.console; + +import cn.fateverse.common.code.model.EngineResult; +import cn.fateverse.common.core.exception.CustomException; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.*; + +/** + * @author Clay + * @date 2024/4/22 17:08 + */ +public class MultiThreadedCapture { + + + private final static ExecutorService executor = Executors.newFixedThreadPool(2); + + + public static EngineResult capture(Task task) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintStream oldOut = System.out; + System.setOut(new PrintStream(baos)); + Object result; + String capturedOutput; + try { + result = task.execute(); + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + System.setOut(oldOut); + // 从捕获的字节数组输出流中获取打印的文本 + capturedOutput = baos.toString(); + } + return new EngineResult(result, capturedOutput); + } + + + public interface Task { + Object execute() throws Exception; + } + + +} diff --git a/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaCodeEngine.java b/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaCodeEngine.java index 180e34e..b15fa60 100644 --- a/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaCodeEngine.java +++ b/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaCodeEngine.java @@ -2,18 +2,21 @@ package cn.fateverse.common.code.engine; import cn.fateverse.common.code.config.JavaCodeProperties; +import cn.fateverse.common.code.console.MultiThreadedCapture; import cn.fateverse.common.code.exception.SandboxClassNotFoundException; import cn.fateverse.common.code.lock.SegmentLock; +import cn.fateverse.common.code.model.EngineResult; import cn.fateverse.common.code.sandbox.SandboxClassLoader; import cn.fateverse.common.code.sandbox.SandboxSecurityManager; +import cn.fateverse.common.core.exception.CustomException; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.springframework.util.ObjectUtils; import javax.tools.JavaCompiler; import javax.tools.ToolProvider; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; +import java.io.*; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; @@ -73,7 +76,7 @@ public class JavaCodeEngine { * @param development 是否为开发环境 开发环境下会将生成的类在执行完成后删除,不是生产环境则会缓存提高运行效率 * @return 执行结果 */ - public T execute(String code, String className, String methodName, Class[] paramClass, Object[] args, boolean development) { + public EngineResult execute(String code, String className, String methodName, Class[] paramClass, Object[] args, boolean development) { if (development) { return developmentExecute(code, className, methodName, paramClass, args); } else { @@ -90,11 +93,10 @@ public class JavaCodeEngine { * @param methodName 方法名 * @param paramClass 参数类型数组 * @param args 参数数组 - * @param 接收泛型 * @return 执行结构 */ @SneakyThrows - private T developmentExecute(String code, String className, String methodName, Class[] paramClass, Object[] args) { + private EngineResult developmentExecute(String code, String className, String methodName, Class[] paramClass, Object[] args) { Class loadClass = null; try { // 加锁,确保类只加载一次 @@ -123,7 +125,8 @@ public class JavaCodeEngine { // 设置安全检查器 System.setSecurityManager(securityManager); // 执行方法并返回结果 - return (T) method.invoke(null, args); + return MultiThreadedCapture.capture(() -> method.invoke(null, args)); + } finally { // 从缓存中移除编译好的类 classCache.remove(className); @@ -155,10 +158,9 @@ public class JavaCodeEngine { * @param methodName 方法名 * @param paramClass 参数类型数组 * @param args 参数数组 - * @param 接收泛型 * @return 执行结构 */ - private T onlineExecute(String code, String className, String methodName, Class[] paramClass, Object[] args) { + private EngineResult onlineExecute(String code, String className, String methodName, Class[] paramClass, Object[] args) { try { Class loadClass = null; loadClass = classCache.get(className); @@ -166,7 +168,8 @@ public class JavaCodeEngine { loadClass = getLoadClass(code, className); Method method = loadClass.getMethod(methodName, paramClass); System.setSecurityManager(securityManager); - return (T) method.invoke(null, args); + Object result = (Object) method.invoke(null, args); + return new EngineResult(result); } } catch (Exception e) { e.printStackTrace(); @@ -215,22 +218,31 @@ public class JavaCodeEngine { * @return 编译完成的类对象 */ private Class compilerClass(String className, String code, URLClassLoader classLoader) { - log.info(code); File tempFile = new File(CLASS_PATH + className + JAVA_SUFFIX); try (FileWriter writer = new FileWriter(tempFile)) { writer.write(code); writer.close(); + ByteArrayOutputStream errorStream = new ByteArrayOutputStream(10240); // 编译.java文件 - compiler.run(null, null, null, tempFile.getPath()); + compiler.run(null, null, errorStream, tempFile.getPath()); + String trace = errorStream.toString();//存放控制台输出的字符串 + if (!ObjectUtils.isEmpty(trace)) { + trace = trace.replace(CLASS_PATH + className + ".", ""); + throw new CustomException("编译错误: " + trace); + } return classLoader.loadClass(className); } catch (Exception e) { e.printStackTrace(); - throw new RuntimeException(e); + if (e instanceof CustomException) { + throw (CustomException) e; + } + throw new CustomException("执行或者编辑错误!"); } } /** * 删除类 + * * @param className 删除类 * @return 删除结果 */ diff --git a/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaScriptEngine.java b/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaScriptEngine.java index 085390d..c54dc58 100644 --- a/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaScriptEngine.java +++ b/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaScriptEngine.java @@ -1,9 +1,17 @@ package cn.fateverse.common.code.engine; -import javax.script.Invocable; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; +import cn.fateverse.common.code.console.MultiThreadedCapture; +import cn.fateverse.common.code.lock.SegmentLock; +import cn.fateverse.common.code.model.EngineResult; +import cn.fateverse.common.core.exception.CustomException; +import com.alibaba.fastjson2.JSON; +import org.graalvm.polyglot.Context; +import org.graalvm.polyglot.Value; +import org.springframework.security.core.parameters.P; + +import javax.script.*; +import java.util.HashMap; +import java.util.Map; /** * js 工具类 @@ -13,25 +21,60 @@ import javax.script.ScriptException; */ public class JavaScriptEngine { + + // 创建 GraalVM 上下文 + private static final Context context = Context.newBuilder() + .allowAllAccess(true) +// .allowHostClassLoading(true) +// .allowIO(true) +// .allowNativeAccess(true) + .build(); + + + private static final Map functionMap = new HashMap<>(); + + /** * 执行js代码 - * @param script js脚本 - * @param function js函数名 - * @param args 参数 + * + * @param script js脚本 + * @param functionName js函数名 + * @param args 参数 * @return 返回结构 - * @param 泛型类型 */ - public static T executeScript(String script, String function, Object... args) { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine engine = manager.getEngineByName("JavaScript"); - try { - engine.eval(script); - Invocable inv = (Invocable) engine; - return (T) inv.invokeFunction(function, args); - } catch (ScriptException | NoSuchMethodException e) { - throw new RuntimeException(e); + public static EngineResult execute(String script, String functionName, boolean development, Object args) { + if (development) { + return MultiThreadedCapture.capture(() -> { + Context context = Context.newBuilder() + .allowAllAccess(true) + .allowHostClassLoading(true) + .allowIO(true) + .allowNativeAccess(true).build(); + context.eval("js", script); + Value executeFunction = context.getBindings("js").getMember(functionName); + Value javaObjectAsValue = Value.asValue(args); + Value result = executeFunction.execute(javaObjectAsValue); + return result.as(Object.class); + }); + } else { + Value executeFunction = getFunction(functionName, script); + Value result = executeFunction.execute(JSON.toJSONString(args)); + return new EngineResult(result.as(Object.class)); } } + private static Value getFunction(String functionName, String script) { + return SegmentLock.lock(functionName, () -> { + if (functionMap.containsKey(functionName)) { + return functionMap.get(functionName); + } + context.eval("js", script); + Value executeFunction = context.getBindings("js").getMember(functionName); + functionMap.put(functionName, executeFunction); + return executeFunction; + }); + } + + } diff --git a/common/common-code/src/main/java/cn/fateverse/common/code/model/EngineResult.java b/common/common-code/src/main/java/cn/fateverse/common/code/model/EngineResult.java new file mode 100644 index 0000000..c3580af --- /dev/null +++ b/common/common-code/src/main/java/cn/fateverse/common/code/model/EngineResult.java @@ -0,0 +1,25 @@ +package cn.fateverse.common.code.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author Clay + * @date 2024/4/22 17:10 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class EngineResult { + + private Object result; + + + private String console; + + + public EngineResult(Object result) { + this.result = result; + } +} diff --git a/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/annotation/Encrypt.java b/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/annotation/Encrypt.java index a378b65..9f2daf5 100644 --- a/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/annotation/Encrypt.java +++ b/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/annotation/Encrypt.java @@ -12,4 +12,23 @@ import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Encrypt { + + Position value() default Position.ALL; + + + EncryptType type() default EncryptType.SM4; + + + enum EncryptType { + + SM4, + + } + + enum Position { + ALL, + OUT, + IN + } + } diff --git a/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/annotation/EncryptField.java b/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/annotation/EncryptField.java index d3d5582..f361306 100644 --- a/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/annotation/EncryptField.java +++ b/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/annotation/EncryptField.java @@ -11,4 +11,12 @@ import java.lang.annotation.Target; @Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface EncryptField { + + Position value() default Position.ALL; + + enum Position { + ALL, + OUT, + IN + } } \ No newline at end of file diff --git a/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/aspect/EncryptAspect.java b/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/aspect/EncryptAspect.java index e72f998..73152dc 100644 --- a/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/aspect/EncryptAspect.java +++ b/common/common-decrypt/src/main/java/cn/fateverse/common/decrypt/aspect/EncryptAspect.java @@ -2,6 +2,7 @@ package cn.fateverse.common.decrypt.aspect; import cn.fateverse.common.core.exception.CustomException; import cn.fateverse.common.core.result.Result; +import cn.fateverse.common.decrypt.annotation.Encrypt; import cn.fateverse.common.decrypt.annotation.EncryptField; import cn.fateverse.common.decrypt.service.EncryptService; import lombok.extern.slf4j.Slf4j; @@ -11,12 +12,10 @@ import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.util.ReflectionUtils; -import javax.annotation.Resource; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Parameter; -import java.util.Collection; -import java.util.List; +import java.util.*; @Slf4j @Aspect @@ -41,36 +40,35 @@ public class EncryptAspect { @Around("@annotation(cn.fateverse.common.decrypt.annotation.Encrypt)") public Object decryptField(ProceedingJoinPoint point) throws Throwable { MethodSignature signature = (MethodSignature) point.getSignature(); - //获取请求参数 - Object[] args = point.getArgs(); //获取方法 Method method = signature.getMethod(); - //获取方法参数 Parameter对象集 参数修饰符、参数名、注解及注解类型 - Parameter[] parameters = method.getParameters(); - for (int i = 0; i < parameters.length; i++) { - Parameter parameter = parameters[i]; - //获取参数注解 - EncryptField encryptField = parameter.getAnnotation(EncryptField.class); - Object arg = args[i]; - if (null != encryptField) { - if (arg instanceof String) { - String decrypt = encryptService.decrypt((String) arg); - args[i] = decrypt; - } else if (arg instanceof List) { - try { - List list = (List) arg; - list.replaceAll(encryptService::decrypt); - args[i] = list; - } catch (Exception e) { - throw new CustomException("接受参数类型错误,请使用String类型的泛型参数"); - } - } - } else if (parameter.getType().getName().startsWith(BASE_PACKAGE)) { //返回一个类对象,该类对象标识此参数对象表示的参数的声明类型 - decrypt(arg); - } + Encrypt encrypt = method.getAnnotation(Encrypt.class); + if (encrypt == null) { + return point.proceed(); + } + //获取请求参数 + Object[] args = point.getArgs(); + if (Encrypt.Position.ALL.equals(encrypt.value()) || Encrypt.Position.IN.equals(encrypt.value())) { + decryptParams(args, method); } //正常执行业务,最后返回的返回值为Result Object proceed = point.proceed(args); + if (Encrypt.Position.ALL.equals(encrypt.value()) || Encrypt.Position.OUT.equals(encrypt.value())) { + Result error = encryptResult(proceed); + if (error != null) { + return error; + } + } + return proceed; + } + + /** + * 加密返回值 + * + * @param proceed 返回执 + * @return 加密结果 + */ + private Result encryptResult(Object proceed) { if (proceed instanceof Result) { Result result = (Result) proceed; Object data = result.getData(); @@ -91,29 +89,71 @@ public class EncryptAspect { return Result.error("加密异常!"); } } - return proceed; + return null; } + /** + * 解密参数 + * + * @param args 参数 + * @param method 方法 + * @throws Exception 异常 + */ + private void decryptParams(Object[] args, Method method) throws Exception { + //获取方法参数 Parameter对象集 参数修饰符、参数名、注解及注解类型 + Parameter[] parameters = method.getParameters(); + for (int i = 0; i < parameters.length; i++) { + Parameter parameter = parameters[i]; + //获取参数注解 + EncryptField encryptField = parameter.getAnnotation(EncryptField.class); + Object arg = args[i]; + if (null != encryptField) { + if (arg instanceof String) { + String decrypt = encryptService.decrypt((String) arg); + args[i] = decrypt; + } else if (arg instanceof List) { + try { + List list = (List) arg; + list.replaceAll(encryptService::decrypt); + args[i] = list; + } catch (Exception e) { + throw new CustomException("接受参数类型错误,请使用String类型的泛型参数"); + } + } + } else if (parameter.getType().getName().startsWith(BASE_PACKAGE)) { + //返回一个类对象,该类对象标识此参数对象表示的参数的声明类型 + decrypt(arg); + } + } + } - private void encrypt(Object data) throws Exception { + /** + * 加密 + * + * @param data 数据 + */ + private void encrypt(Object data) { if (data == null) { return; } Class argClass = data.getClass(); + List fieldList = new ArrayList<>(); if (argClass.getTypeName().startsWith(BASE_PACKAGE)) { - Field[] fields = argClass.getDeclaredFields(); - for (Field field : fields) { + getFields(argClass, fieldList); + for (Field field : fieldList) { EncryptField encryptField = field.getAnnotation(EncryptField.class); field.setAccessible(true); Object value = ReflectionUtils.getField(field, data); if (null == value) { continue; } - if (null != encryptField && value instanceof String) { + if (null != encryptField && value instanceof String + && (EncryptField.Position.ALL.equals(encryptField.value()) + || EncryptField.Position.IN.equals(encryptField.value()))) { String decrypt = encryptService.encrypt((String) value); ReflectionUtils.setField(field, data, decrypt); } else if (field.getType().getName().startsWith(BASE_PACKAGE)) { - if (!value.getClass().isEnum()){ + if (!value.getClass().isEnum()) { encrypt(value); } } else if (value instanceof Collection) { @@ -128,29 +168,49 @@ public class EncryptAspect { for (Object item : collection) { encrypt(item); } + } else if (data instanceof Map) { + Map map = (Map) data; + for (Object key : map.keySet()) { + Object value = map.get(key); + encrypt(key); + encrypt(value); + } } } private void decrypt(Object arg) throws Exception { Class argClass = arg.getClass(); - Field[] fields = argClass.getDeclaredFields(); - for (Field field : fields) { + List fieldList = new ArrayList<>(); + getFields(argClass, fieldList); + for (Field field : fieldList) { EncryptField encryptField = field.getAnnotation(EncryptField.class); field.setAccessible(true); Object value = ReflectionUtils.getField(field, arg); if (null == value) { continue; } - if (null != encryptField && value instanceof String) { + if (null != encryptField && value instanceof String + && (EncryptField.Position.ALL.equals(encryptField.value()) + || EncryptField.Position.OUT.equals(encryptField.value()))) { String decrypt = encryptService.decrypt((String) value); ReflectionUtils.setField(field, arg, decrypt); } else if (field.getType().getName().startsWith(BASE_PACKAGE)) { - if (!value.getClass().isEnum()){ + if (!value.getClass().isEnum()) { decrypt(value); } } } } + + private void getFields(Class argClass, List fieldList) { + if (argClass.getTypeName().startsWith(BASE_PACKAGE)) { + Field[] fields = argClass.getDeclaredFields(); + fieldList.addAll(Arrays.asList(fields)); + getFields(argClass.getSuperclass(), fieldList); + } + } + + } diff --git a/custom-query/custom-query-biz/pom.xml b/custom-query/custom-query-biz/pom.xml index f037425..4e393cf 100644 --- a/custom-query/custom-query-biz/pom.xml +++ b/custom-query/custom-query-biz/pom.xml @@ -76,6 +76,10 @@ cn.fateverse common-excel + + com.squareup.okhttp3 + okhttp + ${project.artifactId} diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/config/RestTemplateConfig.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/config/RestTemplateConfig.java new file mode 100644 index 0000000..3513760 --- /dev/null +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/config/RestTemplateConfig.java @@ -0,0 +1,53 @@ +package cn.fateverse.query.config; + +import okhttp3.ConnectionPool; +import okhttp3.OkHttpClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.OkHttp3ClientHttpRequestFactory; +import org.springframework.web.client.RestTemplate; + +import java.util.concurrent.TimeUnit; + +/** + * @author Clay + * @date 2024/4/22 10:28 + */ +@Configuration +public class RestTemplateConfig { + + + @Bean + public RestTemplate httpRestTemplate() { + ClientHttpRequestFactory factory = httpRequestFactory(); + RestTemplate restTemplate = new RestTemplate(factory); + // 可以添加消息转换 + //restTemplate.setMessageConverters(...); + // 可以增加拦截器 + //restTemplate.setInterceptors(...); + return restTemplate; + } + + public ClientHttpRequestFactory httpRequestFactory() { + return new OkHttp3ClientHttpRequestFactory(okHttpConfigClient()); + } + + public OkHttpClient okHttpConfigClient() { + return new OkHttpClient().newBuilder() + .connectionPool(pool()) + .connectTimeout(1, TimeUnit.SECONDS) + .readTimeout(3, TimeUnit.SECONDS) + .writeTimeout(3, TimeUnit.SECONDS) + .hostnameVerifier((hostname, session) -> true) + // 设置代理 +// .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8888))) + // 拦截器 +// .addInterceptor() + .build(); + } + + public ConnectionPool pool() { + return new ConnectionPool(2000, 300, TimeUnit.SECONDS); + } +} diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/constant/QueryConstant.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/constant/QueryConstant.java index 8c07ad9..efd8172 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/constant/QueryConstant.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/constant/QueryConstant.java @@ -6,9 +6,29 @@ package cn.fateverse.query.constant; */ public class QueryConstant { - + /** + * 自定义查询权限前缀 + */ public static final String PERMISSIONS_KEY = "custom:query:online:"; + /** + * 自定义接口Redis前缀key + */ public static final String PORTAL_KEY = "custom:query:portal:"; + /** + * 接口开发状态 + */ + public static final Integer PORTAL_DEV = 0; + + /** + * 接口发布状态 + */ + public static final Integer PORTAL_PUBLISH = 1; + + /** + * 接口内部使用 + */ + public static final Integer PORTAL_INWARD = 2; + } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/controller/DataAdapterController.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/controller/DataAdapterController.java index f0a9cfd..b7c776b 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/controller/DataAdapterController.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/controller/DataAdapterController.java @@ -66,13 +66,11 @@ public class DataAdapterController { } @ApiOperation("获取数据源适配器详细信息") - @Encrypt @GetMapping("/{adapterId}") @PreAuthorize("@ss.hasPermission('query:adapter:info')") - public Result info(@PathVariable @EncryptField String adapterId) { + public Result info(@PathVariable Long adapterId) { ObjectUtils.checkPk(adapterId); - Long id = Long.valueOf(adapterId); - DataAdapterVo dataAdapter = dataAdapterService.searchById(id); + DataAdapterVo dataAdapter = dataAdapterService.searchById(adapterId); return Result.ok(dataAdapter); } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/controller/PortalController.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/controller/PortalController.java index cac86e4..0e50a59 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/controller/PortalController.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/controller/PortalController.java @@ -5,6 +5,7 @@ import cn.fateverse.common.core.result.page.TableDataInfo; import cn.fateverse.common.core.utils.ObjectUtils; import cn.fateverse.common.decrypt.annotation.Encrypt; import cn.fateverse.common.decrypt.annotation.EncryptField; +import cn.fateverse.query.entity.dto.MockParam; import cn.fateverse.query.entity.dto.PortalDto; import cn.fateverse.query.entity.query.PortalQuery; import cn.fateverse.query.entity.vo.PortalIdWrapper; @@ -36,7 +37,7 @@ public class PortalController { } @ApiOperation("获取接口管理表详细信息") - @Encrypt + @Encrypt(Encrypt.Position.IN) @GetMapping("/{portalId}") @PreAuthorize("@ss.hasPermission('query:portal:info')") public Result info(@PathVariable @EncryptField String portalId) { @@ -47,6 +48,17 @@ public class PortalController { } + @ApiOperation("详情接口") + @Encrypt(Encrypt.Position.IN) + @GetMapping("/detail/{portalId}") + public Result detail(@PathVariable @EncryptField String portalId) { + ObjectUtils.checkPk(portalId); + Long value = Long.valueOf(portalId); + PortalVo portal = portalService.searchDetailById(value); + return Result.ok(portal); + } + + @ApiOperation("获取接口管理表列表") @GetMapping @Encrypt @@ -57,7 +69,7 @@ public class PortalController { } @ApiOperation("新增接口") - @Encrypt + @Encrypt(Encrypt.Position.OUT) @PostMapping @PreAuthorize("@ss.hasPermission('query:portal:add')") public Result add(@RequestBody @Validated PortalDto portalDto) { @@ -66,7 +78,7 @@ public class PortalController { } @ApiOperation("修改接口") - @Encrypt + @Encrypt(Encrypt.Position.OUT) @PutMapping @PreAuthorize("@ss.hasPermission('query:portal:edit')") public Result edit(@RequestBody @Validated PortalDto portalDto) { @@ -76,4 +88,48 @@ public class PortalController { } + @ApiOperation("模拟执行") + @PostMapping("/mock/execute") + @PreAuthorize("@ss.hasPermission('query:portal:execute')") + public Result mockExecute(@RequestBody @Validated MockParam mockParam) { + if (ObjectUtils.isEmpty(mockParam.getCode())) { + return Result.error("代码不能为空"); + } + Object result = portalService.mockExecute(mockParam); + return Result.ok(result); + } + + @ApiOperation("获取接口数据") + @PostMapping("/mock/data") + @PreAuthorize("@ss.hasPermission('query:portal:data')") + public Result mockData(@RequestBody @Validated MockParam mockParam) { + Object result = portalService.mockData(mockParam); + return Result.ok(result); + } + + + @ApiOperation("撤销发布") + @Encrypt + @PutMapping("/cancel/{portalId}") + @PreAuthorize("@ss.hasPermission('query:portal:edit')") + public Result cancel(@PathVariable @EncryptField String portalId) { + ObjectUtils.checkPk(portalId); + Long value = Long.valueOf(portalId); + portalService.cancel(value); + return Result.ok(); + } + + + @ApiOperation("删除接口") + @Encrypt + @DeleteMapping("/{portalId}") + @PreAuthorize("@ss.hasPermission('query:portal:remove')") + public Result remove(@PathVariable @EncryptField String portalId) { + ObjectUtils.checkPk(portalId); + Long value = Long.valueOf(portalId); + portalService.delete(value); + return Result.ok(); + } + + } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/DataAdapter.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/DataAdapter.java index 6b3c62c..a4419b4 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/DataAdapter.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/DataAdapter.java @@ -78,6 +78,9 @@ public class DataAdapter extends BaseEntity { "}\n"; } else if (DataAdapterType.JAVA_SCRIPT.equals(type)) { //JavaScript代码初始化 + this.code = "function execute(data) {\n" + + "\n" + + "}"; } } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/Portal.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/Portal.java index 87a7cbd..d71f3db 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/Portal.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/Portal.java @@ -58,9 +58,16 @@ public class Portal extends BaseEntity { */ private String requestMethod; - + /** + * 是否创建数据适配器 + */ private Boolean createDataAdapter; + /** + * 是否分页 + */ + private Boolean page; + /** * 系统暴露地址 */ diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/PortalMapping.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/PortalMapping.java index d5cb4cc..e97e18c 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/PortalMapping.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/PortalMapping.java @@ -43,12 +43,23 @@ public class PortalMapping { * 映射值 自定义查询映射值为查询条件的id 第三方接口则为接口查询的key */ private String mappingValue; + /** + * 输入类型 + */ + private String inputType; + + /** + * 描述 + */ + private String description; public Boolean check() { if (ObjectUtils.isEmpty(mappingKey) || ObjectUtils.isEmpty(mappingValue) - || ObjectUtils.isEmpty(mappingType)){ + || ObjectUtils.isEmpty(mappingType) +// || ObjectUtils.isEmpty(inputType) + ) { return Boolean.FALSE; } return Boolean.TRUE; diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/bo/PortalBo.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/bo/PortalBo.java index b70e1b6..6627664 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/bo/PortalBo.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/bo/PortalBo.java @@ -25,6 +25,8 @@ public class PortalBo implements Serializable { private Long adapterId; private PortalEnum type; private String requestMethod; + private Boolean createDataAdapter; + private Boolean page; private String path; private String url; private Integer state; @@ -37,6 +39,8 @@ public class PortalBo implements Serializable { .adapterId(portal.getAdapterId()) .type(portal.getType()) .requestMethod(portal.getRequestMethod()) + .createDataAdapter(portal.getCreateDataAdapter()) + .page(portal.getPage()) .path(portal.getPath()) .url(portal.getUrl()) .state(portal.getState()) diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/MockParam.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/MockParam.java new file mode 100644 index 0000000..0cadc5b --- /dev/null +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/MockParam.java @@ -0,0 +1,33 @@ +package cn.fateverse.query.entity.dto; + +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * @author Clay + * @date 2024/4/21 19:07 + */ +@Data +public class MockParam { + + @NotNull(message = "id不能为空") + private Long portalId; + + private String code; + + private Integer pageSize; + + private Integer pageNum; + + private List params; + + @Data + public static class Param { + + private String key; + + private Object value; + } +} diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/PortalDto.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/PortalDto.java index f110fd6..864cd8c 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/PortalDto.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/PortalDto.java @@ -70,6 +70,11 @@ public class PortalDto { @NotNull(message = "是否创建数据适配器不能为空!") private Boolean createDataAdapter; + /** + * 是否分页 + */ + private Boolean page; + /** * 系统暴露地址 */ @@ -113,6 +118,7 @@ public class PortalDto { .anonymity(anonymity) .createDataAdapter(createDataAdapter) .requestMethod(requestMethod) + .page(page) .type(type) .path(path) .url(url) @@ -120,7 +126,7 @@ public class PortalDto { .build(); try { RequestMethod.valueOf(requestMethod); - }catch (Exception e){ + } catch (Exception e) { throw new RuntimeException("请求类型不支持!"); } if (!ObjectUtils.isEmpty(portalId)) { diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/query/PortalQuery.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/query/PortalQuery.java index 41b6a27..5d5465b 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/query/PortalQuery.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/query/PortalQuery.java @@ -1,4 +1,4 @@ -package cn.fateverse.query.entity.query; +package cn.fateverse.query.entity.query; import cn.fateverse.query.enums.PortalEnum; import io.swagger.annotations.ApiModel; @@ -42,4 +42,6 @@ public class PortalQuery { */ @ApiModelProperty("系统暴露地址") private String path; + + private Integer state; } \ No newline at end of file diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/vo/PortalVo.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/vo/PortalVo.java index f514e5c..4b94fcb 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/vo/PortalVo.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/vo/PortalVo.java @@ -2,6 +2,7 @@ package cn.fateverse.query.entity.vo; import cn.fateverse.query.entity.Portal; import cn.fateverse.query.entity.PortalMapping; +import com.fasterxml.jackson.annotation.JsonInclude; import io.swagger.annotations.ApiModel; import lombok.Data; import org.springframework.beans.BeanUtils; @@ -20,12 +21,32 @@ import java.util.List; @ApiModel("接口详细管理表Vo") public class PortalVo extends SimplePortalVo { + /** + * 查询类型 + */ private Integer queryType; + /** + * 是否创建数据适配器 + */ private Boolean createDataAdapter; + /** + * 是否分页 + */ + private Boolean page; + + /** + * 条件映射 + */ private List mappings; + /** + * 数据适配器信息 + */ + @JsonInclude(JsonInclude.Include.NON_NULL) + private DataAdapterVo dataAdapter; + public static PortalVo toPortalVo(Portal portal) { return toPortalVo(portal, null); } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/vo/SimplePortalVo.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/vo/SimplePortalVo.java index 2df83c3..9131023 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/vo/SimplePortalVo.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/vo/SimplePortalVo.java @@ -37,16 +37,14 @@ public class SimplePortalVo { * 自定义查询id */ @ApiModelProperty("自定义查询id") - @EncryptField - private String queryId; + private Long queryId; /** * 数据适配器id */ @ApiModelProperty("数据适配器id") - @EncryptField - private String adapterId; + private Long adapterId; /** * 接口名称 @@ -127,6 +125,8 @@ public class SimplePortalVo { .portalId(String.valueOf(portal.getPortalId())) .portalName(portal.getPortalName()) .anonymity(portal.getAnonymity()) + .queryId(portal.getQueryId()) + .adapterId(portal.getAdapterId()) .type(portal.getType()) .path(portal.getPath()) .state(portal.getState()) @@ -136,12 +136,6 @@ public class SimplePortalVo { .build(); portalVo.setCreateTime(portal.getCreateTime()); portalVo.setUpdateTime(portal.getUpdateTime()); - if (!ObjectUtils.isEmpty(portal.getQueryId())) { - portalVo.setQueryId(String.valueOf(portal.getQueryId())); - } - if (!ObjectUtils.isEmpty(portal.getAdapterId())) { - portalVo.setAdapterId(String.valueOf(portal.getAdapterId())); - } return portalVo; } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/AbstractDataAdapterHandler.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/AbstractDataAdapterHandler.java new file mode 100644 index 0000000..269d7f8 --- /dev/null +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/AbstractDataAdapterHandler.java @@ -0,0 +1,73 @@ +package cn.fateverse.query.handler.adapter; + +import cn.fateverse.common.code.model.EngineResult; +import cn.fateverse.query.entity.DataAdapter; +import cn.fateverse.query.handler.reader.EngineExecuteHandlerReader; +import cn.fateverse.query.mapper.DataAdapterMapper; +import org.springframework.util.ObjectUtils; + +/** + * @author Clay + * @date 2024/4/19 22:44 + */ +public abstract class AbstractDataAdapterHandler implements DataAdapterHandler { + + protected final DataAdapterMapper dataAdapterMapper; + + + protected final EngineExecuteHandlerReader handlerReader; + + + protected AbstractDataAdapterHandler(DataAdapterMapper dataAdapterMapper, EngineExecuteHandlerReader handlerReader) { + this.dataAdapterMapper = dataAdapterMapper; + this.handlerReader = handlerReader; + } + + protected Object execute(Long adapterId, Object data, boolean development) { + if (ObjectUtils.isEmpty(adapterId)) { + return data; + } + //获取当当前接口对应的数据适配器 + DataAdapter dataAdapter = dataAdapterMapper.selectById(adapterId); + if (ObjectUtils.isEmpty(dataAdapter)) { + throw new RuntimeException("dataAdapter is null"); + } + handlerReader.preconditioning(dataAdapter); + EngineResult execute = handlerReader.execute(dataAdapter, data, development); + if (ObjectUtils.isEmpty(execute)) { + throw new RuntimeException("执行结果错误"); + } + return execute.getResult(); + } + + + protected EngineResult mockExecute(Long adapterId, String code, Object data, boolean development) { + //获取当当前接口对应的数据适配器 + DataAdapter dataAdapter = dataAdapterMapper.selectById(adapterId); + if (ObjectUtils.isEmpty(dataAdapter)) { + throw new RuntimeException("dataAdapter is null"); + } + dataAdapter.setCode(code); + handlerReader.preconditioning(dataAdapter); + EngineResult execute = handlerReader.execute(dataAdapter, data, development); + if (ObjectUtils.isEmpty(execute)) { + throw new RuntimeException("执行结果错误"); + } + dataAdapterMapper.updateCode(dataAdapter); + return execute; + } + + + @Override + public boolean remove(Long adapterId) { + if (ObjectUtils.isEmpty(adapterId)) { + throw new RuntimeException("adapterId is null"); + } + DataAdapter dataAdapter = dataAdapterMapper.selectById(adapterId); + if (ObjectUtils.isEmpty(dataAdapter)) { + throw new RuntimeException("dataAdapter is null"); + } + return handlerReader.remove(dataAdapter); + } + +} diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/DataAdapterHandler.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/DataAdapterHandler.java index 32d4638..a2c12b2 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/DataAdapterHandler.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/DataAdapterHandler.java @@ -1,8 +1,10 @@ package cn.fateverse.query.handler.adapter; -import cn.fateverse.query.entity.DataAdapter; +import cn.fateverse.query.entity.dto.MockParam; import cn.fateverse.query.entity.bo.PortalBo; +import javax.servlet.http.HttpServletRequest; + /** * @author Clay * @date 2023-10-31 20:52 @@ -12,19 +14,27 @@ public interface DataAdapterHandler { /** * 模拟执行 * - * @param dataAdapter 数据适配器信息 - * @param portal + * @param portal 接口对象 + * @param mockParam 请求头 * @return 执行结果 */ - Object mockExecute(DataAdapter dataAdapter, PortalBo portal, Object param); + Object mockExecute(PortalBo portal, MockParam mockParam); /** * 真实执行 * - * @param dataAdapter 数据适配器信息 - * @param portal + * @param portal 接口对象 + * @param request * @return 执行结果 */ - Object execute(DataAdapter dataAdapter, PortalBo portal, Object param); + Object execute(PortalBo portal, HttpServletRequest request); + + /** + * 删除数据适配器 + * + * @param adapterId 数据适配器id + * @return 删除结果 + */ + boolean remove(Long adapterId); } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/impl/ExternalDataAdapterHandler.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/impl/ExternalDataAdapterHandler.java new file mode 100644 index 0000000..2682ec4 --- /dev/null +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/impl/ExternalDataAdapterHandler.java @@ -0,0 +1,73 @@ +package cn.fateverse.query.handler.adapter.impl; + +import cn.fateverse.common.core.exception.CustomException; +import cn.fateverse.query.entity.dto.MockParam; +import cn.fateverse.query.entity.bo.PortalBo; +import cn.fateverse.query.enums.PortalEnum; +import cn.fateverse.query.handler.adapter.AbstractDataAdapterHandler; +import cn.fateverse.query.handler.reader.EngineExecuteHandlerReader; +import cn.fateverse.query.mapper.DataAdapterMapper; +import com.alibaba.fastjson2.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; + +/** + * @author Clay + * @date 2024/4/19 22:12 + */ +@Slf4j +@Service +public class ExternalDataAdapterHandler extends AbstractDataAdapterHandler { + + /** + * 请求对象 + */ + private final RestTemplate restTemplate; + + public ExternalDataAdapterHandler(DataAdapterMapper dataAdapterMapper, + EngineExecuteHandlerReader handlerReader, + RestTemplate restTemplate) { + super(dataAdapterMapper, handlerReader); + this.restTemplate = restTemplate; + } + + + @Override + public Object mockExecute(PortalBo portal, MockParam mockParam) { + if (!PortalEnum.EXTERNAL.equals(portal.getType())) { + return null; + } + HttpHeaders headers = new HttpHeaders(); + MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8"); + headers.setContentType(type); + headers.add("Accept", MediaType.APPLICATION_JSON.toString()); + HashMap map = new HashMap<>(); + JSONObject response = null; + switch (portal.getRequestMethod()) { + case "GET": + response = restTemplate.getForObject(portal.getUrl(), JSONObject.class, map); + break; + case "POST": + response = restTemplate.postForObject(portal.getUrl(), map, JSONObject.class); + break; + default: + throw new CustomException("请求方式错误"); + } + if (portal.getCreateDataAdapter()) { + return super.execute(portal.getAdapterId(), response, true); + } else { + return response; + } + } + + @Override + public Object execute(PortalBo portal, HttpServletRequest request) { + return null; + } +} diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/impl/LocalDataAdapterHandler.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/impl/LocalDataAdapterHandler.java index d5cd0c3..556de02 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/impl/LocalDataAdapterHandler.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/impl/LocalDataAdapterHandler.java @@ -2,20 +2,23 @@ package cn.fateverse.query.handler.adapter.impl; import cn.fateverse.common.core.exception.CustomException; import cn.fateverse.common.core.result.page.TableDataInfo; -import cn.fateverse.query.entity.DataAdapter; +import cn.fateverse.query.entity.dto.MockParam; +import cn.fateverse.query.entity.PortalMapping; import cn.fateverse.query.entity.UniQuery; import cn.fateverse.query.entity.bo.PortalBo; -import cn.fateverse.query.entity.dto.SearchInfo; +import cn.fateverse.query.entity.dto.UniConDto; import cn.fateverse.query.enums.PortalEnum; -import cn.fateverse.query.handler.adapter.DataAdapterHandler; +import cn.fateverse.query.handler.adapter.AbstractDataAdapterHandler; import cn.fateverse.query.handler.reader.EngineExecuteHandlerReader; +import cn.fateverse.query.mapper.DataAdapterMapper; import cn.fateverse.query.mapper.UniQueryMapper; import cn.fateverse.query.service.DynamicDataSearchService; -import com.alibaba.fastjson2.JSON; -import com.alibaba.fastjson2.TypeReference; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.util.ObjectUtils; +import javax.servlet.http.HttpServletRequest; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -25,55 +28,86 @@ import java.util.Map; */ @Slf4j @Service -public class LocalDataAdapterHandler implements DataAdapterHandler { +public class LocalDataAdapterHandler extends AbstractDataAdapterHandler { private final UniQueryMapper uniQueryMapper; - - private final EngineExecuteHandlerReader handlerReader; - private final DynamicDataSearchService dynamicDataSearchService; public LocalDataAdapterHandler(UniQueryMapper uniQueryMapper, + DataAdapterMapper dataAdapterMapper, EngineExecuteHandlerReader handlerReader, DynamicDataSearchService dynamicDataSearchService) { + super(dataAdapterMapper, handlerReader); this.uniQueryMapper = uniQueryMapper; - this.handlerReader = handlerReader; this.dynamicDataSearchService = dynamicDataSearchService; } @Override - public Object mockExecute(DataAdapter dataAdapter, PortalBo portal, Object param) { + public Object mockExecute(PortalBo portal, MockParam mockParam) { if (portal.getType() != PortalEnum.LOCAL) { return null; } - handlerReader.preconditioning(dataAdapter); - if (null == param) { - throw new CustomException("参数对象不能为空"); + //自定义查询编辑查询对象 + List uniConList = new ArrayList<>(); + if (!ObjectUtils.isEmpty(mockParam.getParams())) { + for (MockParam.Param param : mockParam.getParams()) { + if (!ObjectUtils.isEmpty(param.getKey()) && !ObjectUtils.isEmpty(param.getValue())) { + UniConDto uniCon = new UniConDto(); + uniCon.setQuery(param.getValue()); + uniCon.setUcId(Long.parseLong(param.getKey())); + } + } } - if (!(param instanceof SearchInfo)) { - throw new CustomException("数据类型不匹配"); - } - SearchInfo info = (SearchInfo) param; UniQuery query = uniQueryMapper.selectSampleById(portal.getQueryId()); if (null == query) { throw new CustomException("数据源为空!"); } //根据设置的参数动态调整当前是否需要分页操作 - TableDataInfo> tableDataInfo = dynamicDataSearchService.searchData(info.getList(), query, null, Boolean.TRUE); - return handlerReader.execute(dataAdapter, tableDataInfo.getRows(), true); + TableDataInfo> tableDataInfo = dynamicDataSearchService.searchData(uniConList, query, null, Boolean.TRUE); + if (portal.getCreateDataAdapter()) { + return super.mockExecute(portal.getAdapterId(), mockParam.getCode(), tableDataInfo.getRows(), true); + } else { + return tableDataInfo.getRows(); + } } @Override - public Object execute(DataAdapter dataAdapter, PortalBo portal, Object param) { + public Object execute(PortalBo portal, HttpServletRequest request) { if (portal.getType() != PortalEnum.LOCAL) { return null; } - handlerReader.preconditioning(dataAdapter); - List> data = JSON.parseObject(dataAdapter.getMockData(), new TypeReference>>() { - }); - return handlerReader.execute(dataAdapter, data, false); + //自定义查询编辑查询对象 + List uniConList = new ArrayList<>(); + //根据映射关系从request中获取请求参数 + for (PortalMapping portalMapping : portal.getMappings()) { + UniConDto uniCon = new UniConDto(); + String mappingValue = portalMapping.getMappingValue(); + String mappingKey = portalMapping.getMappingKey(); + uniCon.setUcId(Long.parseLong(mappingValue)); + if (portalMapping.getMappingType() == 0) { + uniCon.setQuery(request.getParameter(mappingKey)); + } else if (portalMapping.getMappingType() == 1) { + uniCon.setQuery(request.getHeaders(mappingKey)); + } else { + uniCon.setQuery(request.getParameter(mappingKey)); + } + uniConList.add(uniCon); + } + UniQuery query = uniQueryMapper.selectSampleById(portal.getQueryId()); + if (null == query) { + throw new CustomException("数据源为空!"); + } + //根据设置的参数动态调整当前是否需要分页操作 + TableDataInfo> tableDataInfo = dynamicDataSearchService.searchData(uniConList, query, null, Boolean.TRUE); + if (portal.getCreateDataAdapter()) { + return super.execute(portal.getAdapterId(), tableDataInfo.getRows(), false); + } else { + return tableDataInfo.getRows(); + } } + + } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/engine/EngineExecuteHandler.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/engine/EngineExecuteHandler.java index 708b751..5db4504 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/engine/EngineExecuteHandler.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/engine/EngineExecuteHandler.java @@ -1,5 +1,6 @@ package cn.fateverse.query.handler.engine; +import cn.fateverse.common.code.model.EngineResult; import cn.fateverse.query.entity.DataAdapter; public interface EngineExecuteHandler { @@ -13,7 +14,7 @@ public interface EngineExecuteHandler { * @param development * @return JSONObject对象 */ - Object execute(DataAdapter dataAdapter, Object data, boolean development); + EngineResult execute(DataAdapter dataAdapter, Object data, boolean development); /** * 预处理数据适配器 @@ -25,6 +26,7 @@ public interface EngineExecuteHandler { /** * 删除数据适配器 + * * @param dataAdapter 数据适配器 * @return 删除结果 */ diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/engine/impl/JavaEngineExecuteHandler.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/engine/impl/JavaEngineExecuteHandler.java index 357f509..431f03d 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/engine/impl/JavaEngineExecuteHandler.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/engine/impl/JavaEngineExecuteHandler.java @@ -1,6 +1,7 @@ package cn.fateverse.query.handler.engine.impl; import cn.fateverse.common.code.engine.JavaCodeEngine; +import cn.fateverse.common.code.model.EngineResult; import cn.fateverse.common.core.exception.CustomException; import cn.fateverse.query.entity.DataAdapter; import cn.fateverse.query.enums.DataAdapterType; @@ -31,8 +32,8 @@ public class JavaEngineExecuteHandler implements EngineExecuteHandler { @Override - public Object execute(DataAdapter dataAdapter, Object data, boolean development) { - if (!DataAdapterType.JAVA.equals(dataAdapter.getType())){ + public EngineResult execute(DataAdapter dataAdapter, Object data, boolean development) { + if (!DataAdapterType.JAVA.equals(dataAdapter.getType())) { return null; } return javaCodeEngine.execute(dataAdapter.getExecuteCode(), getClassName(dataAdapter), diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/engine/impl/JavaScriptEngineExecuteHandler.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/engine/impl/JavaScriptEngineExecuteHandler.java index 945ea28..9f08e1a 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/engine/impl/JavaScriptEngineExecuteHandler.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/engine/impl/JavaScriptEngineExecuteHandler.java @@ -1,12 +1,17 @@ package cn.fateverse.query.handler.engine.impl; import cn.fateverse.common.code.engine.JavaScriptEngine; +import cn.fateverse.common.code.model.EngineResult; +import cn.fateverse.common.core.exception.CustomException; import cn.fateverse.query.entity.DataAdapter; import cn.fateverse.query.enums.DataAdapterType; import cn.fateverse.query.handler.engine.EngineExecuteHandler; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** * JavaScript 代码执行器 * @@ -18,19 +23,31 @@ import org.springframework.stereotype.Component; public class JavaScriptEngineExecuteHandler implements EngineExecuteHandler { @Override - public Object execute(DataAdapter dataAdapter, Object data, boolean development) { + public EngineResult execute(DataAdapter dataAdapter, Object data, boolean development) { if (!DataAdapterType.JAVA_SCRIPT.equals(dataAdapter.getType())) { return null; } - return JavaScriptEngine.executeScript(dataAdapter.getExecuteCode(), "execute", data); + return JavaScriptEngine.execute(dataAdapter.getExecuteCode(), "execute" + dataAdapter.getAdapterId(), development, data); } @Override public Boolean preconditioning(DataAdapter dataAdapter) { - if (DataAdapterType.JAVA_SCRIPT.equals(dataAdapter.getType())) { - return Boolean.TRUE; + if (!DataAdapterType.JAVA_SCRIPT.equals(dataAdapter.getType())) { + return Boolean.FALSE; } - return Boolean.FALSE; + String code = dataAdapter.getCode(); + // 正则表达式匹配类定义 + String regex = "function .*? "; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(code); + if (matcher.find()) { + // 执行替换操作 + String replacedCode = code.replaceFirst(regex, "function execute" + dataAdapter.getAdapterId() + "(data) "); + dataAdapter.setExecuteCode(replacedCode); + } else { + throw new CustomException("请勿修改类定义"); + } + return Boolean.TRUE; } @Override diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/reader/DataAdapterHandlerReader.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/reader/DataAdapterHandlerReader.java index 4975f8c..6ff1a29 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/reader/DataAdapterHandlerReader.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/reader/DataAdapterHandlerReader.java @@ -2,12 +2,13 @@ package cn.fateverse.query.handler.reader; import cn.fateverse.common.core.exception.CustomException; -import cn.fateverse.query.entity.DataAdapter; +import cn.fateverse.query.entity.dto.MockParam; import cn.fateverse.query.entity.bo.PortalBo; import cn.fateverse.query.handler.adapter.DataAdapterHandler; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import javax.servlet.http.HttpServletRequest; import java.util.List; /** @@ -28,9 +29,9 @@ public class DataAdapterHandlerReader { } - public Object mockExecute(DataAdapter dataAdapter, PortalBo portal, Object params) { + public Object mockExecute(PortalBo portal, MockParam mockParam) { for (DataAdapterHandler dataAdapterHandler : handlerList) { - Object result = dataAdapterHandler.mockExecute(dataAdapter, portal, params); + Object result = dataAdapterHandler.mockExecute(portal, mockParam); if (result != null) { return result; } @@ -39,9 +40,9 @@ public class DataAdapterHandlerReader { } - public Object execute(DataAdapter dataAdapter, PortalBo portal, Object params) { + public Object execute(PortalBo portal, HttpServletRequest request) { for (DataAdapterHandler dataAdapterHandler : handlerList) { - Object result = dataAdapterHandler.execute(dataAdapter, portal, params); + Object result = dataAdapterHandler.execute(portal, request); if (result != null) { return result; } @@ -49,5 +50,15 @@ public class DataAdapterHandlerReader { throw new CustomException("当前数据源类型不支持!"); } + public Boolean remove(Long adaptorId) { + for (DataAdapterHandler dataAdapterHandler : handlerList) { + boolean result = dataAdapterHandler.remove(adaptorId); + if (result) { + return true; + } + } + return false; + } + } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/reader/EngineExecuteHandlerReader.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/reader/EngineExecuteHandlerReader.java index 7e84e5e..60a3e93 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/reader/EngineExecuteHandlerReader.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/reader/EngineExecuteHandlerReader.java @@ -1,5 +1,6 @@ package cn.fateverse.query.handler.reader; +import cn.fateverse.common.code.model.EngineResult; import cn.fateverse.query.entity.DataAdapter; import cn.fateverse.query.handler.engine.EngineExecuteHandler; import lombok.extern.slf4j.Slf4j; @@ -47,11 +48,11 @@ public class EngineExecuteHandlerReader { * @param data 数据列表 * @return 执行结果 */ - public Object execute(DataAdapter dataAdapter, Object data, boolean development) { + public EngineResult execute(DataAdapter dataAdapter, Object data, boolean development) { // 遍历引擎执行处理器列表 for (EngineExecuteHandler engineExecuteHandler : handlerList) { // 执行数据适配器的处理方法 - Object result = engineExecuteHandler.execute(dataAdapter, data, development); + EngineResult result = engineExecuteHandler.execute(dataAdapter, data, development); if (result != null) { return result; } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/mapper/DataAdapterMapper.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/mapper/DataAdapterMapper.java index 02e293d..f469b42 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/mapper/DataAdapterMapper.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/mapper/DataAdapterMapper.java @@ -48,6 +48,14 @@ public interface DataAdapterMapper { */ int update(DataAdapter dataAdapter); + /** + * 更新代码 + * + * @param dataAdapter 数据适配器 + * @return 结果 + */ + int updateCode(DataAdapter dataAdapter); + /** * 删除数据源适配器 * diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/mapper/PortalMapper.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/mapper/PortalMapper.java index 6e8961c..41c97e9 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/mapper/PortalMapper.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/mapper/PortalMapper.java @@ -48,4 +48,28 @@ public interface PortalMapper { * @return 更新数量 */ int insert(Portal portal); + + /** + * 修改接口 + * + * @param portal 接口信息 + * @return 更新数量 + */ + int update(Portal portal); + + /** + * 更新状态 + * + * @param portalId 接口id + * @param state 状态 + */ + void updateState(@Param("portalId") Long portalId, @Param("state") Integer state); + + /** + * 删除 + * + * @param portalId id + * @return 删除行数 + */ + int deleteById(Long portalId); } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/portal/PortalDispatchServlet.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/portal/PortalDispatchServlet.java index fe80175..cf443cf 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/portal/PortalDispatchServlet.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/portal/PortalDispatchServlet.java @@ -70,34 +70,13 @@ public class PortalDispatchServlet { portalBo = PortalBo.toPortalBo(portal, portalMappings); redisTemplate.opsForValue().set(QueryConstant.PORTAL_KEY + portalBo.getPath() + ":" + portalBo.getRequestMethod(), portalBo); } - //自定义查询编辑查询对象 - SearchInfo searchInfo = new SearchInfo(); - List uniConList = new ArrayList<>(); - //根据映射关系从request中获取请求参数 - for (PortalMapping portalMapping : portalBo.getMappings()) { - UniConDto uniCon = new UniConDto(); - String mappingValue = portalMapping.getMappingValue(); - String mappingKey = portalMapping.getMappingKey(); - uniCon.setUcId(Long.parseLong(mappingValue)); - if (portalMapping.getMappingType() == 0) { - uniCon.setQuery(request.getParameter(mappingKey)); - } else if (portalMapping.getMappingType() == 1) { - uniCon.setQuery(request.getHeaders(mappingKey)); - } else { - uniCon.setQuery(request.getParameter(mappingKey)); - } - uniConList.add(uniCon); - } - searchInfo.setList(uniConList); - //获取当当前接口对应的数据适配器 - DataAdapter dataAdapter = dataAdapterMapper.selectById(portalBo.getAdapterId()); //进行数据适配器的执行逻辑 Object result = null; - if (portalBo.getState() == 1 || portalBo.getState() == 2) { - result = dataAdapterHandler.execute(dataAdapter, portalBo, searchInfo); - } else { - result = dataAdapterHandler.mockExecute(dataAdapter, portalBo, searchInfo); - } +// if (portalBo.getState() == 1 || portalBo.getState() == 2) { + result = dataAdapterHandler.execute(portalBo, request); +// } else { +// result = dataAdapterHandler.mockExecute(portalBo, request); +// } //将返回结果放入response ResponseRender.renderString(response, Result.ok(result)); } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/portal/service/DispatchSyncService.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/portal/service/DispatchSyncService.java index 89d2705..9e11fb2 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/portal/service/DispatchSyncService.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/portal/service/DispatchSyncService.java @@ -140,6 +140,7 @@ public class DispatchSyncService { } } } catch (NacosException e) { + log.error("NacosException: {}", e.getMessage()); throw new RuntimeException(e); } } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/DynamicDataSearchService.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/DynamicDataSearchService.java index d9221bc..9117eac 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/DynamicDataSearchService.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/DynamicDataSearchService.java @@ -71,7 +71,9 @@ public class DynamicDataSearchService { } else { uniConList = uniConMapper.selectByQueryIdAndUcIdList(query.getId(), ids); } - uniConList = uniConList.stream().filter(uniCon -> null != queryMap.get(uniCon.getUcId())).peek(uniCon -> uniCon.setUcMock(queryMap.get(uniCon.getUcId()))).collect(Collectors.toList()); + uniConList = uniConList.stream().filter(uniCon -> null != queryMap.get(uniCon.getUcId())) + .peek(uniCon -> uniCon.setUcMock(queryMap.get(uniCon.getUcId()))) + .collect(Collectors.toList()); if (query.getType() == 1) { SqlSelect select = new SqlSelect(); select.setSelectSql(query.getUqSql()); diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/PortalService.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/PortalService.java index 77fa46f..c5a870d 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/PortalService.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/PortalService.java @@ -1,6 +1,7 @@ package cn.fateverse.query.service; import cn.fateverse.common.core.result.page.TableDataInfo; +import cn.fateverse.query.entity.dto.MockParam; import cn.fateverse.query.entity.dto.PortalDto; import cn.fateverse.query.entity.query.PortalQuery; import cn.fateverse.query.entity.vo.PortalIdWrapper; @@ -21,6 +22,14 @@ public interface PortalService { */ PortalVo searchById(Long portalId); + /** + * 根据id查询详情 + * + * @param portalId id + * @return 结果 + */ + PortalVo searchDetailById(Long portalId); + /** * 查询接口列表 * @@ -29,6 +38,23 @@ public interface PortalService { */ TableDataInfo searchList(PortalQuery query); + /** + * 模拟执行 + * + * @param mockParam 执行数据 + * @return 执行结果 + */ + Object mockExecute(MockParam mockParam); + + + /** + * 获取到模拟数据 + * + * @param mockParam + * @return + */ + Object mockData(MockParam mockParam); + /** * 保存接口信息 * @@ -44,4 +70,19 @@ public interface PortalService { * @return 修改完成后接口id和数据适配器id */ PortalIdWrapper edit(PortalDto portalDto); + + /** + * 取消发布 + * + * @param portalId 接口id + */ + void cancel(Long portalId); + + /** + * 删除接口信息 + * + * @param portalId 接口id + */ + void delete(Long portalId); + } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java index b41e856..0b3ad93 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java @@ -3,14 +3,14 @@ package cn.fateverse.query.service.impl; import cn.fateverse.common.core.exception.CustomException; import cn.fateverse.common.core.result.page.TableDataInfo; import cn.fateverse.common.mybatis.utils.PageUtils; +import cn.fateverse.query.entity.*; import cn.fateverse.query.entity.bo.PortalBo; +import cn.fateverse.query.entity.dto.MockParam; +import cn.fateverse.query.entity.vo.DataAdapterVo; import cn.fateverse.query.entity.vo.PortalIdWrapper; +import cn.fateverse.query.handler.reader.DataAdapterHandlerReader; import cn.fateverse.query.portal.service.HandlerMethodService; import cn.fateverse.query.constant.QueryConstant; -import cn.fateverse.query.entity.DataAdapter; -import cn.fateverse.query.entity.Portal; -import cn.fateverse.query.entity.PortalMapping; -import cn.fateverse.query.entity.UniQuery; import cn.fateverse.query.entity.dto.DataAdapterDto; import cn.fateverse.query.entity.dto.PortalDto; import cn.fateverse.query.entity.query.PortalQuery; @@ -32,7 +32,6 @@ import org.springframework.web.bind.annotation.RequestMethod; import javax.annotation.Resource; import java.util.*; -import java.util.function.Function; import java.util.stream.Collectors; /** @@ -57,19 +56,26 @@ public class PortalServiceImpl implements PortalService { private final PortalMappingMapper portalMappingMapper; + + private final DataAdapterHandlerReader handlerReader; + public PortalServiceImpl(PortalMapper portalMapper, UniQueryMapper queryMapper, DataAdapterMapper adapterMapper, PortalMappingMapper portalMappingMapper, ThreadPoolTaskExecutor taskExecuteExecutor, - HandlerMethodService methodService) { + HandlerMethodService methodService, + DataAdapterHandlerReader handlerReader) { this.portalMapper = portalMapper; this.queryMapper = queryMapper; this.adapterMapper = adapterMapper; this.portalMappingMapper = portalMappingMapper; this.methodService = methodService; + this.handlerReader = handlerReader; taskExecuteExecutor.execute(() -> { - List portalList = portalMapper.selectList(new PortalQuery()); + PortalQuery query = new PortalQuery(); +// query.setState(QueryConstant.PORTAL_PUBLISH); + List portalList = portalMapper.selectList(query); if (ObjectUtils.isEmpty(portalList)) { log.info("portal is empty!"); return; @@ -116,6 +122,20 @@ public class PortalServiceImpl implements PortalService { return portalVo; } + @Override + public PortalVo searchDetailById(Long portalId) { + PortalVo portalVo = searchById(portalId); + if (!ObjectUtils.isEmpty(portalVo.getAdapterId()) && portalVo.getCreateDataAdapter()) { + DataAdapter dataAdapter = adapterMapper.selectById(portalVo.getAdapterId()); + if (ObjectUtils.isEmpty(dataAdapter)) { + return portalVo; + } + DataAdapterVo dataAdapterVo = DataAdapterVo.toDataAdapterVo(dataAdapter); + portalVo.setDataAdapter(dataAdapterVo); + } + return portalVo; + } + @Override public TableDataInfo searchList(PortalQuery query) { PageUtils.startPage(); @@ -162,6 +182,21 @@ public class PortalServiceImpl implements PortalService { }); } + @Override + public Object mockExecute(MockParam mockParam) { + Portal portal = portalMapper.selectById(mockParam.getPortalId()); + PortalBo portalBo = PortalBo.toPortalBo(portal, null); + return handlerReader.mockExecute(portalBo, mockParam); + } + + + @Override + public Object mockData(MockParam mockParam) { + Portal portal = portalMapper.selectById(mockParam.getPortalId()); + PortalBo portalBo = PortalBo.toPortalBo(portal, null); + portalBo.setCreateDataAdapter(false); + return handlerReader.mockExecute(portalBo, mockParam); + } @Override @Transactional(rollbackFor = Exception.class) @@ -176,7 +211,7 @@ public class PortalServiceImpl implements PortalService { if (ObjectUtils.isEmpty(uniQuery)) { throw new CustomException("未找到对应的查询接口!"); } - portal.setState(0); + portal.setState(QueryConstant.PORTAL_DEV); // 判断是否需要创建数据适配器 if (portal.getCreateDataAdapter()) { createDataAdapter(portalDto, portal); @@ -203,6 +238,7 @@ public class PortalServiceImpl implements PortalService { } @Override + @Transactional(rollbackFor = Exception.class) public PortalIdWrapper edit(PortalDto portalDto) { Portal portal = portalDto.toPortal(); checkPortalType(portal); @@ -210,7 +246,6 @@ public class PortalServiceImpl implements PortalService { if (!ObjectUtils.isEmpty(old) && !old.getPortalId().equals(portal.getPortalId())) { throw new CustomException("系统中存在当前请求路径"); } - if (portal.getCreateDataAdapter() != old.getCreateDataAdapter()) { if (portal.getCreateDataAdapter()) { createDataAdapter(portalDto, portal); @@ -218,51 +253,55 @@ public class PortalServiceImpl implements PortalService { adapterMapper.deleteById(old.getAdapterId()); } } - PortalBo portalBo = PortalBo.toPortalBo(portal, portalDto.getMappings()); - //存在接口路径或者请求类型不同则需要重新发布 - if (!old.getPath().equals(portal.getPath()) - || !old.getRequestMethod().equals(portal.getRequestMethod())) { - //先卸载接口,需要进行数据同步 - unpublishPortal(old, true); - //注册新的映射 - methodService.registerMapping(portalBo.getPath(), RequestMethod.valueOf(portalBo.getRequestMethod()), true); + portalMappingMapper.deleteByPortalId(portal.getPortalId()); + portalMapper.update(portal); + if (!ObjectUtils.isEmpty(portalDto.getMappings())) { + List mappings = portalDto.getMappings(); + for (PortalMapping mapping : mappings) { + mapping.setPortalId(portal.getPortalId()); + } + portalMappingMapper.insertBatch(mappings); } - //修改Redis中的数据信息 - redisTemplate.opsForValue().set(QueryConstant.PORTAL_KEY + portalBo.getPath() + ":" + portalBo.getRequestMethod(), portalBo); //返回接口id和适配器id return PortalIdWrapper.builder() .portalId(String.valueOf(portal.getPortalId())) .adapterId(String.valueOf(portal.getAdapterId())) .build(); - } - private boolean mappingCheckEquals(List oldPortalMappingList, List mappings) { - if (ObjectUtils.isEmpty(oldPortalMappingList) && ObjectUtils.isEmpty(mappings)) { - return true; + @Override + public void cancel(Long portalId) { + Portal portal = portalMapper.selectById(portalId); + if (ObjectUtils.isEmpty(portal)) { + return; } - if (ObjectUtils.isEmpty(oldPortalMappingList) || ObjectUtils.isEmpty(mappings)) { - return false; + if (QueryConstant.PORTAL_DEV.equals(portal.getState())) { + throw new CustomException("当前状态错误"); } - Optional optional = mappings.stream().filter(ObjectUtils::isEmpty).findAny(); - if (optional.isEmpty()) { - return false; + portalMapper.updateState(portalId, QueryConstant.PORTAL_DEV); + if (QueryConstant.PORTAL_PUBLISH.equals(portal.getState())) { + unpublishPortal(portal, Boolean.TRUE); } - if (oldPortalMappingList.size() == mappings.size()) { - Map oldPortalMappingMap = oldPortalMappingList.stream() - .collect(Collectors.toMap(PortalMapping::getMappingId, Function.identity())); - Map portalMappingMap = mappings.stream() - .collect(Collectors.toMap(PortalMapping::getMappingId, Function.identity())); - for (Long mappingId : oldPortalMappingMap.keySet()) { - PortalMapping portalMapping = portalMappingMap.get(mappingId); - if (ObjectUtils.isEmpty(portalMapping)) { - return false; - } - } - } - return false; } + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Long portalId) { + Portal portal = portalMapper.selectById(portalId); + if (ObjectUtils.isEmpty(portal)) { + return; + } + if (!QueryConstant.PORTAL_DEV.equals(portal.getState())) { + throw new CustomException("当前状态不允许删除"); + } + if (portal.getCreateDataAdapter()) { + adapterMapper.deleteById(portal.getAdapterId()); + } + portalMappingMapper.deleteByPortalId(portalId); + portalMapper.deleteById(portalId); + } + + /** * 发布接口 * @@ -302,7 +341,7 @@ public class PortalServiceImpl implements PortalService { if (ObjectUtils.isEmpty(dataAdapter.getType())) { throw new CustomException("请选择数据适配器类型!"); } - dataAdapter.setAdapterName(portal.getPortalName() + "专用数据适配器!"); + dataAdapter.setAdapterName(portal.getPortalName() + "专用"); dataAdapter.setCommon(Boolean.FALSE); //初始化对应的数据适配器 dataAdapter.init(); diff --git a/custom-query/custom-query-biz/src/main/resources/mapper/DataAdapterMapper.xml b/custom-query/custom-query-biz/src/main/resources/mapper/DataAdapterMapper.xml index 0b9ac8b..cff9939 100644 --- a/custom-query/custom-query-biz/src/main/resources/mapper/DataAdapterMapper.xml +++ b/custom-query/custom-query-biz/src/main/resources/mapper/DataAdapterMapper.xml @@ -20,9 +20,10 @@ select adapter_id, adapter_name, - `type`, + type, common, code, + execute_code, mock_data, create_by, create_time, @@ -35,8 +36,10 @@ @@ -58,7 +61,7 @@ insert into data_adapter adapter_name, - `type`, + type, common, code, mock_data, @@ -80,7 +83,7 @@ update data_adapter adapter_name = #{adapterName}, - `type` = #{type}, + type = #{type}, code = #{code}, mock_data = #{mockData}, update_by = #{updateBy}, @@ -89,6 +92,18 @@ where adapter_id = #{adapterId} + + update data_adapter + + code = #{code}, + execute_code = #{code}, + mock_data = #{mockData}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where adapter_id = #{adapterId} + + delete from data_adapter diff --git a/custom-query/custom-query-biz/src/main/resources/mapper/PortalMapper.xml b/custom-query/custom-query-biz/src/main/resources/mapper/PortalMapper.xml index a88c432..3fe99ba 100644 --- a/custom-query/custom-query-biz/src/main/resources/mapper/PortalMapper.xml +++ b/custom-query/custom-query-biz/src/main/resources/mapper/PortalMapper.xml @@ -13,6 +13,7 @@ type, request_method, create_data_adapter, + page, path, url, state, @@ -23,7 +24,6 @@ remark from portal - - and portal_name like concat('%', #{portalName}, '%') + and portal_name like concat('%', #{portalName}, '%') and anonymity = #{anonymity} and type = #{type} + and state = #{state} and path like concat('%', #{path}, '%') @@ -52,6 +53,7 @@ portal_name, anonymity, type, + page, request_method, create_data_adapter, path, @@ -66,6 +68,7 @@ #{portalName}, #{anonymity}, #{type}, + #{page}, #{requestMethod}, #{createDataAdapter}, #{path}, @@ -75,4 +78,35 @@ #{createTime}, + + + update portal + + query_id = #{queryId}, + adapter_id = #{adapterId}, + portal_name = #{portalName}, + anonymity = #{anonymity}, + type = #{type}, + type = #{page}, + request_method = #{requestMethod}, + create_data_adapter = #{createDataAdapter}, + path = #{path}, + url = #{url}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + where portal_id = #{portalId} + + + + update portal + set state = #{state} + where portal_id = #{portalId} + + + + delete + from portal + where portal_id = #{portalId} + \ No newline at end of file diff --git a/custom-query/custom-query-biz/src/main/resources/mapper/PortalMappingMapper.xml b/custom-query/custom-query-biz/src/main/resources/mapper/PortalMappingMapper.xml index 9f6d8ab..2b8f4be 100644 --- a/custom-query/custom-query-biz/src/main/resources/mapper/PortalMappingMapper.xml +++ b/custom-query/custom-query-biz/src/main/resources/mapper/PortalMappingMapper.xml @@ -4,7 +4,7 @@ "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - select mapping_id, portal_id, mapping_key, mapping_type, mapping_value + select mapping_id, portal_id, mapping_key, mapping_type, mapping_value, input_type, description from portal_mapping @@ -23,10 +23,11 @@ - insert into portal_mapping (portal_id, mapping_key, mapping_type, mapping_value) + insert into portal_mapping (portal_id, mapping_key, mapping_type, mapping_value, input_type, description) values - (#{item.portalId}, #{item.mappingKey}, #{item.mappingType}, #{item.mappingValue}) + (#{item.portalId}, #{item.mappingKey}, #{item.mappingType}, #{item.mappingValue}, #{item.inputType}, + #{item.description}) diff --git a/custom-query/custom-query-biz/src/test/java/cn/fateverse/query/ConsoleCapture.java b/custom-query/custom-query-biz/src/test/java/cn/fateverse/query/ConsoleCapture.java new file mode 100644 index 0000000..fae08b2 --- /dev/null +++ b/custom-query/custom-query-biz/src/test/java/cn/fateverse/query/ConsoleCapture.java @@ -0,0 +1,32 @@ +package cn.fateverse.query; + +import java.io.*; + + public class ConsoleCapture { + public static String captureOutput(Runnable codeToRun) throws IOException { + PrintStream originalOut = System.out; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintStream capturingOut = new PrintStream(baos); + + try { + System.setOut(capturingOut); + codeToRun.run(); + } finally { + System.setOut(originalOut); + } + + return baos.toString(); + } + + // 使用示例 + public static void main(String[] args) throws IOException { + String capturedText = captureOutput(() -> { + System.out.println("Hello, Console!"); + System.out.println("This is being captured."); + }); + + System.out.println("Captured output:"); + System.out.println(capturedText); + } + } + \ No newline at end of file diff --git a/custom-query/custom-query-biz/src/test/java/cn/fateverse/query/DataAdapter.java b/custom-query/custom-query-biz/src/test/java/cn/fateverse/query/DataAdapter.java deleted file mode 100644 index 2d5ab74..0000000 --- a/custom-query/custom-query-biz/src/test/java/cn/fateverse/query/DataAdapter.java +++ /dev/null @@ -1,14 +0,0 @@ -package cn.fateverse.query; - -import java.util.*; -import java.util.stream.*; - -public class DataAdapter { - - public static Object execute(List> data) { - for (Map objectMap : data) { - objectMap.remove("oper_location"); - } - return data; - } -} \ No newline at end of file diff --git a/custom-query/custom-query-biz/src/test/java/cn/fateverse/query/DataAdapter1100.java b/custom-query/custom-query-biz/src/test/java/cn/fateverse/query/DataAdapter1100.java new file mode 100644 index 0000000..1f8b529 --- /dev/null +++ b/custom-query/custom-query-biz/src/test/java/cn/fateverse/query/DataAdapter1100.java @@ -0,0 +1,16 @@ +package cn.fateverse.query; + +/** + * @author Clay + * @date 2024/4/22 18:59 + */ +public class DataAdapter1100 { + + public static Object execute(String data) { + for (int i = 0; i < 1000; i++) { + System.out.println(i); + } + return "qwewe"; + } + +} diff --git a/custom-query/custom-query-biz/src/test/java/cn/fateverse/query/JavaScriptParamTest.java b/custom-query/custom-query-biz/src/test/java/cn/fateverse/query/JavaScriptParamTest.java new file mode 100644 index 0000000..ff04661 --- /dev/null +++ b/custom-query/custom-query-biz/src/test/java/cn/fateverse/query/JavaScriptParamTest.java @@ -0,0 +1,77 @@ +package cn.fateverse.query; + +import cn.fateverse.common.code.engine.JavaScriptEngine; +import cn.fateverse.common.code.model.EngineResult; +import com.alibaba.fastjson2.JSONObject; +import org.graalvm.polyglot.Context; +import org.graalvm.polyglot.Value; +import org.junit.jupiter.api.Test; + +import javax.script.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; + +/** + * @author Clay + * @date 2024/4/23 9:42 + */ +public class JavaScriptParamTest { + + + static String finalCode = "function execute1(data) {\n" + + " let res = [data.length];\n" + + " for (let i = 0; i < data.length; i++) {\n" + + " console.log(data[i])\n" + + " console.log(data[i].foo)\n" + + " res[i] = data[i].foo\n" + + " }\n" + + " return res;\n" + + "}"; + + @Test + public void testParam() { + List list = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + + Map param = new HashMap<>(); + param.put("foo", "sdsdsdsds"); + list.add(param); + } + + ScriptEngineManager engineManager = new ScriptEngineManager(); + ScriptEngine jsEngine = engineManager.getEngineByName("graal.js"); + Context context = Context.newBuilder() + .allowAllAccess(true) + .build(); +// Context context = Context.create(); + context.eval("js", finalCode); + + Value executeFunction = context.getBindings("js").getMember("execute1"); + Value javaObjectAsValue = Value.asValue(list); + Value result = executeFunction.execute(javaObjectAsValue); + System.out.println(result); + + } + + + @Test + public void testParam2() throws Exception { + + ScriptEngineManager engineManager = new ScriptEngineManager(); + ScriptEngine jsEngine = engineManager.getEngineByName("graal.js"); + Invocable funcCall = (Invocable) jsEngine; + Bindings bindings = jsEngine.getBindings(ScriptContext.ENGINE_SCOPE); + bindings.put("polyglot.js.allowHostAccess", true); + bindings.put("polyglot.js.allowHostClassLookup", (Predicate) s -> true); + + jsEngine.eval(finalCode); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("foo", "sdsdsdsds"); + Object res= funcCall.invokeFunction("execute1", jsonObject); + + } + +} diff --git a/custom-query/custom-query-biz/src/test/java/cn/fateverse/query/JavaScriptTest.java b/custom-query/custom-query-biz/src/test/java/cn/fateverse/query/JavaScriptTest.java new file mode 100644 index 0000000..50ae687 --- /dev/null +++ b/custom-query/custom-query-biz/src/test/java/cn/fateverse/query/JavaScriptTest.java @@ -0,0 +1,122 @@ +package cn.fateverse.query; + +import cn.fateverse.common.code.config.JavaCodeProperties; +import cn.fateverse.common.code.engine.JavaCodeEngine; +import cn.fateverse.common.code.engine.JavaScriptEngine; +import cn.fateverse.common.code.model.EngineResult; + +import java.util.concurrent.FutureTask; + + +/** + * @author Clay + * @date 2024/4/22 16:04 + */ +public class JavaScriptTest { + public static void main(String[] args) throws Exception { + String code = "function execute(data) {\n" + + " console.log(data)\n" + + " console.log(\"test console!\")\n" + + " let add = (a, b) => a + b; // 使用箭头函数\n" + + " console.log(\"Adding 5 and 3:\", add(5, 3));\n\n" + + " for (let i = 0; i < 1000; i++) {\n" + + " console.log(i)\n" + + " }" + + " return \"success\";\n" + + "}"; + + + JavaCodeProperties properties = new JavaCodeProperties(); + properties.setClassPath("C:\\home\\clay\\code\\"); + JavaCodeEngine javaCodeEngine = new JavaCodeEngine(properties); + + +// EngineResult executeScript = JavaScriptEngine.executeScript(code, "execute", "测试控制台输出"); + + String finalCode = "function execute(data) {\n" + + " console.log(data)\n" + + " console.log(\"test console!\")\n" + + " let add = (a, b) => a + b; // 使用箭头函数\n" + + " console.log(\"Adding 5 and 3:\", add(5, 3));\n\n" + + " for (let i = 0; i < 1000; i++) {\n" + + " console.log(i)\n" + + " }" + + " return \"success\";\n" + + "}"; + FutureTask engineResultFutureTask = new FutureTask<>(() -> { + return JavaScriptEngine.execute(finalCode, "execute", false, "测试控制台输出"); + }); + + + String finalCode1 = "import java.util.*;\n" + + "import java.util.stream.*;\n" + + "\n" + + "public class DataAdapter100 {" + + "\n" + + " public static Object execute(String data) {\n" + + " for (int i = 0; i < 1000; i++) {\n" + + " System.out.println(i);\n" + + " }\n" + + " return \"qwewe\";\n" + + " }" + + "}\n"; + FutureTask engineResultFutureTask1 = new FutureTask<>(() -> { + return javaCodeEngine.execute(finalCode1, "DataAdapter100", "execute", new Class[]{String.class}, new Object[]{"test"}, true); + }); + new Thread(engineResultFutureTask).start(); + new Thread(engineResultFutureTask1).start(); +// EngineResult execute = javaCodeEngine.execute(code, "DataAdapter100", "execute", new Class[]{String.class}, new Object[]{"test"}, true); + + + EngineResult x = engineResultFutureTask.get(); + EngineResult x1 = engineResultFutureTask1.get(); + System.out.println(x); + System.out.println(x1); + + +// EngineResult capture = MultiThreadedCapture.capture(() -> { +// ScriptEngine engine = new ScriptEngineManager().getEngineByName("graal.js"); +// Invocable inv = (Invocable) engine; +// try { +// engine.eval(finalCode); +// return inv.invokeFunction("execute", "args"); +// } catch (ScriptException | NoSuchMethodException e) { +// throw new RuntimeException(e); +// } +// }); +// System.out.println(capture); +// EngineResult objectEngineResult = JavaScriptEngine.executeScript(finalCode, "execute", "测试控制台输出"); +// +// ByteArrayOutputStream baos = new ByteArrayOutputStream(); +// PrintStream oldOut = System.out; +// System.setOut(new PrintStream(baos)); + + +// EngineResult capture = MultiThreadedCapture.capture(() -> { +// int someNumber = 42; +// System.out.println(someNumber); +// return null; +// }); + + + // 执行产生数值输出的代码 +// System.out.println(objectEngineResult); +// ScriptEngine engine = JavaScriptEngine.getEngine(); +// Invocable inv = (Invocable) engine; +// engine.eval(finalCode); +// inv.invokeFunction("execute", "args"); +// System.out.println(capture); + +// MultiThreadedCapture.executor.shutdown(); + // 恢复标准输出流 +// System.setOut(oldOut); +// +// System.setOut(oldOut); +// // 从捕获的字节数组输出流中获取打印的文本 +// String capturedOutput = baos.toString(); +// System.out.println("Captured output: " + capturedOutput); + + } + + +} diff --git a/custom-query/custom-query-biz/src/test/java/cn/fateverse/query/Main.java b/custom-query/custom-query-biz/src/test/java/cn/fateverse/query/Main.java new file mode 100644 index 0000000..9749c38 --- /dev/null +++ b/custom-query/custom-query-biz/src/test/java/cn/fateverse/query/Main.java @@ -0,0 +1,38 @@ +package cn.fateverse.query; + +import org.graalvm.polyglot.Context; +import org.graalvm.polyglot.Value; + +public class Main { + public static void main(String[] args) { + // 创建 GraalVM 上下文 + Context context = Context.create(); + + // 定义一个 JavaScript 函数 + String script = "function execute(data) {\n" + + " console.log(data)\n" + + " console.log(\"test console!\")\n" + + " let add = (a, b) => a + b; // 使用箭头函数\n" + + " console.log(\"Adding 5 and 3:\", add(5, 3));\n\n" + + " for (let i = 0; i < 1000; i++) {\n" + + " console.log(i)\n" + + " }" + + " return \"success\";\n" + + "}"; + + // 编译 JavaScript 函数 + context.eval("js", script); + + // 获取函数对象 + Value addFunction = context.getBindings("js").getMember("execute"); + + // 执行函数并传入参数 + Value result = addFunction.execute("测试"); + Value result2 = addFunction.execute("测试"); + // 获取返回值 +// int sum = result.asInt(); + + // 输出结果 + System.out.println("Sum: "); // 输出:Sum: 5 + } +} diff --git a/custom-query/custom-query-biz/src/test/java/cn/fateverse/query/SystemOut.java b/custom-query/custom-query-biz/src/test/java/cn/fateverse/query/SystemOut.java new file mode 100644 index 0000000..5b6e8e2 --- /dev/null +++ b/custom-query/custom-query-biz/src/test/java/cn/fateverse/query/SystemOut.java @@ -0,0 +1,45 @@ +package cn.fateverse.query; + +import cn.fateverse.common.code.engine.JavaScriptEngine; +import cn.fateverse.common.code.model.EngineResult; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +public class SystemOut { + public static void outTest() { + ByteArrayOutputStream baoStream = new ByteArrayOutputStream(1024); + PrintStream cacheStream = new PrintStream(baoStream);//临时输出 + PrintStream oldStream = System.out;//缓存系统输出 + System.setOut(cacheStream); + System.out.print("...");//不会打印到控制台 + String result = baoStream.toString();//存放控制台输出的字符串 + System.setOut(oldStream);//还原到系统输出 + System.out.println("result"); + } + + public static void main(String[] args) { +// outTest(); + + String finalCode = "function execute1(data) {\n" + + " console.log(data)\n" + + " console.log(\"test console!\")\n" + + " let add = (a, b) => a + b; // 使用箭头函数\n" + + " console.log(\"Adding 5 and 3:\", add(5, 3));\n\n" + + " for (let i = 0; i < 1000; i++) {\n" + + " console.log(i)\n" + + " }" + + " return \"success\";\n" + + "}"; +// String finalCode = "function myFunction() { return 'Hello, world!'; }"; + long start1 = System.currentTimeMillis(); + EngineResult execute = JavaScriptEngine.execute(finalCode, "execute1", false, "测试控制台输出"); + long start2 = System.currentTimeMillis(); + EngineResult execute1 = JavaScriptEngine.execute(finalCode, "execute1", false, "测试控制台输出"); + long start3 = System.currentTimeMillis(); + System.out.println("耗时1:" + (start2 - start1) + "ms"); + System.out.println("耗时2:" + (start3 - start2) + "ms"); + System.out.println(execute); + + } +} \ No newline at end of file diff --git a/visual/pom.xml b/visual/pom.xml index e4b1e6b..fdb2ec2 100644 --- a/visual/pom.xml +++ b/visual/pom.xml @@ -16,10 +16,10 @@ true - monitor + - sentinel-dashboard + diff --git a/workflow/src/main/java/cn/fateverse/workflow/process/TriggerService.java b/workflow/src/main/java/cn/fateverse/workflow/process/TriggerService.java index 5db6c3c..a4ecdbb 100644 --- a/workflow/src/main/java/cn/fateverse/workflow/process/TriggerService.java +++ b/workflow/src/main/java/cn/fateverse/workflow/process/TriggerService.java @@ -1,6 +1,7 @@ package cn.fateverse.workflow.process; import cn.fateverse.common.code.engine.JavaScriptEngine; +import cn.fateverse.common.code.model.EngineResult; import cn.fateverse.workflow.constant.ProcessConstant; import cn.fateverse.workflow.entity.bpmn.*; import cn.hutool.core.util.StrUtil; @@ -158,14 +159,14 @@ public class TriggerService { } //获取到请求的返回结果 Map result = response.getBody(); - ScriptObjectMirror jsResult; + EngineResult engineResult; try { //判断请求是否有效 if (response.getStatusCode() == HttpStatus.OK) { - jsResult = JavaScriptEngine.executeScript(http.getSuccess(), "handlerSuccess", result); + engineResult = JavaScriptEngine.execute(http.getSuccess(), "handlerSuccess", false, result); operation.setState(OperationStateEnums.SUCCESS); } else { - jsResult = JavaScriptEngine.executeScript(http.getFail(), "handlerFail", result); + engineResult = JavaScriptEngine.execute(http.getFail(), "handlerFail", false, result); operation.setState(OperationStateEnums.FAILURE); } } catch (Exception e) { @@ -177,6 +178,7 @@ public class TriggerService { } return; } + ScriptObjectMirror jsResult = (ScriptObjectMirror) engineResult.getResult(); //获取到自定义脚本的状态 boolean state = (Boolean) jsResult.get("state"); //获取到js脚本中的内容 From f3c2ef4cd916d908b7d329ebe5987f612bfb99a9 Mon Sep 17 00:00:00 2001 From: clay <20932067@zju.edu.cn> Date: Wed, 24 Apr 2024 10:48:14 +0800 Subject: [PATCH 03/10] =?UTF-8?q?feat:=20js=E5=BC=95=E6=93=8E=E8=B0=83?= =?UTF-8?q?=E8=AF=95=E6=88=90=E5=8A=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../code/console/MultiThreadedCapture.java | 3 ++ .../common/code/engine/JavaScriptEngine.java | 15 ++++++-- .../query/controller/PortalController.java | 9 +++++ .../query/entity/dto/DataAdapterCodeDto.java | 21 ++++++++++ .../query/entity/query/DataAdapterQuery.java | 1 - .../query/entity/vo/SimplePortalVo.java | 11 ++++-- .../query/enums/DataAdapterType.java | 2 +- .../impl/ExternalDataAdapterHandler.java | 7 ++-- .../adapter/impl/LocalDataAdapterHandler.java | 14 +++---- .../query/service/PortalService.java | 12 +++++- .../service/impl/DataAdapterServiceImpl.java | 3 ++ .../query/service/impl/PortalServiceImpl.java | 38 ++++++++++++++++++- 12 files changed, 112 insertions(+), 24 deletions(-) create mode 100644 custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/DataAdapterCodeDto.java diff --git a/common/common-code/src/main/java/cn/fateverse/common/code/console/MultiThreadedCapture.java b/common/common-code/src/main/java/cn/fateverse/common/code/console/MultiThreadedCapture.java index a0f4ddf..491b792 100644 --- a/common/common-code/src/main/java/cn/fateverse/common/code/console/MultiThreadedCapture.java +++ b/common/common-code/src/main/java/cn/fateverse/common/code/console/MultiThreadedCapture.java @@ -27,6 +27,9 @@ public class MultiThreadedCapture { try { result = task.execute(); } catch (Exception e) { + if (e instanceof CustomException){ + throw (CustomException) e; + } throw new RuntimeException(e); } finally { System.setOut(oldOut); diff --git a/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaScriptEngine.java b/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaScriptEngine.java index c54dc58..e75db28 100644 --- a/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaScriptEngine.java +++ b/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaScriptEngine.java @@ -47,10 +47,17 @@ public class JavaScriptEngine { return MultiThreadedCapture.capture(() -> { Context context = Context.newBuilder() .allowAllAccess(true) - .allowHostClassLoading(true) - .allowIO(true) - .allowNativeAccess(true).build(); - context.eval("js", script); +// .allowHostClassLoading(true) +// .allowIO(true) +// .allowNativeAccess(true) + .build(); + try { + context.eval("js", script); + } catch (Exception e) { + String message = e.getMessage(); + message = message.replace("java.lang.RuntimeException: org.graalvm.polyglot.PolyglotException: SyntaxError:", ""); + throw new CustomException("js has error : " + message); + } Value executeFunction = context.getBindings("js").getMember(functionName); Value javaObjectAsValue = Value.asValue(args); Value result = executeFunction.execute(javaObjectAsValue); diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/controller/PortalController.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/controller/PortalController.java index 0e50a59..f254e0e 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/controller/PortalController.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/controller/PortalController.java @@ -5,6 +5,7 @@ import cn.fateverse.common.core.result.page.TableDataInfo; import cn.fateverse.common.core.utils.ObjectUtils; import cn.fateverse.common.decrypt.annotation.Encrypt; import cn.fateverse.common.decrypt.annotation.EncryptField; +import cn.fateverse.query.entity.dto.DataAdapterCodeDto; import cn.fateverse.query.entity.dto.MockParam; import cn.fateverse.query.entity.dto.PortalDto; import cn.fateverse.query.entity.query.PortalQuery; @@ -107,6 +108,14 @@ public class PortalController { return Result.ok(result); } + @ApiOperation("保存代码") + @PostMapping("/save/code") + @PreAuthorize("@ss.hasPermission('query:portal:edit')") + public Result saveCode(@RequestBody @Validated DataAdapterCodeDto dataAdapterCodeDto) { + portalService.saveCode(dataAdapterCodeDto); + return Result.ok(); + } + @ApiOperation("撤销发布") @Encrypt diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/DataAdapterCodeDto.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/DataAdapterCodeDto.java new file mode 100644 index 0000000..a07659e --- /dev/null +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/DataAdapterCodeDto.java @@ -0,0 +1,21 @@ +package cn.fateverse.query.entity.dto; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * @author Clay + * @date 2024/4/24 8:57 + */ +@Data +public class DataAdapterCodeDto { + + @NotNull(message = "id不能为空") + private Long portalId; + + @NotBlank(message = "代码内容不能为空!") + private String code; + +} diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/query/DataAdapterQuery.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/query/DataAdapterQuery.java index 5ad8d3c..2a65503 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/query/DataAdapterQuery.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/query/DataAdapterQuery.java @@ -31,7 +31,6 @@ public class DataAdapterQuery { @ApiModelProperty("数据适配器代码类型 Java or Js") private DataAdapterType type; - @ApiModelProperty("是否通用") private Boolean common; } \ No newline at end of file diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/vo/SimplePortalVo.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/vo/SimplePortalVo.java index 9131023..b75566d 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/vo/SimplePortalVo.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/vo/SimplePortalVo.java @@ -10,7 +10,6 @@ import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import org.springframework.util.ObjectUtils; import java.util.Date; @@ -66,9 +65,12 @@ public class SimplePortalVo { /** * 数据适配器名称 */ - @ApiModelProperty("数据适配器名称") - @Excel("数据适配器名称") - private String adapterName; + @ApiModelProperty("数据适配器类型") + @Excel("数据适配器类型") + private String adapterCodeType; + + + private Boolean createDataAdapter; /** @@ -127,6 +129,7 @@ public class SimplePortalVo { .anonymity(portal.getAnonymity()) .queryId(portal.getQueryId()) .adapterId(portal.getAdapterId()) + .createDataAdapter(portal.getCreateDataAdapter()) .type(portal.getType()) .path(portal.getPath()) .state(portal.getState()) diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/enums/DataAdapterType.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/enums/DataAdapterType.java index a52aa44..fc4d238 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/enums/DataAdapterType.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/enums/DataAdapterType.java @@ -2,7 +2,7 @@ package cn.fateverse.query.enums; public enum DataAdapterType { - JAVA("java"), + JAVA("Java"), JAVA_SCRIPT("JavaScript"); diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/impl/ExternalDataAdapterHandler.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/impl/ExternalDataAdapterHandler.java index 2682ec4..0c0c857 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/impl/ExternalDataAdapterHandler.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/impl/ExternalDataAdapterHandler.java @@ -12,6 +12,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; +import org.springframework.util.ObjectUtils; import org.springframework.web.client.RestTemplate; import javax.servlet.http.HttpServletRequest; @@ -59,10 +60,10 @@ public class ExternalDataAdapterHandler extends AbstractDataAdapterHandler { default: throw new CustomException("请求方式错误"); } - if (portal.getCreateDataAdapter()) { - return super.execute(portal.getAdapterId(), response, true); - } else { + if (ObjectUtils.isEmpty(portal.getAdapterId()) || !portal.getCreateDataAdapter()) { return response; + } else { + return super.mockExecute(portal.getAdapterId(), mockParam.getCode(), response, true); } } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/impl/LocalDataAdapterHandler.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/impl/LocalDataAdapterHandler.java index 556de02..eca8562 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/impl/LocalDataAdapterHandler.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/adapter/impl/LocalDataAdapterHandler.java @@ -66,10 +66,10 @@ public class LocalDataAdapterHandler extends AbstractDataAdapterHandler { } //根据设置的参数动态调整当前是否需要分页操作 TableDataInfo> tableDataInfo = dynamicDataSearchService.searchData(uniConList, query, null, Boolean.TRUE); - if (portal.getCreateDataAdapter()) { - return super.mockExecute(portal.getAdapterId(), mockParam.getCode(), tableDataInfo.getRows(), true); - } else { + if (ObjectUtils.isEmpty(portal.getAdapterId()) || !portal.getCreateDataAdapter()) { return tableDataInfo.getRows(); + } else { + return super.mockExecute(portal.getAdapterId(), mockParam.getCode(), tableDataInfo.getRows(), true); } } @@ -86,13 +86,13 @@ public class LocalDataAdapterHandler extends AbstractDataAdapterHandler { UniConDto uniCon = new UniConDto(); String mappingValue = portalMapping.getMappingValue(); String mappingKey = portalMapping.getMappingKey(); - uniCon.setUcId(Long.parseLong(mappingValue)); + uniCon.setUcId(Long.parseLong(mappingKey)); if (portalMapping.getMappingType() == 0) { - uniCon.setQuery(request.getParameter(mappingKey)); + uniCon.setQuery(request.getParameter(mappingValue)); } else if (portalMapping.getMappingType() == 1) { - uniCon.setQuery(request.getHeaders(mappingKey)); + uniCon.setQuery(request.getHeaders(mappingValue)); } else { - uniCon.setQuery(request.getParameter(mappingKey)); + uniCon.setQuery(request.getParameter(mappingValue)); } uniConList.add(uniCon); } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/PortalService.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/PortalService.java index c5a870d..91d5bf0 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/PortalService.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/PortalService.java @@ -1,6 +1,7 @@ package cn.fateverse.query.service; import cn.fateverse.common.core.result.page.TableDataInfo; +import cn.fateverse.query.entity.dto.DataAdapterCodeDto; import cn.fateverse.query.entity.dto.MockParam; import cn.fateverse.query.entity.dto.PortalDto; import cn.fateverse.query.entity.query.PortalQuery; @@ -50,11 +51,18 @@ public interface PortalService { /** * 获取到模拟数据 * - * @param mockParam - * @return + * @param mockParam 模拟参数 + * @return 执行结果 */ Object mockData(MockParam mockParam); + /** + * 保存代码 + * + * @param dataAdapterCodeDto 数据适配器代码 + */ + void saveCode(DataAdapterCodeDto dataAdapterCodeDto); + /** * 保存接口信息 * diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/DataAdapterServiceImpl.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/DataAdapterServiceImpl.java index 2f0adf5..9f1f81c 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/DataAdapterServiceImpl.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/DataAdapterServiceImpl.java @@ -50,6 +50,7 @@ public class DataAdapterServiceImpl implements DataAdapterService { @Override public TableDataInfo searchList(DataAdapterQuery query) { PageUtils.startPage(); + query.setCommon(true); List list = dataAdapterMapper.selectList(query); return PageUtils.convertDataTable(list, DataAdapterVo::toDataAdapterVo); } @@ -87,6 +88,8 @@ public class DataAdapterServiceImpl implements DataAdapterService { @Transactional(rollbackFor = Exception.class) public int save(DataAdapterDto dataAdapter) { DataAdapter info = dataAdapter.toDataAdapter(); + info.setCommon(Boolean.TRUE); + info.init(); info.setCreateBy(SecurityUtils.getUsername()); return dataAdapterMapper.insert(info); } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java index 0b3ad93..4cddbb1 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java @@ -5,6 +5,7 @@ import cn.fateverse.common.core.result.page.TableDataInfo; import cn.fateverse.common.mybatis.utils.PageUtils; import cn.fateverse.query.entity.*; import cn.fateverse.query.entity.bo.PortalBo; +import cn.fateverse.query.entity.dto.DataAdapterCodeDto; import cn.fateverse.query.entity.dto.MockParam; import cn.fateverse.query.entity.vo.DataAdapterVo; import cn.fateverse.query.entity.vo.PortalIdWrapper; @@ -109,6 +110,9 @@ public class PortalServiceImpl implements PortalService { @Override public PortalVo searchById(Long portalId) { Portal portal = portalMapper.selectById(portalId); + if (!QueryConstant.PORTAL_DEV.equals(portal.getState())) { + throw new CustomException("当前状态不允许查询"); + } PortalVo portalVo = PortalVo.toPortalVo(portal); List portalMappings = portalMappingMapper.selectByPortalId(portalId); if (ObjectUtils.isEmpty(portalMappings)) { @@ -118,6 +122,12 @@ public class PortalServiceImpl implements PortalService { UniQuery uniQuery = queryMapper.selectById(portal.getQueryId()); portalVo.setQueryType(uniQuery.getType()); } + if (portal.getCreateDataAdapter()) { + DataAdapter dataAdapter = adapterMapper.selectById(portal.getAdapterId()); + if (!ObjectUtils.isEmpty(dataAdapter)) { + portalVo.setAdapterCodeType(dataAdapter.getType().name()); + } + } portalVo.setMappings(portalMappings); return portalVo; } @@ -166,7 +176,7 @@ public class PortalServiceImpl implements PortalService { if (!ObjectUtils.isEmpty(adapterIds)) { List adapterList = adapterMapper.selectListByIds(adapterIds); for (DataAdapter adapter : adapterList) { - adapterMap.put(adapter.getAdapterId(), adapter.getAdapterName()); + adapterMap.put(adapter.getAdapterId(), adapter.getType().name()); } } //映射重组 @@ -177,7 +187,7 @@ public class PortalServiceImpl implements PortalService { simplePortalVo.setQueryName(uniQuery.getUqName()); simplePortalVo.setQueryType(uniQuery.getType()); } - simplePortalVo.setAdapterName(adapterMap.getOrDefault(portal.getAdapterId(), null)); + simplePortalVo.setAdapterCodeType(adapterMap.getOrDefault(portal.getAdapterId(), null)); return simplePortalVo; }); } @@ -185,6 +195,9 @@ public class PortalServiceImpl implements PortalService { @Override public Object mockExecute(MockParam mockParam) { Portal portal = portalMapper.selectById(mockParam.getPortalId()); + if (!QueryConstant.PORTAL_DEV.equals(portal.getState())) { + throw new CustomException("当前状态不允许执行"); + } PortalBo portalBo = PortalBo.toPortalBo(portal, null); return handlerReader.mockExecute(portalBo, mockParam); } @@ -198,6 +211,24 @@ public class PortalServiceImpl implements PortalService { return handlerReader.mockExecute(portalBo, mockParam); } + @Override + public void saveCode(DataAdapterCodeDto dataAdapterCodeDto) { + Portal portal = portalMapper.selectById(dataAdapterCodeDto.getPortalId()); + if (ObjectUtils.isEmpty(portal)) { + throw new CustomException("未找到对应的接口"); + } + if (!QueryConstant.PORTAL_DEV.equals(portal.getState())) { + throw new CustomException("当前状态不允许保存"); + } + if (ObjectUtils.isEmpty(portal.getAdapterId()) || !portal.getCreateDataAdapter()) { + throw new CustomException("未找到数据适配器"); + } + DataAdapter dataAdapter = new DataAdapter(); + dataAdapter.setAdapterId(portal.getAdapterId()); + dataAdapter.setCode(dataAdapterCodeDto.getCode()); + adapterMapper.update(dataAdapter); + } + @Override @Transactional(rollbackFor = Exception.class) public PortalIdWrapper save(PortalDto portalDto) { @@ -243,6 +274,9 @@ public class PortalServiceImpl implements PortalService { Portal portal = portalDto.toPortal(); checkPortalType(portal); Portal old = portalMapper.selectByPath(portal.getPath(), portal.getRequestMethod()); + if (!QueryConstant.PORTAL_DEV.equals(old.getState())) { + throw new CustomException("当前状态不允许修改"); + } if (!ObjectUtils.isEmpty(old) && !old.getPortalId().equals(portal.getPortalId())) { throw new CustomException("系统中存在当前请求路径"); } From 5e417c2e20c15472207e3f4a4ee10634964f9aa3 Mon Sep 17 00:00:00 2001 From: clay <20932067@zju.edu.cn> Date: Wed, 24 Apr 2024 11:49:10 +0800 Subject: [PATCH 04/10] =?UTF-8?q?feat:=20=E6=9D=83=E9=99=90=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/fateverse/query/entity/Portal.java | 6 +++--- .../fateverse/query/entity/dto/PortalDto.java | 18 +++++++++--------- .../query/entity/query/PortalQuery.java | 7 ++++--- .../query/entity/vo/SimplePortalVo.java | 14 ++++++++------ .../fateverse/query/enums/PortalPremEnum.java | 14 ++++++++++++++ .../query/service/impl/PortalServiceImpl.java | 13 +++++++------ .../src/main/resources/mapper/PortalMapper.xml | 10 +++++----- 7 files changed, 50 insertions(+), 32 deletions(-) create mode 100644 custom-query/custom-query-biz/src/main/java/cn/fateverse/query/enums/PortalPremEnum.java diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/Portal.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/Portal.java index d71f3db..b33e50e 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/Portal.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/Portal.java @@ -3,11 +3,11 @@ package cn.fateverse.query.entity; import cn.fateverse.common.core.annotaion.EnableAutoField; import cn.fateverse.common.core.entity.BaseEntity; import cn.fateverse.query.enums.PortalEnum; +import cn.fateverse.query.enums.PortalPremEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import org.springframework.web.bind.annotation.RequestMethod; /** @@ -44,9 +44,9 @@ public class Portal extends BaseEntity { private String portalName; /** - * 是否匿名 + * 权限类型 */ - private Boolean anonymity; + private PortalPremEnum permissionType; /** * 接口类型 diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/PortalDto.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/PortalDto.java index 864cd8c..9665506 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/PortalDto.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/PortalDto.java @@ -3,7 +3,9 @@ package cn.fateverse.query.entity.dto; import cn.fateverse.common.core.utils.ObjectUtils; import cn.fateverse.query.entity.Portal; import cn.fateverse.query.entity.PortalMapping; +import cn.fateverse.query.enums.DataAdapterType; import cn.fateverse.query.enums.PortalEnum; +import cn.fateverse.query.enums.PortalPremEnum; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -49,11 +51,11 @@ public class PortalDto { private String portalName; /** - * 是否匿名 + * 权限类型 */ - @ApiModelProperty("是否匿名") - @NotNull(message = "是否匿名不能为空") - private Boolean anonymity; + @ApiModelProperty("权限类型") + @NotNull(message = "权限类型不能为空") + private PortalPremEnum permissionType; /** * 接口类型 @@ -101,10 +103,8 @@ public class PortalDto { @ApiModelProperty("备注") private String remark; - - @ApiModelProperty("数据适配器信息") - private DataAdapterDto dataAdapter; - + @ApiModelProperty("适配器代码类型") + private DataAdapterType adapterCodeType; @ApiModelProperty("映射关系") private List mappings; @@ -115,7 +115,7 @@ public class PortalDto { .queryId(queryId) .adapterId(adapterId) .portalName(portalName) - .anonymity(anonymity) + .permissionType(permissionType) .createDataAdapter(createDataAdapter) .requestMethod(requestMethod) .page(page) diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/query/PortalQuery.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/query/PortalQuery.java index 5d5465b..b407291 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/query/PortalQuery.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/query/PortalQuery.java @@ -1,6 +1,7 @@ package cn.fateverse.query.entity.query; import cn.fateverse.query.enums.PortalEnum; +import cn.fateverse.query.enums.PortalPremEnum; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; @@ -26,10 +27,10 @@ public class PortalQuery { private String portalName; /** - * 是否匿名 + * 权限类型 */ - @ApiModelProperty("是否匿名") - private Boolean anonymity; + @ApiModelProperty("权限类型") + private PortalPremEnum permissionType; /** * 接口类型 diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/vo/SimplePortalVo.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/vo/SimplePortalVo.java index b75566d..940ac16 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/vo/SimplePortalVo.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/vo/SimplePortalVo.java @@ -3,7 +3,9 @@ package cn.fateverse.query.entity.vo; import cn.fateverse.common.core.annotaion.Excel; import cn.fateverse.common.decrypt.annotation.EncryptField; import cn.fateverse.query.entity.Portal; +import cn.fateverse.query.enums.DataAdapterType; import cn.fateverse.query.enums.PortalEnum; +import cn.fateverse.query.enums.PortalPremEnum; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; @@ -67,18 +69,18 @@ public class SimplePortalVo { */ @ApiModelProperty("数据适配器类型") @Excel("数据适配器类型") - private String adapterCodeType; + private DataAdapterType adapterCodeType; private Boolean createDataAdapter; /** - * 是否匿名 + * 权限类型 */ - @ApiModelProperty("是否匿名") - @Excel("是否匿名") - private Boolean anonymity; + @ApiModelProperty("权限类型") + @Excel("权限类型") + private PortalPremEnum permissionType; /** * 接口类型 @@ -126,7 +128,7 @@ public class SimplePortalVo { SimplePortalVo portalVo = SimplePortalVo.builder() .portalId(String.valueOf(portal.getPortalId())) .portalName(portal.getPortalName()) - .anonymity(portal.getAnonymity()) + .permissionType(portal.getPermissionType()) .queryId(portal.getQueryId()) .adapterId(portal.getAdapterId()) .createDataAdapter(portal.getCreateDataAdapter()) diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/enums/PortalPremEnum.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/enums/PortalPremEnum.java new file mode 100644 index 0000000..0791556 --- /dev/null +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/enums/PortalPremEnum.java @@ -0,0 +1,14 @@ +package cn.fateverse.query.enums; + +/** + * @author Clay + * @date 2024/4/15 11:23 + */ +public enum PortalPremEnum { + + ANONYMITY, + EXTERNAL, + LOCAL + ; + +} diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java index 4cddbb1..fbe6974 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java @@ -9,6 +9,7 @@ import cn.fateverse.query.entity.dto.DataAdapterCodeDto; import cn.fateverse.query.entity.dto.MockParam; import cn.fateverse.query.entity.vo.DataAdapterVo; import cn.fateverse.query.entity.vo.PortalIdWrapper; +import cn.fateverse.query.enums.DataAdapterType; import cn.fateverse.query.handler.reader.DataAdapterHandlerReader; import cn.fateverse.query.portal.service.HandlerMethodService; import cn.fateverse.query.constant.QueryConstant; @@ -125,7 +126,7 @@ public class PortalServiceImpl implements PortalService { if (portal.getCreateDataAdapter()) { DataAdapter dataAdapter = adapterMapper.selectById(portal.getAdapterId()); if (!ObjectUtils.isEmpty(dataAdapter)) { - portalVo.setAdapterCodeType(dataAdapter.getType().name()); + portalVo.setAdapterCodeType(dataAdapter.getType()); } } portalVo.setMappings(portalMappings); @@ -172,11 +173,11 @@ public class PortalServiceImpl implements PortalService { } } //映射数据适配器名称 - Map adapterMap = new HashMap<>(); + Map adapterMap = new HashMap<>(); if (!ObjectUtils.isEmpty(adapterIds)) { List adapterList = adapterMapper.selectListByIds(adapterIds); for (DataAdapter adapter : adapterList) { - adapterMap.put(adapter.getAdapterId(), adapter.getType().name()); + adapterMap.put(adapter.getAdapterId(), adapter.getType()); } } //映射重组 @@ -367,11 +368,11 @@ public class PortalServiceImpl implements PortalService { * @param portal 接口信息 */ private void createDataAdapter(PortalDto portalDto, Portal portal) { - DataAdapterDto dataAdapterDto = portalDto.getDataAdapter(); - if (ObjectUtils.isEmpty(dataAdapterDto)) { + if (ObjectUtils.isEmpty(portalDto.getAdapterCodeType())) { throw new CustomException("数据适配器为空!"); } - DataAdapter dataAdapter = dataAdapterDto.toDataAdapter(); + DataAdapter dataAdapter = new DataAdapter(); + dataAdapter.setType(portalDto.getAdapterCodeType()); if (ObjectUtils.isEmpty(dataAdapter.getType())) { throw new CustomException("请选择数据适配器类型!"); } diff --git a/custom-query/custom-query-biz/src/main/resources/mapper/PortalMapper.xml b/custom-query/custom-query-biz/src/main/resources/mapper/PortalMapper.xml index 3fe99ba..d1e89c4 100644 --- a/custom-query/custom-query-biz/src/main/resources/mapper/PortalMapper.xml +++ b/custom-query/custom-query-biz/src/main/resources/mapper/PortalMapper.xml @@ -9,7 +9,7 @@ query_id, adapter_id, portal_name, - anonymity, + permission_type, type, request_method, create_data_adapter, @@ -33,7 +33,7 @@ and portal_name like concat('%', #{portalName}, '%') - and anonymity = #{anonymity} + and permission_type = #{permissionType} and type = #{type} and state = #{state} and path like concat('%', #{path}, '%') @@ -51,7 +51,7 @@ query_id, adapter_id, portal_name, - anonymity, + permission_type, type, page, request_method, @@ -66,7 +66,7 @@ #{queryId}, #{adapterId}, #{portalName}, - #{anonymity}, + #{permissionType}, #{type}, #{page}, #{requestMethod}, @@ -85,7 +85,7 @@ query_id = #{queryId}, adapter_id = #{adapterId}, portal_name = #{portalName}, - anonymity = #{anonymity}, + permission_type = #{permissionType}, type = #{type}, type = #{page}, request_method = #{requestMethod}, From a1712c18d654a16319a5431bb6136e63f8f7a8d6 Mon Sep 17 00:00:00 2001 From: clay <20932067@zju.edu.cn> Date: Wed, 24 Apr 2024 16:37:26 +0800 Subject: [PATCH 05/10] =?UTF-8?q?readme=20:=20=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 446a9c8..9bf4832 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ | 依赖 | 版本 | |----------------------|------------| -| Spring Boot | 2.7.5 | +| Spring Boot | 2.7.3 | | Spring Cloud | 2021.0.5 | | Spring Cloud Alibaba | 2021.0.4.0 | | Mybatis | 3.5.2 | From 2e7c0c042e4484b44d6a69ebfc2b669af08929ae Mon Sep 17 00:00:00 2001 From: clay <20932067@zju.edu.cn> Date: Thu, 25 Apr 2024 14:08:24 +0800 Subject: [PATCH 06/10] =?UTF-8?q?feat=20:=20=E6=B7=BB=E5=8A=A0=E5=BF=85?= =?UTF-8?q?=E8=A6=81=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- .../fateverse/query/entity/PortalMapping.java | 3 +++ .../fateverse/query/entity/dto/PortalDto.java | 3 +++ .../fateverse/query/enums/PortalPremEnum.java | 12 ++++++++++-- .../portal/service/DispatchSyncService.java | 19 ++++++++++++++++--- .../query/service/impl/PortalServiceImpl.java | 11 +++++++++-- .../resources/mapper/PortalMappingMapper.xml | 15 +++++++++++---- 7 files changed, 53 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 9bf4832..7572941 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ | Spring Cloud Alibaba | 2021.0.4.0 | | Mybatis | 3.5.2 | | Vue | 3.1.3 | -| React | 3.1.3 | +| React | 18.2.0 | ### 模块说明 diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/PortalMapping.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/PortalMapping.java index e97e18c..2e2f400 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/PortalMapping.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/PortalMapping.java @@ -48,6 +48,9 @@ public class PortalMapping { */ private String inputType; + + private Boolean required; + /** * 描述 */ diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/PortalDto.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/PortalDto.java index 9665506..6ee3695 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/PortalDto.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/PortalDto.java @@ -137,6 +137,9 @@ public class PortalDto { if (!mapping.check()) { throw new RuntimeException("映射关系不完全,请检查映射关系"); } + if (ObjectUtils.isEmpty(mapping.getRequired())) { + mapping.setRequired(Boolean.FALSE); + } } } portal.setRemark(remark); diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/enums/PortalPremEnum.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/enums/PortalPremEnum.java index 0791556..ac5d3f0 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/enums/PortalPremEnum.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/enums/PortalPremEnum.java @@ -6,9 +6,17 @@ package cn.fateverse.query.enums; */ public enum PortalPremEnum { + /** + * 匿名 + */ ANONYMITY, + /** + * 第三方授权 + */ EXTERNAL, - LOCAL - ; + /** + * 内部使用 + */ + LOCAL; } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/portal/service/DispatchSyncService.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/portal/service/DispatchSyncService.java index 9e11fb2..9c61390 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/portal/service/DispatchSyncService.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/portal/service/DispatchSyncService.java @@ -14,6 +14,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboReference; import org.apache.dubbo.rpc.cluster.specifyaddress.Address; import org.apache.dubbo.rpc.cluster.specifyaddress.UserSpecifiedAddressUtil; +import org.bouncycastle.jcajce.provider.asymmetric.RSA; import org.springframework.context.event.EventListener; import org.springframework.core.env.Environment; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @@ -122,18 +123,28 @@ public class DispatchSyncService { } //如果为false,则将当前任务重新放入到队列中,等待下一次执行 if (state == null || !state) { - queue.add(this); + retry(); } } catch (NacosException e) { log.error("NacosException: {}", e.getMessage()); //如果发生异常也是 - //todo 后续可以添加当前任务报错次数的处理 - queue.add(this); + retry(); } finally { //将指定的地址恢复 UserSpecifiedAddressUtil.setAddress(null); } } + + /** + * 进行重试 + */ + private void retry() { + retryCount++; + if (retryCount > 5) { + log.error("任务超过最大重试次数!"); + } + queue.add(this); + } }; //像阻塞队列中添加任务 queue.add(task); @@ -169,6 +180,8 @@ public class DispatchSyncService { protected final String requestMethod; + protected Integer retryCount = 0; + private Task(String ip, int port, String path, Boolean publish, String requestMethod) { this.ip = ip; this.port = port; diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java index fbe6974..7865128 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java @@ -10,10 +10,10 @@ import cn.fateverse.query.entity.dto.MockParam; import cn.fateverse.query.entity.vo.DataAdapterVo; import cn.fateverse.query.entity.vo.PortalIdWrapper; import cn.fateverse.query.enums.DataAdapterType; +import cn.fateverse.query.enums.PortalPremEnum; import cn.fateverse.query.handler.reader.DataAdapterHandlerReader; import cn.fateverse.query.portal.service.HandlerMethodService; import cn.fateverse.query.constant.QueryConstant; -import cn.fateverse.query.entity.dto.DataAdapterDto; import cn.fateverse.query.entity.dto.PortalDto; import cn.fateverse.query.entity.query.PortalQuery; import cn.fateverse.query.entity.vo.PortalVo; @@ -76,12 +76,19 @@ public class PortalServiceImpl implements PortalService { this.handlerReader = handlerReader; taskExecuteExecutor.execute(() -> { PortalQuery query = new PortalQuery(); -// query.setState(QueryConstant.PORTAL_PUBLISH); + query.setState(QueryConstant.PORTAL_PUBLISH); List portalList = portalMapper.selectList(query); if (ObjectUtils.isEmpty(portalList)) { log.info("portal is empty!"); return; } + portalList = portalList.stream() + .filter(portal -> PortalPremEnum.ANONYMITY.equals(portal.getPermissionType()) || PortalPremEnum.EXTERNAL.equals(portal.getPermissionType())) + .collect(Collectors.toList()); + if (ObjectUtils.isEmpty(portalList)) { + log.info("portal is empty!"); + return; + } List portalIds = portalList.stream().map(Portal::getPortalId).collect(Collectors.toList()); if (ObjectUtils.isEmpty(portalIds)) { log.info("portalIds is empty!"); diff --git a/custom-query/custom-query-biz/src/main/resources/mapper/PortalMappingMapper.xml b/custom-query/custom-query-biz/src/main/resources/mapper/PortalMappingMapper.xml index 2b8f4be..ae5395d 100644 --- a/custom-query/custom-query-biz/src/main/resources/mapper/PortalMappingMapper.xml +++ b/custom-query/custom-query-biz/src/main/resources/mapper/PortalMappingMapper.xml @@ -4,7 +4,14 @@ "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - select mapping_id, portal_id, mapping_key, mapping_type, mapping_value, input_type, description + select mapping_id, + portal_id, + mapping_key, + mapping_type, + mapping_value, + input_type, + required, + description from portal_mapping @@ -21,13 +28,13 @@ - - insert into portal_mapping (portal_id, mapping_key, mapping_type, mapping_value, input_type, description) + insert into portal_mapping (portal_id, mapping_key, mapping_type, mapping_value, input_type, required, + description) values (#{item.portalId}, #{item.mappingKey}, #{item.mappingType}, #{item.mappingValue}, #{item.inputType}, - #{item.description}) + #{item.required},#{item.description}) From a4286ba65db7e56f9fbba43eb34241f2e9501489 Mon Sep 17 00:00:00 2001 From: clay <20932067@zju.edu.cn> Date: Fri, 26 Apr 2024 11:58:28 +0800 Subject: [PATCH 07/10] =?UTF-8?q?feat=20:=20=E6=B7=BB=E5=8A=A0=E5=A4=96?= =?UTF-8?q?=E9=83=A8=E6=8E=A5=E5=8F=A3=E5=BF=85=E8=A6=81=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/fateverse/query/entity/Portal.java | 15 ++-- .../query/entity/PortalInterface.java | 34 +++++++++ .../fateverse/query/entity/bo/PortalBo.java | 3 +- .../fateverse/query/entity/dto/PortalDto.java | 18 ++--- .../query/mapper/PortalInterfaceMapper.java | 44 ++++++++++++ .../query/service/impl/PortalServiceImpl.java | 70 +++++++++++++++---- .../mapper/PortalInterfaceMapper.xml | 31 ++++++++ .../main/resources/mapper/PortalMapper.xml | 12 ++-- 8 files changed, 195 insertions(+), 32 deletions(-) create mode 100644 custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/PortalInterface.java create mode 100644 custom-query/custom-query-biz/src/main/java/cn/fateverse/query/mapper/PortalInterfaceMapper.java create mode 100644 custom-query/custom-query-biz/src/main/resources/mapper/PortalInterfaceMapper.xml diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/Portal.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/Portal.java index b33e50e..cd72111 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/Portal.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/Portal.java @@ -33,6 +33,16 @@ public class Portal extends BaseEntity { */ private Long queryId; + /** + * 菜单id + */ + private Long menuId; + + /** + * 接口id + */ + private Long interfaceId; + /** * 数据适配器id */ @@ -73,11 +83,6 @@ public class Portal extends BaseEntity { */ private String path; - /** - * 第三方接口地址 - */ - private String url; - /** * 状态 */ diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/PortalInterface.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/PortalInterface.java new file mode 100644 index 0000000..115b55d --- /dev/null +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/PortalInterface.java @@ -0,0 +1,34 @@ +package cn.fateverse.query.entity; + +import lombok.Data; + +/** + * 第三方接口信息 + * + * @author Clay + * @date 2024/4/26 11:17 + */ +@Data +public class PortalInterface { + + /** + * 接口id + */ + private Long interfaceId; + + /** + * 请求地址 + */ + private String url; + + /** + * 请求类型 + */ + private String contentType; + + /** + * 请求类型 + */ + private String requestMethod; + +} diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/bo/PortalBo.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/bo/PortalBo.java index 6627664..32b1b01 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/bo/PortalBo.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/bo/PortalBo.java @@ -22,6 +22,7 @@ import java.util.List; public class PortalBo implements Serializable { private Long portalId; private Long queryId; + private Long interfaceId; private Long adapterId; private PortalEnum type; private String requestMethod; @@ -36,13 +37,13 @@ public class PortalBo implements Serializable { return PortalBo.builder() .portalId(portal.getPortalId()) .queryId(portal.getQueryId()) + .interfaceId(portal.getInterfaceId()) .adapterId(portal.getAdapterId()) .type(portal.getType()) .requestMethod(portal.getRequestMethod()) .createDataAdapter(portal.getCreateDataAdapter()) .page(portal.getPage()) .path(portal.getPath()) - .url(portal.getUrl()) .state(portal.getState()) .mappings(mappings) .build(); diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/PortalDto.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/PortalDto.java index 6ee3695..310a4ce 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/PortalDto.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/PortalDto.java @@ -72,6 +72,16 @@ public class PortalDto { @NotNull(message = "是否创建数据适配器不能为空!") private Boolean createDataAdapter; + @ApiModelProperty("请求地址") + private String url; + + @ApiModelProperty("请求类型") + private String contentType; + + + @ApiModelProperty("接口请求方法类型") + private String interfaceRequestMethod; + /** * 是否分页 */ @@ -84,13 +94,6 @@ public class PortalDto { @NotBlank(message = "系统暴露地址不能为空") private String path; - /** - * 第三方接口地址 - */ - @ApiModelProperty("第三方接口地址") - private String url; - - /** * 状态 */ @@ -121,7 +124,6 @@ public class PortalDto { .page(page) .type(type) .path(path) - .url(url) .state(state) .build(); try { diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/mapper/PortalInterfaceMapper.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/mapper/PortalInterfaceMapper.java new file mode 100644 index 0000000..006debd --- /dev/null +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/mapper/PortalInterfaceMapper.java @@ -0,0 +1,44 @@ +package cn.fateverse.query.mapper; + +import cn.fateverse.query.entity.PortalInterface; + +/** + * @author Clay + * @date 2024/4/26 11:23 + */ +public interface PortalInterfaceMapper { + + /** + * 根据id查询 + * + * @param interfaceId 接口id + * @return 接口信息 + */ + PortalInterface selectById(Long interfaceId); + + /** + * 新增 + * + * @param portalInterface 接口信息 + * @return 影响行数 + */ + Integer insert(PortalInterface portalInterface); + + /** + * 修改 + * + * @param portalInterface 接口信息 + * @return 影响行数 + */ + Integer update(PortalInterface portalInterface); + + /** + * 删除 + * + * @param interfaceId 接口id + * @return 影响行数 + */ + Integer deleteById(Long interfaceId); + + +} diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java index 7865128..b6d6963 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java @@ -12,6 +12,7 @@ import cn.fateverse.query.entity.vo.PortalIdWrapper; import cn.fateverse.query.enums.DataAdapterType; import cn.fateverse.query.enums.PortalPremEnum; import cn.fateverse.query.handler.reader.DataAdapterHandlerReader; +import cn.fateverse.query.mapper.*; import cn.fateverse.query.portal.service.HandlerMethodService; import cn.fateverse.query.constant.QueryConstant; import cn.fateverse.query.entity.dto.PortalDto; @@ -19,10 +20,6 @@ import cn.fateverse.query.entity.query.PortalQuery; import cn.fateverse.query.entity.vo.PortalVo; import cn.fateverse.query.entity.vo.SimplePortalVo; import cn.fateverse.query.enums.PortalEnum; -import cn.fateverse.query.mapper.DataAdapterMapper; -import cn.fateverse.query.mapper.PortalMapper; -import cn.fateverse.query.mapper.PortalMappingMapper; -import cn.fateverse.query.mapper.UniQueryMapper; import cn.fateverse.query.service.PortalService; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; @@ -58,6 +55,8 @@ public class PortalServiceImpl implements PortalService { private final PortalMappingMapper portalMappingMapper; + private final PortalInterfaceMapper portalInterfaceMapper; + private final DataAdapterHandlerReader handlerReader; @@ -67,12 +66,14 @@ public class PortalServiceImpl implements PortalService { PortalMappingMapper portalMappingMapper, ThreadPoolTaskExecutor taskExecuteExecutor, HandlerMethodService methodService, + PortalInterfaceMapper portalInterfaceMapper, DataAdapterHandlerReader handlerReader) { this.portalMapper = portalMapper; this.queryMapper = queryMapper; this.adapterMapper = adapterMapper; this.portalMappingMapper = portalMappingMapper; this.methodService = methodService; + this.portalInterfaceMapper = portalInterfaceMapper; this.handlerReader = handlerReader; taskExecuteExecutor.execute(() -> { PortalQuery query = new PortalQuery(); @@ -240,8 +241,8 @@ public class PortalServiceImpl implements PortalService { @Override @Transactional(rollbackFor = Exception.class) public PortalIdWrapper save(PortalDto portalDto) { + checkPortalType(portalDto); Portal portal = portalDto.toPortal(); - checkPortalType(portal); Portal old = portalMapper.selectByPath(portal.getPath(), portal.getRequestMethod()); if (!ObjectUtils.isEmpty(old)) { throw new CustomException("系统中存在当前请求路径"); @@ -260,6 +261,9 @@ public class PortalServiceImpl implements PortalService { throw new CustomException("未找到对应的数据适配器!"); } } + if (PortalEnum.EXTERNAL.equals(portal.getType())) { + createPortalInterface(portalDto, portal); + } portalMapper.insert(portal); List mappings = portalDto.getMappings(); if (!ObjectUtils.isEmpty(mappings)) { @@ -279,8 +283,8 @@ public class PortalServiceImpl implements PortalService { @Override @Transactional(rollbackFor = Exception.class) public PortalIdWrapper edit(PortalDto portalDto) { + checkPortalType(portalDto); Portal portal = portalDto.toPortal(); - checkPortalType(portal); Portal old = portalMapper.selectByPath(portal.getPath(), portal.getRequestMethod()); if (!QueryConstant.PORTAL_DEV.equals(old.getState())) { throw new CustomException("当前状态不允许修改"); @@ -295,6 +299,22 @@ public class PortalServiceImpl implements PortalService { adapterMapper.deleteById(old.getAdapterId()); } } + if (!old.getType().equals(portal.getType())) { + if (PortalEnum.LOCAL.equals(portal.getType())) { + portalInterfaceMapper.deleteById(old.getInterfaceId()); + } else { + createPortalInterface(portalDto, portal); + } + } else { + if (PortalEnum.EXTERNAL.equals(portal.getType())) { + PortalInterface portalInterface = new PortalInterface(); + portalInterface.setInterfaceId(old.getInterfaceId()); + portalInterface.setContentType(portalDto.getContentType()); + portalInterface.setRequestMethod(portalDto.getInterfaceRequestMethod()); + portalInterface.setUrl(portalDto.getUrl()); + portalInterfaceMapper.update(portalInterface); + } + } portalMappingMapper.deleteByPortalId(portal.getPortalId()); portalMapper.update(portal); if (!ObjectUtils.isEmpty(portalDto.getMappings())) { @@ -340,6 +360,9 @@ public class PortalServiceImpl implements PortalService { adapterMapper.deleteById(portal.getAdapterId()); } portalMappingMapper.deleteByPortalId(portalId); + if (PortalEnum.EXTERNAL.equals(portal.getType())) { + portalInterfaceMapper.deleteById(portal.getInterfaceId()); + } portalMapper.deleteById(portalId); } @@ -393,19 +416,40 @@ public class PortalServiceImpl implements PortalService { portal.setAdapterId(dataAdapter.getAdapterId()); } + /** + * 创建第三方接口 + * + * @param portalDto 接口dto对象 + * @param portal 接口对象 + */ + private void createPortalInterface(PortalDto portalDto, Portal portal) { + PortalInterface portalInterface = new PortalInterface(); + portalInterface.setContentType(portalDto.getContentType()); + portalInterface.setRequestMethod(portalDto.getInterfaceRequestMethod()); + portalInterface.setUrl(portalDto.getUrl()); + portalInterfaceMapper.insert(portalInterface); + portal.setInterfaceId(portalInterface.getInterfaceId()); + } + + /** * 检查接口类型是否正确 * - * @param portal 接口信息 + * @param portalDto 接口信息 */ - private void checkPortalType(Portal portal) { - if (PortalEnum.LOCAL.equals(portal.getType())) { - if (ObjectUtils.isEmpty(portal.getQueryId())) { + private void checkPortalType(PortalDto portalDto) { + if (PortalEnum.LOCAL.equals(portalDto.getType())) { + if (ObjectUtils.isEmpty(portalDto.getQueryId())) { throw new CustomException("请选择查询接口!"); } - portal.setUrl(null); - } else if (PortalEnum.EXTERNAL.equals(portal.getType())) { - if (ObjectUtils.isEmpty(portal.getUrl())) { + } else if (PortalEnum.EXTERNAL.equals(portalDto.getType())) { + if (ObjectUtils.isEmpty(portalDto.getContentType())) { + throw new CustomException("外部接口请求类型不能为空"); + } + if (ObjectUtils.isEmpty(portalDto.getInterfaceRequestMethod())) { + throw new CustomException("外部接口请求方法不能为空"); + } + if (ObjectUtils.isEmpty(portalDto.getUrl())) { throw new CustomException("第三方接口地址不能为空!"); } } else { diff --git a/custom-query/custom-query-biz/src/main/resources/mapper/PortalInterfaceMapper.xml b/custom-query/custom-query-biz/src/main/resources/mapper/PortalInterfaceMapper.xml new file mode 100644 index 0000000..c1d54dd --- /dev/null +++ b/custom-query/custom-query-biz/src/main/resources/mapper/PortalInterfaceMapper.xml @@ -0,0 +1,31 @@ + + + + + + + + insert into portal_interface (interface_id, content_type, request_method) + values (#{interfaceId}, #{contentType}, #{requestMethod}) + + + + update portal_interface + set content_type = #{contentType}, + request_method = #{requestMethod} + where interface_id = #{interfaceId} + + + + delete + from portal_interface + where interface_id = #{interfaceId} + + + \ No newline at end of file diff --git a/custom-query/custom-query-biz/src/main/resources/mapper/PortalMapper.xml b/custom-query/custom-query-biz/src/main/resources/mapper/PortalMapper.xml index d1e89c4..22f4273 100644 --- a/custom-query/custom-query-biz/src/main/resources/mapper/PortalMapper.xml +++ b/custom-query/custom-query-biz/src/main/resources/mapper/PortalMapper.xml @@ -7,6 +7,8 @@ select portal_id, query_id, + menu_id, + interface_id, adapter_id, portal_name, permission_type, @@ -15,7 +17,6 @@ create_data_adapter, page, path, - url, state, create_by, create_time, @@ -32,7 +33,8 @@ - select interface_id, content_type, request_method + select interface_id, url, content_type, request_method from portal_interface where interface_id = #{interfaceId} - insert into portal_interface (interface_id, content_type, request_method) - values (#{interfaceId}, #{contentType}, #{requestMethod}) + insert into portal_interface (interface_id, url, content_type, request_method) + values (#{interfaceId}, #{url}, #{contentType}, #{requestMethod}) update portal_interface set content_type = #{contentType}, + url = #{url}, request_method = #{requestMethod} where interface_id = #{interfaceId} diff --git a/workflow/src/main/java/cn/fateverse/workflow/process/TriggerService.java b/workflow/src/main/java/cn/fateverse/workflow/process/TriggerService.java index a4ecdbb..3e62d8e 100644 --- a/workflow/src/main/java/cn/fateverse/workflow/process/TriggerService.java +++ b/workflow/src/main/java/cn/fateverse/workflow/process/TriggerService.java @@ -1,7 +1,6 @@ package cn.fateverse.workflow.process; import cn.fateverse.common.code.engine.JavaScriptEngine; -import cn.fateverse.common.code.model.EngineResult; import cn.fateverse.workflow.constant.ProcessConstant; import cn.fateverse.workflow.entity.bpmn.*; import cn.hutool.core.util.StrUtil; @@ -159,14 +158,14 @@ public class TriggerService { } //获取到请求的返回结果 Map result = response.getBody(); - EngineResult engineResult; + ScriptObjectMirror jsResult; try { //判断请求是否有效 if (response.getStatusCode() == HttpStatus.OK) { - engineResult = JavaScriptEngine.execute(http.getSuccess(), "handlerSuccess", false, result); + jsResult = (ScriptObjectMirror) JavaScriptEngine.execute(http.getSuccess(), "handlerSuccess", result); operation.setState(OperationStateEnums.SUCCESS); } else { - engineResult = JavaScriptEngine.execute(http.getFail(), "handlerFail", false, result); + jsResult = (ScriptObjectMirror) JavaScriptEngine.execute(http.getFail(), "handlerFail", result); operation.setState(OperationStateEnums.FAILURE); } } catch (Exception e) { @@ -178,7 +177,6 @@ public class TriggerService { } return; } - ScriptObjectMirror jsResult = (ScriptObjectMirror) engineResult.getResult(); //获取到自定义脚本的状态 boolean state = (Boolean) jsResult.get("state"); //获取到js脚本中的内容 From 41fbf21128745935317d4e19df9ebc57eb94ef05 Mon Sep 17 00:00:00 2001 From: clay <20932067@zju.edu.cn> Date: Mon, 29 Apr 2024 22:07:31 +0800 Subject: [PATCH 09/10] =?UTF-8?q?fix=20:=20js=20=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/code/engine/JavaScriptEngine.java | 22 +++++++++++++++---- .../fateverse/query/entity/vo/PortalVo.java | 2 ++ .../engine/impl/JavaEngineExecuteHandler.java | 3 +++ .../query/service/impl/PortalServiceImpl.java | 11 ++++++++-- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaScriptEngine.java b/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaScriptEngine.java index 7809420..50ff47d 100644 --- a/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaScriptEngine.java +++ b/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaScriptEngine.java @@ -41,9 +41,15 @@ public class JavaScriptEngine { * @return 返回结构 */ public static Object execute(String script, String functionName, Object args) { - Value executeFunction = getFunction(functionName, script); - Value result = executeFunction.execute(JSON.toJSONString(args)); - return result.as(Object.class); + try { + Value executeFunction = getFunction(functionName, script); + Value javaObjectAsValue = Value.asValue(args); + Value result = executeFunction.execute(javaObjectAsValue); + return result.as(Object.class); + } catch (Exception e) { + remove(functionName); + throw new CustomException("运行失败!"); + } } @@ -68,7 +74,7 @@ public class JavaScriptEngine { Value result = executeFunction.execute(javaObjectAsValue); return result.as(Object.class); }); - }catch (CustomException e){ + } catch (CustomException e) { EngineResult result = new EngineResult(); result.setSuccess(Boolean.FALSE); result.setConsole(e.getMessage()); @@ -90,4 +96,12 @@ public class JavaScriptEngine { } + private static void remove(String functionName) { + SegmentLock.lock(functionName, () -> { + functionMap.remove(functionName); + return null; + }); + } + + } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/vo/PortalVo.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/vo/PortalVo.java index 4b94fcb..c3348d9 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/vo/PortalVo.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/vo/PortalVo.java @@ -36,6 +36,8 @@ public class PortalVo extends SimplePortalVo { */ private Boolean page; + private String url; + /** * 条件映射 */ diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/engine/impl/JavaEngineExecuteHandler.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/engine/impl/JavaEngineExecuteHandler.java index 1d09ef7..81b6816 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/engine/impl/JavaEngineExecuteHandler.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/engine/impl/JavaEngineExecuteHandler.java @@ -41,6 +41,9 @@ public class JavaEngineExecuteHandler implements EngineExecuteHandler { @Override public EngineResult mockExecute(DataAdapter dataAdapter, Object data) { + if (!DataAdapterType.JAVA.equals(dataAdapter.getType())) { + return null; + } return javaCodeEngine.mockExecute(dataAdapter.getExecuteCode(), getClassName(dataAdapter), "execute", new Object[]{data}); } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java index 5aa2834..3335652 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java @@ -129,7 +129,14 @@ public class PortalServiceImpl implements PortalService { } if (PortalEnum.LOCAL.equals(portal.getType())) { UniQuery uniQuery = queryMapper.selectById(portal.getQueryId()); - portalVo.setQueryType(uniQuery.getType()); + if (!ObjectUtils.isEmpty(uniQuery)) { + portalVo.setQueryType(uniQuery.getType()); + } + } else { + PortalInterface portalInterface = portalInterfaceMapper.selectById(portal.getInterfaceId()); + if (!ObjectUtils.isEmpty(portalInterface)) { + portalVo.setUrl(portalInterface.getUrl()); + } } if (portal.getCreateDataAdapter()) { DataAdapter dataAdapter = adapterMapper.selectById(portal.getAdapterId()); @@ -249,7 +256,7 @@ public class PortalServiceImpl implements PortalService { } if (PortalEnum.EXTERNAL.equals(portal.getType())) { createPortalInterface(portalDto, portal); - }else { + } else { UniQuery uniQuery = queryMapper.selectById(portal.getQueryId()); if (ObjectUtils.isEmpty(uniQuery)) { throw new CustomException("未找到对应的查询接口!"); From 52a230d7fb87db63da7f129a5a5cfff3feeb49f8 Mon Sep 17 00:00:00 2001 From: clay <20932067@zju.edu.cn> Date: Wed, 8 May 2024 21:28:53 +0800 Subject: [PATCH 10/10] =?UTF-8?q?build=20:=20=E6=B7=BB=E5=8A=A0skywalking?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .drone.yml | 2 +- Dockerfile | 8 ++--- README.md | 4 +-- .../common/code/engine/JavaScriptEngine.java | 2 +- .../query/controller/PortalController.java | 20 +++++++++++ .../DubboDispatchServletPublishImpl.java | 19 ++++++++-- .../query/entity/dto/PortalPublish.java | 26 ++++++++++++++ .../impl/JavaScriptEngineExecuteHandler.java | 7 +++- .../query/portal/PortalDispatchServlet.java | 13 +------ .../portal/service/HandlerMethodService.java | 35 ++++--------------- .../query/service/PortalService.java | 9 +++++ .../query/service/impl/PortalServiceImpl.java | 26 +++++++++++++- start.sh | 14 ++++---- 13 files changed, 125 insertions(+), 60 deletions(-) create mode 100644 custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/PortalPublish.java diff --git a/.drone.yml b/.drone.yml index f1d8d41..3dec36a 100644 --- a/.drone.yml +++ b/.drone.yml @@ -74,7 +74,7 @@ volumes: path: /home/build/fateverse - name: skywalking host: - path: /home/skywalking-agent + path: /home/build/skywalking-agent - name: config # k8s对接的配置文件 host: path: /home/kubect diff --git a/Dockerfile b/Dockerfile index d28e349..172bad7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,17 +2,15 @@ FROM azul/zulu-openjdk:11.0.22-jdk VOLUME /tmp RUN useradd -b /home -m -s /bin/bash clay RUN chmod a+xr -R /home/clay && chown clay:clay -R /home/clay -#COPY skywalking /home/clay/skywalking-agent -#RUN chmod a+xr -R /home/clay/skywalking-agent && chown clay:clay -R /home/clay/skywalking-agent +COPY skywalking /home/clay/skywalking-agent +RUN chmod a+xr -R /home/clay/skywalking-agent && chown clay:clay -R /home/clay/skywalking-agent USER clay ARG NAME=$DRONE_COMMIT_BRANCH COPY ./$NAME.jar /home/clay/$NAME.jar COPY start.sh /home/clay/start.sh WORKDIR /home/clay RUN mkdir -p /home/clay/logs && touch /home/clay/logs/spring.log -#RUN mkdir -p /home/clay/code -#RUN chmod 777 /home/clay/code -#RUN mkdir -p /home/clay/skywalking-agent/logs && touch /home/clay/skywalking-agent/logs/skywalking-api.log +RUN mkdir -p /home/clay/skywalking-agent/logs && touch /home/clay/skywalking-agent/logs/skywalking-api.log ENV REF_NAME dev EXPOSE 8080 CMD bash /home/clay/start.sh $REF_NAME && echo "start logging..." && : > /home/clay/logs/spring.log && tail -F -n 500 /home/clay/logs/spring.log \ No newline at end of file diff --git a/README.md b/README.md index 7572941..a0024d1 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,8 @@ | 依赖 | 版本 | |----------------------|------------| | Spring Boot | 2.7.3 | -| Spring Cloud | 2021.0.5 | -| Spring Cloud Alibaba | 2021.0.4.0 | +| Spring Cloud | 2021.0.3 | +| Spring Cloud Alibaba | 2021.0.1.0 | | Mybatis | 3.5.2 | | Vue | 3.1.3 | | React | 18.2.0 | diff --git a/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaScriptEngine.java b/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaScriptEngine.java index 50ff47d..dd0542b 100644 --- a/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaScriptEngine.java +++ b/common/common-code/src/main/java/cn/fateverse/common/code/engine/JavaScriptEngine.java @@ -96,7 +96,7 @@ public class JavaScriptEngine { } - private static void remove(String functionName) { + public static void remove(String functionName) { SegmentLock.lock(functionName, () -> { functionMap.remove(functionName); return null; diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/controller/PortalController.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/controller/PortalController.java index f254e0e..7b34fde 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/controller/PortalController.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/controller/PortalController.java @@ -8,6 +8,7 @@ import cn.fateverse.common.decrypt.annotation.EncryptField; import cn.fateverse.query.entity.dto.DataAdapterCodeDto; import cn.fateverse.query.entity.dto.MockParam; import cn.fateverse.query.entity.dto.PortalDto; +import cn.fateverse.query.entity.dto.PortalPublish; import cn.fateverse.query.entity.query.PortalQuery; import cn.fateverse.query.entity.vo.PortalIdWrapper; import cn.fateverse.query.entity.vo.PortalVo; @@ -116,6 +117,25 @@ public class PortalController { return Result.ok(); } + @ApiOperation("列表接口发布") + @PostMapping("/list/publish") + @Encrypt(Encrypt.Position.IN) + @PreAuthorize("@ss.hasPermission('query:portal:edit')") + public Result listPublish(@RequestBody @Validated PortalPublish portalPublish) { + portalService.publish(portalPublish, Boolean.TRUE); + return Result.ok(); + } + @ApiOperation("设计器接口发布") + @PostMapping("/publish") + @PreAuthorize("@ss.hasPermission('query:portal:edit')") + public Result publish(@RequestBody @Validated PortalPublish portalPublish) { + if (ObjectUtils.isEmpty(portalPublish.getCode())){ + return Result.error("代码不能为空!"); + } + portalService.publish(portalPublish, Boolean.FALSE); + return Result.ok(); + } + @ApiOperation("撤销发布") @Encrypt diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/dubbo/DubboDispatchServletPublishImpl.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/dubbo/DubboDispatchServletPublishImpl.java index 3eeb9d2..c6bb27d 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/dubbo/DubboDispatchServletPublishImpl.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/dubbo/DubboDispatchServletPublishImpl.java @@ -1,7 +1,11 @@ package cn.fateverse.query.dubbo; import cn.fateverse.query.constant.QueryConstant; +import cn.fateverse.query.entity.Portal; +import cn.fateverse.query.entity.PortalMapping; import cn.fateverse.query.entity.bo.PortalBo; +import cn.fateverse.query.mapper.PortalMapper; +import cn.fateverse.query.mapper.PortalMappingMapper; import cn.fateverse.query.portal.service.HandlerMethodService; import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboService; @@ -9,6 +13,7 @@ import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.RequestMethod; import javax.annotation.Resource; +import java.util.List; /** * @author Clay @@ -18,10 +23,14 @@ import javax.annotation.Resource; @DubboService(scope = "remote") public class DubboDispatchServletPublishImpl implements DubboDispatchServletPublish { - @Resource private HandlerMethodService methodService; + @Resource + private PortalMapper portalMapper; + + @Resource + private PortalMappingMapper portalMappingMapper; @Resource private RedisTemplate redisTemplate; @@ -30,7 +39,13 @@ public class DubboDispatchServletPublishImpl implements DubboDispatchServletPubl public Boolean publish(String path, String requestMethod) { PortalBo portalBo = redisTemplate.opsForValue().get(QueryConstant.PORTAL_KEY + path + ":" + requestMethod); if (portalBo == null) { - return Boolean.FALSE; + Portal portal = portalMapper.selectByPath(path, requestMethod); + if (portal == null) { + return Boolean.FALSE; + } + List portalMappings = portalMappingMapper.selectByPortalId(portal.getPortalId()); + portalBo = PortalBo.toPortalBo(portal, portalMappings); + redisTemplate.opsForValue().set(QueryConstant.PORTAL_KEY + portalBo.getPath() + ":" + portalBo.getRequestMethod(), portalBo); } try { log.info("registerMapping, path:{}, requestMethod:{}", path, requestMethod); diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/PortalPublish.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/PortalPublish.java new file mode 100644 index 0000000..6703399 --- /dev/null +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/entity/dto/PortalPublish.java @@ -0,0 +1,26 @@ +package cn.fateverse.query.entity.dto; + +import cn.fateverse.common.decrypt.annotation.EncryptField; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * @author Clay + * @date 2024/4/30 16:58 + */ +@Data +public class PortalPublish { + + @EncryptField + @NotBlank(message = "接口id不能为空") + private String portalId; + + private String code; + + + public Long getLongPortalId() { + return Long.valueOf(portalId); + } + +} diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/engine/impl/JavaScriptEngineExecuteHandler.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/engine/impl/JavaScriptEngineExecuteHandler.java index 9a512f0..52113d6 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/engine/impl/JavaScriptEngineExecuteHandler.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/handler/engine/impl/JavaScriptEngineExecuteHandler.java @@ -61,6 +61,11 @@ public class JavaScriptEngineExecuteHandler implements EngineExecuteHandler { @Override public Boolean remove(DataAdapter dataAdapter) { - return Boolean.FALSE; + if (!DataAdapterType.JAVA_SCRIPT.equals(dataAdapter.getType())) { + return Boolean.FALSE; + } + JavaScriptEngine.remove("execute" + dataAdapter.getAdapterId()); + return Boolean.TRUE; } + } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/portal/PortalDispatchServlet.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/portal/PortalDispatchServlet.java index 281755e..b0f87d6 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/portal/PortalDispatchServlet.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/portal/PortalDispatchServlet.java @@ -7,7 +7,6 @@ import cn.fateverse.query.entity.Portal; import cn.fateverse.query.entity.PortalMapping; import cn.fateverse.query.entity.bo.PortalBo; import cn.fateverse.query.handler.reader.DataAdapterHandlerReader; -import cn.fateverse.query.mapper.DataAdapterMapper; import cn.fateverse.query.mapper.PortalMapper; import cn.fateverse.query.mapper.PortalMappingMapper; import org.springframework.data.redis.core.RedisTemplate; @@ -31,19 +30,14 @@ public class PortalDispatchServlet { private final PortalMapper portalMapper; - private final DataAdapterMapper dataAdapterMapper; - private final PortalMappingMapper portalMappingMapper; private final DataAdapterHandlerReader dataAdapterHandler; - public PortalDispatchServlet(PortalMapper portalMapper, - DataAdapterMapper dataAdapterMapper, PortalMappingMapper portalMappingMapper, DataAdapterHandlerReader dataAdapterHandler) { this.portalMapper = portalMapper; - this.dataAdapterMapper = dataAdapterMapper; this.portalMappingMapper = portalMappingMapper; this.dataAdapterHandler = dataAdapterHandler; } @@ -67,12 +61,7 @@ public class PortalDispatchServlet { redisTemplate.opsForValue().set(QueryConstant.PORTAL_KEY + portalBo.getPath() + ":" + portalBo.getRequestMethod(), portalBo); } //进行数据适配器的执行逻辑 - Object result = null; -// if (portalBo.getState() == 1 || portalBo.getState() == 2) { - result = dataAdapterHandler.execute(portalBo, request); -// } else { -// result = dataAdapterHandler.mockExecute(portalBo, request); -// } + Object result = dataAdapterHandler.execute(portalBo, request); //将返回结果放入response ResponseRender.renderString(response, Result.ok(result)); } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/portal/service/HandlerMethodService.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/portal/service/HandlerMethodService.java index 0ad8866..15a8857 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/portal/service/HandlerMethodService.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/portal/service/HandlerMethodService.java @@ -2,28 +2,12 @@ package cn.fateverse.query.portal.service; import cn.fateverse.common.core.exception.CustomException; import cn.fateverse.common.core.utils.SpringContextHolder; -import cn.fateverse.query.dubbo.DubboDispatchServletPublish; import cn.fateverse.query.portal.PortalDispatchServlet; -import cn.fateverse.query.portal.config.DubboServiceBean; import cn.fateverse.query.portal.event.DispatchSyncEvent; -import com.alibaba.cloud.nacos.NacosDiscoveryProperties; -import com.alibaba.cloud.nacos.NacosServiceManager; -import com.alibaba.cloud.nacos.registry.NacosRegistration; -import com.alibaba.nacos.api.PropertyKeyConst; -import com.alibaba.nacos.api.exception.NacosException; -import com.alibaba.nacos.api.naming.NamingService; -import com.alibaba.nacos.api.naming.pojo.Instance; import lombok.extern.slf4j.Slf4j; -import org.apache.dubbo.config.annotation.DubboReference; -import org.apache.dubbo.rpc.RpcContext; -import org.apache.dubbo.rpc.RpcContextAttachment; -import org.apache.dubbo.rpc.cluster.specifyaddress.Address; -import org.apache.dubbo.rpc.cluster.specifyaddress.UserSpecifiedAddressUtil; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; -import org.springframework.core.env.Environment; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; import org.springframework.web.bind.annotation.RequestMethod; @@ -32,12 +16,7 @@ import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import java.lang.reflect.Method; -import java.util.List; import java.util.Map; -import java.util.Optional; -import java.util.Properties; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; /** * @author Clay @@ -49,7 +28,7 @@ public class HandlerMethodService implements ApplicationContextAware { public static final String CUSTOM_INTERFACE = "customInterface:"; - private RequestMappingHandlerMapping mapping; + private RequestMappingHandlerMapping handlerMapping; private Method mappingMethod; @@ -73,7 +52,7 @@ public class HandlerMethodService implements ApplicationContextAware { @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { //获取到web mvc的接口存储mapping - mapping = (RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping"); + handlerMapping = (RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping"); } /** @@ -92,12 +71,12 @@ public class HandlerMethodService implements ApplicationContextAware { .consumes(empty) .produces(empty) .mappingName(CUSTOM_INTERFACE + path); - RequestMappingInfo requestMappingInfo = builder.options(mapping.getBuilderConfiguration()).build(); - Map handlerMethods = mapping.getHandlerMethods(); + RequestMappingInfo requestMappingInfo = builder.options(handlerMapping.getBuilderConfiguration()).build(); + Map handlerMethods = handlerMapping.getHandlerMethods(); if (handlerMethods.containsKey(requestMappingInfo)) { throw new CustomException("path is exist"); } - mapping.registerMapping(requestMappingInfo, "portalDispatchServlet", mappingMethod); + handlerMapping.registerMapping(requestMappingInfo, "portalDispatchServlet", mappingMethod); // 判断是否需要发起同步 if (sync) { //使用事件监听机制,避免循环注入 @@ -112,12 +91,12 @@ public class HandlerMethodService implements ApplicationContextAware { * @param requestMethod 请求类型 */ public void unregisterMapping(String path, RequestMethod requestMethod, Boolean sync) { - Map handlerMethods = mapping.getHandlerMethods(); + Map handlerMethods = handlerMapping.getHandlerMethods(); for (RequestMappingInfo mappingInfo : handlerMethods.keySet()) { if (!ObjectUtils.isEmpty(mappingInfo.getName()) && (CUSTOM_INTERFACE + path).equals(mappingInfo.getName()) && mappingInfo.getMethodsCondition().getMethods().contains(requestMethod)) { - mapping.unregisterMapping(mappingInfo); + handlerMapping.unregisterMapping(mappingInfo); if (sync) { SpringContextHolder.publishEvent(new DispatchSyncEvent(path, requestMethod.name(), Boolean.FALSE)); } diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/PortalService.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/PortalService.java index 91d5bf0..7661e93 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/PortalService.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/PortalService.java @@ -4,6 +4,7 @@ import cn.fateverse.common.core.result.page.TableDataInfo; import cn.fateverse.query.entity.dto.DataAdapterCodeDto; import cn.fateverse.query.entity.dto.MockParam; import cn.fateverse.query.entity.dto.PortalDto; +import cn.fateverse.query.entity.dto.PortalPublish; import cn.fateverse.query.entity.query.PortalQuery; import cn.fateverse.query.entity.vo.PortalIdWrapper; import cn.fateverse.query.entity.vo.PortalVo; @@ -79,6 +80,14 @@ public interface PortalService { */ PortalIdWrapper edit(PortalDto portalDto); + /** + * 发布接口 + * + * @param portalPublish 发布接口对象 + * @param isList 是否为list发布 + */ + void publish(PortalPublish portalPublish, Boolean isList); + /** * 取消发布 * diff --git a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java index 3335652..e65d457 100644 --- a/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java +++ b/custom-query/custom-query-biz/src/main/java/cn/fateverse/query/service/impl/PortalServiceImpl.java @@ -7,11 +7,13 @@ import cn.fateverse.query.entity.*; import cn.fateverse.query.entity.bo.PortalBo; import cn.fateverse.query.entity.dto.DataAdapterCodeDto; import cn.fateverse.query.entity.dto.MockParam; +import cn.fateverse.query.entity.dto.PortalPublish; import cn.fateverse.query.entity.vo.DataAdapterVo; import cn.fateverse.query.entity.vo.PortalIdWrapper; import cn.fateverse.query.enums.DataAdapterType; import cn.fateverse.query.enums.PortalPremEnum; import cn.fateverse.query.handler.reader.DataAdapterHandlerReader; +import cn.fateverse.query.handler.reader.EngineExecuteHandlerReader; import cn.fateverse.query.mapper.*; import cn.fateverse.query.portal.service.HandlerMethodService; import cn.fateverse.query.constant.QueryConstant; @@ -60,6 +62,8 @@ public class PortalServiceImpl implements PortalService { private final DataAdapterHandlerReader handlerReader; + private final EngineExecuteHandlerReader executeHandlerReader; + public PortalServiceImpl(PortalMapper portalMapper, UniQueryMapper queryMapper, DataAdapterMapper adapterMapper, @@ -67,7 +71,8 @@ public class PortalServiceImpl implements PortalService { ThreadPoolTaskExecutor taskExecuteExecutor, HandlerMethodService methodService, PortalInterfaceMapper portalInterfaceMapper, - DataAdapterHandlerReader handlerReader) { + DataAdapterHandlerReader handlerReader, + EngineExecuteHandlerReader executeHandlerReader) { this.portalMapper = portalMapper; this.queryMapper = queryMapper; this.adapterMapper = adapterMapper; @@ -75,6 +80,7 @@ public class PortalServiceImpl implements PortalService { this.methodService = methodService; this.portalInterfaceMapper = portalInterfaceMapper; this.handlerReader = handlerReader; + this.executeHandlerReader = executeHandlerReader; taskExecuteExecutor.execute(() -> { PortalQuery query = new PortalQuery(); // query.setState(QueryConstant.PORTAL_PUBLISH); @@ -354,6 +360,24 @@ public class PortalServiceImpl implements PortalService { } } + + @Override + public void publish(PortalPublish portalPublish, Boolean isList) { + Long portalId = portalPublish.getLongPortalId(); + Portal portal = portalMapper.selectById(portalId); + List mappings = portalMappingMapper.selectByPortalId(portalId); + if (!isList && portal.getCreateDataAdapter() && !ObjectUtils.isEmpty(portal.getAdapterId())) { + DataAdapter dataAdapter = adapterMapper.selectById(portal.getAdapterId()); + dataAdapter.setCode(portalPublish.getCode()); + adapterMapper.updateCode(dataAdapter); + } + portalMapper.updateState(portalId, QueryConstant.PORTAL_PUBLISH); + if (PortalPremEnum.EXTERNAL.equals(portal.getPermissionType()) || PortalPremEnum.ANONYMITY.equals(portal.getPermissionType())) { + publishPortal(portal, mappings, Boolean.TRUE); + } + } + + @Override @Transactional(rollbackFor = Exception.class) public void delete(Long portalId) { diff --git a/start.sh b/start.sh index 40e1080..3fffc9c 100644 --- a/start.sh +++ b/start.sh @@ -31,13 +31,13 @@ batch=${DRONE_COMMIT_BRANCH} ignoreArr=("monitor","sentinel-dashboard-pro","sentinel-dashboard") -#if [[ "${ignoreArr[*]}" =~ "${batch}" ]]; then -# JAVA_AGENT="-javaagent:/home/clay/skywalking-agent/skywalking-agent.jar -Dskywalking.agent.service_name=$DRONE_COMMIT_BRANCH -Dskywalking.trace.ignore_path=/actuator/** -Dskywalking.collector.backend_service=10.7.89.101:11800 --add-opens java.base/jdk.internal.misc=ALL-UNNAMED -Dio.netty.tryReflectionSetAccessible=true" -# nohup java -jar $JAVA_AGENT $JAVA_OPTS $JAVA_MEM_OPTS $DRONE_COMMIT_BRANCH.jar --spring.profiles.active=pro --server.port=8080 >./logs/spring.log 2>&1 & -#else -# echo "exist"; -# nohup java -jar $JAVA_OPTS $JAVA_MEM_OPTS $DRONE_COMMIT_BRANCH.jar --spring.profiles.active=pro --server.port=8080 >./logs/spring.log 2>&1 & -#fi +if [[ "${ignoreArr[*]}" =~ "${batch}" ]]; then + JAVA_AGENT="-javaagent:/home/clay/skywalking-agent/skywalking-agent.jar -Dskywalking.agent.service_name=$DRONE_COMMIT_BRANCH -Dskywalking.trace.ignore_path=/actuator/** -Dskywalking.collector.backend_service=10.7.125.151:11800 --add-opens java.base/jdk.internal.misc=ALL-UNNAMED -Dio.netty.tryReflectionSetAccessible=true" + nohup java -jar $JAVA_AGENT $JAVA_OPTS $JAVA_MEM_OPTS $DRONE_COMMIT_BRANCH.jar --spring.profiles.active=pro --server.port=8080 >./logs/spring.log 2>&1 & +else + echo "exist"; + nohup java -jar $JAVA_OPTS $JAVA_MEM_OPTS $DRONE_COMMIT_BRANCH.jar --spring.profiles.active=pro --server.port=8080 >./logs/spring.log 2>&1 & +fi nohup java -jar $JAVA_OPTS $JAVA_MEM_OPTS $DRONE_COMMIT_BRANCH.jar --spring.profiles.active=pro --server.port=8080 >./logs/spring.log 2>&1 &