diff --git a/.drone.yml b/.drone.yml index 8c492b1..b4599fa 100644 --- a/.drone.yml +++ b/.drone.yml @@ -27,11 +27,9 @@ steps: from_secret: docker_password REGISTRY: from_secret: registry - REGISTRY_NAMESPACE: - from_secret: registry_namespace commands: - sed -i 's/$REGISTRY/'"$REGISTRY"'/' deployment.yml - - sed -i 's/$REGISTRY_NAMESPACE/'"$REGISTRY_NAMESPACE"'/' deployment.yml + - sed -i 's/$REGISTRY_NAMESPACE/'"metis"'/' deployment.yml - sed -i 's/$DRONE_COMMIT/${DRONE_COMMIT}/' deployment.yml - sed -i 's/$DRONE_REPO_NAME/${DRONE_REPO_NAME}/' deployment.yml - echo $DOCKER_PASSWORD | docker login $REGISTRY --username $DOCKER_USERNAME --password-stdin @@ -45,32 +43,37 @@ steps: path: /app/config commands: - kubectl apply -f deployment.yml -n metis --kubeconfig=/app/config/base-taishan-kubectl.yml - - + + - name: notify image: 10.7.127.190:38080/plugins/webhook:latest environment: - WEBHOOK_URL: - from_secret: wechat_webhook_url + NOTIFY_WX_URL: + from_secret: notify_wx_url when: status: [ success,failure ] settings: - urls: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=f2b3fcbc-e70f-4826-8b08-340518b3a96f + urls: + from_secret: notify_wx_url content_type: application/json template: | { "msgtype": "markdown", "markdown": { - "content": "{{#success build.status}}✅{{else}}❌{{/success}}**{{ repo.owner }}/{{ repo.name }}** (Build #{{build.number}})\n - >**构建结果**: {{ build.status }} - >**构建详情**: [点击查看]({{ build.link }}) - >**代码分支**: {{ build.branch }} - >**提交标识**: {{ build.commit }} - >**提交发起**: {{ build.author }} - >**提交信息**: {{ build.message }} - " + "content": "{{#success build.status}}✅ 构建成功{{else}}❌ 构建失败{{/success}} + >**构建编号**: #{{build.number}} + >**构建状态**: {{build.status}} + >**代码分支**: {{build.branch}} + >**提交哈希**: {{build.commit}} + >**提交作者**: {{build.author}} + >**持续时间**: {{build.duration}}秒 + >**提交信息**: {{build.message}} + >[查看构建详情]({{build.link}}) + >{{^success build.status}}[查看失败日志]({{build.link}}/logs){{/success}}" } } + volumes: - name: config host: diff --git a/Dockerfile b/Dockerfile index 8da31a9..2d4faca 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,6 +6,6 @@ WORKDIR /app # 定义时区参数并设置时区 ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone -COPY ./target/metis-1.0.0-SNAPSHOT.jar /app/metis.jar +COPY ./metis-applicant/target/metis-applicant-1.0.0-SNAPSHOT.jar /app/metis.jar RUN chmod 755 -R /app/ CMD java -jar /app/metis.jar -Xms256m -Xmx512m --spring.profiles.active=${PROFILES} --server.port=${SERVICE_PORTS} diff --git a/metis-applicant/pom.xml b/metis-applicant/pom.xml new file mode 100644 index 0000000..6900ad5 --- /dev/null +++ b/metis-applicant/pom.xml @@ -0,0 +1,93 @@ + + + 4.0.0 + + com.metis + metis + 1.0.0-SNAPSHOT + + + metis-applicant + + + 17 + 17 + UTF-8 + + + + + com.metis + metis-starter + 1.0.0-SNAPSHOT + + + + com.github.xiaoymin + knife4j-openapi3-jakarta-spring-boot-starter + 4.4.0 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + org.projectlombok + lombok + + + org.mapstruct + mapstruct-processor + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 17 + 17 + UTF-8 + + -parameters + --add-opens + java.base/java.lang=ALL-UNNAMED + + + + + + org.projectlombok + lombok + ${lombok.version} + + + org.mapstruct + mapstruct-processor + ${org.mapstruct.version} + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/metis/MetisApplication.java b/metis-applicant/src/main/java/com/metisapp/MetisApplication.java similarity index 93% rename from src/main/java/com/metis/MetisApplication.java rename to metis-applicant/src/main/java/com/metisapp/MetisApplication.java index b9dc604..5feb08a 100644 --- a/src/main/java/com/metis/MetisApplication.java +++ b/metis-applicant/src/main/java/com/metisapp/MetisApplication.java @@ -1,4 +1,4 @@ -package com.metis; +package com.metisapp; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/src/main/java/com/metis/config/SwaggerConfig.java b/metis-applicant/src/main/java/com/metisapp/config/SwaggerConfig.java similarity index 94% rename from src/main/java/com/metis/config/SwaggerConfig.java rename to metis-applicant/src/main/java/com/metisapp/config/SwaggerConfig.java index 744fe14..77feba0 100644 --- a/src/main/java/com/metis/config/SwaggerConfig.java +++ b/metis-applicant/src/main/java/com/metisapp/config/SwaggerConfig.java @@ -1,7 +1,6 @@ -package com.metis.config; +package com.metisapp.config; import io.swagger.v3.oas.models.OpenAPI; -import io.swagger.v3.oas.models.info.Contact; import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.info.License; import org.springframework.context.annotation.Bean; diff --git a/src/main/java/com/metis/controller/TestController.java b/metis-applicant/src/main/java/com/metisapp/controller/TestController.java similarity index 77% rename from src/main/java/com/metis/controller/TestController.java rename to metis-applicant/src/main/java/com/metisapp/controller/TestController.java index daa011b..be0f467 100644 --- a/src/main/java/com/metis/controller/TestController.java +++ b/metis-applicant/src/main/java/com/metisapp/controller/TestController.java @@ -1,10 +1,10 @@ -package com.metis.controller; +package com.metisapp.controller; -import com.metis.flow.domain.bo.BuildApp; -import com.metis.flow.engine.AppFlowEngineRunnerService; -import com.metis.flow.runner.FlowRunningContext; -import com.metis.flow.runner.RunnerResult; -import com.metis.flow.validator.ValidatorService; +import com.metis.domain.bo.BuildApp; +import com.metis.engine.AppFlowEngineRunnerService; +import com.metis.runner.FlowRunningContext; +import com.metis.runner.RunnerResult; +import com.metis.validator.ValidatorService; import com.metis.result.Result; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.PostMapping; diff --git a/metis-applicant/src/main/java/com/metisapp/custom/CustomTestConfig.java b/metis-applicant/src/main/java/com/metisapp/custom/CustomTestConfig.java new file mode 100644 index 0000000..b7028c1 --- /dev/null +++ b/metis-applicant/src/main/java/com/metisapp/custom/CustomTestConfig.java @@ -0,0 +1,10 @@ +package com.metisapp.custom; + +import com.metis.domain.entity.base.NodeConfig; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class CustomTestConfig extends NodeConfig { +} diff --git a/metis-applicant/src/main/java/com/metisapp/custom/CustomTestRunner.java b/metis-applicant/src/main/java/com/metisapp/custom/CustomTestRunner.java new file mode 100644 index 0000000..d3ec3be --- /dev/null +++ b/metis-applicant/src/main/java/com/metisapp/custom/CustomTestRunner.java @@ -0,0 +1,27 @@ +package com.metisapp.custom; + +import com.metis.domain.context.RunningContext; +import com.metis.domain.context.RunningResult; +import com.metis.domain.entity.base.Edge; +import com.metis.domain.entity.base.Node; +import com.metis.runner.CustomNodeRunner; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Slf4j +@Service +public class CustomTestRunner implements CustomNodeRunner { + + @Override + public String getCustomNodeType() { + return "test"; + } + + @Override + public RunningResult run(RunningContext context, Node node, List edges) { + log.info("自定义节点测试"); + return RunningResult.buildResult(); + } +} diff --git a/metis-applicant/src/main/java/com/metisapp/custom/CustomTestValidator.java b/metis-applicant/src/main/java/com/metisapp/custom/CustomTestValidator.java new file mode 100644 index 0000000..60ce8b7 --- /dev/null +++ b/metis-applicant/src/main/java/com/metisapp/custom/CustomTestValidator.java @@ -0,0 +1,32 @@ +package com.metisapp.custom; + +import com.metis.domain.entity.base.Edge; +import com.metis.domain.entity.base.Node; +import com.metis.validator.CustomNodeValidator; +import com.metis.validator.ValidatorResult; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Slf4j +@Service +public class CustomTestValidator implements CustomNodeValidator { + + @Override + public String getCustomNodeType() { + return "test"; + } + + @Override + public ValidatorResult validateValue(Node node) { + CustomTestConfig config = node.getConfig(); + return ValidatorResult.valid(); + } + + @Override + public ValidatorResult validateRelation(Node node, List sources, List targets) { + CustomTestConfig config = node.getConfig(); + return ValidatorResult.valid(); + } +} diff --git a/src/main/resources/application-dev.yml b/metis-applicant/src/main/resources/application-dev.yml similarity index 100% rename from src/main/resources/application-dev.yml rename to metis-applicant/src/main/resources/application-dev.yml diff --git a/src/main/resources/application-test.yml b/metis-applicant/src/main/resources/application-test.yml similarity index 100% rename from src/main/resources/application-test.yml rename to metis-applicant/src/main/resources/application-test.yml diff --git a/src/main/resources/application.yml b/metis-applicant/src/main/resources/application.yml similarity index 91% rename from src/main/resources/application.yml rename to metis-applicant/src/main/resources/application.yml index 57c0935..d183ce5 100644 --- a/src/main/resources/application.yml +++ b/metis-applicant/src/main/resources/application.yml @@ -34,10 +34,6 @@ springdoc: swagger-ui: tags-sorter: alpha group-configs: - - group: bis - display-name: "业务接口文档" - paths-to-match: '/**' - packages-to-scan: org.shi9.module.bis - group: system display-name: "系统接口文档" paths-to-match: '/**' diff --git a/src/main/resources/json/run.json b/metis-applicant/src/main/resources/json/run.json similarity index 100% rename from src/main/resources/json/run.json rename to metis-applicant/src/main/resources/json/run.json diff --git a/metis-applicant/src/main/resources/json/test.json b/metis-applicant/src/main/resources/json/test.json new file mode 100644 index 0000000..05521ec --- /dev/null +++ b/metis-applicant/src/main/resources/json/test.json @@ -0,0 +1,567 @@ +{ + "id": 0, + "name": "测试流程", + "description": "测试流程", + "graph": { + "nodes": [ + { + "id": "5", + "type": "start", + "initialized": false, + "position": { + "x": -81.81250000000003, + "y": 275.49609375 + }, + "data": { + "label": "开始", + "icon": "SuitcaseLine", + "toolbarPosition": "right", + "description": "开始述描述", + "config": { + "parent": "234" + }, + "handles": [ + { + "id": "51", + "position": "right", + "type": "source", + "connectable": true + } + ], + "item": { + "id": "2", + "type": "run", + "labelType": "knowledge", + "label": "知识检索" + } + }, + "width": 200, + "height": 40 + }, + { + "id": "6", + "type": "end", + "initialized": false, + "position": { + "x": 1281.582055572882, + "y": 236.2912067630247 + }, + "data": { + "label": "结束", + "toolbarPosition": "right", + "handles": [ + { + "id": "61", + "position": "left", + "type": "target", + "connectable": true + } + ] + }, + "width": 200, + "height": 40 + }, + { + "id": "188", + "type": "custom", + "customType": "test", + "initialized": false, + "position": { + "x": 265.87532955148635, + "y": 71.40983063296031 + }, + "data": { + "label": "llm1", + "icon": "", + "description": "llm描述描述", + "toolbarPosition": "right", + "config": { + "labelType": "llm" + }, + "handles": [ + { + "id": "11", + "position": "left", + "type": "source", + "connectable": true + }, + { + "id": "45", + "position": "right", + "type": "source", + "connectable": true + } + ] + }, + "width": 200, + "height": null + }, + { + "id": "850", + "type": "llm", + "initialized": false, + "position": { + "x": 269.7896091295129, + "y": 253.80570624004747 + }, + "data": { + "label": "llm2", + "icon": "", + "description": "llm描述描述", + "toolbarPosition": "right", + "config": { + "labelType": "llm" + }, + "handles": [ + { + "id": "43", + "position": "left", + "type": "source", + "connectable": true + }, + { + "id": "57", + "position": "right", + "type": "source", + "connectable": true + } + ] + }, + "width": 200, + "height": null + }, + { + "id": "979", + "type": "llm", + "initialized": false, + "position": { + "x": 257.0893454883237, + "y": 360 + }, + "data": { + "label": "llm3", + "icon": "", + "description": "llm描述描述", + "toolbarPosition": "right", + "config": { + "labelType": "llm" + }, + "handles": [ + { + "id": "40", + "position": "left", + "type": "source", + "connectable": true + }, + { + "id": "46", + "position": "right", + "type": "source", + "connectable": true + } + ], + "item": { + "id": "1", + "type": "run", + "labelType": "llm", + "label": "llm" + } + }, + "width": 200, + "height": null + }, + { + "id": "818", + "type": "questionClassifier", + "initialized": false, + "position": { + "x": 247.56414775743187, + "y": 467.44099824508874 + }, + "data": { + "label": "知识检索条件", + "icon": "", + "description": "知识检索描述描述", + "toolbarPosition": "right", + "config": { + "labelType": "knowledge" + }, + "handles": [ + { + "id": "86", + "position": "left", + "type": "source", + "connectable": true + }, + { + "id": "11", + "position": "right", + "type": "source", + "connectable": true + } + ], + "item": { + "id": "1", + "type": "run", + "labelType": "llm", + "label": "llm" + } + }, + "width": 200, + "height": null + }, + { + "id": "288", + "type": "llm", + "initialized": false, + "position": { + "x": 545.6891477574318, + "y": 431.4042601585389 + }, + "data": { + "label": "llm5", + "icon": "", + "description": "llm描述描述", + "toolbarPosition": "right", + "config": { + "labelType": "llm" + }, + "handles": [ + { + "id": "27", + "position": "left", + "type": "source", + "connectable": true + }, + { + "id": "90", + "position": "right", + "type": "source", + "connectable": true + } + ] + }, + "width": 200, + "height": null + }, + { + "id": "873", + "type": "llm", + "initialized": false, + "position": { + "x": 561.0654659633774, + "y": 547.6673703535477 + }, + "data": { + "label": "llm6", + "icon": "", + "description": "llm描述描述", + "toolbarPosition": "right", + "config": { + "labelType": "llm" + }, + "handles": [ + { + "id": "31", + "position": "left", + "type": "source", + "connectable": true + }, + { + "id": "51", + "position": "right", + "type": "source", + "connectable": true + } + ] + }, + "width": 200, + "height": null + }, + { + "id": "244", + "type": "llm", + "initialized": false, + "position": { + "x": 543.1540601095024, + "y": 653.309197614774 + }, + "data": { + "label": "llm7", + "icon": "", + "description": "llm描述描述", + "toolbarPosition": "right", + "config": { + "labelType": "llm" + }, + "handles": [ + { + "id": "33", + "position": "left", + "type": "source", + "connectable": true + }, + { + "id": "13", + "position": "right", + "type": "source", + "connectable": true + } + ] + }, + "width": 200, + "height": null + }, + { + "id": "308", + "type": "llm", + "initialized": false, + "position": { + "x": 588.7086470279171, + "y": 318.8609378786052 + }, + "data": { + "label": "llm4", + "icon": "", + "description": "llm描述描述", + "toolbarPosition": "right", + "config": { + "labelType": "llm" + }, + "handles": [ + { + "id": "17", + "position": "left", + "type": "source", + "connectable": true + }, + { + "id": "73", + "position": "right", + "type": "source", + "connectable": true + } + ] + }, + "width": 200, + "height": null + } + ], + "edges": [ + { + "id": "188", + "type": "default", + "source": "5", + "target": "188", + "sourceHandle": "51", + "targetHandle": "11", + "data": {}, + "label": "", + "animated": true, + "sourceX": 124.52083333333331, + "sourceY": 295.3294270833333, + "targetX": 262.70866773530213, + "targetY": 98.2431395846395 + }, + { + "id": "vueflow__edge-18845-661", + "type": "default", + "source": "188", + "target": "6", + "sourceHandle": "45", + "targetHandle": "61", + "data": {}, + "label": "", + "sourceX": 472.20841119628, + "sourceY": 98.2431395846395, + "targetX": 1278.4153889062152, + "targetY": 256.12454009635803 + }, + { + "id": "850", + "type": "default", + "source": "5", + "target": "850", + "sourceHandle": "51", + "targetHandle": "43", + "data": {}, + "label": "", + "animated": true, + "sourceX": 124.52083333333331, + "sourceY": 295.3294270833333, + "targetX": 266.62293379655364, + "targetY": 280.6389855757115 + }, + { + "id": "vueflow__edge-85057-661", + "type": "default", + "source": "850", + "target": "6", + "sourceHandle": "57", + "targetHandle": "61", + "data": {}, + "label": "", + "sourceX": 476.1223496202179, + "sourceY": 280.6389855757115, + "targetX": 1278.4153889062152, + "targetY": 256.12454009635803 + }, + { + "id": "979", + "type": "default", + "source": "5", + "target": "979", + "sourceHandle": "51", + "targetHandle": "40", + "data": {}, + "label": "", + "animated": true, + "sourceX": 124.52083333333331, + "sourceY": 295.3294270833333, + "targetX": 253.92267015536444, + "targetY": 386.83332778318527 + }, + { + "id": "818", + "type": "default", + "source": "5", + "target": "818", + "sourceHandle": "51", + "targetHandle": "86", + "data": {}, + "label": "", + "animated": true, + "sourceX": 124.52083333333331, + "sourceY": 295.3294270833333, + "targetX": 244.3974724244726, + "targetY": 494.2742291332315 + }, + { + "id": "288", + "type": "default", + "source": "818", + "target": "288", + "sourceHandle": "11", + "targetHandle": "27", + "data": {}, + "label": "", + "animated": true, + "sourceX": 453.89688824813686, + "sourceY": 494.2742291332315, + "targetX": 542.5224239769512, + "targetY": 458.2374910466816 + }, + { + "id": "873", + "type": "default", + "source": "818", + "target": "873", + "sourceHandle": "11", + "targetHandle": "31", + "data": {}, + "label": "", + "animated": true, + "sourceX": 453.89688824813686, + "sourceY": 494.2742291332315, + "targetX": 557.8988921284383, + "targetY": 574.5006486940537 + }, + { + "id": "244", + "type": "default", + "source": "818", + "target": "244", + "sourceHandle": "11", + "targetHandle": "33", + "data": {}, + "label": "", + "animated": true, + "sourceX": 453.89688824813686, + "sourceY": 494.2742291332315, + "targetX": 539.9875200651626, + "targetY": 680.1424930622838 + }, + { + "id": "vueflow__edge-28890-661", + "type": "default", + "source": "288", + "target": "6", + "sourceHandle": "90", + "targetHandle": "61", + "data": {}, + "label": "", + "sourceX": 752.0218882481367, + "sourceY": 458.2374910466816, + "targetX": 1278.4153889062152, + "targetY": 256.12454009635803 + }, + { + "id": "vueflow__edge-87351-661", + "type": "default", + "source": "873", + "target": "6", + "sourceHandle": "51", + "targetHandle": "61", + "data": {}, + "label": "", + "sourceX": 767.3988903613488, + "sourceY": 574.5006486940537, + "targetX": 1278.4153889062152, + "targetY": 256.12454009635803 + }, + { + "id": "vueflow__edge-24413-661", + "type": "default", + "source": "244", + "target": "6", + "sourceHandle": "13", + "targetHandle": "61", + "data": {}, + "label": "", + "sourceX": 749.4874144445799, + "sourceY": 680.1424930622838, + "targetX": 1278.4153889062152, + "targetY": 256.12454009635803 + }, + { + "id": "308", + "type": "default", + "source": "979", + "target": "308", + "sourceHandle": "46", + "targetHandle": "17", + "data": {}, + "label": "", + "animated": true, + "sourceX": 463.42208597902874, + "sourceY": 386.83332778318527, + "targetX": 585.5419963013785, + "targetY": 345.6941732530918 + }, + { + "id": "vueflow__edge-30873-661", + "type": "default", + "source": "308", + "target": "6", + "sourceHandle": "73", + "targetHandle": "61", + "data": {}, + "label": "", + "sourceX": 795.0417833691082, + "sourceY": 345.6941732530918, + "targetX": 1278.4153889062152, + "targetY": 256.12454009635803 + } + ], + "position": [ + 447.2060780237498, + 377.80084997067763 + ], + "zoom": 0.8311688311688327, + "viewport": { + "x": 447.2060780237498, + "y": 377.80084997067763, + "zoom": 0.8311688311688327 + } + } +} \ No newline at end of file diff --git a/src/main/resources/script/sse.html b/metis-applicant/src/main/resources/script/sse.html similarity index 100% rename from src/main/resources/script/sse.html rename to metis-applicant/src/main/resources/script/sse.html diff --git a/metis-starter/pom.xml b/metis-starter/pom.xml new file mode 100644 index 0000000..ea66a81 --- /dev/null +++ b/metis-starter/pom.xml @@ -0,0 +1,104 @@ + + + 4.0.0 + + com.metis + metis + 1.0.0-SNAPSHOT + + + metis-starter + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-validation + + + dev.langchain4j + langchain4j-open-ai + + + dev.langchain4j + langchain4j-mcp + + + com.alibaba.fastjson2 + fastjson2 + 2.0.52 + + + org.projectlombok + lombok + + + com.mikesamuel + json-sanitizer + + + com.baomidou + mybatis-plus-spring-boot3-starter + + + mysql + mysql-connector-java + + + cn.hutool + hutool-all + + + + org.mapstruct + mapstruct + + + org.projectlombok + lombok-mapstruct-binding + + + org.springdoc + springdoc-openapi-starter-webmvc-api + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 17 + 17 + UTF-8 + + -parameters + + + + + + org.projectlombok + lombok + ${lombok.version} + + + org.mapstruct + mapstruct-processor + ${org.mapstruct.version} + + + + + + + + \ No newline at end of file diff --git a/metis-starter/src/main/java/com/metis/config/MetisStarterAutoConfiguration.java b/metis-starter/src/main/java/com/metis/config/MetisStarterAutoConfiguration.java new file mode 100644 index 0000000..f96631b --- /dev/null +++ b/metis-starter/src/main/java/com/metis/config/MetisStarterAutoConfiguration.java @@ -0,0 +1,19 @@ +package com.metis.config; + +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Slf4j +@Configuration +@MapperScan(basePackages = {"com.metis.mapper"}) +@ComponentScan("com.metis.*") +public class MetisStarterAutoConfiguration { + + + static { + + } + +} diff --git a/src/main/java/com/metis/flow/constant/BaseConstant.java b/metis-starter/src/main/java/com/metis/constant/BaseConstant.java similarity index 67% rename from src/main/java/com/metis/flow/constant/BaseConstant.java rename to metis-starter/src/main/java/com/metis/constant/BaseConstant.java index 7e0011a..bfac152 100644 --- a/src/main/java/com/metis/flow/constant/BaseConstant.java +++ b/metis-starter/src/main/java/com/metis/constant/BaseConstant.java @@ -1,4 +1,4 @@ -package com.metis.flow.constant; +package com.metis.constant; public interface BaseConstant { diff --git a/src/main/java/com/metis/controller/ProcessDefinitionController.java b/metis-starter/src/main/java/com/metis/controller/ProcessDefinitionController.java similarity index 96% rename from src/main/java/com/metis/controller/ProcessDefinitionController.java rename to metis-starter/src/main/java/com/metis/controller/ProcessDefinitionController.java index ce90d34..8f16bc5 100644 --- a/src/main/java/com/metis/controller/ProcessDefinitionController.java +++ b/metis-starter/src/main/java/com/metis/controller/ProcessDefinitionController.java @@ -2,7 +2,7 @@ package com.metis.controller; import com.metis.domain.bo.ProcessBo; import com.metis.facade.ProcessDefinitionFacade; -import com.metis.flow.domain.entity.App; +import com.metis.domain.entity.App; import com.metis.result.Result; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; diff --git a/src/main/java/com/metis/flow/convert/BaseAppConvert.java b/metis-starter/src/main/java/com/metis/convert/BaseAppConvert.java similarity index 57% rename from src/main/java/com/metis/flow/convert/BaseAppConvert.java rename to metis-starter/src/main/java/com/metis/convert/BaseAppConvert.java index 5029018..7a1122b 100644 --- a/src/main/java/com/metis/flow/convert/BaseAppConvert.java +++ b/metis-starter/src/main/java/com/metis/convert/BaseAppConvert.java @@ -1,9 +1,10 @@ -package com.metis.flow.convert; +package com.metis.convert; -import com.metis.flow.domain.entity.*; -import com.metis.flow.domain.bo.BuildApp; -import com.metis.flow.domain.bo.CreateApp; -import com.metis.flow.domain.bo.UpdateApp; +import com.metis.domain.bo.BuildApp; +import com.metis.domain.bo.CreateApp; +import com.metis.domain.bo.UpdateApp; +import com.metis.domain.entity.App; +import com.metis.domain.entity.BaseApp; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Mappings; @@ -23,6 +24,13 @@ public interface BaseAppConvert { * @param buildApp 基础应用 * @return {@link App } */ + @Mappings({ + @Mapping(target = "id", ignore = true), + @Mapping(target = "workflowId", ignore = true), + @Mapping(target = "createTime", ignore = true), + @Mapping(target = "version", ignore = true), + @Mapping(target = "defaultUse", ignore = true), + }) App toApp(BuildApp buildApp); /** @@ -32,7 +40,7 @@ public interface BaseAppConvert { * @return {@link App } */ @Mappings({ - @Mapping(target = "graph", expression = "java(com.alibaba.fastjson2.JSON.parseObject(baseApp.getGraphJson(), com.metis.flow.domain.bo.Graph.class))"), + @Mapping(target = "graph", expression = "java(com.alibaba.fastjson2.JSON.parseObject(baseApp.getGraphJson(), com.metis.domain.entity.base.Graph.class))"), @Mapping(target = "workflowId", source = "id") }) App toApp(BaseApp baseApp); @@ -44,7 +52,13 @@ public interface BaseAppConvert { * @return {@link BaseApp } */ @Mappings({ - @Mapping(target = "graphJson", expression = "java(com.alibaba.fastjson2.JSON.toJSONString(buildApp.getGraph()))") + @Mapping(target = "graphJson", expression = "java(com.alibaba.fastjson2.JSON.toJSONString(buildApp.getGraph()))"), + @Mapping(target = "createTime", ignore = true), + @Mapping(target = "updateTime", ignore = true), + @Mapping(target = "isDeleted", ignore = true), + @Mapping(target = "id", ignore = true), + @Mapping(target = "createUserId", ignore = true), + @Mapping(target = "defaultUse", ignore = true) }) BaseApp toBaseApp(BuildApp buildApp); @@ -63,6 +77,9 @@ public interface BaseAppConvert { * @param createApp 创建应用程序 * @return {@link BuildApp } */ + @Mappings({ + @Mapping(target = "appId", ignore = true) + }) BuildApp toBuildApp(CreateApp createApp); /** @@ -71,6 +88,9 @@ public interface BaseAppConvert { * @param updateApp 更新应用程序 * @return {@link BuildApp } */ + @Mappings({ + @Mapping(target = "userId", ignore = true) + }) BuildApp toBuildApp(UpdateApp updateApp); } diff --git a/metis-starter/src/main/java/com/metis/convert/GraphConvert.java b/metis-starter/src/main/java/com/metis/convert/GraphConvert.java new file mode 100644 index 0000000..da2fa78 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/convert/GraphConvert.java @@ -0,0 +1,17 @@ +package com.metis.convert; + + +import com.metis.domain.bo.GraphBO; +import com.metis.domain.entity.base.Graph; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface GraphConvert { + + GraphConvert INSTANCE = Mappers.getMapper(GraphConvert.class); + + + Graph toEntity(GraphBO graph); + +} diff --git a/src/main/java/com/metis/domain/SimpleBaseEntity.java b/metis-starter/src/main/java/com/metis/domain/SimpleBaseEntity.java similarity index 100% rename from src/main/java/com/metis/domain/SimpleBaseEntity.java rename to metis-starter/src/main/java/com/metis/domain/SimpleBaseEntity.java diff --git a/src/main/java/com/metis/flow/domain/bo/BuildApp.java b/metis-starter/src/main/java/com/metis/domain/bo/BuildApp.java similarity index 88% rename from src/main/java/com/metis/flow/domain/bo/BuildApp.java rename to metis-starter/src/main/java/com/metis/domain/bo/BuildApp.java index fd78ff5..28d6540 100644 --- a/src/main/java/com/metis/flow/domain/bo/BuildApp.java +++ b/metis-starter/src/main/java/com/metis/domain/bo/BuildApp.java @@ -1,5 +1,6 @@ -package com.metis.flow.domain.bo; +package com.metis.domain.bo; +import com.metis.domain.entity.base.Graph; import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; diff --git a/src/main/java/com/metis/flow/domain/bo/CreateApp.java b/metis-starter/src/main/java/com/metis/domain/bo/CreateApp.java similarity index 88% rename from src/main/java/com/metis/flow/domain/bo/CreateApp.java rename to metis-starter/src/main/java/com/metis/domain/bo/CreateApp.java index 42f2a66..a8a9c1a 100644 --- a/src/main/java/com/metis/flow/domain/bo/CreateApp.java +++ b/metis-starter/src/main/java/com/metis/domain/bo/CreateApp.java @@ -1,5 +1,6 @@ -package com.metis.flow.domain.bo; +package com.metis.domain.bo; +import com.metis.domain.entity.base.Graph; import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; diff --git a/metis-starter/src/main/java/com/metis/domain/bo/EdgeBO.java b/metis-starter/src/main/java/com/metis/domain/bo/EdgeBO.java new file mode 100644 index 0000000..0de8c4b --- /dev/null +++ b/metis-starter/src/main/java/com/metis/domain/bo/EdgeBO.java @@ -0,0 +1,66 @@ +package com.metis.domain.bo; + +import com.metis.enums.EdgeType; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Data +public class EdgeBO { + + /** + * 唯一标识符 + */ + @NotNull(message = "唯一标识符不能为空") + private String id; + + /** + * 标签 + */ + private String label; + + /** + * 节点类型 + */ + @NotNull(message = "线类型不能为空") + private EdgeType type; + + /** + * 源节点ID,对应节点id + */ + @NotNull(message = "源节点ID不能为空") + private Long source; + + /** + * 目标节点ID,对应节点id + */ + @NotNull(message = "目标节点ID不能为空") + private Long target; + /** + * 源句柄id + */ + @NotNull(message = "源句柄ID不能为空") + private Long sourceHandle; + + /** + * 目标句柄id + */ + @NotNull(message = "目标句柄ID不能为空") + private Long targetHandle; + + /** + * 边是否动画true/false + */ + private Boolean animated; + + /** + * 开始标志 + */ + private String markerStart; + + /** + * 结束标记 + */ + private String markerEnd; + + +} diff --git a/metis-starter/src/main/java/com/metis/domain/bo/GraphBO.java b/metis-starter/src/main/java/com/metis/domain/bo/GraphBO.java new file mode 100644 index 0000000..a5b51f5 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/domain/bo/GraphBO.java @@ -0,0 +1,43 @@ +package com.metis.domain.bo; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import lombok.Data; + +import java.util.List; + +@Data +public class GraphBO { + + /** + * 边缘 + */ + @Valid + @NotEmpty(message = "连线不能为空") + private List edges; + + /** + * 节点 + */ + @Valid + @NotEmpty(message = "节点不能为空") + private List nodes; + + + /** + * 位置 + */ + private List position; + + /** + * 变焦 + */ + private Double zoom; + + /** + * 视窗 + */ + private ViewportBo viewport; + + +} diff --git a/metis-starter/src/main/java/com/metis/domain/bo/HandleBO.java b/metis-starter/src/main/java/com/metis/domain/bo/HandleBO.java new file mode 100644 index 0000000..510557d --- /dev/null +++ b/metis-starter/src/main/java/com/metis/domain/bo/HandleBO.java @@ -0,0 +1,36 @@ +package com.metis.domain.bo; + +import com.metis.enums.HandleType; +import com.metis.enums.PositionType; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +/** + * 句柄对象 + */ +@Data +public class HandleBO { + /** + * 句柄id + */ + @NotNull(message = "句柄id不能为空") + private Long id; + + /** + * 句柄类型 + */ + @NotNull(message = "句柄类型不能为空") + private HandleType type; + + /** + * 句柄位置 + */ + @NotNull(message = "句柄位置不能为空") + private PositionType position; + + /** + * 是否可以连接 + */ + @NotNull(message = "是否可以连接不能为空") + private Boolean connectable; +} diff --git a/metis-starter/src/main/java/com/metis/domain/bo/NodeBO.java b/metis-starter/src/main/java/com/metis/domain/bo/NodeBO.java new file mode 100644 index 0000000..9bab140 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/domain/bo/NodeBO.java @@ -0,0 +1,60 @@ +package com.metis.domain.bo; + +import com.metis.enums.NodeType; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Data +public class NodeBO { + + /** + * id + */ + @NotNull(message = "节点id不能为空") + private Long id; + + /** + * 类型 + */ + @NotNull(message = "节点类型不能为空") + private NodeType type; + + /** + * 自定义类型 + */ + private String customType; + + /** + * 位置 + */ + @Valid + @NotNull(message = "节点位置不能为空") + private PositionBO position; + + /** + * 业务数据 + */ + @Valid + @NotNull(message = "节点业务数据不能为空") + private NodeDataBO data; + + /** + * 宽度 + */ +// @NotNull(message = "节点宽度不能为空") + private Integer width; + + /** + * 高度 + */ +// @NotNull(message = "节点高度不能为空") + private Integer height; + + /** + * 节点是否选中 + */ + private Boolean selected; + + +} diff --git a/metis-starter/src/main/java/com/metis/domain/bo/NodeDataBO.java b/metis-starter/src/main/java/com/metis/domain/bo/NodeDataBO.java new file mode 100644 index 0000000..04e0c82 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/domain/bo/NodeDataBO.java @@ -0,0 +1,45 @@ +package com.metis.domain.bo; + +import com.alibaba.fastjson2.JSONObject; +import com.metis.enums.PositionType; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import lombok.Data; + +import java.util.List; + +@Data +public class NodeDataBO { + + /** + * 标签 + */ + @NotBlank(message = "标签不能为空") + private String label; + + /** + * 图标 + */ + private String icon; + + /** + * 工具栏位置 + */ + private PositionType toolbarPosition; + + + /** + * 配置 + */ + private JSONObject config; + + /** + * 句柄列表 + */ + @Valid + @NotEmpty(message = "句柄列表不能为空") + private List handles; + + +} diff --git a/metis-starter/src/main/java/com/metis/domain/bo/PositionBO.java b/metis-starter/src/main/java/com/metis/domain/bo/PositionBO.java new file mode 100644 index 0000000..00f0b50 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/domain/bo/PositionBO.java @@ -0,0 +1,20 @@ +package com.metis.domain.bo; + +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Data +public class PositionBO { + /** + * x坐标 + */ + @NotNull(message = "x坐标不能为空") + private Double x; + + /** + * y坐标 + */ + @NotNull(message = "y坐标不能为空") + private Double y; + +} diff --git a/src/main/java/com/metis/domain/bo/ProcessBo.java b/metis-starter/src/main/java/com/metis/domain/bo/ProcessBo.java similarity index 79% rename from src/main/java/com/metis/domain/bo/ProcessBo.java rename to metis-starter/src/main/java/com/metis/domain/bo/ProcessBo.java index 325018e..c0075af 100644 --- a/src/main/java/com/metis/domain/bo/ProcessBo.java +++ b/metis-starter/src/main/java/com/metis/domain/bo/ProcessBo.java @@ -1,7 +1,7 @@ package com.metis.domain.bo; import com.metis.enums.YesOrNoEnum; -import com.metis.flow.domain.bo.Graph; +import com.metis.domain.bo.GraphBO; import lombok.Data; @Data @@ -13,7 +13,7 @@ public class ProcessBo { private String description; - private Graph graph; + private GraphBO graph; private YesOrNoEnum defaultUse; diff --git a/src/main/java/com/metis/flow/domain/bo/UpdateApp.java b/metis-starter/src/main/java/com/metis/domain/bo/UpdateApp.java similarity index 89% rename from src/main/java/com/metis/flow/domain/bo/UpdateApp.java rename to metis-starter/src/main/java/com/metis/domain/bo/UpdateApp.java index a6a0050..e4c3238 100644 --- a/src/main/java/com/metis/flow/domain/bo/UpdateApp.java +++ b/metis-starter/src/main/java/com/metis/domain/bo/UpdateApp.java @@ -1,6 +1,7 @@ -package com.metis.flow.domain.bo; +package com.metis.domain.bo; import com.metis.enums.YesOrNoEnum; +import com.metis.domain.entity.base.Graph; import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; diff --git a/metis-starter/src/main/java/com/metis/domain/bo/ViewportBo.java b/metis-starter/src/main/java/com/metis/domain/bo/ViewportBo.java new file mode 100644 index 0000000..7209088 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/domain/bo/ViewportBo.java @@ -0,0 +1,10 @@ +package com.metis.domain.bo; + +import lombok.Data; + +@Data +public class ViewportBo { + private Double x; + private Double y; + private Double zoom; +} diff --git a/src/main/java/com/metis/flow/domain/context/RunningContext.java b/metis-starter/src/main/java/com/metis/domain/context/RunningContext.java similarity index 87% rename from src/main/java/com/metis/flow/domain/context/RunningContext.java rename to metis-starter/src/main/java/com/metis/domain/context/RunningContext.java index 87d99d4..c2d1d68 100644 --- a/src/main/java/com/metis/flow/domain/context/RunningContext.java +++ b/metis-starter/src/main/java/com/metis/domain/context/RunningContext.java @@ -1,7 +1,7 @@ -package com.metis.flow.domain.context; +package com.metis.domain.context; import com.alibaba.fastjson2.JSONObject; -import com.metis.flow.runner.FlowRunningContext; +import com.metis.runner.FlowRunningContext; import lombok.Builder; import lombok.Getter; @@ -44,6 +44,11 @@ public class RunningContext { this.nodeRunningContext.put(nodeId, nodeRunningContext); } + public JSONObject getRunningContext(Long nodeId) { + return this.nodeRunningContext.get(nodeId); + } + + /** * 构建上下文 * @@ -58,4 +63,6 @@ public class RunningContext { .build(); } + + } diff --git a/src/main/java/com/metis/flow/domain/context/RunningResult.java b/metis-starter/src/main/java/com/metis/domain/context/RunningResult.java similarity index 77% rename from src/main/java/com/metis/flow/domain/context/RunningResult.java rename to metis-starter/src/main/java/com/metis/domain/context/RunningResult.java index bb5b598..556e6a6 100644 --- a/src/main/java/com/metis/flow/domain/context/RunningResult.java +++ b/metis-starter/src/main/java/com/metis/domain/context/RunningResult.java @@ -1,4 +1,4 @@ -package com.metis.flow.domain.context; +package com.metis.domain.context; import com.alibaba.fastjson2.JSONObject; import lombok.Builder; @@ -35,6 +35,18 @@ public class RunningResult { .build(); } + /** + * 构建结果 + * + * @param nextRunNodeId 下一个运行节点id + * @return {@link RunningResult } + */ + public static RunningResult buildResult(Set nextRunNodeId) { + return RunningResult.builder() + .nextRunNodeId(nextRunNodeId) + .build(); + } + /** * 构建结果 * diff --git a/src/main/java/com/metis/flow/domain/context/SysContext.java b/metis-starter/src/main/java/com/metis/domain/context/SysContext.java similarity index 94% rename from src/main/java/com/metis/flow/domain/context/SysContext.java rename to metis-starter/src/main/java/com/metis/domain/context/SysContext.java index 54bc818..a2327e9 100644 --- a/src/main/java/com/metis/flow/domain/context/SysContext.java +++ b/metis-starter/src/main/java/com/metis/domain/context/SysContext.java @@ -1,4 +1,4 @@ -package com.metis.flow.domain.context; +package com.metis.domain.context; import lombok.Builder; import lombok.Data; diff --git a/src/main/java/com/metis/flow/domain/entity/App.java b/metis-starter/src/main/java/com/metis/domain/entity/App.java similarity index 88% rename from src/main/java/com/metis/flow/domain/entity/App.java rename to metis-starter/src/main/java/com/metis/domain/entity/App.java index 5b97af1..ef48d44 100644 --- a/src/main/java/com/metis/flow/domain/entity/App.java +++ b/metis-starter/src/main/java/com/metis/domain/entity/App.java @@ -1,8 +1,8 @@ -package com.metis.flow.domain.entity; +package com.metis.domain.entity; import com.metis.enums.YesOrNoEnum; -import com.metis.flow.domain.bo.Graph; +import com.metis.domain.entity.base.Graph; import lombok.Data; import java.time.LocalDateTime; diff --git a/src/main/java/com/metis/flow/domain/entity/BaseApp.java b/metis-starter/src/main/java/com/metis/domain/entity/BaseApp.java similarity index 97% rename from src/main/java/com/metis/flow/domain/entity/BaseApp.java rename to metis-starter/src/main/java/com/metis/domain/entity/BaseApp.java index 48e9521..53204e0 100644 --- a/src/main/java/com/metis/flow/domain/entity/BaseApp.java +++ b/metis-starter/src/main/java/com/metis/domain/entity/BaseApp.java @@ -1,4 +1,4 @@ -package com.metis.flow.domain.entity; +package com.metis.domain.entity; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; diff --git a/metis-starter/src/main/java/com/metis/domain/entity/GraphDto.java b/metis-starter/src/main/java/com/metis/domain/entity/GraphDto.java new file mode 100644 index 0000000..5de1cc2 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/domain/entity/GraphDto.java @@ -0,0 +1,131 @@ +package com.metis.domain.entity; + + +import com.metis.domain.entity.base.Edge; +import com.metis.domain.entity.base.Graph; +import com.metis.domain.entity.base.Node; +import com.metis.enums.NodeType; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class GraphDto { + + private final Map nodeMap; + + private final Map nodeReadyMap; + + private final Map> edgeMap; + + private final Map> adjacencyList = new HashMap<>(); + + private final List sortedNodes = new ArrayList<>(); + + + public List getSortedNodes() { + return new ArrayList<>(sortedNodes); + } + + public List getEdgeNodeId(Long nodeId) { + return edgeMap.getOrDefault(nodeId, new ArrayList<>()); + } + + public Node getEndNode(){ + return sortedNodes.stream() + .filter(node -> NodeType.END.equals(node.getType())) + .findFirst() + .orElse(null); + } + + public Node getNode(Long nodeId) { + return nodeMap.get(nodeId); + } + + public void updateNodeReadyMap(Long nodeId, Boolean ready) { + nodeReadyMap.put(nodeId, ready); + } + + public Boolean isNodeReady(Long nodeId) { + return nodeReadyMap.get(nodeId); + } + + + private GraphDto(List nodes, List edges) { + this.edgeMap = edges.stream() + .collect(Collectors.groupingBy(Edge::getSource)); + this.nodeMap = nodes.stream() + .collect(Collectors.toMap(Node::getId, Function.identity())); + this.nodeReadyMap = nodes.stream() + .collect(Collectors.toMap(Node::getId, node -> false)); + initAdjacencyList(edges); + List nodeList = topologicalSort(); + this.sortedNodes.addAll(nodeList); + Node node = sortedNodes.get(0); + if (NodeType.START.equals(node.getType())) { + nodeReadyMap.put(node.getId(), true); + } + } + + private void initAdjacencyList(List edges) { + for (Edge edge : edges) { + List targetList = adjacencyList.getOrDefault(edge.getSource(), new ArrayList<>()); + targetList.add(edge.getTarget()); + adjacencyList.put(edge.getSource(), targetList); + } + } + + + /** + * 拓扑排序 + * + * @return {@link List }<{@link Node }> + */ + private List topologicalSort() { + List sortedNodes = new ArrayList<>(); + Set visited = new HashSet<>(); + Set visiting = new HashSet<>(); + for (Long nodeId : nodeMap.keySet()) { + if (!visited.contains(nodeId)) { + dfs(nodeId, visited, visiting, sortedNodes); + } + } + Collections.reverse(sortedNodes); + return sortedNodes; + } + + /** + * 深度遍历找到运行顺序 + * + * @param nodeId 节点id + * @param visited 参观了 + * @param visiting 参观 + * @param sortedNodes 排序节点 + */ + private void dfs(Long nodeId, Set visited, Set visiting, List sortedNodes) { + if (visiting.contains(nodeId)) { + throw new IllegalStateException("Cycle detected in the graph"); + } + if (!visited.contains(nodeId)) { + visiting.add(nodeId); + for (Long neighbor : adjacencyList.getOrDefault(nodeId, new ArrayList<>())) { + dfs(neighbor, visited, visiting, sortedNodes); + } + visiting.remove(nodeId); + visited.add(nodeId); + sortedNodes.add(nodeMap.get(nodeId)); + } + } + + + /** + * 构建对象 + * + * @param graph 图 + * @return {@link GraphDto } + */ + public static GraphDto of(Graph graph) { + return new GraphDto(graph.getNodes(), graph.getEdges()); + } + +} diff --git a/src/main/java/com/metis/flow/domain/entity/base/Edge.java b/metis-starter/src/main/java/com/metis/domain/entity/base/Edge.java similarity index 93% rename from src/main/java/com/metis/flow/domain/entity/base/Edge.java rename to metis-starter/src/main/java/com/metis/domain/entity/base/Edge.java index 96e72d2..d389fec 100644 --- a/src/main/java/com/metis/flow/domain/entity/base/Edge.java +++ b/metis-starter/src/main/java/com/metis/domain/entity/base/Edge.java @@ -1,6 +1,6 @@ -package com.metis.flow.domain.entity.base; +package com.metis.domain.entity.base; -import com.metis.flow.enums.EdgeType; +import com.metis.enums.EdgeType; import jakarta.validation.constraints.NotNull; import lombok.Data; diff --git a/metis-starter/src/main/java/com/metis/domain/entity/base/Graph.java b/metis-starter/src/main/java/com/metis/domain/entity/base/Graph.java new file mode 100644 index 0000000..c440eb3 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/domain/entity/base/Graph.java @@ -0,0 +1,47 @@ +package com.metis.domain.entity.base; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Graph { + + /** + * 边缘 + */ + @Valid + @NotEmpty(message = "连线不能为空") + private List edges; + + /** + * 节点 + */ + @Valid + @NotEmpty(message = "节点不能为空") + private List nodes; + + /** + * 位置 + */ + private List position; + + /** + * 变焦 + */ + private Double zoom; + + /** + * 视窗 + */ + private Viewport viewport; + + + +} diff --git a/src/main/java/com/metis/flow/domain/entity/base/Handle.java b/metis-starter/src/main/java/com/metis/domain/entity/base/Handle.java similarity index 82% rename from src/main/java/com/metis/flow/domain/entity/base/Handle.java rename to metis-starter/src/main/java/com/metis/domain/entity/base/Handle.java index acaa9b5..f0e3e32 100644 --- a/src/main/java/com/metis/flow/domain/entity/base/Handle.java +++ b/metis-starter/src/main/java/com/metis/domain/entity/base/Handle.java @@ -1,7 +1,7 @@ -package com.metis.flow.domain.entity.base; +package com.metis.domain.entity.base; -import com.metis.flow.enums.HandleType; -import com.metis.flow.enums.PositionType; +import com.metis.enums.HandleType; +import com.metis.enums.PositionType; import jakarta.validation.constraints.NotNull; import lombok.Data; diff --git a/src/main/java/com/metis/flow/domain/entity/base/Node.java b/metis-starter/src/main/java/com/metis/domain/entity/base/Node.java similarity index 65% rename from src/main/java/com/metis/flow/domain/entity/base/Node.java rename to metis-starter/src/main/java/com/metis/domain/entity/base/Node.java index 20dff37..c5d976b 100644 --- a/src/main/java/com/metis/flow/domain/entity/base/Node.java +++ b/metis-starter/src/main/java/com/metis/domain/entity/base/Node.java @@ -1,16 +1,11 @@ -package com.metis.flow.domain.entity.base; +package com.metis.domain.entity.base; -import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.metis.flow.enums.NodeType; +import com.metis.enums.NodeType; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import lombok.Data; -import java.util.Map; -import java.util.stream.Collectors; - @Data public class Node { @@ -26,6 +21,8 @@ public class Node { @NotNull(message = "节点类型不能为空") private NodeType type; + private String customType; + /** * 位置 */ @@ -57,21 +54,31 @@ public class Node { */ private Boolean selected; + private transient Class configClass; - @JsonIgnore - public Map getHandleMap() { - if (CollUtil.isEmpty(data.getHandles())) { - return Map.of(); - } - return data.getHandles().stream().collect(Collectors.toMap(Handle::getId, handle -> handle)); - } - @JsonIgnore + /** + * 获取配置 + * + * @return {@link T } + */ public T getConfig() { if (ObjectUtil.isNull(data.getConfig())) { return null; } - return (T) data.getConfig().to(type.getConfigClass()); + return (T) data.getConfig().to(configClass); + } + + /** + * 设置配置类 + * + * @param configClass 配置类 + */ + public void setConfigClass(Class configClass) { + if (ObjectUtil.isNotNull(this.configClass)) { + return; + } + this.configClass = configClass; } } diff --git a/metis-starter/src/main/java/com/metis/domain/entity/base/NodeConfig.java b/metis-starter/src/main/java/com/metis/domain/entity/base/NodeConfig.java new file mode 100644 index 0000000..f96afd2 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/domain/entity/base/NodeConfig.java @@ -0,0 +1,4 @@ +package com.metis.domain.entity.base; + +public abstract class NodeConfig { +} diff --git a/src/main/java/com/metis/flow/domain/entity/base/NodeData.java b/metis-starter/src/main/java/com/metis/domain/entity/base/NodeData.java similarity index 67% rename from src/main/java/com/metis/flow/domain/entity/base/NodeData.java rename to metis-starter/src/main/java/com/metis/domain/entity/base/NodeData.java index ed632d2..9aa53f7 100644 --- a/src/main/java/com/metis/flow/domain/entity/base/NodeData.java +++ b/metis-starter/src/main/java/com/metis/domain/entity/base/NodeData.java @@ -1,11 +1,10 @@ -package com.metis.flow.domain.entity.base; +package com.metis.domain.entity.base; import com.alibaba.fastjson2.JSONObject; -import com.metis.flow.enums.PositionType; +import com.metis.enums.PositionType; import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; +import jakarta.validation.constraints.NotEmpty; import lombok.Data; import java.util.List; @@ -30,8 +29,6 @@ public class NodeData { private PositionType toolbarPosition; - - /** * 配置 */ @@ -41,8 +38,7 @@ public class NodeData { * 句柄列表 */ @Valid - @NotNull(message = "句柄列表不能为空") - @Size(min = 1, message = "句柄列表不能为空") + @NotEmpty(message = "句柄列表不能为空") private List handles; diff --git a/src/main/java/com/metis/flow/domain/entity/base/NodeVariable.java b/metis-starter/src/main/java/com/metis/domain/entity/base/NodeVariable.java similarity index 94% rename from src/main/java/com/metis/flow/domain/entity/base/NodeVariable.java rename to metis-starter/src/main/java/com/metis/domain/entity/base/NodeVariable.java index 0a93469..3058bbd 100644 --- a/src/main/java/com/metis/flow/domain/entity/base/NodeVariable.java +++ b/metis-starter/src/main/java/com/metis/domain/entity/base/NodeVariable.java @@ -1,11 +1,11 @@ -package com.metis.flow.domain.entity.base; +package com.metis.domain.entity.base; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson2.JSONObject; import com.fasterxml.jackson.annotation.JsonIgnore; -import com.metis.flow.enums.FileUploadType; -import com.metis.flow.enums.NodeVariableType; +import com.metis.enums.FileUploadType; +import com.metis.enums.NodeVariableType; import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; diff --git a/src/main/java/com/metis/flow/domain/entity/base/Position.java b/metis-starter/src/main/java/com/metis/domain/entity/base/Position.java similarity index 87% rename from src/main/java/com/metis/flow/domain/entity/base/Position.java rename to metis-starter/src/main/java/com/metis/domain/entity/base/Position.java index 291cf55..2beec9f 100644 --- a/src/main/java/com/metis/flow/domain/entity/base/Position.java +++ b/metis-starter/src/main/java/com/metis/domain/entity/base/Position.java @@ -1,4 +1,4 @@ -package com.metis.flow.domain.entity.base; +package com.metis.domain.entity.base; import jakarta.validation.constraints.NotNull; import lombok.Data; diff --git a/src/main/java/com/metis/flow/domain/entity/base/VariableOption.java b/metis-starter/src/main/java/com/metis/domain/entity/base/VariableOption.java similarity index 85% rename from src/main/java/com/metis/flow/domain/entity/base/VariableOption.java rename to metis-starter/src/main/java/com/metis/domain/entity/base/VariableOption.java index cc3a4ef..7ac3e13 100644 --- a/src/main/java/com/metis/flow/domain/entity/base/VariableOption.java +++ b/metis-starter/src/main/java/com/metis/domain/entity/base/VariableOption.java @@ -1,4 +1,4 @@ -package com.metis.flow.domain.entity.base; +package com.metis.domain.entity.base; import jakarta.validation.constraints.NotNull; diff --git a/metis-starter/src/main/java/com/metis/domain/entity/base/Viewport.java b/metis-starter/src/main/java/com/metis/domain/entity/base/Viewport.java new file mode 100644 index 0000000..039f996 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/domain/entity/base/Viewport.java @@ -0,0 +1,10 @@ +package com.metis.domain.entity.base; + +import lombok.Data; + +@Data +public class Viewport { + private Double x; + private Double y; + private Double zoom; +} diff --git a/metis-starter/src/main/java/com/metis/domain/entity/config/node/DocumentExtractorNodeConfig.java b/metis-starter/src/main/java/com/metis/domain/entity/config/node/DocumentExtractorNodeConfig.java new file mode 100644 index 0000000..eae223c --- /dev/null +++ b/metis-starter/src/main/java/com/metis/domain/entity/config/node/DocumentExtractorNodeConfig.java @@ -0,0 +1,15 @@ +package com.metis.domain.entity.config.node; + +import com.metis.domain.entity.base.NodeConfig; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class DocumentExtractorNodeConfig extends NodeConfig { + + @NotBlank(message = "文件类型不能为空") + private String fileType; + +} diff --git a/metis-starter/src/main/java/com/metis/domain/entity/config/node/EndNodeConfig.java b/metis-starter/src/main/java/com/metis/domain/entity/config/node/EndNodeConfig.java new file mode 100644 index 0000000..202e601 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/domain/entity/config/node/EndNodeConfig.java @@ -0,0 +1,10 @@ +package com.metis.domain.entity.config.node; + +import com.metis.domain.entity.base.NodeConfig; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class EndNodeConfig extends NodeConfig { +} diff --git a/metis-starter/src/main/java/com/metis/domain/entity/config/node/LLMNodeConfig.java b/metis-starter/src/main/java/com/metis/domain/entity/config/node/LLMNodeConfig.java new file mode 100644 index 0000000..6a2df06 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/domain/entity/config/node/LLMNodeConfig.java @@ -0,0 +1,10 @@ +package com.metis.domain.entity.config.node; + +import com.metis.domain.entity.base.NodeConfig; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class LLMNodeConfig extends NodeConfig { +} diff --git a/metis-starter/src/main/java/com/metis/domain/entity/config/node/QuestionClassifierConfig.java b/metis-starter/src/main/java/com/metis/domain/entity/config/node/QuestionClassifierConfig.java new file mode 100644 index 0000000..caef097 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/domain/entity/config/node/QuestionClassifierConfig.java @@ -0,0 +1,10 @@ +package com.metis.domain.entity.config.node; + +import com.metis.domain.entity.base.NodeConfig; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class QuestionClassifierConfig extends NodeConfig { +} diff --git a/metis-starter/src/main/java/com/metis/domain/entity/config/node/StartNodeConfig.java b/metis-starter/src/main/java/com/metis/domain/entity/config/node/StartNodeConfig.java new file mode 100644 index 0000000..4f37e13 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/domain/entity/config/node/StartNodeConfig.java @@ -0,0 +1,19 @@ +package com.metis.domain.entity.config.node; + +import com.metis.domain.entity.base.NodeConfig; +import com.metis.domain.entity.base.NodeVariable; +import jakarta.validation.Valid; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.List; + +@Data +@EqualsAndHashCode(callSuper = true) +public class StartNodeConfig extends NodeConfig { + + @Valid + private List variables; + + +} diff --git a/metis-starter/src/main/java/com/metis/domain/entity/config/package-info.java b/metis-starter/src/main/java/com/metis/domain/entity/config/package-info.java new file mode 100644 index 0000000..e836bd2 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/domain/entity/config/package-info.java @@ -0,0 +1 @@ +package com.metis.domain.entity.config; \ No newline at end of file diff --git a/src/main/java/com/metis/flow/domain/query/AppQuery.java b/metis-starter/src/main/java/com/metis/domain/query/AppQuery.java similarity index 82% rename from src/main/java/com/metis/flow/domain/query/AppQuery.java rename to metis-starter/src/main/java/com/metis/domain/query/AppQuery.java index 2cd0ebe..5fb28ce 100644 --- a/src/main/java/com/metis/flow/domain/query/AppQuery.java +++ b/metis-starter/src/main/java/com/metis/domain/query/AppQuery.java @@ -1,4 +1,4 @@ -package com.metis.flow.domain.query; +package com.metis.domain.query; import lombok.Builder; import lombok.Data; diff --git a/src/main/java/com/metis/flow/engine/AppEngineService.java b/metis-starter/src/main/java/com/metis/engine/AppEngineService.java similarity index 86% rename from src/main/java/com/metis/flow/engine/AppEngineService.java rename to metis-starter/src/main/java/com/metis/engine/AppEngineService.java index 4ce22c8..dac3ee6 100644 --- a/src/main/java/com/metis/flow/engine/AppEngineService.java +++ b/metis-starter/src/main/java/com/metis/engine/AppEngineService.java @@ -1,9 +1,10 @@ -package com.metis.flow.engine; +package com.metis.engine; -import com.metis.flow.domain.query.AppQuery; -import com.metis.flow.domain.entity.App; -import com.metis.flow.domain.bo.CreateApp; -import com.metis.flow.domain.bo.UpdateApp; + +import com.metis.domain.bo.CreateApp; +import com.metis.domain.bo.UpdateApp; +import com.metis.domain.entity.App; +import com.metis.domain.query.AppQuery; import java.util.List; diff --git a/src/main/java/com/metis/flow/engine/AppFlowEngineRunnerService.java b/metis-starter/src/main/java/com/metis/engine/AppFlowEngineRunnerService.java similarity index 70% rename from src/main/java/com/metis/flow/engine/AppFlowEngineRunnerService.java rename to metis-starter/src/main/java/com/metis/engine/AppFlowEngineRunnerService.java index dfb85c3..fe0d367 100644 --- a/src/main/java/com/metis/flow/engine/AppFlowEngineRunnerService.java +++ b/metis-starter/src/main/java/com/metis/engine/AppFlowEngineRunnerService.java @@ -1,7 +1,7 @@ -package com.metis.flow.engine; +package com.metis.engine; -import com.metis.flow.runner.FlowRunningContext; -import com.metis.flow.runner.RunnerResult; +import com.metis.runner.FlowRunningContext; +import com.metis.runner.RunnerResult; /** * 应用引擎运行器服务 diff --git a/src/main/java/com/metis/flow/engine/impl/AppEngineServiceImpl.java b/metis-starter/src/main/java/com/metis/engine/impl/AppEngineServiceImpl.java similarity index 89% rename from src/main/java/com/metis/flow/engine/impl/AppEngineServiceImpl.java rename to metis-starter/src/main/java/com/metis/engine/impl/AppEngineServiceImpl.java index 92c5bc1..0a3a993 100644 --- a/src/main/java/com/metis/flow/engine/impl/AppEngineServiceImpl.java +++ b/metis-starter/src/main/java/com/metis/engine/impl/AppEngineServiceImpl.java @@ -1,19 +1,20 @@ -package com.metis.flow.engine.impl; +package com.metis.engine.impl; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; +import com.metis.constant.BaseConstant; +import com.metis.convert.BaseAppConvert; +import com.metis.domain.bo.BuildApp; +import com.metis.domain.bo.CreateApp; +import com.metis.domain.bo.UpdateApp; +import com.metis.domain.entity.App; +import com.metis.domain.entity.BaseApp; +import com.metis.domain.query.AppQuery; +import com.metis.engine.AppEngineService; import com.metis.enums.YesOrNoEnum; -import com.metis.flow.constant.BaseConstant; -import com.metis.flow.convert.BaseAppConvert; -import com.metis.flow.domain.bo.BuildApp; -import com.metis.flow.domain.bo.CreateApp; -import com.metis.flow.domain.bo.UpdateApp; -import com.metis.flow.domain.query.AppQuery; -import com.metis.flow.domain.entity.*; -import com.metis.flow.engine.AppEngineService; -import com.metis.flow.service.BaseAppService; -import com.metis.flow.validator.ValidatorService; +import com.metis.service.BaseAppService; +import com.metis.validator.ValidatorService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -67,6 +68,7 @@ public class AppEngineServiceImpl implements AppEngineService { } @Override + @Transactional(rollbackFor = Exception.class) public App create(CreateApp createApp) { BuildApp buildApp = BaseAppConvert.INSTANCE.toBuildApp(createApp); // 校验 diff --git a/metis-starter/src/main/java/com/metis/engine/impl/AppFlowEngineRunnerServiceImpl.java b/metis-starter/src/main/java/com/metis/engine/impl/AppFlowEngineRunnerServiceImpl.java new file mode 100644 index 0000000..9f64f8f --- /dev/null +++ b/metis-starter/src/main/java/com/metis/engine/impl/AppFlowEngineRunnerServiceImpl.java @@ -0,0 +1,159 @@ +package com.metis.engine.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.metis.domain.context.RunningContext; +import com.metis.domain.context.RunningResult; +import com.metis.domain.context.SysContext; +import com.metis.domain.entity.App; +import com.metis.domain.entity.GraphDto; +import com.metis.domain.entity.base.Edge; +import com.metis.domain.entity.base.Node; +import com.metis.engine.AppEngineService; +import com.metis.engine.AppFlowEngineRunnerService; +import com.metis.enums.NodeType; +import com.metis.runner.FlowRunningContext; +import com.metis.runner.NodeRunner; +import com.metis.runner.RunnerResult; +import com.metis.runner.factory.NodeRunnerFactory; +import com.metis.utils.GenericInterfacesUtils; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.*; + +@Slf4j +@Service +@RequiredArgsConstructor +public class AppFlowEngineRunnerServiceImpl implements AppFlowEngineRunnerService { + + private final AppEngineService appEngineService; + + + @Override + public RunnerResult running(FlowRunningContext context) { + App app = getApp(context); + Assert.isTrue(ObjectUtil.isNotNull(app), "app为空"); + // 构建运行实例, 并将运行实例放入上下文 + Long instanceId = IdUtil.getSnowflakeNextId(); + // 构建系统上下文信息 + SysContext sysContext = SysContext.builder() + .files(context.getFiles()) + .appId(app.getId()) + .workflowId(app.getWorkflowId()) + .instanceId(instanceId) + .build(); + // 构建运行中上下文 + RunningContext runningContext = RunningContext.buildContext(sysContext, context); + // 构建节点映射对象 + GraphDto graph = GraphDto.of(app.getGraph()); + Set readyRunningNode = new HashSet<>(); + + // 获取到开始节点 + // 开始节点为空,则表示数据存在异常 + Assert.isTrue(ObjectUtil.isNotNull(readyRunningNode), "流程图不存在开始节点"); + for (Node node : graph.getSortedNodes()) { + Long nodeId = node.getId(); + if (!graph.isNodeReady(nodeId)) { + continue; + } + log.info("当前运行节点 id:{}, name:{}, type:{}", node.getId(), node.getData().getLabel(), node.getType()); + // 当前节点接下来的连接线信息 + List edges = graph.getEdgeNodeId(nodeId); + // 执行 + NodeRunner nodeRunner = getNodeRunner(node); + node.setConfigClass(GenericInterfacesUtils.getClass(nodeRunner)); + // 下一个需要运行的节点id加入到可以运行的节点中 + // 获取到返回结果 + RunningResult result = nodeRunner.run(runningContext, node, edges); + log.info("节点执行结果:{}", JSON.toJSONString(result)); + // 节点执行结果参数放入上下文中 + if (ObjectUtil.isNotNull(result.getNodeContext())) { + runningContext.addNodeRunningContext(node.getId(), result.getNodeContext()); + } + // 下一个需要运行的节点id加入到可以运行的节点中 + if (CollUtil.isNotEmpty(result.getNextRunNodeId())) { + for (Long nextNodeId : result.getNextRunNodeId()) { + graph.updateNodeReadyMap(nextNodeId, true); + } + } else { + // 如果没有返回, 则认为所有的下级节点都需要运行 + edges.forEach(edge -> { + graph.updateNodeReadyMap(edge.getTarget(), true); + }); + } + } + Node endNode = graph.getEndNode(); + + JSONObject endRunningContext = runningContext.getRunningContext(endNode.getId()); + + return RunnerResult.builder() + .result(endRunningContext) + .context(sysContext) + .build(); + + } + + private void doRunning(Set readyRunningNode, Map> edgeMap, RunningContext runningContext) { + Set nextRunningNodeId = new HashSet<>(); + for (Node runningNode : readyRunningNode) { + // 当前节点接下来的连接线信息 + List edges = edgeMap.getOrDefault(runningNode.getId(), new ArrayList<>()); + // 执行 + NodeRunner nodeRunner = getNodeRunner(runningNode); + runningNode.setConfigClass(GenericInterfacesUtils.getClass(nodeRunner)); + // 获取到返回结果 + RunningResult result = nodeRunner.run(runningContext, runningNode, edges); + // 节点执行结果参数放入上下文中 + if (ObjectUtil.isNotNull(result.getNodeContext())) { + runningContext.addNodeRunningContext(runningNode.getId(), result.getNodeContext()); + } + if (CollUtil.isNotEmpty(result.getNextRunNodeId())) { + nextRunningNodeId.addAll(result.getNextRunNodeId()); + } + } + } + + + private RunningResult doRunning(RunningContext runningContext, Node node, List edges) { + NodeRunner nodeRunner = getNodeRunner(node); + node.setConfigClass(GenericInterfacesUtils.getClass(nodeRunner)); + // 获取到返回结果 + return nodeRunner.run(runningContext, node, edges); + } + + + /** + * 获取节点运行程序 + * + * @param node 节点 + * @return {@link NodeRunner } + */ + private NodeRunner getNodeRunner(Node node) { + if (NodeType.CUSTOM.equals(node.getType())) { + Assert.isTrue(StrUtil.isNotBlank(node.getCustomType()), "自定义节点类型不能为空"); + return NodeRunnerFactory.getCustom(node.getCustomType()); + } + return NodeRunnerFactory.get(node.getType()); + } + + + /** + * 获取到应用程序信息 + * + * @param context 上下文 + * @return {@link App } + */ + private App getApp(FlowRunningContext context) { + if (ObjectUtil.isNotNull(context.getWorkflowId())) { + return appEngineService.getByWorkflowId(context.getWorkflowId()); + } + return appEngineService.getByAppId(context.getAppId()); + } +} diff --git a/src/main/java/com/metis/enums/BaseEnum.java b/metis-starter/src/main/java/com/metis/enums/BaseEnum.java similarity index 100% rename from src/main/java/com/metis/enums/BaseEnum.java rename to metis-starter/src/main/java/com/metis/enums/BaseEnum.java diff --git a/src/main/java/com/metis/flow/enums/EdgeType.java b/metis-starter/src/main/java/com/metis/enums/EdgeType.java similarity index 96% rename from src/main/java/com/metis/flow/enums/EdgeType.java rename to metis-starter/src/main/java/com/metis/enums/EdgeType.java index 4113c13..0a53b1a 100644 --- a/src/main/java/com/metis/flow/enums/EdgeType.java +++ b/metis-starter/src/main/java/com/metis/enums/EdgeType.java @@ -1,4 +1,4 @@ -package com.metis.flow.enums; +package com.metis.enums; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; diff --git a/src/main/java/com/metis/flow/enums/FileUploadType.java b/metis-starter/src/main/java/com/metis/enums/FileUploadType.java similarity index 96% rename from src/main/java/com/metis/flow/enums/FileUploadType.java rename to metis-starter/src/main/java/com/metis/enums/FileUploadType.java index 15181df..f1bde0a 100644 --- a/src/main/java/com/metis/flow/enums/FileUploadType.java +++ b/metis-starter/src/main/java/com/metis/enums/FileUploadType.java @@ -1,4 +1,4 @@ -package com.metis.flow.enums; +package com.metis.enums; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; diff --git a/src/main/java/com/metis/flow/enums/HandleType.java b/metis-starter/src/main/java/com/metis/enums/HandleType.java similarity index 96% rename from src/main/java/com/metis/flow/enums/HandleType.java rename to metis-starter/src/main/java/com/metis/enums/HandleType.java index 37dc51e..227ac69 100644 --- a/src/main/java/com/metis/flow/enums/HandleType.java +++ b/metis-starter/src/main/java/com/metis/enums/HandleType.java @@ -1,4 +1,4 @@ -package com.metis.flow.enums; +package com.metis.enums; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; diff --git a/src/main/java/com/metis/flow/enums/NodeType.java b/metis-starter/src/main/java/com/metis/enums/NodeType.java similarity index 65% rename from src/main/java/com/metis/flow/enums/NodeType.java rename to metis-starter/src/main/java/com/metis/enums/NodeType.java index a56c7fb..89717e7 100644 --- a/src/main/java/com/metis/flow/enums/NodeType.java +++ b/metis-starter/src/main/java/com/metis/enums/NodeType.java @@ -1,9 +1,7 @@ -package com.metis.flow.enums; +package com.metis.enums; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; -import com.metis.flow.domain.entity.config.node.DocumentExtractorNodeConfig; -import com.metis.flow.domain.entity.config.node.StartNodeConfig; import lombok.AllArgsConstructor; import lombok.Getter; @@ -13,9 +11,16 @@ import java.util.Arrays; @AllArgsConstructor public enum NodeType { - START(1, "start", "开始", StartNodeConfig.class), - END(2, "end", "结束", Object.class), - DOCUMENT_EXTRACTOR(3, "document-extractor", "文档提取器", DocumentExtractorNodeConfig.class); + START(1, "start", "开始"), + END(2, "end", "结束"), + DOCUMENT_EXTRACTOR(3, "documentExtractor", "文档提取器"), + CUSTOM(4, "custom", "自定义节点"), + LLM(5, "llm", "LLM"), + QUESTION_CLASSIFIER(6, "questionClassifier", "问题分类器"), + IF_ELSE(7, "ifElse", "条件判断"), + + + ; private final Integer code; @@ -25,8 +30,6 @@ public enum NodeType { private final String name; - private final Class configClass; - /** * 枚举序列化器(前端传code时自动转换为对应枚举) diff --git a/src/main/java/com/metis/flow/enums/NodeVariableType.java b/metis-starter/src/main/java/com/metis/enums/NodeVariableType.java similarity index 97% rename from src/main/java/com/metis/flow/enums/NodeVariableType.java rename to metis-starter/src/main/java/com/metis/enums/NodeVariableType.java index e9617ca..09ca06d 100644 --- a/src/main/java/com/metis/flow/enums/NodeVariableType.java +++ b/metis-starter/src/main/java/com/metis/enums/NodeVariableType.java @@ -1,4 +1,4 @@ -package com.metis.flow.enums; +package com.metis.enums; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; diff --git a/src/main/java/com/metis/flow/enums/PositionType.java b/metis-starter/src/main/java/com/metis/enums/PositionType.java similarity index 97% rename from src/main/java/com/metis/flow/enums/PositionType.java rename to metis-starter/src/main/java/com/metis/enums/PositionType.java index 98eb1d0..a5d67a1 100644 --- a/src/main/java/com/metis/flow/enums/PositionType.java +++ b/metis-starter/src/main/java/com/metis/enums/PositionType.java @@ -1,4 +1,4 @@ -package com.metis.flow.enums; +package com.metis.enums; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; diff --git a/src/main/java/com/metis/enums/ResultEnum.java b/metis-starter/src/main/java/com/metis/enums/ResultEnum.java similarity index 100% rename from src/main/java/com/metis/enums/ResultEnum.java rename to metis-starter/src/main/java/com/metis/enums/ResultEnum.java diff --git a/src/main/java/com/metis/enums/YesOrNoEnum.java b/metis-starter/src/main/java/com/metis/enums/YesOrNoEnum.java similarity index 100% rename from src/main/java/com/metis/enums/YesOrNoEnum.java rename to metis-starter/src/main/java/com/metis/enums/YesOrNoEnum.java diff --git a/src/main/java/com/metis/facade/ProcessDefinitionFacade.java b/metis-starter/src/main/java/com/metis/facade/ProcessDefinitionFacade.java similarity index 71% rename from src/main/java/com/metis/facade/ProcessDefinitionFacade.java rename to metis-starter/src/main/java/com/metis/facade/ProcessDefinitionFacade.java index d1b4958..7926301 100644 --- a/src/main/java/com/metis/facade/ProcessDefinitionFacade.java +++ b/metis-starter/src/main/java/com/metis/facade/ProcessDefinitionFacade.java @@ -1,10 +1,12 @@ package com.metis.facade; +import com.metis.convert.GraphConvert; +import com.metis.domain.bo.CreateApp; import com.metis.domain.bo.ProcessBo; -import com.metis.flow.domain.entity.App; -import com.metis.flow.domain.bo.CreateApp; -import com.metis.flow.domain.bo.UpdateApp; -import com.metis.flow.engine.AppEngineService; +import com.metis.domain.bo.UpdateApp; +import com.metis.domain.entity.App; +import com.metis.domain.entity.base.Graph; +import com.metis.engine.AppEngineService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -22,9 +24,10 @@ public class ProcessDefinitionFacade { * @param processBo 过程业务对象 */ public Long create(ProcessBo processBo) { + Graph graph = GraphConvert.INSTANCE.toEntity(processBo.getGraph()); CreateApp createApp = CreateApp.builder() .name(processBo.getName()) - .graph(processBo.getGraph()) + .graph(graph) .build(); App app = appEngineService.create(createApp); return app.getWorkflowId(); @@ -35,11 +38,12 @@ public class ProcessDefinitionFacade { } public void update(ProcessBo processBo) { + Graph graph = GraphConvert.INSTANCE.toEntity(processBo.getGraph()); appEngineService.update(UpdateApp.builder() .defaultUse(processBo.getDefaultUse()) .appId(processBo.getAppId()) .name(processBo.getName()) - .graph(processBo.getGraph()) + .graph(graph) .build()); } diff --git a/src/main/java/com/metis/handle/GlobalExceptionHandler.java b/metis-starter/src/main/java/com/metis/handle/GlobalExceptionHandler.java similarity index 100% rename from src/main/java/com/metis/handle/GlobalExceptionHandler.java rename to metis-starter/src/main/java/com/metis/handle/GlobalExceptionHandler.java diff --git a/src/main/java/com/metis/flow/mapper/BaseAppMapper.java b/metis-starter/src/main/java/com/metis/mapper/BaseAppMapper.java similarity index 76% rename from src/main/java/com/metis/flow/mapper/BaseAppMapper.java rename to metis-starter/src/main/java/com/metis/mapper/BaseAppMapper.java index cb09b20..e9b88fc 100644 --- a/src/main/java/com/metis/flow/mapper/BaseAppMapper.java +++ b/metis-starter/src/main/java/com/metis/mapper/BaseAppMapper.java @@ -1,6 +1,6 @@ -package com.metis.flow.mapper; +package com.metis.mapper; -import com.metis.flow.domain.entity.BaseApp; +import com.metis.domain.entity.BaseApp; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; diff --git a/src/main/java/com/metis/mybatis/MybatisPlusConfiguration.java b/metis-starter/src/main/java/com/metis/mybatis/MybatisPlusConfiguration.java similarity index 100% rename from src/main/java/com/metis/mybatis/MybatisPlusConfiguration.java rename to metis-starter/src/main/java/com/metis/mybatis/MybatisPlusConfiguration.java diff --git a/src/main/java/com/metis/mybatis/handler/BaseEntityMetaObjectHandler.java b/metis-starter/src/main/java/com/metis/mybatis/handler/BaseEntityMetaObjectHandler.java similarity index 100% rename from src/main/java/com/metis/mybatis/handler/BaseEntityMetaObjectHandler.java rename to metis-starter/src/main/java/com/metis/mybatis/handler/BaseEntityMetaObjectHandler.java diff --git a/src/main/java/com/metis/mybatis/logic/SelectIgnoreLogicDelete.java b/metis-starter/src/main/java/com/metis/mybatis/logic/SelectIgnoreLogicDelete.java similarity index 100% rename from src/main/java/com/metis/mybatis/logic/SelectIgnoreLogicDelete.java rename to metis-starter/src/main/java/com/metis/mybatis/logic/SelectIgnoreLogicDelete.java diff --git a/src/main/java/com/metis/mybatis/support/CustomSqlInjector.java b/metis-starter/src/main/java/com/metis/mybatis/support/CustomSqlInjector.java similarity index 100% rename from src/main/java/com/metis/mybatis/support/CustomSqlInjector.java rename to metis-starter/src/main/java/com/metis/mybatis/support/CustomSqlInjector.java diff --git a/src/main/java/com/metis/result/Result.java b/metis-starter/src/main/java/com/metis/result/Result.java similarity index 100% rename from src/main/java/com/metis/result/Result.java rename to metis-starter/src/main/java/com/metis/result/Result.java diff --git a/src/main/java/com/metis/result/page/TableDataInfo.java b/metis-starter/src/main/java/com/metis/result/page/TableDataInfo.java similarity index 100% rename from src/main/java/com/metis/result/page/TableDataInfo.java rename to metis-starter/src/main/java/com/metis/result/page/TableDataInfo.java diff --git a/metis-starter/src/main/java/com/metis/runner/CustomNodeRunner.java b/metis-starter/src/main/java/com/metis/runner/CustomNodeRunner.java new file mode 100644 index 0000000..c0b7143 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/runner/CustomNodeRunner.java @@ -0,0 +1,33 @@ +package com.metis.runner; + +import com.metis.domain.entity.base.NodeConfig; +import com.metis.enums.NodeType; + +/** + * 自定义节点运行器 + * + * @author clay + * @date 2025/04/20 + */ +public interface CustomNodeRunner extends NodeRunner { + + + /** + * 获取自定义节点的节点类型 + * + * @return {@link String } + */ + String getCustomNodeType(); + + + /** + * 得到类型 + * + * @return {@link NodeType } + */ + default NodeType getType() { + return NodeType.CUSTOM; + } + + +} diff --git a/src/main/java/com/metis/flow/runner/FlowRunningContext.java b/metis-starter/src/main/java/com/metis/runner/FlowRunningContext.java similarity index 95% rename from src/main/java/com/metis/flow/runner/FlowRunningContext.java rename to metis-starter/src/main/java/com/metis/runner/FlowRunningContext.java index 5159a44..022f693 100644 --- a/src/main/java/com/metis/flow/runner/FlowRunningContext.java +++ b/metis-starter/src/main/java/com/metis/runner/FlowRunningContext.java @@ -1,4 +1,4 @@ -package com.metis.flow.runner; +package com.metis.runner; import com.alibaba.fastjson2.JSONObject; import lombok.AllArgsConstructor; diff --git a/metis-starter/src/main/java/com/metis/runner/NodeRunner.java b/metis-starter/src/main/java/com/metis/runner/NodeRunner.java new file mode 100644 index 0000000..cd59b92 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/runner/NodeRunner.java @@ -0,0 +1,56 @@ +package com.metis.runner; + +import cn.hutool.core.collection.CollUtil; +import com.metis.domain.context.RunningContext; +import com.metis.domain.context.RunningResult; +import com.metis.domain.entity.base.Edge; +import com.metis.domain.entity.base.Node; +import com.metis.domain.entity.base.NodeConfig; +import com.metis.enums.NodeType; + +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 内置节点运行器 + * + * @author clay + * @date 2025/04/20 + */ +public interface NodeRunner { + + + /** + * 运行 + * + * @param context 上下文 + * @param node 节点配置信息 + * @param edges 当前接下来的连线信息, 一些特殊节点需要节点内部判断下一个运行节点 + * @return {@link RunningContext } + */ + RunningResult run(RunningContext context, Node node, List edges); + + + /** + * 获取节点类型 + * + * @return {@link NodeType } + */ + NodeType getType(); + + + /** + * 获取下一个节点id + * + * @param edges 边缘 + * @return {@link Set }<{@link Long }> + */ + default Set getNextNodeIds(List edges) { + if (CollUtil.isEmpty(edges)) { + return Set.of(); + } + return edges.stream().map(Edge::getTarget).collect(Collectors.toSet()); + } + +} diff --git a/src/main/java/com/metis/flow/runner/RunnerResult.java b/metis-starter/src/main/java/com/metis/runner/RunnerResult.java similarity index 61% rename from src/main/java/com/metis/flow/runner/RunnerResult.java rename to metis-starter/src/main/java/com/metis/runner/RunnerResult.java index 0b573f4..3306ea5 100644 --- a/src/main/java/com/metis/flow/runner/RunnerResult.java +++ b/metis-starter/src/main/java/com/metis/runner/RunnerResult.java @@ -1,10 +1,13 @@ -package com.metis.flow.runner; +package com.metis.runner; -import com.metis.flow.domain.context.SysContext; +import com.alibaba.fastjson2.JSONObject; +import com.metis.domain.context.SysContext; import lombok.Builder; import lombok.Data; +import java.util.Map; + /** * 运行结果 * @@ -18,7 +21,7 @@ public class RunnerResult { /** * 运行内容 */ - private String content; + private JSONObject result; /** * 上下文 diff --git a/metis-starter/src/main/java/com/metis/runner/factory/NodeRunnerFactory.java b/metis-starter/src/main/java/com/metis/runner/factory/NodeRunnerFactory.java new file mode 100644 index 0000000..a2204fa --- /dev/null +++ b/metis-starter/src/main/java/com/metis/runner/factory/NodeRunnerFactory.java @@ -0,0 +1,64 @@ +package com.metis.runner.factory; + +import cn.hutool.core.lang.Assert; +import com.metis.enums.NodeType; +import com.metis.runner.CustomNodeRunner; +import com.metis.runner.NodeRunner; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public final class NodeRunnerFactory { + + /** + * 内置节点运行器 + */ + private static final Map NODE_MAP = new ConcurrentHashMap<>(8); + /** + * 自定义节点映射 + */ + private static final Map CUSTOM_NODE_MAP = new ConcurrentHashMap<>(8); + + /** + * 注册 + * + * @param runner 跑步者 + */ + static void register(NodeRunner runner) { + NODE_MAP.put(runner.getType(), runner); + } + + + /** + * 得到 + * + * @param type 类型 + * @return {@link NodeRunner } + */ + public static NodeRunner get(NodeType type) { + return NODE_MAP.get(type); + } + + + /** + * 注册自定义节点 + * + * @param runner 跑步者 + */ + static void registerCustom(CustomNodeRunner runner) { + Assert.isTrue(!CUSTOM_NODE_MAP.containsKey(runner.getCustomNodeType()), "已存在类型:{}, class:{}的运行器", runner.getCustomNodeType(), runner.getClass()); + CUSTOM_NODE_MAP.put(runner.getCustomNodeType(), runner); + } + + /** + * 得到自定义节点运行器 + * + * @param type 类型 + * @return {@link NodeRunner } + */ + public static NodeRunner getCustom(String type) { + return CUSTOM_NODE_MAP.get(type); + } + + +} diff --git a/src/main/java/com/metis/flow/runner/RunnerInitialize.java b/metis-starter/src/main/java/com/metis/runner/factory/RunnerInitialize.java similarity index 51% rename from src/main/java/com/metis/flow/runner/RunnerInitialize.java rename to metis-starter/src/main/java/com/metis/runner/factory/RunnerInitialize.java index 094d7fc..b02873a 100644 --- a/src/main/java/com/metis/flow/runner/RunnerInitialize.java +++ b/metis-starter/src/main/java/com/metis/runner/factory/RunnerInitialize.java @@ -1,6 +1,9 @@ -package com.metis.flow.runner; +package com.metis.runner.factory; -import com.metis.flow.runner.factory.RunnerFactory; +import cn.hutool.core.lang.Assert; +import com.metis.enums.NodeType; +import com.metis.runner.CustomNodeRunner; +import com.metis.runner.NodeRunner; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -19,9 +22,16 @@ public class RunnerInitialize implements ApplicationContextAware { @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + Map runnerMap = applicationContext.getBeansOfType(NodeRunner.class); - runnerMap.forEach((k, v) -> { - RunnerFactory.register(v); + + runnerMap.forEach((runnerBeanName, runner) -> { + if (NodeType.CUSTOM.equals(runner.getType())) { + Assert.isTrue(runner instanceof CustomNodeRunner, "自定义节点必须实现CustomNodeRunner接口"); + NodeRunnerFactory.registerCustom((CustomNodeRunner) runner); + } else { + NodeRunnerFactory.register(runner); + } }); } diff --git a/metis-starter/src/main/java/com/metis/runner/impl/EndNodeRunner.java b/metis-starter/src/main/java/com/metis/runner/impl/EndNodeRunner.java new file mode 100644 index 0000000..4aacda8 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/runner/impl/EndNodeRunner.java @@ -0,0 +1,33 @@ +package com.metis.runner.impl; + + +import com.alibaba.fastjson2.JSONObject; +import com.metis.domain.context.RunningContext; +import com.metis.domain.context.RunningResult; +import com.metis.domain.entity.base.Edge; +import com.metis.domain.entity.base.Node; +import com.metis.domain.entity.config.node.EndNodeConfig; +import com.metis.enums.NodeType; +import com.metis.runner.NodeRunner; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Slf4j +@Service +public class EndNodeRunner implements NodeRunner { + + @Override + public RunningResult run(RunningContext context, Node node, List edges) { + JSONObject contextNodeValue = new JSONObject(); + contextNodeValue.put("userId", context.getSys().getAppId()); + return RunningResult.buildResult(contextNodeValue); + } + + @Override + public NodeType getType() { + return NodeType.END; + } + +} diff --git a/metis-starter/src/main/java/com/metis/runner/impl/LLMNodeRunner.java b/metis-starter/src/main/java/com/metis/runner/impl/LLMNodeRunner.java new file mode 100644 index 0000000..1779a34 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/runner/impl/LLMNodeRunner.java @@ -0,0 +1,27 @@ +package com.metis.runner.impl; + +import com.metis.domain.context.RunningContext; +import com.metis.domain.context.RunningResult; +import com.metis.domain.entity.base.Edge; +import com.metis.domain.entity.base.Node; +import com.metis.domain.entity.config.node.LLMNodeConfig; +import com.metis.enums.NodeType; +import com.metis.runner.NodeRunner; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Slf4j +@Service +public class LLMNodeRunner implements NodeRunner { + @Override + public RunningResult run(RunningContext context, Node node, List edges) { + return RunningResult.buildResult(); + } + + @Override + public NodeType getType() { + return NodeType.LLM; + } +} diff --git a/metis-starter/src/main/java/com/metis/runner/impl/QuestionClassifierRunner.java b/metis-starter/src/main/java/com/metis/runner/impl/QuestionClassifierRunner.java new file mode 100644 index 0000000..d23f7a5 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/runner/impl/QuestionClassifierRunner.java @@ -0,0 +1,36 @@ +package com.metis.runner.impl; + +import com.metis.domain.context.RunningContext; +import com.metis.domain.context.RunningResult; +import com.metis.domain.entity.base.Edge; +import com.metis.domain.entity.base.Node; +import com.metis.domain.entity.config.node.QuestionClassifierConfig; +import com.metis.enums.NodeType; +import com.metis.runner.NodeRunner; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.Set; + +@Slf4j +@Service +public class QuestionClassifierRunner implements NodeRunner { + + @Override + public RunningResult run(RunningContext context, Node node, List edges) { + Set nextNodeIds = getNextNodeIds(edges); + // 生成随机索引 + Random random = new Random(); + int randomIndex = random.nextInt(nextNodeIds.size()); + List nodeIds = new ArrayList<>(nextNodeIds); + return RunningResult.buildResult(Set.of(nodeIds.get(randomIndex))); + } + + @Override + public NodeType getType() { + return NodeType.QUESTION_CLASSIFIER; + } +} diff --git a/src/main/java/com/metis/flow/runner/impl/StartNodeRunner.java b/metis-starter/src/main/java/com/metis/runner/impl/StartNodeRunner.java similarity index 68% rename from src/main/java/com/metis/flow/runner/impl/StartNodeRunner.java rename to metis-starter/src/main/java/com/metis/runner/impl/StartNodeRunner.java index 2975174..7019f92 100644 --- a/src/main/java/com/metis/flow/runner/impl/StartNodeRunner.java +++ b/metis-starter/src/main/java/com/metis/runner/impl/StartNodeRunner.java @@ -1,15 +1,15 @@ -package com.metis.flow.runner.impl; +package com.metis.runner.impl; import cn.hutool.core.collection.CollUtil; import com.alibaba.fastjson2.JSONObject; -import com.metis.flow.domain.context.RunningContext; -import com.metis.flow.domain.context.RunningResult; -import com.metis.flow.domain.entity.base.Edge; -import com.metis.flow.domain.entity.base.Node; -import com.metis.flow.domain.entity.base.NodeVariable; -import com.metis.flow.domain.entity.config.node.StartNodeConfig; -import com.metis.flow.enums.NodeType; -import com.metis.flow.runner.NodeRunner; +import com.metis.domain.context.RunningContext; +import com.metis.domain.context.RunningResult; +import com.metis.domain.entity.base.Edge; +import com.metis.domain.entity.base.Node; +import com.metis.domain.entity.base.NodeVariable; +import com.metis.domain.entity.config.node.StartNodeConfig; +import com.metis.enums.NodeType; +import com.metis.runner.NodeRunner; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -23,11 +23,10 @@ import java.util.List; */ @Slf4j @Service -public class StartNodeRunner implements NodeRunner { +public class StartNodeRunner implements NodeRunner { @Override public RunningResult run(RunningContext context, Node node, List edges) { - log.info("开始节点{}, 节点id: {} 运行", node.getData().getLabel(), node.getId()); StartNodeConfig config = node.getConfig(); // 获取到节点的自定义参数 List variables = config.getVariables(); diff --git a/src/main/java/com/metis/flow/service/BaseAppService.java b/metis-starter/src/main/java/com/metis/service/BaseAppService.java similarity index 92% rename from src/main/java/com/metis/flow/service/BaseAppService.java rename to metis-starter/src/main/java/com/metis/service/BaseAppService.java index 2fa231b..96d1c31 100644 --- a/src/main/java/com/metis/flow/service/BaseAppService.java +++ b/metis-starter/src/main/java/com/metis/service/BaseAppService.java @@ -1,8 +1,8 @@ -package com.metis.flow.service; +package com.metis.service; import com.metis.enums.YesOrNoEnum; -import com.metis.flow.domain.query.AppQuery; -import com.metis.flow.domain.entity.BaseApp; +import com.metis.domain.query.AppQuery; +import com.metis.domain.entity.BaseApp; import com.baomidou.mybatisplus.extension.service.IService; import java.util.List; diff --git a/src/main/java/com/metis/flow/service/impl/BaseAppServiceImpl.java b/metis-starter/src/main/java/com/metis/service/impl/BaseAppServiceImpl.java similarity index 93% rename from src/main/java/com/metis/flow/service/impl/BaseAppServiceImpl.java rename to metis-starter/src/main/java/com/metis/service/impl/BaseAppServiceImpl.java index 5cbe09a..c9263ab 100644 --- a/src/main/java/com/metis/flow/service/impl/BaseAppServiceImpl.java +++ b/metis-starter/src/main/java/com/metis/service/impl/BaseAppServiceImpl.java @@ -1,4 +1,4 @@ -package com.metis.flow.service.impl; +package com.metis.service.impl; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; @@ -6,10 +6,10 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.metis.enums.YesOrNoEnum; -import com.metis.flow.domain.query.AppQuery; -import com.metis.flow.domain.entity.BaseApp; -import com.metis.flow.mapper.BaseAppMapper; -import com.metis.flow.service.BaseAppService; +import com.metis.domain.query.AppQuery; +import com.metis.domain.entity.BaseApp; +import com.metis.mapper.BaseAppMapper; +import com.metis.service.BaseAppService; import com.metis.utils.PageConditionUtil; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/metis/sseclient/ToolSpecificationHelper.java b/metis-starter/src/main/java/com/metis/sseclient/ToolSpecificationHelper.java similarity index 100% rename from src/main/java/com/metis/sseclient/ToolSpecificationHelper.java rename to metis-starter/src/main/java/com/metis/sseclient/ToolSpecificationHelper.java diff --git a/src/main/java/com/metis/sseclient/check/SseCheck.java b/metis-starter/src/main/java/com/metis/sseclient/check/SseCheck.java similarity index 100% rename from src/main/java/com/metis/sseclient/check/SseCheck.java rename to metis-starter/src/main/java/com/metis/sseclient/check/SseCheck.java diff --git a/src/main/java/com/metis/sseclient/event/SseEventListener.java b/metis-starter/src/main/java/com/metis/sseclient/event/SseEventListener.java similarity index 100% rename from src/main/java/com/metis/sseclient/event/SseEventListener.java rename to metis-starter/src/main/java/com/metis/sseclient/event/SseEventListener.java diff --git a/src/main/java/com/metis/sseclient/handler/McpOperationHandler.java b/metis-starter/src/main/java/com/metis/sseclient/handler/McpOperationHandler.java similarity index 100% rename from src/main/java/com/metis/sseclient/handler/McpOperationHandler.java rename to metis-starter/src/main/java/com/metis/sseclient/handler/McpOperationHandler.java diff --git a/metis-starter/src/main/java/com/metis/utils/GenericInterfacesUtils.java b/metis-starter/src/main/java/com/metis/utils/GenericInterfacesUtils.java new file mode 100644 index 0000000..c8b14f8 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/utils/GenericInterfacesUtils.java @@ -0,0 +1,25 @@ +package com.metis.utils; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +public class GenericInterfacesUtils { + + + public static Class getClass(Object object) { + + Type[] genericInterfaces = object.getClass().getGenericInterfaces(); + for (Type genericInterface : genericInterfaces) { + if (genericInterface instanceof ParameterizedType) { + ParameterizedType parameterizedType = (ParameterizedType) genericInterface; + Type[] typeArguments = parameterizedType.getActualTypeArguments(); + if (typeArguments.length > 0) { + return (Class) typeArguments[0]; + } + } + } + throw new IllegalStateException("无法获取泛型类型"); + } + + +} diff --git a/src/main/java/com/metis/utils/LocalDateTimeUtils.java b/metis-starter/src/main/java/com/metis/utils/LocalDateTimeUtils.java similarity index 100% rename from src/main/java/com/metis/utils/LocalDateTimeUtils.java rename to metis-starter/src/main/java/com/metis/utils/LocalDateTimeUtils.java diff --git a/src/main/java/com/metis/utils/PageConditionUtil.java b/metis-starter/src/main/java/com/metis/utils/PageConditionUtil.java similarity index 100% rename from src/main/java/com/metis/utils/PageConditionUtil.java rename to metis-starter/src/main/java/com/metis/utils/PageConditionUtil.java diff --git a/src/main/java/com/metis/utils/PageInfo.java b/metis-starter/src/main/java/com/metis/utils/PageInfo.java similarity index 100% rename from src/main/java/com/metis/utils/PageInfo.java rename to metis-starter/src/main/java/com/metis/utils/PageInfo.java diff --git a/src/main/java/com/metis/utils/TableSupport.java b/metis-starter/src/main/java/com/metis/utils/TableSupport.java similarity index 100% rename from src/main/java/com/metis/utils/TableSupport.java rename to metis-starter/src/main/java/com/metis/utils/TableSupport.java diff --git a/src/main/java/com/metis/utils/TransactionalUtils.java b/metis-starter/src/main/java/com/metis/utils/TransactionalUtils.java similarity index 100% rename from src/main/java/com/metis/utils/TransactionalUtils.java rename to metis-starter/src/main/java/com/metis/utils/TransactionalUtils.java diff --git a/metis-starter/src/main/java/com/metis/validator/CustomNodeValidator.java b/metis-starter/src/main/java/com/metis/validator/CustomNodeValidator.java new file mode 100644 index 0000000..ee37924 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/validator/CustomNodeValidator.java @@ -0,0 +1,34 @@ +package com.metis.validator; + +import com.metis.domain.entity.base.NodeConfig; +import com.metis.enums.NodeType; + +/** + * 自定义节点验证器 + * + * @author clay + * @date 2025/04/20 + */ +public interface CustomNodeValidator extends NodeValidator { + + + /** + * 获取自定义节点的节点类型 + * + * @return {@link String } + */ + String getCustomNodeType(); + + + /** + * 得到类型 + * + * @return {@link NodeType } + */ + default NodeType getType() { + return NodeType.CUSTOM; + } + + + +} diff --git a/src/main/java/com/metis/flow/validator/EdgeValidator.java b/metis-starter/src/main/java/com/metis/validator/EdgeValidator.java similarity index 70% rename from src/main/java/com/metis/flow/validator/EdgeValidator.java rename to metis-starter/src/main/java/com/metis/validator/EdgeValidator.java index a02d1e2..74f87b7 100644 --- a/src/main/java/com/metis/flow/validator/EdgeValidator.java +++ b/metis-starter/src/main/java/com/metis/validator/EdgeValidator.java @@ -1,7 +1,7 @@ -package com.metis.flow.validator; +package com.metis.validator; -import com.metis.flow.domain.entity.base.Edge; -import com.metis.flow.enums.EdgeType; +import com.metis.domain.entity.base.Edge; +import com.metis.enums.EdgeType; public interface EdgeValidator { diff --git a/src/main/java/com/metis/flow/validator/NodeValidator.java b/metis-starter/src/main/java/com/metis/validator/NodeValidator.java similarity index 68% rename from src/main/java/com/metis/flow/validator/NodeValidator.java rename to metis-starter/src/main/java/com/metis/validator/NodeValidator.java index 76f8211..27aac24 100644 --- a/src/main/java/com/metis/flow/validator/NodeValidator.java +++ b/metis-starter/src/main/java/com/metis/validator/NodeValidator.java @@ -1,12 +1,13 @@ -package com.metis.flow.validator; +package com.metis.validator; -import com.metis.flow.domain.entity.base.Edge; -import com.metis.flow.domain.entity.base.Node; -import com.metis.flow.enums.NodeType; +import com.metis.domain.entity.base.Edge; +import com.metis.domain.entity.base.Node; +import com.metis.domain.entity.base.NodeConfig; +import com.metis.enums.NodeType; import java.util.List; -public interface NodeValidator { +public interface NodeValidator { /** diff --git a/src/main/java/com/metis/flow/validator/ValidatorCodeService.java b/metis-starter/src/main/java/com/metis/validator/ValidatorCodeService.java similarity index 98% rename from src/main/java/com/metis/flow/validator/ValidatorCodeService.java rename to metis-starter/src/main/java/com/metis/validator/ValidatorCodeService.java index 9ee3d25..a05e326 100644 --- a/src/main/java/com/metis/flow/validator/ValidatorCodeService.java +++ b/metis-starter/src/main/java/com/metis/validator/ValidatorCodeService.java @@ -1,4 +1,4 @@ -package com.metis.flow.validator; +package com.metis.validator; import cn.hutool.core.collection.CollUtil; import jakarta.validation.ConstraintViolation; diff --git a/src/main/java/com/metis/flow/validator/ValidatorResult.java b/metis-starter/src/main/java/com/metis/validator/ValidatorResult.java similarity index 93% rename from src/main/java/com/metis/flow/validator/ValidatorResult.java rename to metis-starter/src/main/java/com/metis/validator/ValidatorResult.java index 8666b6e..a9e502a 100644 --- a/src/main/java/com/metis/flow/validator/ValidatorResult.java +++ b/metis-starter/src/main/java/com/metis/validator/ValidatorResult.java @@ -1,4 +1,4 @@ -package com.metis.flow.validator; +package com.metis.validator; import lombok.Data; diff --git a/src/main/java/com/metis/flow/validator/ValidatorService.java b/metis-starter/src/main/java/com/metis/validator/ValidatorService.java similarity index 66% rename from src/main/java/com/metis/flow/validator/ValidatorService.java rename to metis-starter/src/main/java/com/metis/validator/ValidatorService.java index ac5f11f..6cf5afb 100644 --- a/src/main/java/com/metis/flow/validator/ValidatorService.java +++ b/metis-starter/src/main/java/com/metis/validator/ValidatorService.java @@ -1,6 +1,6 @@ -package com.metis.flow.validator; +package com.metis.validator; -import com.metis.flow.domain.bo.BuildApp; +import com.metis.domain.bo.BuildApp; public interface ValidatorService { diff --git a/src/main/java/com/metis/flow/validator/factory/EdgeValidatorFactory.java b/metis-starter/src/main/java/com/metis/validator/factory/EdgeValidatorFactory.java similarity index 81% rename from src/main/java/com/metis/flow/validator/factory/EdgeValidatorFactory.java rename to metis-starter/src/main/java/com/metis/validator/factory/EdgeValidatorFactory.java index d3e357f..03c2eab 100644 --- a/src/main/java/com/metis/flow/validator/factory/EdgeValidatorFactory.java +++ b/metis-starter/src/main/java/com/metis/validator/factory/EdgeValidatorFactory.java @@ -1,7 +1,7 @@ -package com.metis.flow.validator.factory; +package com.metis.validator.factory; -import com.metis.flow.enums.EdgeType; -import com.metis.flow.validator.EdgeValidator; +import com.metis.enums.EdgeType; +import com.metis.validator.EdgeValidator; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; diff --git a/metis-starter/src/main/java/com/metis/validator/factory/NodeValidatorFactory.java b/metis-starter/src/main/java/com/metis/validator/factory/NodeValidatorFactory.java new file mode 100644 index 0000000..14a501b --- /dev/null +++ b/metis-starter/src/main/java/com/metis/validator/factory/NodeValidatorFactory.java @@ -0,0 +1,56 @@ +package com.metis.validator.factory; + +import cn.hutool.core.lang.Assert; +import com.metis.enums.NodeType; +import com.metis.validator.CustomNodeValidator; +import com.metis.validator.NodeValidator; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + + +public final class NodeValidatorFactory { + + /** + * 内置节点验证器 + */ + private static final Map NODE_MAP = new ConcurrentHashMap<>(8); + /** + * 自定义节点验证器 + */ + private static final Map CUSTOM_NODE_MAP = new ConcurrentHashMap<>(8); + + + /** + * 注册 + * + * @param validator 验证器 + */ + static void register(NodeValidator validator) { + NODE_MAP.put(validator.getType(), validator); + } + + /** + * 得到 + * + * @param type 类型 + * @return {@link NodeValidator } + */ + public static NodeValidator get(NodeType type) { + return NODE_MAP.get(type); + } + + /** + * @param validator 验证器 + */ + static void registerCustom(CustomNodeValidator validator) { + Assert.isTrue(!CUSTOM_NODE_MAP.containsKey(validator.getCustomNodeType()), "已存在类型:{}, class:{}的验证器", validator.getCustomNodeType(), validator.getClass()); + CUSTOM_NODE_MAP.put(validator.getCustomNodeType(), validator); + } + + public static NodeValidator getCustom(String type) { + return CUSTOM_NODE_MAP.get(type); + } + + +} diff --git a/metis-starter/src/main/java/com/metis/validator/factory/ValidatorInitialize.java b/metis-starter/src/main/java/com/metis/validator/factory/ValidatorInitialize.java new file mode 100644 index 0000000..40b92fe --- /dev/null +++ b/metis-starter/src/main/java/com/metis/validator/factory/ValidatorInitialize.java @@ -0,0 +1,43 @@ +package com.metis.validator.factory; + + +import cn.hutool.core.lang.Assert; +import com.metis.enums.NodeType; +import com.metis.validator.CustomNodeValidator; +import com.metis.validator.EdgeValidator; +import com.metis.validator.NodeValidator; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Service; + +import java.util.Map; + +@Service +public class ValidatorInitialize implements ApplicationContextAware { + + + @Override + public void setApplicationContext(@NotNull ApplicationContext applicationContext) throws BeansException { + + Map edgeMap = applicationContext.getBeansOfType(EdgeValidator.class); + + edgeMap.forEach((edgeValidatorBeanName, edgeValidator) -> { + EdgeValidatorFactory.register(edgeValidator); + }); + + Map nodeMap = applicationContext.getBeansOfType(NodeValidator.class); + + nodeMap.forEach((nodeValidatorBeanName, nodeValidator) -> { + if (NodeType.CUSTOM.equals(nodeValidator.getType())) { + Assert.isTrue(nodeValidator instanceof CustomNodeValidator, "自定义节点必须实现CustomNodeValidator接口"); + NodeValidatorFactory.registerCustom((CustomNodeValidator) nodeValidator); + } else { + NodeValidatorFactory.register(nodeValidator); + } + }); + } + + +} diff --git a/src/main/java/com/metis/flow/validator/impl/ValidatorServiceImpl.java b/metis-starter/src/main/java/com/metis/validator/impl/ValidatorServiceImpl.java similarity index 84% rename from src/main/java/com/metis/flow/validator/impl/ValidatorServiceImpl.java rename to metis-starter/src/main/java/com/metis/validator/impl/ValidatorServiceImpl.java index 17b4e8d..bd42907 100644 --- a/src/main/java/com/metis/flow/validator/impl/ValidatorServiceImpl.java +++ b/metis-starter/src/main/java/com/metis/validator/impl/ValidatorServiceImpl.java @@ -1,17 +1,19 @@ -package com.metis.flow.validator.impl; +package com.metis.validator.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjectUtil; -import com.metis.flow.domain.bo.BuildApp; -import com.metis.flow.domain.bo.Graph; -import com.metis.flow.domain.entity.base.Edge; -import com.metis.flow.domain.entity.base.Node; -import com.metis.flow.enums.EdgeType; -import com.metis.flow.enums.NodeType; -import com.metis.flow.validator.*; -import com.metis.flow.validator.factory.EdgeValidatorFactory; -import com.metis.flow.validator.factory.NodeValidatorFactory; +import cn.hutool.core.util.StrUtil; +import com.metis.domain.bo.BuildApp; +import com.metis.domain.entity.base.Edge; +import com.metis.domain.entity.base.Graph; +import com.metis.domain.entity.base.Node; +import com.metis.enums.EdgeType; +import com.metis.enums.NodeType; +import com.metis.validator.*; +import com.metis.validator.factory.EdgeValidatorFactory; +import com.metis.validator.factory.NodeValidatorFactory; +import com.metis.utils.GenericInterfacesUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -28,16 +30,16 @@ public class ValidatorServiceImpl implements ValidatorService { private final ValidatorCodeService validatorCodeService; @Override - public void validate(BuildApp graph) { + public void validate(BuildApp buildApp) { // validation 编程式校验 - validatorCodeService.validateThrow(graph); - Graph model = graph.getGraph(); + validatorCodeService.validateThrow(buildApp); + Graph graph = buildApp.getGraph(); // 节点参数校验 - validateNode(model.getNodes()); + validateNode(graph.getNodes()); // 线参数校验 - validateEdge(model.getEdges()); + validateEdge(graph.getEdges()); // 关系验证 - validateRelation(model.getNodes(), model.getEdges()); + validateRelation(graph.getNodes(), graph.getEdges()); } @@ -50,7 +52,8 @@ public class ValidatorServiceImpl implements ValidatorService { List errorMessage = new ArrayList<>(); for (Node node : nodes) { NodeType type = node.getType(); - NodeValidator validator = NodeValidatorFactory.get(type); + NodeValidator validator = getNodeValidator(node); + node.setConfigClass(GenericInterfacesUtils.getClass(validator)); // 节点校验器 Assert.isTrue(ObjectUtil.isNotNull(validator), "无:{}类型的节点校验器", type.getName()); ValidatorResult result = validator.validateValue(node); @@ -237,7 +240,7 @@ public class ValidatorServiceImpl implements ValidatorService { Map> targetMap = edges.stream().collect(Collectors.groupingBy(Edge::getTarget)); for (Node node : nodes) { - NodeValidator validator = NodeValidatorFactory.get(node.getType()); + NodeValidator validator = getNodeValidator(node); // 获取当前节点的 source 和 target List sources = targetMap.getOrDefault(node.getId(), new ArrayList<>()); List targets = sourceMap.getOrDefault(node.getId(), new ArrayList<>()); @@ -247,4 +250,19 @@ public class ValidatorServiceImpl implements ValidatorService { } } + + /** + * 获取节点验证器 + * + * @param node 节点 + * @return {@link NodeValidator } + */ + private NodeValidator getNodeValidator(Node node) { + if (NodeType.CUSTOM.equals(node.getType())) { + Assert.isTrue(StrUtil.isNotBlank(node.getCustomType()), "自定义节点类型不能为空"); + return NodeValidatorFactory.getCustom(node.getCustomType()); + } + return NodeValidatorFactory.get(node.getType()); + } + } diff --git a/src/main/java/com/metis/flow/validator/impl/edge/DefaultEdgeValidator.java b/metis-starter/src/main/java/com/metis/validator/impl/edge/DefaultEdgeValidator.java similarity index 61% rename from src/main/java/com/metis/flow/validator/impl/edge/DefaultEdgeValidator.java rename to metis-starter/src/main/java/com/metis/validator/impl/edge/DefaultEdgeValidator.java index 3012647..086d98e 100644 --- a/src/main/java/com/metis/flow/validator/impl/edge/DefaultEdgeValidator.java +++ b/metis-starter/src/main/java/com/metis/validator/impl/edge/DefaultEdgeValidator.java @@ -1,9 +1,9 @@ -package com.metis.flow.validator.impl.edge; +package com.metis.validator.impl.edge; -import com.metis.flow.domain.entity.base.Edge; -import com.metis.flow.enums.EdgeType; -import com.metis.flow.validator.EdgeValidator; -import com.metis.flow.validator.ValidatorResult; +import com.metis.domain.entity.base.Edge; +import com.metis.enums.EdgeType; +import com.metis.validator.EdgeValidator; +import com.metis.validator.ValidatorResult; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/metis/flow/validator/impl/node/DocumentExtractorNodeValidator.java b/metis-starter/src/main/java/com/metis/validator/impl/node/DocumentExtractorNodeValidator.java similarity index 72% rename from src/main/java/com/metis/flow/validator/impl/node/DocumentExtractorNodeValidator.java rename to metis-starter/src/main/java/com/metis/validator/impl/node/DocumentExtractorNodeValidator.java index 6d82c99..7fd2ca8 100644 --- a/src/main/java/com/metis/flow/validator/impl/node/DocumentExtractorNodeValidator.java +++ b/metis-starter/src/main/java/com/metis/validator/impl/node/DocumentExtractorNodeValidator.java @@ -1,13 +1,13 @@ -package com.metis.flow.validator.impl.node; +package com.metis.validator.impl.node; import cn.hutool.core.lang.Assert; -import com.metis.flow.domain.entity.base.Edge; -import com.metis.flow.domain.entity.base.Node; -import com.metis.flow.domain.entity.config.node.DocumentExtractorNodeConfig; -import com.metis.flow.enums.NodeType; -import com.metis.flow.validator.NodeValidator; -import com.metis.flow.validator.ValidatorCodeService; -import com.metis.flow.validator.ValidatorResult; +import com.metis.domain.entity.base.Edge; +import com.metis.domain.entity.base.Node; +import com.metis.domain.entity.config.node.DocumentExtractorNodeConfig; +import com.metis.enums.NodeType; +import com.metis.validator.NodeValidator; +import com.metis.validator.ValidatorCodeService; +import com.metis.validator.ValidatorResult; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -17,7 +17,7 @@ import java.util.List; @Slf4j @Service @RequiredArgsConstructor -public class DocumentExtractorNodeValidator implements NodeValidator { +public class DocumentExtractorNodeValidator implements NodeValidator { private final ValidatorCodeService validatorCodeService; @Override diff --git a/src/main/java/com/metis/flow/validator/impl/node/EndNodeValidator.java b/metis-starter/src/main/java/com/metis/validator/impl/node/EndNodeValidator.java similarity index 58% rename from src/main/java/com/metis/flow/validator/impl/node/EndNodeValidator.java rename to metis-starter/src/main/java/com/metis/validator/impl/node/EndNodeValidator.java index fbe87d0..9e62e56 100644 --- a/src/main/java/com/metis/flow/validator/impl/node/EndNodeValidator.java +++ b/metis-starter/src/main/java/com/metis/validator/impl/node/EndNodeValidator.java @@ -1,11 +1,12 @@ -package com.metis.flow.validator.impl.node; +package com.metis.validator.impl.node; import cn.hutool.core.lang.Assert; -import com.metis.flow.domain.entity.base.Edge; -import com.metis.flow.domain.entity.base.Node; -import com.metis.flow.enums.NodeType; -import com.metis.flow.validator.NodeValidator; -import com.metis.flow.validator.ValidatorResult; +import com.metis.domain.entity.base.Edge; +import com.metis.domain.entity.base.Node; +import com.metis.domain.entity.config.node.EndNodeConfig; +import com.metis.enums.NodeType; +import com.metis.validator.NodeValidator; +import com.metis.validator.ValidatorResult; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -15,7 +16,7 @@ import java.util.List; @Slf4j @Service @RequiredArgsConstructor -public class EndNodeValidator implements NodeValidator { +public class EndNodeValidator implements NodeValidator { @@ -30,8 +31,8 @@ public class EndNodeValidator implements NodeValidator { Assert.isTrue(targets.isEmpty(), "结束节点 {} 不允许有目标连接", node.getId()); // 2. 检查 sources 数量是否小于 handles 数量 - int handleCount = node.getData().getHandles().size(); - Assert.isTrue(sources.size() <= handleCount, "结束节点 {} 的源连接数超过 handles 数量", node.getId()); +// int handleCount = node.getData().getHandles().size(); +// Assert.isTrue(sources.size() <= handleCount, "结束节点 {} 的源连接数超过 handles 数量", node.getId()); return ValidatorResult.valid(); } diff --git a/metis-starter/src/main/java/com/metis/validator/impl/node/LLMNodeValidator.java b/metis-starter/src/main/java/com/metis/validator/impl/node/LLMNodeValidator.java new file mode 100644 index 0000000..2dd04a6 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/validator/impl/node/LLMNodeValidator.java @@ -0,0 +1,33 @@ +package com.metis.validator.impl.node; + +import com.metis.domain.entity.base.Edge; +import com.metis.domain.entity.base.Node; +import com.metis.domain.entity.config.node.LLMNodeConfig; +import com.metis.enums.NodeType; +import com.metis.validator.NodeValidator; +import com.metis.validator.ValidatorResult; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Slf4j +@Service +@RequiredArgsConstructor +public class LLMNodeValidator implements NodeValidator { + @Override + public ValidatorResult validateValue(Node node) { + return ValidatorResult.valid(); + } + + @Override + public ValidatorResult validateRelation(Node node, List sources, List targets) { + return ValidatorResult.valid(); + } + + @Override + public NodeType getType() { + return NodeType.LLM; + } +} diff --git a/metis-starter/src/main/java/com/metis/validator/impl/node/QuestionClassifierValidator.java b/metis-starter/src/main/java/com/metis/validator/impl/node/QuestionClassifierValidator.java new file mode 100644 index 0000000..23c3e19 --- /dev/null +++ b/metis-starter/src/main/java/com/metis/validator/impl/node/QuestionClassifierValidator.java @@ -0,0 +1,31 @@ +package com.metis.validator.impl.node; + +import com.metis.domain.entity.base.Edge; +import com.metis.domain.entity.base.Node; +import com.metis.domain.entity.config.node.QuestionClassifierConfig; +import com.metis.enums.NodeType; +import com.metis.validator.NodeValidator; +import com.metis.validator.ValidatorResult; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Slf4j +@Service +public class QuestionClassifierValidator implements NodeValidator { + @Override + public ValidatorResult validateValue(Node node) { + return ValidatorResult.valid(); + } + + @Override + public ValidatorResult validateRelation(Node node, List sources, List targets) { + return ValidatorResult.valid(); + } + + @Override + public NodeType getType() { + return NodeType.QUESTION_CLASSIFIER; + } +} diff --git a/src/main/java/com/metis/flow/validator/impl/node/StartNodeValidator.java b/metis-starter/src/main/java/com/metis/validator/impl/node/StartNodeValidator.java similarity index 81% rename from src/main/java/com/metis/flow/validator/impl/node/StartNodeValidator.java rename to metis-starter/src/main/java/com/metis/validator/impl/node/StartNodeValidator.java index 97dfc11..797873d 100644 --- a/src/main/java/com/metis/flow/validator/impl/node/StartNodeValidator.java +++ b/metis-starter/src/main/java/com/metis/validator/impl/node/StartNodeValidator.java @@ -1,16 +1,16 @@ -package com.metis.flow.validator.impl.node; +package com.metis.validator.impl.node; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjectUtil; -import com.metis.flow.domain.entity.base.Edge; -import com.metis.flow.domain.entity.base.Node; -import com.metis.flow.domain.entity.base.NodeVariable; -import com.metis.flow.domain.entity.config.node.StartNodeConfig; -import com.metis.flow.enums.NodeType; -import com.metis.flow.validator.NodeValidator; -import com.metis.flow.validator.ValidatorCodeService; -import com.metis.flow.validator.ValidatorResult; +import com.metis.domain.entity.base.Edge; +import com.metis.domain.entity.base.Node; +import com.metis.domain.entity.base.NodeVariable; +import com.metis.domain.entity.config.node.StartNodeConfig; +import com.metis.enums.NodeType; +import com.metis.validator.NodeValidator; +import com.metis.validator.ValidatorCodeService; +import com.metis.validator.ValidatorResult; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -20,7 +20,7 @@ import java.util.List; @Slf4j @Service @RequiredArgsConstructor -public class StartNodeValidator implements NodeValidator { +public class StartNodeValidator implements NodeValidator { private final ValidatorCodeService validatorCodeService; @@ -84,8 +84,8 @@ public class StartNodeValidator implements NodeValidator { Assert.isTrue(sources.isEmpty(), "开始节点 {} 不允许有源连接", node.getId()); // 2. 检查 targets 数量是否小于 handles 数量 - int handleCount = node.getData().getHandles().size(); - Assert.isTrue(targets.size() <= handleCount, "开始节点 {} 的目标连接数超过 handles 数量", node.getId()); +// int handleCount = node.getData().getHandles().size(); +// Assert.isTrue(targets.size() <= handleCount, "开始节点 {} 的目标连接数超过 handles 数量", node.getId()); return ValidatorResult.valid(); } diff --git a/metis-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/metis-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..0e5852e --- /dev/null +++ b/metis-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +com.metis.config.MetisStarterAutoConfiguration \ No newline at end of file diff --git a/pom.xml b/pom.xml index dbb661b..299c6b8 100644 --- a/pom.xml +++ b/pom.xml @@ -7,6 +7,11 @@ com.metis metis 1.0.0-SNAPSHOT + pom + + metis-starter + metis-applicant + org.springframework.boot @@ -19,8 +24,9 @@ 17 UTF-8 3.3.4 - 2.0.45 + 2.0.56 1.18.34 + 1.6.2 1.2.3 1.0.0-beta2 3.5.8 @@ -36,126 +42,60 @@ pom import + + dev.langchain4j + langchain4j-open-ai + ${langchain4j.version} + + + dev.langchain4j + langchain4j-mcp + 1.0.0-beta2 + + + com.alibaba.fastjson2 + fastjson2 + ${fastjson.version} + + + com.mikesamuel + json-sanitizer + ${sanitizer.version} + + + com.baomidou + mybatis-plus-spring-boot3-starter + ${mybatis-plus.version} + + + mysql + mysql-connector-java + 8.0.33 + + + cn.hutool + hutool-all + 5.8.24 + + + + org.mapstruct + mapstruct + ${org.mapstruct.version} + + + org.projectlombok + lombok-mapstruct-binding + 0.2.0 + + + org.springdoc + springdoc-openapi-starter-webmvc-api + 2.2.0 + - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-validation - - - dev.langchain4j - langchain4j-open-ai - ${langchain4j.version} - - - dev.langchain4j - langchain4j-mcp - 1.0.0-beta2 - - - com.alibaba.fastjson2 - fastjson2 - ${fastjson.version} - - - org.projectlombok - lombok - - - com.mikesamuel - json-sanitizer - ${sanitizer.version} - - - com.baomidou - mybatis-plus-spring-boot3-starter - ${mybatis-plus.version} - - - mysql - mysql-connector-java - 8.0.33 - - - cn.hutool - hutool-all - 5.8.22 - - - org.mapstruct - mapstruct - 1.6.2 - - - org.projectlombok - lombok-mapstruct-binding - 0.2.0 - - - org.springdoc - springdoc-openapi-starter-webmvc-api - 2.2.0 - - - com.github.xiaoymin - knife4j-openapi3-jakarta-spring-boot-starter - 4.4.0 - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 17 - 17 - UTF-8 - - -parameters - - - - - - org.mapstruct - mapstruct-processor - 1.6.2 - - - org.projectlombok - lombok - 1.18.34 - - - org.projectlombok - lombok-mapstruct-binding - 0.2.0 - - - - - - \ No newline at end of file diff --git a/src/main/java/com/metis/domain/package-info.java b/src/main/java/com/metis/domain/package-info.java deleted file mode 100644 index 8890ae6..0000000 --- a/src/main/java/com/metis/domain/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package com.metis.domain; \ No newline at end of file diff --git a/src/main/java/com/metis/flow/config/FlowMybatisPlusConfiguration.java b/src/main/java/com/metis/flow/config/FlowMybatisPlusConfiguration.java deleted file mode 100644 index 77d35d6..0000000 --- a/src/main/java/com/metis/flow/config/FlowMybatisPlusConfiguration.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.metis.flow.config; - -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.context.annotation.Configuration; - -@Configuration -@MapperScan(basePackages = {"com.metis.flow.mapper"}) -public class FlowMybatisPlusConfiguration { -} diff --git a/src/main/java/com/metis/flow/domain/bo/Graph.java b/src/main/java/com/metis/flow/domain/bo/Graph.java deleted file mode 100644 index 626974c..0000000 --- a/src/main/java/com/metis/flow/domain/bo/Graph.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.metis.flow.domain.bo; - -import com.metis.flow.domain.entity.base.Edge; -import com.metis.flow.domain.entity.base.Node; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import lombok.Data; - -import java.util.List; - -@Data -public class Graph { - - /** - * 边缘 - */ - @Valid - @NotNull(message = "连线不能为空") - private List edges; - - /** - * 节点 - */ - @Valid - @NotNull(message = "节点不能为空") - @Size(min = 1, message = "节点不能为空") - private List nodes; -} diff --git a/src/main/java/com/metis/flow/domain/entity/config/node/DocumentExtractorNodeConfig.java b/src/main/java/com/metis/flow/domain/entity/config/node/DocumentExtractorNodeConfig.java deleted file mode 100644 index 76d1fc4..0000000 --- a/src/main/java/com/metis/flow/domain/entity/config/node/DocumentExtractorNodeConfig.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.metis.flow.domain.entity.config.node; - -import jakarta.validation.constraints.NotBlank; -import lombok.Data; - -@Data -public class DocumentExtractorNodeConfig { - - @NotBlank(message = "文件类型不能为空") - private String fileType; - -} diff --git a/src/main/java/com/metis/flow/domain/entity/config/node/StartNodeConfig.java b/src/main/java/com/metis/flow/domain/entity/config/node/StartNodeConfig.java deleted file mode 100644 index 685c1c4..0000000 --- a/src/main/java/com/metis/flow/domain/entity/config/node/StartNodeConfig.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.metis.flow.domain.entity.config.node; - -import com.metis.flow.domain.entity.base.NodeVariable; -import jakarta.validation.Valid; -import lombok.Data; - -import java.util.List; - -@Data -public class StartNodeConfig { - - - @Valid - private List variables; - - -} diff --git a/src/main/java/com/metis/flow/domain/entity/config/package-info.java b/src/main/java/com/metis/flow/domain/entity/config/package-info.java deleted file mode 100644 index a2ccdb1..0000000 --- a/src/main/java/com/metis/flow/domain/entity/config/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package com.metis.flow.domain.entity.config; \ No newline at end of file diff --git a/src/main/java/com/metis/flow/engine/impl/AppFlowEngineRunnerServiceImpl.java b/src/main/java/com/metis/flow/engine/impl/AppFlowEngineRunnerServiceImpl.java deleted file mode 100644 index ff00289..0000000 --- a/src/main/java/com/metis/flow/engine/impl/AppFlowEngineRunnerServiceImpl.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.metis.flow.engine.impl; - -import cn.hutool.core.lang.Assert; -import cn.hutool.core.util.IdUtil; -import cn.hutool.core.util.ObjectUtil; -import com.metis.flow.domain.bo.Graph; -import com.metis.flow.domain.context.RunningContext; -import com.metis.flow.domain.context.RunningResult; -import com.metis.flow.domain.context.SysContext; -import com.metis.flow.domain.entity.App; -import com.metis.flow.domain.entity.base.Edge; -import com.metis.flow.domain.entity.base.Node; -import com.metis.flow.engine.AppEngineService; -import com.metis.flow.engine.AppFlowEngineRunnerService; -import com.metis.flow.enums.NodeType; -import com.metis.flow.runner.FlowRunningContext; -import com.metis.flow.runner.NodeRunner; -import com.metis.flow.runner.RunnerResult; -import com.metis.flow.runner.factory.RunnerFactory; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - -@Slf4j -@Service -@RequiredArgsConstructor -public class AppFlowEngineRunnerServiceImpl implements AppFlowEngineRunnerService { - - private final AppEngineService appEngineService; - - - @Override - public RunnerResult running(FlowRunningContext context) { - App app = getApp(context); - // todo 构建运行实例, 并将运行实例放入上下文 - - Long instanceId = IdUtil.getSnowflakeNextId(); - // 构建系统上下文信息 - SysContext sysContext = SysContext.builder() - .files(context.getFiles()) - .appId(app.getId()) - .workflowId(app.getWorkflowId()) - .instanceId(instanceId) - .build(); - // 构建运行中上下文 - RunningContext runningContext = RunningContext.buildContext(sysContext, context); - // 构建节点映射对象 - Graph graph = app.getGraph(); - Map nodeMap = graph.getNodes().stream() - .collect(Collectors.toMap(Node::getId, Function.identity())); - Map> edgeMap = graph.getEdges().stream() - .collect(Collectors.groupingBy(Edge::getSource)); - // 获取到开始节点 - Node runningNode = graph.getNodes().stream().filter(node -> node.getType() == NodeType.START) - .findFirst().orElse(null); - // 开始节点为空,则表示数据存在异常 - Assert.isTrue(ObjectUtil.isNotNull(runningNode), "流程图不存在开始节点"); - while (ObjectUtil.isNotNull(runningNode)) { - NodeRunner nodeRunner = RunnerFactory.get(runningNode.getType()); - // 获取到返回结果 - RunningResult result = nodeRunner.run(runningContext, runningNode, edgeMap.get(runningNode.getId())); - if (ObjectUtil.isNotNull(result.getNodeContext())) { - runningContext.addNodeRunningContext(runningNode.getId(), result.getNodeContext()); - } - runningNode = null; - } - - - return RunnerResult.builder() - .content("你他妈的!") - .context(sysContext) - .build(); - - } - - - /** - * 获取到应用程序信息 - * - * @param context 上下文 - * @return {@link App } - */ - private App getApp(FlowRunningContext context) { - if (ObjectUtil.isNotNull(context.getWorkflowId())) { - return appEngineService.getByWorkflowId(context.getWorkflowId()); - } - return appEngineService.getByAppId(context.getAppId()); - } -} diff --git a/src/main/java/com/metis/flow/runner/NodeRunner.java b/src/main/java/com/metis/flow/runner/NodeRunner.java deleted file mode 100644 index 855a7f7..0000000 --- a/src/main/java/com/metis/flow/runner/NodeRunner.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.metis.flow.runner; - -import com.metis.flow.domain.context.RunningContext; -import com.metis.flow.domain.context.RunningResult; -import com.metis.flow.domain.entity.base.Edge; -import com.metis.flow.domain.entity.base.Node; -import com.metis.flow.enums.NodeType; - -import java.util.List; - -public interface NodeRunner { - - - /** - * 运行 - * - * @param context 上下文 - * @param node 节点配置信息 - * @param edges - * @return {@link RunningContext } - */ - RunningResult run(RunningContext context, Node node, List edges); - - - /** - * 获取节点类型 - * - * @return {@link NodeType } - */ - NodeType getType(); - -} diff --git a/src/main/java/com/metis/flow/runner/factory/RunnerFactory.java b/src/main/java/com/metis/flow/runner/factory/RunnerFactory.java deleted file mode 100644 index 3a71a82..0000000 --- a/src/main/java/com/metis/flow/runner/factory/RunnerFactory.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.metis.flow.runner.factory; - -import com.metis.flow.enums.NodeType; -import com.metis.flow.runner.NodeRunner; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -public class RunnerFactory { - - private static final Map MAP = new ConcurrentHashMap<>(8); - - - /** - * 注册 - * - * @param runner 跑步者 - */ - public static void register(NodeRunner runner) { - MAP.put(runner.getType(), runner); - } - - - /** - * 得到 - * - * @param type 类型 - * @return {@link NodeRunner } - */ - public static NodeRunner get(NodeType type) { - return MAP.get(type); - } - - - -} diff --git a/src/main/java/com/metis/flow/runner/impl/EndNodeRunner.java b/src/main/java/com/metis/flow/runner/impl/EndNodeRunner.java deleted file mode 100644 index 8b252c3..0000000 --- a/src/main/java/com/metis/flow/runner/impl/EndNodeRunner.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.metis.flow.runner.impl; - - -import com.metis.flow.domain.context.RunningContext; -import com.metis.flow.domain.context.RunningResult; -import com.metis.flow.domain.entity.base.Edge; -import com.metis.flow.domain.entity.base.Node; -import com.metis.flow.enums.NodeType; -import com.metis.flow.runner.NodeRunner; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import java.util.List; - -@Slf4j -@Service -public class EndNodeRunner implements NodeRunner { - - @Override - public RunningResult run(RunningContext context, Node node, List edges) { - return RunningResult.buildResult(); - } - - @Override - public NodeType getType() { - return NodeType.END; - } - -} diff --git a/src/main/java/com/metis/flow/validator/ValidatorInitialize.java b/src/main/java/com/metis/flow/validator/ValidatorInitialize.java deleted file mode 100644 index 7201eb7..0000000 --- a/src/main/java/com/metis/flow/validator/ValidatorInitialize.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.metis.flow.validator; - - -import com.metis.flow.validator.factory.EdgeValidatorFactory; -import com.metis.flow.validator.factory.NodeValidatorFactory; -import org.jetbrains.annotations.NotNull; -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.stereotype.Service; - -import java.util.Map; - -@Service -public class ValidatorInitialize implements ApplicationContextAware { - - - @Override - public void setApplicationContext(@NotNull ApplicationContext applicationContext) throws BeansException { - Map edgeMap = applicationContext.getBeansOfType(EdgeValidator.class); - - edgeMap.forEach((k, v) -> { - EdgeValidatorFactory.register(v); - }); - - - Map nodeMap = applicationContext.getBeansOfType(NodeValidator.class); - nodeMap.forEach((k, v) -> { - NodeValidatorFactory.register(v); - }); - } - - -} diff --git a/src/main/java/com/metis/flow/validator/factory/NodeValidatorFactory.java b/src/main/java/com/metis/flow/validator/factory/NodeValidatorFactory.java deleted file mode 100644 index ac00792..0000000 --- a/src/main/java/com/metis/flow/validator/factory/NodeValidatorFactory.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.metis.flow.validator.factory; - -import com.metis.flow.enums.NodeType; -import com.metis.flow.validator.NodeValidator; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - - -public class NodeValidatorFactory { - - private static final Map MAP = new ConcurrentHashMap<>(8); - - /** - * 注册 - * - * @param validator 验证器 - */ - public static void register(NodeValidator validator) { - MAP.put(validator.getType(), validator); - } - - /** - * 得到 - * - * @param type 类型 - * @return {@link NodeValidator } - */ - public static NodeValidator get(NodeType type) { - return MAP.get(type); - } - - -} diff --git a/src/main/resources/json/test.json b/src/main/resources/json/test.json deleted file mode 100644 index 00df0ea..0000000 --- a/src/main/resources/json/test.json +++ /dev/null @@ -1,152 +0,0 @@ - -{ - "id": 0, - "name": "测试流程", - "description": "测试流程", - "graph": { - "nodes": [ - { - "id": "5", - "type": "start", - "dimensions": { - "width": 300, - "height": 300 - }, - "draggable": true, - "resizing": false, - "selected": true, - "data": { - "label": "开始", - "toolbarPosition": "right", - "config": { - "variables": [ - { - "variable": "context", - "label": "段落", - "type": "paragraph", - "maxLength": 48, - "required": true - }, - { - "variable": "text", - "label": "文本", - "type": "text-input", - "maxLength": 48, - "required": true, - "options": [] - }, - { - "variable": "select", - "label": "下拉", - "type": "select", - "maxLength": 48, - "required": true, - "options": [ - { - "label": "选型1", - "value": "1" - }, - { - "label": "选型2", - "value": "2" - } - ] - }, - { - "variable": "number", - "label": "数字", - "type": "number", - "maxLength": 48, - "required": true, - "options": [] - }, - { - "variable": "singlefile", - "label": "singlefile单文件", - "type": "file", - "maxLength": 48, - "required": true, - "options": [], - "allowedFileUploadMethods": [ - "local_file", - "remote_url" - ], - "allowedFileTypes": [ - "image", - "document", - "audio", - "video" - ], - "allowedFileExtensions": [] - }, - { - "variable": "mufile", - "label": "多文件", - "type": "file-list", - "maxLength": 5, - "required": true, - "options": [], - "allowedFileUploadMethods": [ - "local_file" - ], - "allowedFileTypes": [ - "custom" - ], - "allowedFileExtensions": [ - "docx", - "aaa" - ] - } - ], - "parent": "234" - }, - "handles": [ - { - "id": "7", - "position": "right", - "type": "source", - "connectable": true - } - ] - }, - "position": { "x": 0, "y": 300 } - }, - { - "id": "6", - "type": "end", - "selected": false, - "data": { - "label": "结束", - "toolbarPosition": "right", - "handles": [ - { - "id": "8", - "position": "left", - "type": "target", - "connectable": true - } - ] - }, - "position": { "x": 500, "y": 300 } - } - ], - "edges": [ - { - "id": "6", - "type": "default", - "source": "5", - "target": "6", - "sourceHandle": "7", - "animated": true, - "targetHandle": "8", - "label": "线标签", - "markerEnd": "none", - "markerStart": "none", - "updatable": true, - "selectable": true, - "deletable": true - } - ] - } - -} \ No newline at end of file diff --git a/src/test/java/AnsMsgHandler.java b/src/test/java/AnsMsgHandler.java deleted file mode 100644 index 8d79f62..0000000 --- a/src/test/java/AnsMsgHandler.java +++ /dev/null @@ -1,8 +0,0 @@ - -import java.io.InputStream; - -public interface AnsMsgHandler { - - void actMsg(InputStream is, String line); - -} diff --git a/src/test/java/SSeTest.java b/src/test/java/SSeTest.java deleted file mode 100644 index 63f3d19..0000000 --- a/src/test/java/SSeTest.java +++ /dev/null @@ -1,27 +0,0 @@ -import com.fasterxml.jackson.core.JsonProcessingException; -import com.metis.sseclient.check.SseCheck; -import dev.langchain4j.agent.tool.ToolSpecification; -import dev.langchain4j.mcp.client.DefaultMcpClient; -import dev.langchain4j.mcp.client.transport.McpTransport; -import dev.langchain4j.mcp.client.transport.http.HttpMcpTransport; -import lombok.extern.slf4j.Slf4j; - -import java.util.List; - - -@Slf4j -public class SSeTest { - public static void main(String[] args) throws JsonProcessingException { - McpTransport transport = new HttpMcpTransport.Builder() - .sseUrl("http://localhost:8081/sse") - .build(); - new DefaultMcpClient.Builder() - .transport(transport) - .build() - .listTools(); - - SseCheck sseCheck = new SseCheck("http://localhost:8081/sse"); - List listTools = sseCheck.listTools(); - System.out.println(listTools); - } -} diff --git a/src/test/java/SseClient.java b/src/test/java/SseClient.java deleted file mode 100644 index b3615f6..0000000 --- a/src/test/java/SseClient.java +++ /dev/null @@ -1,77 +0,0 @@ - -import java.io.BufferedInputStream; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; - -/** - * - * @author hyd - * - */ -public class SseClient { - - /** - * 获取SSE输入流。 - * - * @param urlPath - * @return - * @throws IOException - */ - public static InputStream getSseInputStream(String urlPath) throws IOException { - URL url = new URL(urlPath); - HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); - // 这儿根据自己的情况选择get或post - urlConnection.setRequestMethod("GET"); - urlConnection.setDoOutput(true); - urlConnection.setDoInput(true); - urlConnection.setUseCaches(false); - urlConnection.setRequestProperty("Connection", "Keep-Alive"); - urlConnection.setRequestProperty("Charset", "UTF-8"); - //读取过期时间(很重要,建议加上) - urlConnection.setReadTimeout(60 * 1000); - // text/plain模式 - urlConnection.setRequestProperty("Content-Type", "text/plain; charset=UTF-8"); - InputStream inputStream = urlConnection.getInputStream(); - InputStream is = new BufferedInputStream(inputStream); - return is; - } - - /** - * 读取数据。 - * - * @param is - * @param ansMsgHandler - * @throws IOException - */ - public static void readStream(InputStream is, AnsMsgHandler ansMsgHandler) throws IOException { - try { - BufferedReader reader = new BufferedReader(new InputStreamReader(is)); - String line = ""; - while ((line = reader.readLine()) != null) { - // 处理数据接口 - ansMsgHandler.actMsg(is, line); - } - // 当服务器端主动关闭的时候,客户端无法获取到信号。现在还不清楚原因。所以无法执行的此处。 - reader.close(); - } catch (IOException e) { - e.printStackTrace(); - throw new IOException("关闭数据流!"); - } - } - - public static void main(String[] args) throws IOException { - String urlPath = "http://localhost:8081/sse"; - InputStream inputStream = getSseInputStream(urlPath); - readStream(inputStream, new AnsMsgHandler() { - - public void actMsg(InputStream is, String line) { - System.out.println(line); - } - }); - } - -}