Browse Source

开发构建部署接口

reghao 4 years ago
parent
commit
9b452d18db
21 changed files with 261 additions and 308 deletions
  1. 1 3
      common/src/main/java/cn/reghao/autodop/common/dagent/app/api/data/AppStatus.java
  2. 8 2
      common/src/main/java/cn/reghao/autodop/common/dagent/app/api/data/DeployResult.java
  3. 18 11
      common/src/main/java/cn/reghao/autodop/common/shell/ShellExecutor.java
  4. 0 39
      common/src/main/java/cn/reghao/autodop/common/utils/file/FileFingerprint.java
  5. 0 11
      common/src/main/java/cn/reghao/autodop/common/utils/file/FileHandler.java
  6. 0 95
      common/src/main/java/cn/reghao/autodop/common/utils/file/FileOps.java
  7. 18 6
      dagent/src/main/java/cn/reghao/autodop/dagent/app/App.java
  8. 1 2
      dagent/src/main/java/cn/reghao/autodop/dagent/app/AppService.java
  9. 13 11
      dagent/src/main/java/cn/reghao/autodop/dagent/app/DockerAppServiceImpl.java
  10. 1 2
      dagent/src/main/java/cn/reghao/autodop/dagent/app/ZipAppServiceImpl.java
  11. 2 1
      dagent/src/main/java/cn/reghao/autodop/dagent/dispatcher/AppOpsDispatcher.java
  12. 2 9
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/AppPageController.java
  13. 11 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/log/DeployLog.java
  14. 10 9
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/BuildDeployDispatcher.java
  15. 1 18
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/bd/AppDeployer.java
  16. 0 71
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/bd/BuildDeployNotifyMsg.java
  17. 59 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/bd/BuildNotifyMsg.java
  18. 66 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/bd/DeployNotifyMsg.java
  19. 42 7
      dmaster/src/main/java/cn/reghao/autodop/dmaster/utils/dispatcher/AppOpsDispatcher.java
  20. 4 6
      dmaster/src/main/java/cn/reghao/autodop/dmaster/utils/notifier/NotifyService.java
  21. 4 4
      dmaster/src/main/resources/application.yml

+ 1 - 3
common/src/main/java/cn/reghao/autodop/common/dagent/app/api/data/AppStatus.java

@@ -15,9 +15,7 @@ public class AppStatus {
     private String machineId;
     private String machineIpv4;
     private String appId;
-    private String appType;
-    private String env;
-    private String commitId;
+    private String packagePath;
     private Boolean isRunning;
     private LocalDateTime startTime;
     private Integer pid;

+ 8 - 2
common/src/main/java/cn/reghao/autodop/common/dagent/app/api/data/DeployResult.java

@@ -1,17 +1,23 @@
 package cn.reghao.autodop.common.dagent.app.api.data;
 
 import cn.reghao.autodop.common.result.Result;
-import lombok.AllArgsConstructor;
 import lombok.Data;
 
 /**
  * @author reghao
  * @date 2021-05-28 13:48:01
  */
-@AllArgsConstructor
 @Data
 public class DeployResult {
     private String buildLogId;
+    private String machineId;
+    private String machineIpv4;
     private Result result;
     private AppStatus appStatus;
+
+    public DeployResult(String buildLogId, String machineId, String machineIpv4) {
+        this.buildLogId = buildLogId;
+        this.machineId = machineId;
+        this.machineIpv4 = machineIpv4;
+    }
 }

+ 18 - 11
common/src/main/java/cn/reghao/autodop/common/shell/ShellExecutor.java

@@ -22,23 +22,30 @@ public class ShellExecutor {
      * @return
      * @date 2020-11-09 下午11:22
      */
-    public ShellResult exec(String cmd, String dir) throws IOException, InterruptedException {
+    public ShellResult exec(String cmd, String dir) {
         String[] cmdarray = cmd.split("\\s+");
         String output = System.getProperty("java.io.tmpdir") + "/" + UUID.randomUUID().toString() + ".out";
         File ofile = new File(output);
-        ofile.createNewFile();
 
-        pb.command(cmdarray)
-                // 将标准错误合并到标准输出
-                .redirectErrorStream(true)
-                // 将所有输出重定向到文件
-                .redirectOutput(ofile);
-        if (dir != null) {
-            pb.directory(new File(dir));
+        ShellResult shellResult;
+        try {
+            ofile.createNewFile();
+            pb.command(cmdarray)
+                    // 将标准错误合并到标准输出
+                    .redirectErrorStream(true)
+                    // 将所有输出重定向到文件
+                    .redirectOutput(ofile);
+            if (dir != null) {
+                pb.directory(new File(dir));
+            }
+
+            shellResult = exec(pb, ofile);
+            ofile.delete();
+        } catch (IOException | InterruptedException e) {
+            shellResult = new ShellResult(1);
+            shellResult.setOutput(e.getMessage());
         }
 
-        ShellResult shellResult = exec(pb, ofile);
-        ofile.delete();
         return shellResult;
     }
 

+ 0 - 39
common/src/main/java/cn/reghao/autodop/common/utils/file/FileFingerprint.java

@@ -1,39 +0,0 @@
-package cn.reghao.autodop.common.utils.file;
-
-import org.apache.commons.codec.digest.DigestUtils;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * 文件指纹
- *
- * @author reghao
- * @date 2021-01-14 21:07:17
- */
-public class FileFingerprint implements FileHandler {
-    private Map<String, String> map = new HashMap<>();
-
-    @Override
-    public void handleFile(String filePath) throws IOException {
-        String sum = sha256sum(filePath);
-        if (map.containsKey(sum)) {
-            new File(filePath).delete();
-        } else {
-            map.putIfAbsent(sum, filePath);
-        }
-    }
-
-    public Map<String, String> map() {
-        return map;
-    }
-
-    public String sha256sum(String filepath) throws IOException {
-        File file = new File(filepath);
-        FileInputStream fileInputStream = new FileInputStream(file);
-        return DigestUtils.sha256Hex(fileInputStream);
-    }
-}

+ 0 - 11
common/src/main/java/cn/reghao/autodop/common/utils/file/FileHandler.java

@@ -1,11 +0,0 @@
-package cn.reghao.autodop.common.utils.file;
-
-import java.io.IOException;
-
-/**
- * @author reghao
- * @date 2021-03-11 10:01:42
- */
-public interface FileHandler {
-    void handleFile(String filePath) throws IOException;
-}

+ 0 - 95
common/src/main/java/cn/reghao/autodop/common/utils/file/FileOps.java

@@ -1,95 +0,0 @@
-package cn.reghao.autodop.common.utils.file;
-
-import cn.reghao.autodop.common.shell.ShellExecutor;
-import cn.reghao.autodop.common.shell.ShellResult;
-
-import java.io.IOException;
-import java.nio.file.*;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 文件相关操作
- *
- * @author reghao
- * @date 2021-01-15 00:43:41
- */
-public class FileOps {
-    private String cmd = "ffprobe -select_streams v -show_entries format=duration,size,bit_rate,filename -show_streams -v quiet -of csv=\"p=0\" -of json -i ";
-    private ShellExecutor shellExecutor = new ShellExecutor();
-    private List<ShellResult> list = new ArrayList<>();
-    private Map<String, ShellResult> map = new HashMap<>();
-    private FileFingerprint fileFingerprint = new FileFingerprint();
-
-    void walkDir(Path path) throws IOException {
-        final String BLANK = "";
-        if (path.toString().equals(BLANK)) {
-            throw new IOException("CAN NOT specify a BLANK path");
-        }
-
-        Files.walkFileTree(path, new FileVisitor<>() {
-            @Override
-            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
-                return FileVisitResult.CONTINUE;
-            }
-
-            @Override
-            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
-                String filePath = file.toString();
-                //fileFingerprint.handleFile(filePath);
-                try {
-                    /*ShellResult shellResult = shellExecutor.exec(cmd + filePath);
-                    map.put(filePath, shellResult);*/
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-                return FileVisitResult.CONTINUE;
-            }
-
-            @Override
-            public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
-                return FileVisitResult.CONTINUE;
-            }
-
-            @Override
-            public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
-                return FileVisitResult.CONTINUE;
-            }
-        });
-    }
-
-    public Map<String, ShellResult> map() {
-        return this.map;
-    }
-
-    public String full2Half(String str) {
-        char[] chars = str.toCharArray();
-        for (int i = 0; i < chars.length; i++) {
-            if (chars[i] == 12288) {
-                chars[i] = ' ';
-            } else if (chars[i] >= ' ' && chars[i] <= 65372) {
-                chars[i] = (char) (chars[i] - 65248);
-            }
-        }
-
-        return String.valueOf(chars);
-    }
-
-    public static void main(String[] args) throws IOException {
-        String dir = "/home/reghao/data/videos/aaa";
-        FileOps fileOps = new FileOps();
-        Path path = Paths.get(dir);
-        fileOps.walkDir(path);
-        Map<String, ShellResult> map = fileOps.map();
-        Map<String, ShellResult> tmp = new HashMap<>();
-        map.forEach((k, v) -> {
-            if (!v.isSuccess()) {
-                tmp.put(k, v);
-            }
-        });
-        System.out.println();
-    }
-}

+ 18 - 6
dagent/src/main/java/cn/reghao/autodop/dagent/app/App.java

@@ -8,11 +8,13 @@ import cn.reghao.autodop.common.dagent.app.api.data.deploy.PackerType;
 import cn.reghao.autodop.common.dagent.app.api.data.log.AppLogArgs;
 import cn.reghao.autodop.common.dagent.app.api.data.log.LogConfig;
 import cn.reghao.autodop.common.dagent.app.api.data.log.LogFile;
+import cn.reghao.autodop.common.dagent.machine.hardware.network.Network;
 import cn.reghao.autodop.common.docker.exception.DockerException;
 import cn.reghao.autodop.common.message.CallResult;
 import cn.reghao.autodop.common.result.Result;
 import cn.reghao.autodop.common.result.ResultStatus;
 import cn.reghao.autodop.common.utils.ExceptionUtil;
+import cn.reghao.autodop.common.utils.MachineId;
 import cn.reghao.autodop.common.utils.serializer.JsonConverter;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
@@ -26,11 +28,16 @@ import java.util.List;
 @Slf4j
 @Component
 public class App {
+    private String machineId;
+    private String machineIpv4;
     private DockerAppServiceImpl dockerAppServiceImpl;
     private ZipAppServiceImpl zipAppServiceImpl;
 
     public App() {
-        this.dockerAppServiceImpl = new DockerAppServiceImpl();
+        // TODO 对于托管给 Spring 的对象,这种创建对象的方式是否合理
+        this.machineId = MachineId.id();
+        this.machineIpv4 = new Network().info().get(0).getIpv4();
+        this.dockerAppServiceImpl = new DockerAppServiceImpl(machineId, machineIpv4);
         this.zipAppServiceImpl = new ZipAppServiceImpl();
     }
 
@@ -39,24 +46,29 @@ public class App {
         String buildLogId = appDeployArgs.getBuildLogId();
         String packerType = appDeployArgs.getPackerType();
 
-        DeployResult deployResult;
+        AppStatus appStatus;
+        DeployResult deployResult = new DeployResult(buildLogId, machineId, machineIpv4);
         switch (PackerType.valueOf(packerType)) {
             case docker:
                 try {
-                    deployResult = dockerAppServiceImpl.deploy(appDeployArgs);
+                    appStatus = dockerAppServiceImpl.deploy(appDeployArgs);
+                    deployResult.setResult(new Result(ResultStatus.SUCCESS));
+                    deployResult.setAppStatus(appStatus);
                 } catch (DockerException e) {
                     Result result = new Result(ResultStatus.FAIL);
                     result.setMsg(ExceptionUtil.errorMsg(e));
-                    return new DeployResult(buildLogId, result, null);
+                    deployResult.setResult(result);
                 }
                 break;
             case zip:
-                deployResult = zipAppServiceImpl.deploy(appDeployArgs);
+                appStatus = zipAppServiceImpl.deploy(appDeployArgs);
+                deployResult.setResult(new Result(ResultStatus.SUCCESS));
+                deployResult.setAppStatus(appStatus);
                 break;
             default:
                 Result result = new Result(ResultStatus.ERROR);
                 result.setMsg("打包类型 " + appDeployArgs.getPackerType() + " 不存在");
-                return new DeployResult(buildLogId, result, null);
+                deployResult.setResult(result);
         }
         return deployResult;
     }

+ 1 - 2
dagent/src/main/java/cn/reghao/autodop/dagent/app/AppService.java

@@ -1,7 +1,6 @@
 package cn.reghao.autodop.dagent.app;
 
 import cn.reghao.autodop.common.dagent.app.api.data.AppStatus;
-import cn.reghao.autodop.common.dagent.app.api.data.DeployResult;
 import cn.reghao.autodop.common.dagent.app.api.data.deploy.AppDeployArgs;
 import cn.reghao.autodop.common.dagent.app.api.data.log.AppLogArgs;
 import cn.reghao.autodop.common.dagent.app.api.data.log.LogFile;
@@ -14,7 +13,7 @@ import java.util.List;
  * @date 2021-02-22 16:21:28
  */
 public interface AppService {
-    DeployResult deploy(AppDeployArgs appDeployArgs) throws DockerException;
+    AppStatus deploy(AppDeployArgs appDeployArgs) throws DockerException;
     /**
      * 日志文件列表
      *

+ 13 - 11
dagent/src/main/java/cn/reghao/autodop/dagent/app/DockerAppServiceImpl.java

@@ -1,20 +1,16 @@
 package cn.reghao.autodop.dagent.app;
 
 import cn.reghao.autodop.common.dagent.app.api.data.AppStatus;
-import cn.reghao.autodop.common.dagent.app.api.data.DeployResult;
 import cn.reghao.autodop.common.dagent.app.api.data.deploy.AppDeployArgs;
 import cn.reghao.autodop.common.dagent.app.api.data.log.AppLogArgs;
 import cn.reghao.autodop.common.dagent.app.api.data.log.LogConfig;
 import cn.reghao.autodop.common.dagent.app.api.data.log.LogFile;
 import cn.reghao.autodop.common.dagent.app.api.data.log.LogType;
-import cn.reghao.autodop.common.dagent.machine.Machine;
 import cn.reghao.autodop.common.docker.Docker;
 import cn.reghao.autodop.common.docker.exception.DockerException;
 import cn.reghao.autodop.common.docker.pojo.Config;
 import cn.reghao.autodop.common.docker.pojo.State;
 import cn.reghao.autodop.common.docker.pojo.result.ContainerInfo;
-import cn.reghao.autodop.common.result.Result;
-import cn.reghao.autodop.common.result.ResultStatus;
 import cn.reghao.autodop.common.utils.DateTimeConverter;
 import cn.reghao.autodop.common.utils.ExceptionUtil;
 
@@ -26,24 +22,28 @@ import java.util.List;
  * @date 2021-02-22 16:21:37
  */
 public class DockerAppServiceImpl implements AppService {
+    private String machineId;
+    private String machineIpv4;
     private final long sleep = 10_000;
 
+    public DockerAppServiceImpl(String machineId, String machineIpv4) {
+        this.machineId = machineId;
+        this.machineIpv4 = machineIpv4;
+    }
+
     @Override
-    public DeployResult deploy(AppDeployArgs appDeployArgs) throws DockerException {
+    public AppStatus deploy(AppDeployArgs appDeployArgs) throws DockerException {
         String appId = appDeployArgs.getAppId();
         String packagePath = appDeployArgs.getPackagePath();
         Config dockerConfig = appDeployArgs.getDockerConfig();
 
         try (Docker docker = new Docker()) {
-            String repoTag = appDeployArgs.getPackagePath();
-            docker.pull(repoTag);
+            docker.pull(packagePath);
             String containerId = docker.run(appId, packagePath, dockerConfig);
             Thread.sleep(sleep);
 
             ContainerInfo containerInfo = docker.inspectContainer(containerId);
-            AppStatus appStatus = getAppStatus(appId, containerInfo);
-            Result result = new Result(ResultStatus.SUCCESS);
-            return new DeployResult(appDeployArgs.getBuildLogId(), result, appStatus);
+            return getAppStatus(appId, containerInfo);
         } catch (InterruptedException e) {
             throw new DockerException(ExceptionUtil.errorMsg(e));
         }
@@ -51,8 +51,10 @@ public class DockerAppServiceImpl implements AppService {
 
     private AppStatus getAppStatus(String appId, ContainerInfo containerInfo) {
         AppStatus appStatus = new AppStatus();
-        appStatus.setMachineId(Machine.machineId());
+        appStatus.setMachineId(machineId);
+        appStatus.setMachineIpv4(machineIpv4);
         appStatus.setAppId(appId);
+        appStatus.setPackagePath(containerInfo.getConfig().getImage());
 
         State state = containerInfo.getState();
         boolean isRunning = state.isRunning();

+ 1 - 2
dagent/src/main/java/cn/reghao/autodop/dagent/app/ZipAppServiceImpl.java

@@ -1,7 +1,6 @@
 package cn.reghao.autodop.dagent.app;
 
 import cn.reghao.autodop.common.dagent.app.api.data.AppStatus;
-import cn.reghao.autodop.common.dagent.app.api.data.DeployResult;
 import cn.reghao.autodop.common.dagent.app.api.data.deploy.AppDeployArgs;
 import cn.reghao.autodop.common.dagent.app.api.data.log.AppLogArgs;
 import cn.reghao.autodop.common.dagent.app.api.data.log.LogFile;
@@ -17,7 +16,7 @@ import java.util.List;
 @Slf4j
 public class ZipAppServiceImpl implements AppService {
     @Override
-    public DeployResult deploy(AppDeployArgs appDeployArgs) {
+    public AppStatus deploy(AppDeployArgs appDeployArgs) {
         log.info("zip 部署...");
         return null;
     }

+ 2 - 1
dagent/src/main/java/cn/reghao/autodop/dagent/dispatcher/AppOpsDispatcher.java

@@ -5,6 +5,7 @@ import cn.reghao.autodop.common.message.CallResult;
 import cn.reghao.autodop.common.message.MessageType;
 import cn.reghao.autodop.common.message.AppOps;
 import cn.reghao.autodop.common.mqtt.MqttPub;
+import cn.reghao.autodop.common.utils.MachineId;
 import cn.reghao.autodop.common.utils.serializer.JsonConverter;
 import cn.reghao.autodop.dagent.app.App;
 import lombok.extern.slf4j.Slf4j;
@@ -20,7 +21,7 @@ import org.springframework.stereotype.Component;
 public class AppOpsDispatcher {
     private MqttPub mqttPub;
     private String topic;
-    public App app;
+    private App app;
     
     public AppOpsDispatcher(MqttPub mqttPub, App app) {
         this.mqttPub = mqttPub;

+ 2 - 9
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/AppPageController.java

@@ -1,6 +1,5 @@
 package cn.reghao.autodop.dmaster.app.controller;
 
-import cn.reghao.autodop.common.result.Result;
 import cn.reghao.autodop.dmaster.app.constant.AppType;
 import cn.reghao.autodop.dmaster.app.constant.EnvType;
 import cn.reghao.autodop.dmaster.app.entity.config.AppOrchestration;
@@ -80,14 +79,8 @@ public class AppPageController {
     @ApiOperation(value = "构建日志结果页面")
     @GetMapping("/log/build/{buildLogId}/result")
     public String buildLogResultPage(@PathVariable("buildLogId") BuildLog buildLog, Model model) {
-        Result result = buildLog.getResult();
-        if (result != null) {
-            String msg = buildLog.getResult().getMsg();
-            model.addAttribute("msg", msg);
-        } else {
-            model.addAttribute("msg", "尚未构建");
-        }
-
+        String msg = buildLog.getResult().getMsg();
+        model.addAttribute("msg", msg);
         return "/app/log";
     }
 

+ 11 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/log/DeployLog.java

@@ -1,5 +1,7 @@
 package cn.reghao.autodop.dmaster.app.entity.log;
 
+import cn.reghao.autodop.common.dagent.app.api.data.AppStatus;
+import cn.reghao.autodop.common.dagent.app.api.data.DeployResult;
 import cn.reghao.autodop.common.result.Result;
 import cn.reghao.autodop.dmaster.common.orm.BaseDocument;
 import lombok.Data;
@@ -24,8 +26,16 @@ public class DeployLog extends BaseDocument {
     private LocalDateTime deployTime;
     private Result result;
 
-    public static DeployLog from(BuildLog buildLog) {
+    public static DeployLog from(DeployResult deployResult) {
         DeployLog deployLog = new DeployLog();
+        deployLog.setBuildLogId(deployResult.getBuildLogId());
+        deployLog.setResult(deployResult.getResult());
+        AppStatus appStatus = deployResult.getAppStatus();
+        if (appStatus != null) {
+            deployLog.setMachineId(appStatus.getMachineId());
+            deployLog.setMachineIpv4(appStatus.getMachineIpv4());
+            deployLog.setDeployTime(appStatus.getStartTime());
+        }
         return deployLog;
     }
 }

+ 10 - 9
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/BuildDeployDispatcher.java

@@ -12,7 +12,8 @@ import cn.reghao.autodop.dmaster.app.repository.log.BuildLogRepository;
 import cn.reghao.autodop.dmaster.app.service.bd.AppIntegrate;
 import cn.reghao.autodop.dmaster.app.service.bd.AppDeployer;
 import cn.reghao.autodop.dmaster.app.entity.config.AppOrchestration;
-import cn.reghao.autodop.dmaster.app.service.bd.BuildDeployNotifyMsg;
+import cn.reghao.autodop.dmaster.app.service.bd.BuildNotifyMsg;
+import cn.reghao.autodop.dmaster.utils.notifier.DingMsg;
 import cn.reghao.autodop.dmaster.utils.notifier.NotifyService;
 import cn.reghao.autodop.dmaster.common.thread.ThreadPoolWrapper;
 import lombok.extern.slf4j.Slf4j;
@@ -90,8 +91,7 @@ public class BuildDeployDispatcher {
 
         BuildSupplier supplier = new BuildSupplier(appIntegrate);
         final List<NotifyReceiver> notifyReceivers = appIntegrate.app().getNotifyReceivers();
-        //log.info("开始异步构建 {}...", appId);
-        log.info("线程 {} 开始异步构建 {}...", Thread.currentThread().getName(), appId);
+        log.info("开始异步构建 {}...", appId);
         CompletableFuture.supplyAsync(supplier, threadPool)
                 .whenComplete((buildLog, throwable) -> {
                     buildLog = buildLogRepository.save(buildLog);
@@ -105,16 +105,17 @@ public class BuildDeployDispatcher {
                         appBuilding.setUpdateTime(LocalDateTime.now());
                         appBuildingRepository.save(appBuilding);
                     }
-                    //log.info("{} 构建完成...", appId);
-                    log.info("线程 {} 构建 {} 完成...", Thread.currentThread().getName(), appId);
+                    log.info("{} 构建完成...", appId);
                 })
                 .thenAccept(buildLog -> {
-                    // TODO 抛出异常时不会有任何错误
-                    BuildDeployNotifyMsg msg = BuildDeployNotifyMsg.buildNotifyMsg(buildLog);
-                    notifyReceivers.forEach(notifyReceiver -> notifyService.notify(notifyReceiver, msg));
+                    if (!isDeploy) {
+                        // TODO 抛出异常时不会有任何错误
+                        DingMsg dingMsg = new BuildNotifyMsg(buildLog).dingMsg();
+                        notifyReceivers.forEach(notifyReceiver -> notifyService.notify(notifyReceiver, dingMsg));
+                    }
 
                     if (buildLog.getResult().getCode() == ResultStatus.SUCCESS.getCode() && isDeploy) {
-                        log.info("线程 {} 开始部署 {}...", Thread.currentThread().getName(), appId);
+                        log.info("开始部署 {}...", appId);
                         try {
                             appDeployer.deploy(buildLog);
                         } catch (MqttException e) {

+ 1 - 18
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/bd/AppDeployer.java

@@ -11,9 +11,6 @@ import cn.reghao.autodop.dmaster.app.cache.BuildDeployCache;
 import cn.reghao.autodop.dmaster.app.entity.config.deploy.DeployConfig;
 import cn.reghao.autodop.dmaster.app.entity.log.BuildLog;
 import cn.reghao.autodop.dmaster.app.entity.log.DeployLog;
-import cn.reghao.autodop.dmaster.machine.entity.MachineInfo;
-import cn.reghao.autodop.dmaster.machine.entity.NetworkInfo;
-import cn.reghao.autodop.dmaster.machine.repository.MachineInfoRepository;
 import lombok.extern.slf4j.Slf4j;
 import org.eclipse.paho.client.mqttv3.MqttException;
 import org.springframework.stereotype.Service;
@@ -31,14 +28,10 @@ import java.util.*;
 public class AppDeployer {
     private MqttPub mqttPub;
     private BuildDeployCache cache;
-    private MachineInfoRepository machineInfoRepository;
 
-    public AppDeployer(MqttPub mqttPub,
-                       BuildDeployCache cache,
-                       MachineInfoRepository machineInfoRepository) {
+    public AppDeployer(MqttPub mqttPub, BuildDeployCache cache) {
         this.mqttPub = mqttPub;
         this.cache = cache;
-        this.machineInfoRepository = machineInfoRepository;
     }
 
     public void deploy(BuildLog buildLog) throws MqttException {
@@ -97,14 +90,4 @@ public class AppDeployer {
 
         return new ArrayList<>();
     }
-
-    private String machineIpv4(String machineId) {
-        MachineInfo machineInfo = machineInfoRepository.findByMachineId(machineId);
-        List<NetworkInfo> networkInfos = machineInfo.getNetworkInfo();
-        if (!networkInfos.isEmpty()) {
-            return networkInfos.get(0).getIpv4();
-        } else {
-            return "0.0.0.0";
-        }
-    }
 }

+ 0 - 71
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/bd/BuildDeployNotifyMsg.java

@@ -1,71 +0,0 @@
-package cn.reghao.autodop.dmaster.app.service.bd;
-
-import cn.reghao.autodop.common.utils.DateTimeConverter;
-import cn.reghao.autodop.dmaster.app.entity.log.BuildLog;
-import cn.reghao.autodop.dmaster.app.entity.log.DeployLog;
-import cn.reghao.autodop.dmaster.app.service.bd.tools.repo.CommitInfo;
-import lombok.Data;
-
-import java.util.Map;
-
-/**
- * 应用构建部署通知消息
- *
- * @author reghao
- * @date 2020-06-24 10:32:34
- */
-@Data
-public class BuildDeployNotifyMsg {
-    private String title;
-    private String text;
-
-    private String appId;
-    private String env;
-    private String commitId;
-    private Map<String, String> map;
-
-    public static BuildDeployNotifyMsg buildNotifyMsg(BuildLog buildLog) {
-        BuildDeployNotifyMsg buildDeployNotifyMsg = new BuildDeployNotifyMsg();
-        buildDeployNotifyMsg.title = "应用构建消息";
-        StringBuilder sb = new StringBuilder();
-        sb.append("应用构建").append(System.lineSeparator());
-        sb.append("# 应用: ").append(buildLog.getAppId()).append(System.lineSeparator());
-        sb.append("# 环境: ").append(buildLog.getEnv()).append(System.lineSeparator());
-
-        CommitInfo commitInfo = buildLog.getCommitInfo();
-        sb.append("# 分支: ").append(commitInfo != null ? commitInfo.getBranch() : null)
-                .append(System.lineSeparator());
-        sb.append("# 版本: ").append(commitInfo != null ? commitInfo.getCommitId() : null)
-                .append(System.lineSeparator());
-        sb.append("# 提交时间: ")
-                .append(commitInfo != null ? DateTimeConverter.format(commitInfo.getMsCommitTime()) : null)
-                .append(System.lineSeparator());
-        sb.append("# 构建结果: ").append(buildLog.getResult().getMsg()).append(System.lineSeparator());
-        sb.append("# 构建时间: ").append(DateTimeConverter.format(buildLog.getBuildTime().getBuildTime()))
-                .append(System.lineSeparator());
-        sb.append("# 执行用户: ").append("某人");
-
-        buildDeployNotifyMsg.text = sb.toString();
-        return buildDeployNotifyMsg;
-    }
-
-    public static BuildDeployNotifyMsg deployNotifyMsg(BuildLog buildLog, DeployLog deployLog) {
-        BuildDeployNotifyMsg buildDeployNotifyMsg = new BuildDeployNotifyMsg();
-        buildDeployNotifyMsg.title = "应用部署消息";
-        StringBuilder sb = new StringBuilder();
-        sb.append("应用部署").append(System.lineSeparator());
-        sb.append("# 应用: ").append(buildLog.getAppId()).append(System.lineSeparator());
-        sb.append("# 环境: ").append(buildLog.getEnv()).append(System.lineSeparator());
-        sb.append("# 版本: ").append(buildLog.getCommitInfo().getCommitId()).append(System.lineSeparator());
-        sb.append("# 提交时间: ").append(DateTimeConverter.format(buildLog.getCommitInfo().getMsCommitTime()))
-                .append(System.lineSeparator());
-        sb.append("# 部署结果: ").append(deployLog.getMachineIpv4()).append(" -> ").append(deployLog.getResult().getMsg())
-                .append(System.lineSeparator());
-        sb.append("# 部署时间: ").append(DateTimeConverter.format(deployLog.getDeployTime()))
-                .append(System.lineSeparator());
-        sb.append("# 执行用户: ").append("某人");
-
-        buildDeployNotifyMsg.text = sb.toString();
-        return buildDeployNotifyMsg;
-    }
-}

+ 59 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/bd/BuildNotifyMsg.java

@@ -0,0 +1,59 @@
+package cn.reghao.autodop.dmaster.app.service.bd;
+
+import cn.reghao.autodop.common.dagent.app.api.data.AppStatus;
+import cn.reghao.autodop.common.dagent.app.api.data.DeployResult;
+import cn.reghao.autodop.common.utils.DateTimeConverter;
+import cn.reghao.autodop.dmaster.app.entity.log.BuildLog;
+import cn.reghao.autodop.dmaster.app.service.bd.tools.repo.CommitInfo;
+import cn.reghao.autodop.dmaster.utils.notifier.DingMsg;
+import lombok.Data;
+
+/**
+ * 应用构建通知消息
+ *
+ * @author reghao
+ * @date 2020-06-24 10:32:34
+ */
+@Data
+public class BuildNotifyMsg {
+    private String buildId;
+    private String appId;
+    private String env;
+    private String branch;
+    private String commitId;
+    private String commitTime;
+    private String buildResult;
+    private String buildTime;
+    private String buildBy;
+
+    public BuildNotifyMsg(BuildLog buildLog) {
+        this.buildId = buildLog.getId();
+        this.appId = buildLog.getAppId();
+        this.env = buildLog.getEnv();
+        this.branch = buildLog.getBranch();
+        this.commitId = buildLog.getCommitInfo().getCommitId();
+        this.commitTime = DateTimeConverter.format(buildLog.getCommitInfo().getMsCommitTime());
+        this.buildResult = buildLog.getResult().getMsg();
+        this.buildTime = DateTimeConverter.format(buildLog.getBuildTime().getBuildTime());
+        this.buildBy = "某人";
+    }
+
+    public DingMsg dingMsg() {
+        String title = "应用构建消息";
+
+        StringBuilder sb = new StringBuilder();
+        sb.append("应用构建").append(System.lineSeparator());
+        sb.append("# 构建 ID: ").append(buildId).append(System.lineSeparator());
+        sb.append("# 应用: ").append(appId).append(System.lineSeparator());
+        sb.append("# 环境: ").append(env).append(System.lineSeparator());
+        sb.append("# 分支: ").append(branch).append(System.lineSeparator());
+        sb.append("# 版本: ").append(commitId).append(System.lineSeparator());
+        sb.append("# 提交时间: ").append(commitTime).append(System.lineSeparator());
+        sb.append("# 构建结果: ").append(buildResult).append(System.lineSeparator());
+        sb.append("# 构建时间: ").append(buildTime).append(System.lineSeparator());
+        sb.append("# 执行用户: ").append(buildBy);
+        String text = sb.toString();
+
+        return new DingMsg(title, text);
+    }
+}

+ 66 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/bd/DeployNotifyMsg.java

@@ -0,0 +1,66 @@
+package cn.reghao.autodop.dmaster.app.service.bd;
+
+import cn.reghao.autodop.common.dagent.app.api.data.AppStatus;
+import cn.reghao.autodop.common.dagent.app.api.data.DeployResult;
+import cn.reghao.autodop.common.utils.DateTimeConverter;
+import cn.reghao.autodop.dmaster.app.entity.log.BuildLog;
+import cn.reghao.autodop.dmaster.utils.notifier.DingMsg;
+import lombok.Data;
+
+/**
+ * 应用部署通知消息
+ *
+ * @author reghao
+ * @date 2020-06-24 10:32:34
+ */
+@Data
+public class DeployNotifyMsg {
+    private String buildId;
+    private String appId;
+    private String env;
+    private String branch;
+    private String commitId;
+    private String commitTime;
+    private String machineIpv4;
+    private String deployResult;
+    private String deployTime;
+    private String deployBy;
+
+    public DeployNotifyMsg(BuildLog buildLog, DeployResult deployResult) {
+        this.buildId = buildLog.getId();
+        this.appId = buildLog.getAppId();
+        this.env = buildLog.getEnv();
+        this.branch = buildLog.getBranch();
+        this.commitId = buildLog.getCommitInfo().getCommitId();
+        this.commitTime = DateTimeConverter.format(buildLog.getCommitInfo().getMsCommitTime());
+        this.machineIpv4 = deployResult.getMachineIpv4();
+        this.deployResult = deployResult.getResult().getMsg();
+        AppStatus appStatus = deployResult.getAppStatus();
+        if (appStatus != null) {
+            this.deployTime = DateTimeConverter.format(appStatus.getStartTime());
+        } else {
+            this.deployTime = DateTimeConverter.format(0);
+        }
+        this.deployBy = "某人";
+    }
+
+    public DingMsg dingMsg() {
+        String title = "应用部署消息";
+
+        StringBuilder sb = new StringBuilder();
+        sb.append("应用部署").append(System.lineSeparator());
+        sb.append("# 构建 ID: ").append(buildId).append(System.lineSeparator());
+        sb.append("# 应用: ").append(appId).append(System.lineSeparator());
+        sb.append("# 环境: ").append(env).append(System.lineSeparator());
+        sb.append("# 分支: ").append(branch).append(System.lineSeparator());
+        sb.append("# 版本: ").append(commitId).append(System.lineSeparator());
+        sb.append("# 提交时间: ").append(commitTime).append(System.lineSeparator());
+        sb.append("# 部署结果: ").append(machineIpv4).append(" -> ").append(deployResult)
+                .append(System.lineSeparator());
+        sb.append("# 部署时间: ").append(deployTime)
+                .append(System.lineSeparator());
+        sb.append("# 执行用户: ").append(deployBy);
+        String text = sb.toString();
+        return new DingMsg(title, text);
+    }
+}

+ 42 - 7
dmaster/src/main/java/cn/reghao/autodop/dmaster/utils/dispatcher/AppOpsDispatcher.java

@@ -3,14 +3,23 @@ package cn.reghao.autodop.dmaster.utils.dispatcher;
 import cn.reghao.autodop.common.dagent.app.api.data.AppStatus;
 import cn.reghao.autodop.common.dagent.app.api.data.DeployResult;
 import cn.reghao.autodop.common.message.AppOps;
-import cn.reghao.autodop.common.message.CallResult;
 import cn.reghao.autodop.common.result.ResultStatus;
 import cn.reghao.autodop.common.utils.serializer.JsonConverter;
-import com.google.gson.reflect.TypeToken;
+import cn.reghao.autodop.dmaster.app.cache.BuildDeployCache;
+import cn.reghao.autodop.dmaster.app.entity.config.AppOrchestration;
+import cn.reghao.autodop.dmaster.app.entity.config.NotifyReceiver;
+import cn.reghao.autodop.dmaster.app.entity.log.BuildLog;
+import cn.reghao.autodop.dmaster.app.entity.log.DeployLog;
+import cn.reghao.autodop.dmaster.app.repository.log.BuildLogRepository;
+import cn.reghao.autodop.dmaster.app.repository.log.DeployLogRepository;
+import cn.reghao.autodop.dmaster.app.service.bd.DeployNotifyMsg;
+import cn.reghao.autodop.dmaster.utils.notifier.DingMsg;
+import cn.reghao.autodop.dmaster.utils.notifier.NotifyService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 
-import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Optional;
 
 /**
  * 分发对 App 的操作
@@ -21,16 +30,42 @@ import java.lang.reflect.Type;
 @Slf4j
 @Component
 public class AppOpsDispatcher {
+    private BuildLogRepository buildLogRepository;
+    private DeployLogRepository deployLogRepository;
+    private BuildDeployCache cache;
+    private NotifyService notifyService;
+
+    public AppOpsDispatcher(BuildLogRepository buildLogRepository,
+                            DeployLogRepository deployLogRepository,
+                            BuildDeployCache cache,
+                            NotifyService notifyService) {
+        this.buildLogRepository = buildLogRepository;
+        this.deployLogRepository = deployLogRepository;
+        this.cache = cache;
+        this.notifyService = notifyService;
+    }
+
     public void dispatch(String ops, String payload) {
         switch (AppOps.valueOf(ops)) {
             case appDeployResult:
                 DeployResult deployResult = JsonConverter.jsonToObject(payload, DeployResult.class);
+                DeployLog deployLog = DeployLog.from(deployResult);
+                deployLogRepository.save(deployLog);
+
+                String buildId = deployResult.getBuildLogId();
+                // TODO 部署时将 BuildLog 放到缓存中
+                Optional<BuildLog> optional = buildLogRepository.findById(buildId);
+                if (optional.isPresent()) {
+                    BuildLog buildLog = optional.get();
+                    AppOrchestration app = cache.findByAppId(buildLog.getAppId());
+                    DingMsg dingMsg = new DeployNotifyMsg(buildLog, deployResult).dingMsg();
+                    List<NotifyReceiver> notifyReceivers = app.getNotifyReceivers();
+                    notifyReceivers.forEach(notifyReceiver -> notifyService.notify(notifyReceiver, dingMsg));
+                    log.info("应用 {} 部署成功...", buildLog.getAppId());
+                }
+
                 if (deployResult.getResult().getCode() == ResultStatus.SUCCESS.getCode()) {
                     AppStatus appStatus = deployResult.getAppStatus();
-                    log.info("应用 {} 部署成功...", appStatus.getAppId());
-                    //BuildDeployNotifyMsg msg = BuildDeployNotifyMsg.deployNotifyMsg(null);
-                } else {
-                    log.info("应用部署失败...");
                 }
                 break;
             case appStatusResult:

+ 4 - 6
dmaster/src/main/java/cn/reghao/autodop/dmaster/utils/notifier/NotifyService.java

@@ -2,7 +2,6 @@ package cn.reghao.autodop.dmaster.utils.notifier;
 
 import cn.reghao.autodop.dmaster.app.constant.NotifyType;
 import cn.reghao.autodop.dmaster.app.entity.config.NotifyReceiver;
-import cn.reghao.autodop.dmaster.app.service.bd.BuildDeployNotifyMsg;
 import cn.reghao.autodop.dmaster.common.thread.ThreadPoolWrapper;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -25,11 +24,10 @@ public class NotifyService {
     public void notify(NotifyReceiver notifyReceiver, Object msg) {
         switch (NotifyType.valueOf(notifyReceiver.getNotifyType())) {
             case webhook:
-                DingNotify dingNotify = new DingNotify();
-                if (msg instanceof BuildDeployNotifyMsg) {
-                    BuildDeployNotifyMsg buildDeployNotifyMsg = (BuildDeployNotifyMsg) msg;
-                    threadPool.execute(new NotifyTask<>(dingNotify, notifyReceiver.getReceiver(),
-                            new DingMsg(buildDeployNotifyMsg.getTitle(), buildDeployNotifyMsg.getText())));
+                if (msg instanceof DingMsg) {
+                    DingNotify dingNotify = new DingNotify();
+                    DingMsg dingMsg = (DingMsg) msg;
+                    threadPool.execute(new NotifyTask<>(dingNotify, notifyReceiver.getReceiver(), dingMsg));
                 }
                 break;
             case sms:

+ 4 - 4
dmaster/src/main/resources/application.yml

@@ -4,16 +4,16 @@ server:
     session:
       timeout: 86400
 spring:
+  servlet:
+    multipart:
+      max-file-size: 1GB
+      max-request-size: 1GB
   application:
     name: autodop-master
   profiles:
     active: @profile.active@
   banner:
     location: classpath:banner.txt
-  servlet:
-    multipart:
-      max-file-size: 1GB
-      max-request-size: 1GB
 #  cache:
 #    cache-names: buildDeployApp
   datasource: