diff --git "a/magic-api-plugins/magic-api-plugin-nebula/nebula\346\217\222\344\273\266.md" "b/magic-api-plugins/magic-api-plugin-nebula/nebula\346\217\222\344\273\266.md"
new file mode 100644
index 0000000000000000000000000000000000000000..62317085e299a444334fefe0770a800a67593f3c
--- /dev/null
+++ "b/magic-api-plugins/magic-api-plugin-nebula/nebula\346\217\222\344\273\266.md"
@@ -0,0 +1,99 @@
+---
+title: nebula插件
+date: 2023-08-16 09:16:55
+---
+
+### 引入依赖
+
+```xml
+
+
+ org.ssssssss
+ magic-api-plugin-nebula
+ magic-api-lastest-version
+
+```
+
+### 配置
+
+```yml
+nebula:
+ hostAddress: ${NEBULA_HOSTADDRESS:localhost:9669}
+ userName: ${NEBULA_USERNAME:root}
+ password: ${NEBULA_PASSWORD:nebula}
+
+```
+
+### 使用
+
+```js
+import nebula;
+var ngsl =
+ """"
+ USE db_name;MATCH p_=(p:`assignee`)-[*3]-(p2:`transferor`) where id(p2) == "阿里巴巴" or id(p)== "阿里巴巴" RETURN p_ limit 1000'
+ """
+var resultJson = nebula.executeJson(ngsl)
+nebula.convert(resultJson)
+
+
+nebula.executeNebulaModel(ngsl)
+
+其他支持的方法不太常用, 这里不再一一列举, 可参考源码
+org.ssssssss.magicapi.nebula.NebulaModule
+```
+
+#### 返回的数据格式为:
+```
+ 该结构的数据可被很多前端组件库支持进行可视化展示
+```
+如: [angv G6](http://antv-2018.alipay.com/zh-cn/g6/3.x/demo/index.html)
+
+
+```json
+{
+ "code": 0,
+ "message": "success",
+ "data": {
+ "nodes": [
+ {
+ "edgeSize": 1,
+ "assignee.name": "中航纽赫融资租赁(上海)有限公司",
+ "type": "vertex",
+ "assignee.addr": "上海市中国(上海)自由贸易试验区正定路530号A5库区集中辅助区三层318室",
+ "assignee.legal_person": "周勇",
+ "registrant.addr": "上海市浦东新区南泉路1261号",
+ "registrant.name": "中航国际租赁有限公司",
+ "id": "中航纽赫融资租赁(上海)有限公司",
+ "assignee.type": "企业"
+ },
+ {
+ "edgeSize": 15,
+ "type": "vertex",
+ "transferor.name": "陕西海富融资租赁有限公司",
+ "transferor.legal_person": "刘子瑜",
+ "transferor.type": "企业",
+ "transferor.addr": "陕西省西安市西安经济技术开发区未央路170号赛高城市广场2号楼企业总部大厦26层05单元",
+ "registrant.addr": "广东省深圳市前海深港合作区南山街道梦海大厦5035号前海华润金融中心T5写字楼1808",
+ "registrant.name": "深圳前海盈峰商业保理有限公司",
+ "id": "陕西海富融资租赁有限公司"
+ }, ...
+ ],
+ "edges": [
+ {
+ "dst": "陕西海富融资租赁有限公司",
+ "src": "中航纽赫融资租赁(上海)有限公司",
+ "source": "中航纽赫融资租赁(上海)有限公司",
+ "label": "trans_with",
+ "type": "edge",
+ "target": "陕西海富融资租赁有限公司",
+ "name": "trans_with",
+ "ranking": 0,
+ "value": 0
+ },...
+ ]
+ },
+ "timestamp": 1692149280167,
+ "requestTime": 1692149280143,
+ "executeTime": 24
+}
+```
\ No newline at end of file
diff --git a/magic-api-plugins/magic-api-plugin-nebula/pom.xml b/magic-api-plugins/magic-api-plugin-nebula/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..43e906d013bf7dd3023e6ab4ed0af49014edd248
--- /dev/null
+++ b/magic-api-plugins/magic-api-plugin-nebula/pom.xml
@@ -0,0 +1,33 @@
+
+ 4.0.0
+
+ org.ssssssss
+ magic-api-plugins
+ 2.1.1
+
+
+ magic-api-plugin-nebula
+ jar
+
+ magic-api-plugin-nebula
+
+
+ UTF-8
+ 3.5.0
+
+
+
+
+ com.vesoft
+ client
+ ${vesoft.version}
+
+
+ guava
+ com.google.guava
+
+
+
+
+
diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/MagicNebulaConfiguration.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/MagicNebulaConfiguration.java
new file mode 100644
index 0000000000000000000000000000000000000000..6837fb39f20f775dce9d06f18e4c057d49b3e755
--- /dev/null
+++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/MagicNebulaConfiguration.java
@@ -0,0 +1,104 @@
+package org.ssssssss.magicapi.nebula;
+
+
+import com.vesoft.nebula.client.graph.NebulaPoolConfig;
+import com.vesoft.nebula.client.graph.data.HostAddress;
+import com.vesoft.nebula.client.graph.net.NebulaPool;
+import com.vesoft.nebula.client.graph.net.Session;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.ssssssss.magicapi.core.config.MagicAPIProperties;
+import org.ssssssss.magicapi.core.config.MagicPluginConfiguration;
+import org.ssssssss.magicapi.core.model.Plugin;
+import org.ssssssss.magicapi.utils.Assert;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * Nebula自动配置类
+ */
+
+@Configuration
+@EnableConfigurationProperties(NebulaPoolProperties.class)
+public class MagicNebulaConfiguration implements MagicPluginConfiguration {
+ private static final Logger logger = LoggerFactory.getLogger(MagicNebulaConfiguration.class);
+
+ private NebulaPoolProperties nebulaPoolProperties;
+
+ private final MagicAPIProperties properties;
+
+ public MagicNebulaConfiguration(MagicAPIProperties properties, NebulaPoolProperties nebulaPoolProperties) {
+ this.properties = properties;
+ this.nebulaPoolProperties = nebulaPoolProperties;
+ }
+
+ /**
+ * 创建nebula pool
+ * @param nebulaPoolProperties
+ * @return
+ */
+ @Bean
+ public NebulaPool nebulaPool(@Autowired NebulaPoolProperties nebulaPoolProperties) {
+ Session session = null;
+ try {
+
+ NebulaPoolConfig nebulaPoolConfig = buildNebulaPoolConfig(nebulaPoolProperties);
+ Assert.isNotBlank(nebulaPoolProperties.getHostAddress(), "nebula.hostAddress 不能为空, 格式为 ip:port,ip:port 配置多个地址用逗号分隔");
+ String[] hostAddress = nebulaPoolProperties.getHostAddress().split(",");
+ List addresses = Arrays.stream(hostAddress).map(address -> {
+ String[] ipAndPort = address.split(":");
+ Assert.isTrue(ipAndPort.length == 2, "nebula.hostAddress 格式错误, 格式为 ip:port,ip:port 配置多个地址用逗号分隔");
+ return new HostAddress(ipAndPort[0], Integer.parseInt(ipAndPort[1]));
+ }).collect(Collectors.toList());
+
+ NebulaPool pool = new NebulaPool();
+ pool.init(addresses, nebulaPoolConfig);
+ session = pool.getSession(nebulaPoolProperties.getUserName(), nebulaPoolProperties.getPassword(), nebulaPoolProperties.isReconnect());
+ return pool;
+ } catch (Exception e) {
+ logger.error("初始化nebula pool 异常", e);
+ throw new RuntimeException(e);
+ } finally {
+ logger.info("初始化nebula pool 完成");
+ Optional.ofNullable(session).ifPresent(Session::release);
+ }
+ }
+
+ /**
+ * 注入模块
+ * @return
+ */
+ @Bean
+ public NebulaModule nebulaModule() {
+ return new NebulaModule();
+ }
+
+ @Override
+ public Plugin plugin() {
+ return new Plugin("Nebula");
+ }
+
+
+ public NebulaPoolConfig buildNebulaPoolConfig(NebulaPoolProperties nebulaPoolProperties) {
+
+ NebulaPoolConfig nebulaPoolConfig = new NebulaPoolConfig();
+ //将nebulaPoolProperties的同名属性赋值到nebulaPoolConfig
+ nebulaPoolConfig.setMinConnSize(nebulaPoolProperties.getMinConnsSize());
+ nebulaPoolConfig.setSslParam(nebulaPoolProperties.getSslParam());
+ nebulaPoolConfig.setWaitTime(nebulaPoolProperties.getWaitTime());
+ nebulaPoolConfig.setTimeout(nebulaPoolProperties.getTimeout());
+ nebulaPoolConfig.setMaxConnSize(nebulaPoolProperties.getMaxConnsSize());
+ nebulaPoolConfig.setIntervalIdle(nebulaPoolProperties.getIntervalIdle());
+ nebulaPoolConfig.setMinClusterHealthRate(nebulaPoolProperties.getMinClusterHealthRate());
+ nebulaPoolConfig.setIdleTime(nebulaPoolProperties.getIdleTime());
+ nebulaPoolConfig.setEnableSsl(nebulaPoolProperties.isEnableSsl());
+ return nebulaPoolConfig;
+ }
+}
diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/NebulaModule.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/NebulaModule.java
new file mode 100644
index 0000000000000000000000000000000000000000..4d3aa3face6ddcbfee0c297fbb8fa6ff8ba93440
--- /dev/null
+++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/NebulaModule.java
@@ -0,0 +1,157 @@
+package org.ssssssss.magicapi.nebula;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.vesoft.nebula.client.graph.data.ResultSet;
+import com.vesoft.nebula.client.graph.net.NebulaPool;
+import com.vesoft.nebula.client.graph.net.Session;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.ssssssss.magicapi.core.annotation.MagicModule;
+import org.ssssssss.magicapi.nebula.model.Edge;
+import org.ssssssss.magicapi.nebula.model.NebulaModel;
+import org.ssssssss.magicapi.nebula.model.Node;
+import org.ssssssss.magicapi.nebula.response.*;
+import org.ssssssss.script.annotation.Comment;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Optional;
+
+
+@MagicModule("nebula")
+public class NebulaModule {
+
+ @Autowired
+ private NebulaPool nebulaPool;
+
+ @Autowired
+ private NebulaPoolProperties nebulaPoolProperties;
+
+ private static final Logger logger = LoggerFactory.getLogger(NebulaModule.class);
+
+
+ /**
+ * 执行ngsl脚本, 返回json格式结果
+ *
+ * @param script
+ * @return
+ */
+ @Comment("执行ngsl脚本, 返回json格式结果")
+ public Object executeJson(String script) {
+ Session session = getNebulaSession();
+ try {
+ String json = session.executeJson(script);
+ return json;
+ } catch (Exception e) {
+ logger.error("执行Nebula脚本异常, script: {}", script, e);
+ throw new RuntimeException(e);
+ } finally {
+ Optional.ofNullable(session).ifPresent(Session::release);
+ }
+ }
+
+
+ /**
+ * 执行ngsl脚本, 并解析为可视化格式
+ *
+ * @param script
+ * @return
+ */
+ @Comment("执行ngsl脚本, 返回json格式结果, 并解析为可视化格式")
+ public NebulaModel executeNebulaModel(String script) {
+ Session session = getNebulaSession();
+ try {
+ String json = session.executeJson(script);
+ return convert(json);
+ } catch (Exception e) {
+ logger.error("执行Nebula脚本异常, script: {}", script, e);
+ throw new RuntimeException(e);
+ } finally {
+ Optional.ofNullable(session).ifPresent(Session::release);
+ }
+ }
+
+
+ /**
+ * 执行ngsl脚本, 返回ResultSet格式结果, 不可直接使用
+ *
+ * @param script
+ * @return
+ */
+ @Comment("执行ngsl脚本, 返回ResultSet格式结果, 无法直接使用")
+ public Object execute(String script) {
+ Session session = getNebulaSession();
+ try {
+ ResultSet resultSet = session.execute(script);
+ return resultSet;
+ } catch (Exception e) {
+ logger.error("执行Nebula脚本异常, script: {}", script, e);
+ throw new RuntimeException(e);
+ } finally {
+ Optional.ofNullable(session).ifPresent(Session::release);
+ }
+ }
+
+ public Session getNebulaSession() {
+ try {
+ return nebulaPool.getSession(nebulaPoolProperties.getUserName(), nebulaPoolProperties.getPassword(), nebulaPoolProperties.isReconnect());
+ } catch (NoSuchBeanDefinitionException e) {
+ throw new RuntimeException(String.format("NebulaPool 未初始化, 或初始化异常, 请检查配置文件"));
+ } catch (Exception e) {
+ logger.error("获取nebula session 异常", e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Comment("解析nebula结果为可视化格式")
+ public NebulaModel convert(String json) throws Exception {
+ ObjectMapper objectMapper = new ObjectMapper();
+ NebulaJsonBody response = objectMapper.readValue(json, NebulaJsonBody.class);
+
+ //状态码不为0则为异常, 解析提示异常信息
+ if (response.getErrorCode() != 0) {
+ logger.error("执行Nebula脚本异常, script: {}, errorMsg: {}", json, response.getErrorMsg());
+ throw new RuntimeException(response.getErrorMsg());
+ }
+
+ NebulaModel nebulaModel = new NebulaModel();
+ HashMap nodeEdges = new HashMap<>();
+ List datas = response.getResults().get(0).getData();
+ for (int index = 0; index < datas.size(); index++) {
+ List> meta = datas.get(index).getMeta();
+ List>> row = datas.get(index).getRow();
+ for (int i = 0; i < meta.get(0).size(); i++) {
+ Element element = meta.get(0).get(i);
+ HashMap elementDetail = row.get(0).get(i);
+ Node node = new Node();
+ Edge edge = new Edge();
+
+ if (element instanceof Vertex) {
+ node.setId(((Vertex) element).getId());
+ node.getProp().putAll(elementDetail);
+ nebulaModel.addNode(node);
+
+ } else if (element instanceof EdgeElement) {
+ edge.getProp().putAll(elementDetail);
+ EdgeId id = ((EdgeElement) element).getId();
+ edge.setTarget(id.getDst());
+ edge.setSource(id.getSrc());
+ edge.setLabel(id.getName());
+ edge.setValue(id.getRanking());
+ nebulaModel.getEdges().add(edge);
+
+ nodeEdges.put(id.getDst(), nodeEdges.getOrDefault(id.getDst(), 0) + 1);
+ nodeEdges.put(id.getSrc(), nodeEdges.getOrDefault(id.getSrc(), 0) + 1);
+ }
+ }
+ // 补充节点边的数量值
+ for (Node node : nebulaModel.getNodes()) {
+ node.setEdgeSize(nodeEdges.getOrDefault(node.getId(), 0));
+ }
+ }
+ return nebulaModel;
+ }
+
+}
diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/NebulaPoolProperties.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/NebulaPoolProperties.java
new file mode 100644
index 0000000000000000000000000000000000000000..7f4c28a294ec306ca6387cbd2a3135cc7910b98a
--- /dev/null
+++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/NebulaPoolProperties.java
@@ -0,0 +1,141 @@
+package org.ssssssss.magicapi.nebula;
+
+import com.vesoft.nebula.client.graph.data.SSLParam;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+
+@ConfigurationProperties(prefix = "nebula")
+public class NebulaPoolProperties {
+
+ /** nebula 服务地址, 多个则逗号分割, 格式为 ip:port */
+ private String hostAddress;
+ /** nebula 用户名 */
+ private String userName;
+ /** nebula 密码 */
+ private String password;
+
+ private boolean reconnect = true;
+ /** nebula 连接池最小连接数 */
+ private int minConnsSize = 0;
+ /** nebula 连接池最大连接数 */
+ private int maxConnsSize = 10;
+ /** nebula 连接池最大等待时间 */
+ private int timeout = 0;
+ /** nebula 连接池空闲时间 */
+ private int idleTime = 0;
+ /** nebula 连接池心跳间隔 */
+ private int intervalIdle = -1;
+
+ private int waitTime = 0;
+
+ private double minClusterHealthRate = 1.0;
+
+ private boolean enableSsl = false;
+
+ private SSLParam sslParam = null;
+
+ public String getHostAddress() {
+ return hostAddress;
+ }
+
+ public void setHostAddress(String hostAddress) {
+ this.hostAddress = hostAddress;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public boolean isReconnect() {
+ return reconnect;
+ }
+
+ public void setReconnect(boolean reconnect) {
+ this.reconnect = reconnect;
+ }
+
+ public int getMinConnsSize() {
+ return minConnsSize;
+ }
+
+ public void setMinConnsSize(int minConnsSize) {
+ this.minConnsSize = minConnsSize;
+ }
+
+ public int getMaxConnsSize() {
+ return maxConnsSize;
+ }
+
+ public void setMaxConnsSize(int maxConnsSize) {
+ this.maxConnsSize = maxConnsSize;
+ }
+
+ public int getTimeout() {
+ return timeout;
+ }
+
+ public void setTimeout(int timeout) {
+ this.timeout = timeout;
+ }
+
+ public int getIdleTime() {
+ return idleTime;
+ }
+
+ public void setIdleTime(int idleTime) {
+ this.idleTime = idleTime;
+ }
+
+ public int getIntervalIdle() {
+ return intervalIdle;
+ }
+
+ public void setIntervalIdle(int intervalIdle) {
+ this.intervalIdle = intervalIdle;
+ }
+
+ public int getWaitTime() {
+ return waitTime;
+ }
+
+ public void setWaitTime(int waitTime) {
+ this.waitTime = waitTime;
+ }
+
+ public double getMinClusterHealthRate() {
+ return minClusterHealthRate;
+ }
+
+ public void setMinClusterHealthRate(double minClusterHealthRate) {
+ this.minClusterHealthRate = minClusterHealthRate;
+ }
+
+ public boolean isEnableSsl() {
+ return enableSsl;
+ }
+
+ public void setEnableSsl(boolean enableSsl) {
+ this.enableSsl = enableSsl;
+ }
+
+ public SSLParam getSslParam() {
+ return sslParam;
+ }
+
+ public void setSslParam(SSLParam sslParam) {
+ this.sslParam = sslParam;
+ }
+}
diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/model/Edge.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/model/Edge.java
new file mode 100644
index 0000000000000000000000000000000000000000..8ef9b90e63df8d629d2fd2d8634c1c7e69687586
--- /dev/null
+++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/model/Edge.java
@@ -0,0 +1,69 @@
+package org.ssssssss.magicapi.nebula.model;
+
+import java.util.HashMap;
+
+/**
+ * 描述node的方向的边
+ */
+public class Edge {
+
+ /**
+ * 起始节点的id
+ */
+ private String source;
+
+ /**
+ * 终止节点的id
+ */
+ private String target;
+
+ /**
+ * 边描述
+ */
+ private String label;
+
+
+ private String value;
+
+ private HashMap prop = new HashMap<>();
+
+ public String getSource() {
+ return source;
+ }
+
+ public void setSource(String source) {
+ this.source = source;
+ }
+
+ public String getTarget() {
+ return target;
+ }
+
+ public void setTarget(String target) {
+ this.target = target;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public HashMap getProp() {
+ return prop;
+ }
+
+ public void setProp(HashMap prop) {
+ this.prop = prop;
+ }
+}
diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/model/NebulaModel.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/model/NebulaModel.java
new file mode 100644
index 0000000000000000000000000000000000000000..72d9a38e0a044d2892ddf85973ac9d014c78cc79
--- /dev/null
+++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/model/NebulaModel.java
@@ -0,0 +1,69 @@
+package org.ssssssss.magicapi.nebula.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.ssssssss.script.annotation.Comment;
+
+import java.util.*;
+
+/**
+ * 经过加工后的nebula数据结构, 用于前端数据展示
+ * 目前很多前端组件库支持这种数据, 并可视化展示, 如ntV G6等
+ * @see AntV G6
+ */
+public class NebulaModel {
+
+ @JsonIgnore
+ private List nodeIds = new ArrayList<>();
+
+ /**
+ * 包含的节点集合
+ */
+ @Comment("包含的节点集合")
+ private List nodes = new ArrayList<>();
+
+ /**
+ * 包含的边集合
+ */
+
+ @Comment("包含的边集合")
+ private List edges = new ArrayList<>();
+
+ public List getNodeIds() {
+ return nodeIds;
+ }
+
+ public void setNodeIds(List nodeIds) {
+ this.nodeIds = nodeIds;
+ }
+
+ public List getNodes() {
+ return nodes;
+ }
+
+ public void setNodes(List nodes) {
+ this.nodes = nodes;
+ }
+
+ public List getEdges() {
+ return edges;
+ }
+
+ public void setEdges(List edges) {
+ this.edges = edges;
+ }
+
+ /**
+ * 添加节点, 根据id去重
+ * @param node
+ */
+ @Comment("添加节点, 根据id去重")
+ public void addNode(Node node) {
+ String nodeId = Objects.toString(node.getId(), null);
+ if (nodeIds.contains(nodeId)) {
+ return;
+ }
+ nodeIds.add(nodeId);
+ nodes.add(node);
+ }
+
+}
\ No newline at end of file
diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/model/Node.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/model/Node.java
new file mode 100644
index 0000000000000000000000000000000000000000..7faf2b5480e9024065531f7c9a06542fd55dc4ca
--- /dev/null
+++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/model/Node.java
@@ -0,0 +1,36 @@
+package org.ssssssss.magicapi.nebula.model;
+
+import java.util.HashMap;
+
+public class Node {
+
+ private String id;
+
+ private int EdgeSize;
+
+ private HashMap prop = new HashMap<>();
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public int getEdgeSize() {
+ return EdgeSize;
+ }
+
+ public void setEdgeSize(int edgeSize) {
+ EdgeSize = edgeSize;
+ }
+
+ public HashMap getProp() {
+ return prop;
+ }
+
+ public void setProp(HashMap prop) {
+ this.prop = prop;
+ }
+}
diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/EdgeElement.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/EdgeElement.java
new file mode 100644
index 0000000000000000000000000000000000000000..864dc6e89966f2f492a5d18fd537d9f3397863da
--- /dev/null
+++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/EdgeElement.java
@@ -0,0 +1,14 @@
+package org.ssssssss.magicapi.nebula.response;
+
+public class EdgeElement extends Element {
+
+ private EdgeId id;
+
+ public EdgeId getId() {
+ return id;
+ }
+
+ public void setId(EdgeId id) {
+ this.id = id;
+ }
+}
diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/EdgeId.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/EdgeId.java
new file mode 100644
index 0000000000000000000000000000000000000000..1c706278b509a4ab0ec300b17172bd6b28cf5e4c
--- /dev/null
+++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/EdgeId.java
@@ -0,0 +1,50 @@
+package org.ssssssss.magicapi.nebula.response;
+
+public class EdgeId {
+
+ private String ranking;
+ private String name;
+ private Integer type;
+ private String dst;
+ private String src;
+
+ public String getRanking() {
+ return ranking;
+ }
+
+ public void setRanking(String ranking) {
+ this.ranking = ranking;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Integer getType() {
+ return type;
+ }
+
+ public void setType(Integer type) {
+ this.type = type;
+ }
+
+ public String getDst() {
+ return dst;
+ }
+
+ public void setDst(String dst) {
+ this.dst = dst;
+ }
+
+ public String getSrc() {
+ return src;
+ }
+
+ public void setSrc(String src) {
+ this.src = src;
+ }
+}
diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/Element.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/Element.java
new file mode 100644
index 0000000000000000000000000000000000000000..69642344a5c26f07c73f7d4ef24fb724b758717d
--- /dev/null
+++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/Element.java
@@ -0,0 +1,26 @@
+package org.ssssssss.magicapi.nebula.response;
+
+import com.fasterxml.jackson.annotation.JsonSubTypes;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+
+@JsonTypeInfo(
+ use = JsonTypeInfo.Id.NAME,
+ property = "type")
+@JsonSubTypes(value = {
+ @JsonSubTypes.Type(value = EdgeElement.class, name = "edge"),
+ @JsonSubTypes.Type(value = Vertex.class, name = "vertex")
+})
+public abstract class Element {
+
+ protected String type;
+
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+}
diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/NebulaJsonBody.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/NebulaJsonBody.java
new file mode 100644
index 0000000000000000000000000000000000000000..03652c54316c7d11665e93a5b31c02024cc850d8
--- /dev/null
+++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/NebulaJsonBody.java
@@ -0,0 +1,132 @@
+package org.ssssssss.magicapi.nebula.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.HashMap;
+import java.util.List;
+
+public class NebulaJsonBody {
+ private List errors;
+ private List results;
+
+ public List getErrors() {
+ return errors;
+ }
+
+ public void setErrors(List errors) {
+ this.errors = errors;
+ }
+
+
+ public int getErrorCode() {
+ return this.errors.get(0).getCode();
+ }
+
+ public String getErrorMsg() {
+ return this.errors.get(0).getMessage();
+ }
+
+ public List getResults() {
+ return results;
+ }
+
+ public void setResults(List results) {
+ this.results = results;
+ }
+
+
+ public static class NebulaError {
+ private int code;
+ private String message;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+ }
+
+ public static class Result {
+ @JsonProperty("spaceName")
+ private String spaceName;
+ private List data;
+ private List columns;
+ private NebulaError errors;
+ @JsonProperty("latencyInUs")
+ private long latencyInUs;
+
+ public String getSpaceName() {
+ return spaceName;
+ }
+
+ public void setSpaceName(String spaceName) {
+ this.spaceName = spaceName;
+ }
+
+ public List getData() {
+ return data;
+ }
+
+ public void setData(List data) {
+ this.data = data;
+ }
+
+ public List getColumns() {
+ return columns;
+ }
+
+ public void setColumns(List columns) {
+ this.columns = columns;
+ }
+
+ public NebulaError getErrors() {
+ return errors;
+ }
+
+ public void setErrors(NebulaError errors) {
+ this.errors = errors;
+ }
+
+ public long getLatencyInUs() {
+ return latencyInUs;
+ }
+
+ public void setLatencyInUs(long latencyInUs) {
+ this.latencyInUs = latencyInUs;
+ }
+ }
+
+ public static class Data {
+ private List> meta;
+ private List>> row;
+
+ public List> getMeta() {
+ return meta;
+ }
+
+ public void setMeta(List> meta) {
+ this.meta = meta;
+ }
+
+ public List>> getRow() {
+ return row;
+ }
+
+ public void setRow(List>> row) {
+ this.row = row;
+ }
+ }
+}
+
+
+
diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/Vertex.java b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/Vertex.java
new file mode 100644
index 0000000000000000000000000000000000000000..43dbded6ef02e18dea5b20b0b12c185e8aff947b
--- /dev/null
+++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/java/org/ssssssss/magicapi/nebula/response/Vertex.java
@@ -0,0 +1,14 @@
+package org.ssssssss.magicapi.nebula.response;
+
+public class Vertex extends Element {
+
+ private String id;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+}
diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/resources/META-INF/spring.factories b/magic-api-plugins/magic-api-plugin-nebula/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000000000000000000000000000000000000..5c0648a4220c56f721e70d4911c69eead156ec43
--- /dev/null
+++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/resources/META-INF/spring.factories
@@ -0,0 +1 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.ssssssss.magicapi.nebula.MagicNebulaConfiguration
\ No newline at end of file
diff --git a/magic-api-plugins/magic-api-plugin-nebula/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/magic-api-plugins/magic-api-plugin-nebula/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 0000000000000000000000000000000000000000..e77bfd5fd58dd3dc52681078b8b6cbacdf057bfb
--- /dev/null
+++ b/magic-api-plugins/magic-api-plugin-nebula/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1 @@
+org.ssssssss.magicapi.nebula.MagicNebulaConfiguration
\ No newline at end of file
diff --git a/magic-api-plugins/magic-api-plugin-springdoc/src/main/java/org/ssssssss/magicapi/springdoc/MagicSpringDocConfiguration.java b/magic-api-plugins/magic-api-plugin-springdoc/src/main/java/org/ssssssss/magicapi/springdoc/MagicSpringDocConfiguration.java
index b071e758005161fba0ab841740216583760266aa..f370a02a6102ec98be105fca300b9af6d2caf506 100644
--- a/magic-api-plugins/magic-api-plugin-springdoc/src/main/java/org/ssssssss/magicapi/springdoc/MagicSpringDocConfiguration.java
+++ b/magic-api-plugins/magic-api-plugin-springdoc/src/main/java/org/ssssssss/magicapi/springdoc/MagicSpringDocConfiguration.java
@@ -87,7 +87,7 @@ public class MagicSpringDocConfiguration implements MagicPluginConfiguration {
} else {
urls = new HashSet<>(urls);
}
- urls.add(new SwaggerUrl(springDocConfig.getGroupName(), springDocConfig.getLocation(), null));
+ urls.add(new SwaggerUrl(springDocConfig.getGroupName(), servletContext.getContextPath() + springDocConfig.getLocation(), null));
params.put("urls", urls);
return params;
}
@@ -96,7 +96,6 @@ public class MagicSpringDocConfiguration implements MagicPluginConfiguration {
private void createSwaggerProvider(ObjectProvider requestMagicDynamicRegistryObjectProvider, MagicResourceService magicResourceService, ServletContext servletContext) throws NoSuchMethodException {
-
Mapping mapping = Mapping.create(requestMappingHandlerMapping);
RequestMappingInfo requestMappingInfo = mapping.paths(springDocConfig.getLocation()).build();
SwaggerEntity.License license = new SwaggerEntity.License("MIT", "https://gitee.com/ssssssss-team/magic-api/blob/master/LICENSE");
diff --git a/magic-api-plugins/magic-api-plugin-springdoc/src/main/java/org/ssssssss/magicapi/springdoc/entity/SwaggerProvider.java b/magic-api-plugins/magic-api-plugin-springdoc/src/main/java/org/ssssssss/magicapi/springdoc/entity/SwaggerProvider.java
index 7a69584eddcde712afff71bebcee8af7afff829e..f930fc0d59812ab4d5539e95ef4a649208eac703 100644
--- a/magic-api-plugins/magic-api-plugin-springdoc/src/main/java/org/ssssssss/magicapi/springdoc/entity/SwaggerProvider.java
+++ b/magic-api-plugins/magic-api-plugin-springdoc/src/main/java/org/ssssssss/magicapi/springdoc/entity/SwaggerProvider.java
@@ -4,10 +4,7 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.ResponseBody;
import org.ssssssss.magicapi.core.config.MagicConfiguration;
-import org.ssssssss.magicapi.core.model.ApiInfo;
-import org.ssssssss.magicapi.core.model.BaseDefinition;
-import org.ssssssss.magicapi.core.model.DataType;
-import org.ssssssss.magicapi.core.model.Path;
+import org.ssssssss.magicapi.core.model.*;
import org.ssssssss.magicapi.core.service.MagicResourceService;
import org.ssssssss.magicapi.core.service.impl.RequestMagicDynamicRegistry;
import org.ssssssss.magicapi.utils.JsonUtils;
@@ -73,7 +70,7 @@ public class SwaggerProvider {
swaggerEntity.addSecurity(securityMap);
for (ApiInfo info : infos) {
- String groupName = magicResourceService.getGroupName(info.getGroupId()).replace("/", "-");
+ String groupName = getRootGroupName(info.getGroupId());
String requestPath = PathUtils.replaceSlash(this.prefix + magicResourceService.getGroupPath(info.getGroupId()) + "/" + info.getPath());
SwaggerEntity.Path path = new SwaggerEntity.Path(info.getId());
path.addTag(groupName);
@@ -123,6 +120,14 @@ public class SwaggerProvider {
return swaggerEntity;
}
+ private String getRootGroupName(String groupId) {
+ Group group = magicResourceService.getGroup(groupId);
+ if (!Objects.equals(group.getParentId(), "0")) {
+ return getRootGroupName(group.getParentId());
+ }
+ return group.getName();
+ }
+
private List