Procházet zdrojové kódy

feat: 流水线构建初始化

370774330@qq.com před 5 roky
rodič
revize
93ccaca06e

+ 10 - 0
core/src/main/java/seecoder/devcloud/core/PipelineException.java

@@ -0,0 +1,10 @@
+package seecoder.devcloud.core;
+
+/**
+ * @author PuHong Weng
+ * @date 2021/3/10
+ * @description: 流水线模块出现的异常的包装
+ */
+public class PipelineException extends RuntimeException{
+    //todo exception
+}

+ 9 - 4
core/src/main/java/seecoder/devcloud/core/pipeline/Context.java

@@ -2,9 +2,11 @@ package seecoder.devcloud.core.pipeline;
 
 import lombok.Builder;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 import seecoder.devcloud.api.ApplicationProperties;
 
 import java.util.HashMap;
+import java.util.Map;
 
 /**
  * @author PuHong Weng
@@ -13,18 +15,20 @@ import java.util.HashMap;
  */
 @Data
 @Builder
+@NoArgsConstructor
 public class Context {
 
     private ApplicationProperties applicationProperties;
 
-    private String pipelineId;
+    private Integer pipelineId;
 
     private String pipelineName;
 
+
     /**
-     * 流水线所属小组
+     * 流水线所属namespace
      */
-    private String groupName;
+    private String namespace;
 
     /**
      * 项目名称
@@ -35,7 +39,8 @@ public class Context {
     /**
      * 用来存放一些杂项信息,根据key去取
      */
-    private HashMap<String, String> configs;
+    @Builder.Default
+    private Map<String, String> configs = new HashMap<>();
 
 
 }

+ 3 - 0
core/src/main/java/seecoder/devcloud/core/pipeline/Handler.java

@@ -1,5 +1,7 @@
 package seecoder.devcloud.core.pipeline;
 
+import seecoder.devcloud.core.pipeline.handler.AbstractHandler;
+
 /**
  * @author PuHong Weng
  * @date 2021/1/18
@@ -13,4 +15,5 @@ public interface Handler {
 
     void invokeNext(Context context);
 
+    void setNextHandler(Handler nextHandler);
 }

+ 11 - 2
core/src/main/java/seecoder/devcloud/core/pipeline/Pipeline.java

@@ -3,11 +3,20 @@ package seecoder.devcloud.core.pipeline;
 /**
  * @author PuHong Weng
  * @date 2021/1/18
- * @description:
+ * @description: pipeline实体
  */
 public interface Pipeline {
 
-    void init(PipelineConfig config);
     void start();
+
     Context getContext();
+
+    /**
+     * 用于方便用户给pipeline中context的config添加配置
+     */
+    default Context addContextConfig(String key, String value) {
+        Context context = getContext( );
+        context.getConfigs().put(key, value);
+        return context;
+    };
 }

+ 0 - 15
core/src/main/java/seecoder/devcloud/core/pipeline/PipelineConfig.java

@@ -1,15 +0,0 @@
-package seecoder.devcloud.core.pipeline;
-
-import lombok.Data;
-
-/**
- * @author PuHong Weng
- * @date 2021/2/2
- * @description:
- */
-@Data
-public class PipelineConfig {
-
-
-    private String configJson;
-}

+ 76 - 0
core/src/main/java/seecoder/devcloud/core/pipeline/PipelineFactory.java

@@ -0,0 +1,76 @@
+package seecoder.devcloud.core.pipeline;
+
+import seecoder.devcloud.core.pipeline.config.HandlerConfig;
+import seecoder.devcloud.core.pipeline.config.HandlerConfigTable;
+import seecoder.devcloud.core.pipeline.config.PipelineConfig;
+import seecoder.devcloud.core.pipeline.pipeline.PipelineImpl;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author PuHong Weng
+ * @date 2021/3/10
+ * @description:
+ */
+public class PipelineFactory {
+    /**
+     * 流水线初始化
+     * @param configJson configJson 流水线配置的json字符串
+     * @param namespace 流水线所属的namespace,需要用户自己指定,例如devcloud后端使用用户所属的groupName中作为namespace
+     * @param projectName 流水线所属的project,需要用户自己指定
+     * @param pipelineId 流水线标识符,需要用户自己指定
+     * @param pipelineName 流水线名称,需要用户自己指定
+     * @return
+     */
+    public static Pipeline init(String configJson, String namespace, String projectName, Integer pipelineId, String pipelineName) {
+
+        PipelineConfig pipelineConfig = PipelineConfig.init(configJson);
+
+        //初始化context
+        Context context = Context.builder()
+                .projectName(projectName)
+                .namespace(namespace)
+                .pipelineId(pipelineId)
+                .pipelineName(pipelineName)
+                .build();
+
+        Handler firstHandler = initHandlerChainAndContext(pipelineConfig,context.getConfigs());
+
+        return new PipelineImpl(firstHandler, context);
+    }
+
+    /**
+     * 根据 handlerConfig 构筑 Handler 的流水线,以及将配置属性统一放入 Context
+     * @param pipelineConfig 流水线配置
+     * @param configs 将此handler配置的所有config加入context中的config中
+     *                (所以这一步要避免配置的覆盖,即不要用相同名字的key)
+     * @return
+     */
+    private static Handler initHandlerChainAndContext(PipelineConfig pipelineConfig, Map<String,String> configs){
+        Handler firstHandler = null;
+        Handler currentHandler = null;
+
+        //转换成对应的Handler实例
+        List<HandlerConfig> handlerConfigs = pipelineConfig.getHandlerConfigs();
+
+
+        HandlerConfig firstHandlerConfig = handlerConfigs.get(0);
+        //todo 相同名字的key可能导致覆盖 这里应该抛出warning
+        configs.putAll(firstHandlerConfig.getConfigs());
+        firstHandler = HandlerConfigTable.transToHandler(firstHandlerConfig);
+        currentHandler = firstHandler;
+
+
+        for (int i = 1; i < handlerConfigs.size(); i++){
+            HandlerConfig nextHandlerConfig = handlerConfigs.get(i);
+            //todo 相同名字的key可能导致覆盖 这里应该抛出warning
+            configs.putAll(nextHandlerConfig.getConfigs());
+            Handler nextHandler = HandlerConfigTable.transToHandler(nextHandlerConfig);
+            currentHandler.setNextHandler(nextHandler);
+            currentHandler = nextHandler;
+        }
+
+        return firstHandler;
+    }
+}

+ 31 - 0
core/src/main/java/seecoder/devcloud/core/pipeline/config/HandlerConfig.java

@@ -0,0 +1,31 @@
+package seecoder.devcloud.core.pipeline.config;
+
+/**
+ * @author PuHong Weng
+ * @date 2021/3/10
+ * @description:
+ */
+
+import lombok.Builder;
+import lombok.Data;
+import seecoder.devcloud.core.pipeline.Handler;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 代表着pipeline的一个handler配置实体
+ */
+@Data
+@Builder
+public class HandlerConfig{
+
+    private String name;
+
+    /**
+     * 对应Handler的配置
+     */
+    @Builder.Default
+    private Map<String,String> configs = new HashMap<>();
+
+}

+ 40 - 0
core/src/main/java/seecoder/devcloud/core/pipeline/config/HandlerConfigTable.java

@@ -0,0 +1,40 @@
+package seecoder.devcloud.core.pipeline.config;
+
+import lombok.extern.slf4j.Slf4j;
+import seecoder.devcloud.core.pipeline.Handler;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author PuHong Weng
+ * @date 2021/3/10
+ * @description: 表驱动,记录HandlerConfig到Handler的映射
+ *      todo doc config配置关系
+ */
+@Slf4j
+public class HandlerConfigTable {
+
+    private static final Map<String, Class<?>> handlerConfigMap;
+
+    /**
+     * 表驱动的设置
+     * 注意这里的对应并不是一一对应,而是多对一
+     */
+    static {
+        handlerConfigMap = new HashMap<>();
+        //todo 加入表
+    }
+
+    public static Handler transToHandler(HandlerConfig config){
+        Handler handler = null;
+        try {
+            handler = (Handler) handlerConfigMap.get(config).newInstance();
+
+        } catch (InstantiationException | IllegalAccessException e) {
+            log.error("流水线配置转换发生错误",e);
+            //todo throw pipeline exception
+        }
+        return handler;
+    }
+}

+ 29 - 0
core/src/main/java/seecoder/devcloud/core/pipeline/config/PipelineConfig.java

@@ -0,0 +1,29 @@
+package seecoder.devcloud.core.pipeline.config;
+
+import lombok.Builder;
+import lombok.Data;
+import seecoder.devcloud.core.pipeline.Context;
+import seecoder.devcloud.core.pipeline.Handler;
+import seecoder.devcloud.core.pipeline.Pipeline;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author PuHong Weng
+ * @date 2021/2/2
+ * @description: pipeline配置的实体,由对应的pipeline config json转换过来
+ */
+@Data
+public class PipelineConfig {
+
+    private List<HandlerConfig> handlerConfigs;
+
+    public static PipelineConfig init(String configJson){
+        PipelineConfig pipelineConfig = null;
+        //todo jackson转换配置实体
+        return pipelineConfig;
+    }
+
+}

+ 7 - 5
core/src/main/java/seecoder/devcloud/core/pipeline/handler/AbstractHandler.java

@@ -4,8 +4,6 @@ import lombok.Data;
 import seecoder.devcloud.core.pipeline.Context;
 import seecoder.devcloud.core.pipeline.Handler;
 
-import java.util.HashMap;
-
 /**
  * @author PuHong Weng
  * @date 2021/2/2
@@ -15,7 +13,7 @@ import java.util.HashMap;
 public abstract class AbstractHandler implements Handler {
 
 
-    public AbstractHandler nextHandler;
+    public Handler nextHandler;
 
 //    /**
 //     * 用来存放Handler的配置
@@ -24,16 +22,20 @@ public abstract class AbstractHandler implements Handler {
 
     @Override
     public void invoke(Context context) {
+        //todo 改成异步的
         process(context);
         invokeNext(context);
     }
 
     @Override
     public void invokeNext(Context context) {
-        nextHandler.invoke(context);
+        if (nextHandler != null){
+            nextHandler.invoke(context);
+        }
     }
 
-    public void setNextHandler(AbstractHandler nextHandler) {
+    @Override
+    public void setNextHandler(Handler nextHandler) {
         this.nextHandler = nextHandler;
     }
 }

+ 1 - 5
core/src/main/java/seecoder/devcloud/core/pipeline/handler/K8sDeploymentHandler.java

@@ -1,7 +1,6 @@
 package seecoder.devcloud.core.pipeline.handler;
 
 import lombok.extern.slf4j.Slf4j;
-import seecoder.devcloud.api.ApplicationProperties;
 import seecoder.devcloud.api.k8s.DeploymentApi;
 import seecoder.devcloud.api.k8s.K8sConstants;
 import seecoder.devcloud.api.k8s.SecretApi;
@@ -9,15 +8,12 @@ import seecoder.devcloud.api.k8s.exception.K8sApiException;
 import seecoder.devcloud.api.k8s.model.Container;
 import seecoder.devcloud.api.k8s.model.ContainerPort;
 import seecoder.devcloud.api.k8s.model.Deployment;
-import seecoder.devcloud.api.k8s.model.K8sObjectRequest;
 import seecoder.devcloud.api.k8s.util.SecretTypeEnum;
 import seecoder.devcloud.api.k8s.vo.SecretVO;
 import seecoder.devcloud.common.util.SpringUtil;
 import seecoder.devcloud.core.pipeline.Context;
-import seecoder.devcloud.core.pipeline.Handler;
 
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -63,7 +59,7 @@ public class K8sDeploymentHandler extends AbstractHandler {
     public void process(Context context) {
         //配置初始化
         initConfig(context);
-        String groupName = context.getGroupName();
+        String groupName = context.getNamespace();
         String projectName = context.getProjectName();
 
         //配置容器暴露端口

+ 1 - 6
core/src/main/java/seecoder/devcloud/core/pipeline/handler/K8sNamespaceHandler.java

@@ -1,18 +1,13 @@
 package seecoder.devcloud.core.pipeline.handler;
 
-import com.sun.xml.internal.stream.events.NamespaceImpl;
 import lombok.extern.slf4j.Slf4j;
-import seecoder.devcloud.api.ApplicationProperties;
 import seecoder.devcloud.api.k8s.NamespaceApi;
 import seecoder.devcloud.api.k8s.SecretApi;
 import seecoder.devcloud.api.k8s.exception.K8sApiException;
-import seecoder.devcloud.api.k8s.model.K8sObjectRequest;
 import seecoder.devcloud.api.k8s.model.Namespace;
 import seecoder.devcloud.common.util.SpringUtil;
 import seecoder.devcloud.core.pipeline.Context;
 
-import javax.swing.*;
-
 /**
  * @author PuHong Weng
  * @date 2021/2/2
@@ -33,7 +28,7 @@ public class K8sNamespaceHandler extends AbstractHandler {
     @Override
     public void process(Context context) {
         Namespace namespace = new Namespace();
-        namespace.setName(context.getGroupName());
+        namespace.setName(context.getNamespace());
 
         //todo namespace在底下资源未删除时,不能轻易删除重建,只能直接通过异常查是否已创建,丑陋,待修改
         try {

+ 1 - 8
core/src/main/java/seecoder/devcloud/core/pipeline/handler/K8sServiceHandler.java

@@ -4,19 +4,12 @@ import lombok.extern.slf4j.Slf4j;
 import seecoder.devcloud.api.k8s.K8sConstants;
 import seecoder.devcloud.api.k8s.ServiceApi;
 import seecoder.devcloud.api.k8s.exception.K8sApiException;
-import seecoder.devcloud.api.k8s.model.K8sObject;
-import seecoder.devcloud.api.k8s.model.K8sObjectRequest;
 import seecoder.devcloud.api.k8s.model.Service;
 import seecoder.devcloud.api.k8s.model.ServicePort;
 import seecoder.devcloud.common.util.SpringUtil;
 import seecoder.devcloud.core.pipeline.Context;
-import seecoder.devcloud.core.pipeline.Handler;
 
-import java.util.Collection;
 import java.util.Collections;
-import java.util.stream.Collectors;
-
-import static seecoder.devcloud.api.k8s.K8sConstants.APPLICATION_LABEL;
 
 /**
  * @author PuHong Weng
@@ -44,7 +37,7 @@ public class K8sServiceHandler extends AbstractHandler {
 
         //配置K8s的service
         Service service = new Service();
-        service.setNamespace(context.getGroupName());
+        service.setNamespace(context.getNamespace());
         service.setName(context.getProjectName()+ K8sConstants.SERVICE_SUFFIX);
         //标签选择器选择 此项目对应的deployment的name
         service.setSelectors(Collections.singletonMap(K8sConstants.APPLICATION_LABEL, context.getProjectName()));

+ 38 - 0
core/src/main/java/seecoder/devcloud/core/pipeline/pipeline/PipelineImpl.java

@@ -0,0 +1,38 @@
+package seecoder.devcloud.core.pipeline.pipeline;
+
+import seecoder.devcloud.core.pipeline.Context;
+import seecoder.devcloud.core.pipeline.Handler;
+import seecoder.devcloud.core.pipeline.Pipeline;
+
+/**
+ * @author PuHong Weng
+ * @date 2021/3/10
+ * @description:
+ */
+
+public class PipelineImpl implements Pipeline {
+
+    private Handler firstHandler;
+
+    public PipelineImpl(Handler firstHandler, Context context) {
+        this.firstHandler = firstHandler;
+        this.context = context;
+    }
+
+    private Context context;
+
+
+
+    @Override
+    public void start() {
+        //todo 流水线开始事件监听
+        firstHandler.invoke(context);
+        //todo 流水线开始事件监听
+    }
+
+    @Override
+    public Context getContext() {
+        return context;
+    }
+
+}

+ 1 - 8
core/src/test/java/seecoder/devcloud/core/CoreApplicationTests.java

@@ -1,23 +1,16 @@
 package seecoder.devcloud.core;
 
-import org.junit.Before;
-import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.xml.NamespaceHandler;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.junit4.SpringRunner;
 import seecoder.devcloud.api.ApplicationProperties;
 import seecoder.devcloud.api.k8s.DeploymentApi;
 import seecoder.devcloud.core.pipeline.Context;
-import seecoder.devcloud.core.pipeline.handler.K8sDeploymentHandler;
-import seecoder.devcloud.core.pipeline.Pipeline;
 import seecoder.devcloud.core.pipeline.handler.K8sNamespaceHandler;
 
-import java.util.Collection;
-
 @RunWith(SpringRunner.class)
 @SpringBootTest
 class CoreApplicationTests {
@@ -53,7 +46,7 @@ class CoreApplicationTests {
 
     private void mockContext(){
         this.context = Context.builder()
-                .groupName("test-group")
+                .namespace("test-group")
                 .projectName("test-project")
                 .applicationProperties(applicationProperties)
                 .configs(null).build();