|
|
@@ -1,76 +1,205 @@
|
|
|
package cn.reghao.autodop.dmaster.app.service.impl;
|
|
|
|
|
|
+import cn.reghao.autodop.common.mqtt.AsyncMqttClient;
|
|
|
+import cn.reghao.autodop.common.msg.rpc.constant.AppRpcClazz;
|
|
|
+import cn.reghao.autodop.common.msg.rpc.dto.app.DeployParam;
|
|
|
import cn.reghao.autodop.common.util.thread.ThreadPoolWrapper;
|
|
|
+import cn.reghao.autodop.dmaster.app.db.crud.AppBuildingCrud;
|
|
|
+import cn.reghao.autodop.dmaster.app.db.crud.AppDeployingCrud;
|
|
|
+import cn.reghao.autodop.dmaster.app.db.crud.log.BuildLogCrud;
|
|
|
+import cn.reghao.autodop.dmaster.app.db.query.AppBuildingQuery;
|
|
|
+import cn.reghao.autodop.dmaster.app.db.query.AppDeployingQuery;
|
|
|
import cn.reghao.autodop.dmaster.app.db.query.config.AppConfigQuery;
|
|
|
-import cn.reghao.autodop.dmaster.app.db.repository.AppBuildingRepository;
|
|
|
-import cn.reghao.autodop.dmaster.app.db.repository.AppDeployingRepository;
|
|
|
-import cn.reghao.autodop.dmaster.app.db.repository.log.BuildLogRepository;
|
|
|
+import cn.reghao.autodop.dmaster.app.db.query.log.BuildLogQuery;
|
|
|
+import cn.reghao.autodop.dmaster.app.model.po.AppBuilding;
|
|
|
+import cn.reghao.autodop.dmaster.app.model.po.AppDeploying;
|
|
|
+import cn.reghao.autodop.dmaster.app.model.po.config.AppConfig;
|
|
|
+import cn.reghao.autodop.dmaster.app.model.po.log.BuildLog;
|
|
|
+import cn.reghao.autodop.dmaster.app.service.AppBuildSupplier;
|
|
|
import cn.reghao.autodop.dmaster.app.service.BuildDeployService;
|
|
|
import cn.reghao.autodop.dmaster.app.service.AppDeployer;
|
|
|
import cn.reghao.autodop.dmaster.app.service.AppBuilder;
|
|
|
import cn.reghao.autodop.dmaster.notification.service.NotifyService;
|
|
|
import cn.reghao.autodop.dmaster.spring.interceptor.AppIntegrateReinitInterceptor;
|
|
|
+import cn.reghao.jdkutil.result.ResultStatus;
|
|
|
+import cn.reghao.jdkutil.serializer.JsonConverter;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.eclipse.paho.client.mqttv3.MqttException;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
-import java.util.Map;
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.List;
|
|
|
import java.util.Set;
|
|
|
-import java.util.concurrent.ConcurrentHashMap;
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
|
import java.util.concurrent.ConcurrentSkipListSet;
|
|
|
import java.util.concurrent.ExecutorService;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* @author reghao
|
|
|
* @date 2021-09-17 11:30:16
|
|
|
*/
|
|
|
+@Slf4j
|
|
|
@Service
|
|
|
public class BuildDeployServiceImpl implements BuildDeployService {
|
|
|
- private AppBuildingRepository appBuildingRepository;
|
|
|
- private AppDeployingRepository appDeployingRepository;
|
|
|
- private BuildLogRepository buildLogRepository;
|
|
|
- private AppIntegrateReinitInterceptor reinitInterceptor;
|
|
|
- // TODO 多线程访问的集合
|
|
|
- private Set<String> onBuilding = new ConcurrentSkipListSet<>();
|
|
|
- private Set<String> onDeploying = new ConcurrentSkipListSet<>();
|
|
|
- private Map<String, AppBuilder> integrateMap = new ConcurrentHashMap<>();
|
|
|
- private AppConfigQuery appConfigQuery;
|
|
|
- private ExecutorService threadPool;
|
|
|
- private AppDeployer appDeployer;
|
|
|
- private NotifyService notifyService;
|
|
|
-
|
|
|
- public BuildDeployServiceImpl(AppBuildingRepository appBuildingRepository,
|
|
|
- AppDeployingRepository appDeployingRepository,
|
|
|
- AppIntegrateReinitInterceptor reinitInterceptor,
|
|
|
- AppConfigQuery appConfigQuery,
|
|
|
- BuildLogRepository buildLogRepository,
|
|
|
- NotifyService notify,
|
|
|
- AppDeployer appDeployer) {
|
|
|
- this.appBuildingRepository = appBuildingRepository;
|
|
|
- this.appDeployingRepository = appDeployingRepository;
|
|
|
- this.reinitInterceptor = reinitInterceptor;
|
|
|
- this.appConfigQuery = appConfigQuery;
|
|
|
- this.buildLogRepository = buildLogRepository;
|
|
|
- this.notifyService = notify;
|
|
|
- this.appDeployer = appDeployer;
|
|
|
+ private final Set<String> onBuilding = new ConcurrentSkipListSet<>();
|
|
|
+ private final ExecutorService threadPool;
|
|
|
+ private final AsyncMqttClient mqttClient;
|
|
|
+ private final AppDeployer appDeployer;
|
|
|
+ private final AppConfigQuery appConfigQuery;
|
|
|
+ private final AppBuildingQuery buildingQuery;
|
|
|
+ private final AppBuildingCrud buildingCrud;
|
|
|
+ private final AppDeployingQuery deployingQuery;
|
|
|
+ private final AppDeployingCrud deployingCrud;
|
|
|
+ private final BuildLogQuery buildLogQuery;
|
|
|
+ private final BuildLogCrud buildLogCrud;
|
|
|
+
|
|
|
+ public BuildDeployServiceImpl(AsyncMqttClient mqttClient, AppDeployer appDeployer, AppConfigQuery appConfigQuery,
|
|
|
+ AppBuildingQuery buildingQuery, AppBuildingCrud buildingCrud,
|
|
|
+ AppDeployingQuery deployingQuery, AppDeployingCrud deployingCrud,
|
|
|
+ BuildLogQuery buildLogQuery, BuildLogCrud buildLogCrud) {
|
|
|
this.threadPool = ThreadPoolWrapper.threadPool("build-deploy");
|
|
|
+ this.mqttClient = mqttClient;
|
|
|
+ this.appDeployer = appDeployer;
|
|
|
+ this.appConfigQuery = appConfigQuery;
|
|
|
+ this.buildingQuery = buildingQuery;
|
|
|
+ this.buildingCrud = buildingCrud;
|
|
|
+ this.deployingQuery = deployingQuery;
|
|
|
+ this.deployingCrud = deployingCrud;
|
|
|
+ this.buildLogQuery = buildLogQuery;
|
|
|
+ this.buildLogCrud = buildLogCrud;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public String buildAndDeploy(String appId) {
|
|
|
- return "";
|
|
|
+ build(appId);
|
|
|
+
|
|
|
+ if (!onBuilding.add(appId)) {
|
|
|
+ return appId + " 正在构建中";
|
|
|
+ }
|
|
|
+
|
|
|
+ AppConfig app = appConfigQuery.findByAppId(appId);
|
|
|
+ if (app == null) {
|
|
|
+ onBuilding.remove(appId);
|
|
|
+ //throw new Exception(appId + " 不存在");
|
|
|
+ }
|
|
|
+ AppBuilder appIntegrate = new AppBuilder(app);
|
|
|
+
|
|
|
+ AppBuildSupplier supplier = new AppBuildSupplier(appIntegrate);
|
|
|
+ log.info("开始异步构建 {}", appId);
|
|
|
+ CompletableFuture.supplyAsync(supplier, threadPool)
|
|
|
+ .whenComplete((buildLog, throwable) -> {
|
|
|
+ onBuilding.remove(appId);
|
|
|
+ if (throwable != null) {
|
|
|
+ String msg = throwable.getMessage();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ buildLog = buildLogCrud.save(buildLog);
|
|
|
+ AppBuilding appBuilding = buildingQuery.findByAppId(appId);
|
|
|
+ if (appBuilding != null) {
|
|
|
+ appBuilding.update(buildLog);
|
|
|
+ buildingCrud.save(appBuilding);
|
|
|
+ }
|
|
|
+
|
|
|
+ List<AppDeploying> appDeployings = deployingQuery.findByAppId(appId);
|
|
|
+ if (!appDeployings.isEmpty()) {
|
|
|
+ for (AppDeploying appDeploying : appDeployings) {
|
|
|
+ appDeploying.setBuildLogId(buildLog.getId());
|
|
|
+ }
|
|
|
+ deployingCrud.saveAll(appDeployings);
|
|
|
+ }
|
|
|
+ log.info("{} 构建完成", appId);
|
|
|
+ })
|
|
|
+ .thenAccept(buildLog -> {
|
|
|
+ if (buildLog.getResult().getCode() == ResultStatus.SUCCESS.getCode()) {
|
|
|
+ log.info("开始部署 {}", appId);
|
|
|
+ try {
|
|
|
+ appDeployer.deploy(buildLog);
|
|
|
+ } catch (MqttException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return appId + " 已开始构建";
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public String build(String appId) {
|
|
|
- return "";
|
|
|
+ if (!onBuilding.add(appId)) {
|
|
|
+ return appId + " 正在构建中";
|
|
|
+ }
|
|
|
+
|
|
|
+ AppConfig app = appConfigQuery.findByAppId(appId);
|
|
|
+ if (app == null) {
|
|
|
+ onBuilding.remove(appId);
|
|
|
+ //throw new Exception(appId + " 不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ AppBuilder appIntegrate = new AppBuilder(app);
|
|
|
+ AppBuildSupplier supplier = new AppBuildSupplier(appIntegrate);
|
|
|
+ log.info("开始异步构建 {}", appId);
|
|
|
+ CompletableFuture.supplyAsync(supplier, threadPool)
|
|
|
+ .whenComplete((buildLog, throwable) -> {
|
|
|
+ onBuilding.remove(appId);
|
|
|
+ if (throwable != null) {
|
|
|
+ String msg = throwable.getMessage();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ buildLog = buildLogCrud.save(buildLog);
|
|
|
+ AppBuilding appBuilding = buildingQuery.findByAppId(appId);
|
|
|
+ if (appBuilding != null) {
|
|
|
+ appBuilding.update(buildLog);
|
|
|
+ buildingCrud.save(appBuilding);
|
|
|
+ }
|
|
|
+
|
|
|
+ List<AppDeploying> appDeployings = deployingQuery.findByAppId(appId);
|
|
|
+ if (!appDeployings.isEmpty()) {
|
|
|
+ for (AppDeploying appDeploying : appDeployings) {
|
|
|
+ appDeploying.setBuildLogId(buildLog.getId());
|
|
|
+ }
|
|
|
+ deployingCrud.saveAll(appDeployings);
|
|
|
+ }
|
|
|
+ log.info("{} 构建完成", appId);
|
|
|
+ })
|
|
|
+ .thenAccept(buildLog -> {
|
|
|
+ });
|
|
|
+ return appId + " 已开始构建";
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public String build(String appId, String commitId) {
|
|
|
- return "";
|
|
|
+ public boolean deploy(String buildLogId) {
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public boolean deploy(String appId, String commitId) {
|
|
|
- return false;
|
|
|
+ public void downloadPackage(String buildLogId) {
|
|
|
+ BuildLog buildLog = buildLogQuery.findById(buildLogId);
|
|
|
+ if (buildLog == null) {
|
|
|
+ String msg = "构建不存在";
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ String packagePath = buildLog.getPackagePath();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<String> currentlyBuilding() {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<String> currentlyDeploying() {
|
|
|
+ List<DeployParam> list = mqttClient.unreturnedRpc().values().stream()
|
|
|
+ .filter(rpcMsg -> {
|
|
|
+ String clazz = rpcMsg.getClazz();
|
|
|
+ String method = rpcMsg.getMethod();
|
|
|
+ return clazz.equals(AppRpcClazz.class.getSimpleName()) && method.equals(AppRpcClazz.deploy.name());
|
|
|
+ })
|
|
|
+ .map(rpcMsg -> JsonConverter.jsonToObject(rpcMsg.getJsonParam(), DeployParam.class))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ return list.stream().map(DeployParam::getAppId).collect(Collectors.toList());
|
|
|
}
|
|
|
}
|