|
@@ -0,0 +1,155 @@
|
|
|
+package com.qmth.ops.biz.service;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
+import com.qmth.boot.core.exception.ParameterException;
|
|
|
+import com.qmth.boot.core.exception.StatusException;
|
|
|
+import com.qmth.ops.biz.dao.ConfigItemDao;
|
|
|
+import com.qmth.ops.biz.domain.*;
|
|
|
+import com.qmth.ops.biz.utils.PropertyFileUtil;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import javax.validation.constraints.NotNull;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.InputStream;
|
|
|
+import java.util.Comparator;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.function.Function;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+@Service
|
|
|
+public class ConfigService {
|
|
|
+
|
|
|
+ private static final long BASELINE_ENV_ID = 0L;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private ConfigItemDao configItemDao;
|
|
|
+
|
|
|
+ public List<ConfigItem> listBaseline(Long appId, Long versionId, Long moduleId) {
|
|
|
+ return configItemDao.selectList(new LambdaQueryWrapper<ConfigItem>().eq(ConfigItem::getAppId, appId)
|
|
|
+ .eq(ConfigItem::getVersionId, versionId).eq(ConfigItem::getModuleId, moduleId)
|
|
|
+ .eq(ConfigItem::getEnvId, BASELINE_ENV_ID).orderByAsc(ConfigItem::getKey));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Transactional
|
|
|
+ public List<ConfigItem> updateBaseline(@NotNull App app, @NotNull Version version, @NotNull Module module,
|
|
|
+ @NotNull InputStream file, Version inheritVersion) throws IOException {
|
|
|
+ if (!version.getAppId().equals(app.getId())) {
|
|
|
+ throw new ParameterException("指定版本不属于该应用");
|
|
|
+ }
|
|
|
+ if (!version.getArchived()) {
|
|
|
+ throw new ParameterException("指定版本已归档不能操作");
|
|
|
+ }
|
|
|
+ if (!module.getAppId().equals(app.getId())) {
|
|
|
+ throw new ParameterException("指定模块不属于该应用");
|
|
|
+ }
|
|
|
+ long time = System.currentTimeMillis();
|
|
|
+ configItemDao.delete(new LambdaUpdateWrapper<ConfigItem>().eq(ConfigItem::getAppId, app.getId())
|
|
|
+ .eq(ConfigItem::getVersionId, version.getId()).eq(ConfigItem::getModuleId, module.getId())
|
|
|
+ .eq(ConfigItem::getEnvId, BASELINE_ENV_ID));
|
|
|
+ Map<String, ConfigItem> baseMap = new HashMap<>();
|
|
|
+ if (inheritVersion != null) {
|
|
|
+ listBaseline(app.getId(), inheritVersion.getId(), module.getId())
|
|
|
+ .forEach(item -> baseMap.put(item.getKey(), item));
|
|
|
+ }
|
|
|
+ List<ConfigItem> list = PropertyFileUtil.read(file);
|
|
|
+ for (ConfigItem item : list) {
|
|
|
+ item.setAppId(app.getId());
|
|
|
+ item.setVersionId(version.getId());
|
|
|
+ item.setModuleId(module.getId());
|
|
|
+ item.setEnvId(BASELINE_ENV_ID);
|
|
|
+ item.setCreateTime(time);
|
|
|
+ item.setUpdateTime(time);
|
|
|
+ ConfigItem base = baseMap.get(item.getKey());
|
|
|
+ if (base != null) {
|
|
|
+ item.setMode(base.getMode());
|
|
|
+ item.setComment(base.getComment());
|
|
|
+ }
|
|
|
+ configItemDao.insert(item);
|
|
|
+ }
|
|
|
+ return listBaseline(app.getId(), version.getId(), module.getId());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Transactional
|
|
|
+ public ConfigItem updateBaselineItem(ConfigItem item) {
|
|
|
+ configItemDao.update(item,
|
|
|
+ new LambdaUpdateWrapper<ConfigItem>().set(item.getMode() != null, ConfigItem::getMode, item.getMode())
|
|
|
+ .set(item.getComment() != null, ConfigItem::getComment, item.getComment())
|
|
|
+ .eq(ConfigItem::getAppId, item.getAppId()).eq(ConfigItem::getVersionId, item.getVersionId())
|
|
|
+ .eq(ConfigItem::getModuleId, item.getModuleId()).eq(ConfigItem::getEnvId, BASELINE_ENV_ID)
|
|
|
+ .eq(ConfigItem::getKey, item.getKey()));
|
|
|
+ return findOne(item.getAppId(), item.getVersionId(), item.getModuleId(), BASELINE_ENV_ID, item.getKey());
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<ConfigItem> listConfigItem(Long appId, Long versionId, Long moduleId, Long envId) {
|
|
|
+ return configItemDao.selectList(new LambdaQueryWrapper<ConfigItem>().eq(ConfigItem::getAppId, appId)
|
|
|
+ .eq(ConfigItem::getVersionId, versionId).eq(ConfigItem::getModuleId, moduleId)
|
|
|
+ .eq(ConfigItem::getEnvId, envId).orderByAsc(ConfigItem::getKey));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Transactional
|
|
|
+ public ConfigItem updateConfigItem(ConfigItem item) {
|
|
|
+ ConfigItem base = findOne(item.getAppId(), item.getVersionId(), item.getModuleId(), BASELINE_ENV_ID,
|
|
|
+ item.getKey());
|
|
|
+ ConfigItem previous = findOne(item.getAppId(), item.getVersionId(), item.getModuleId(), item.getEnvId(),
|
|
|
+ item.getKey());
|
|
|
+ if (base != null && base.getMode() == ConfigMode.READONLY) {
|
|
|
+ throw new ParameterException("配置项只读");
|
|
|
+ }
|
|
|
+ if (item.getValue() == null) {
|
|
|
+ throw new ParameterException("配置值不能为空");
|
|
|
+ }
|
|
|
+ if (previous != null) {
|
|
|
+ configItemDao.update(previous,
|
|
|
+ new LambdaUpdateWrapper<ConfigItem>().set(ConfigItem::getValue, item.getValue())
|
|
|
+ .set(item.getComment() != null, ConfigItem::getComment, item.getComment())
|
|
|
+ .set(ConfigItem::getUpdateTime, System.currentTimeMillis())
|
|
|
+ .eq(ConfigItem::getAppId, item.getAppId()).eq(ConfigItem::getVersionId, item.getVersionId())
|
|
|
+ .eq(ConfigItem::getModuleId, item.getModuleId()).eq(ConfigItem::getEnvId, item.getEnvId())
|
|
|
+ .eq(ConfigItem::getKey, item.getKey()));
|
|
|
+ return findOne(item.getAppId(), item.getVersionId(), item.getModuleId(), item.getEnvId(), item.getKey());
|
|
|
+ } else {
|
|
|
+ item.setCreateTime(System.currentTimeMillis());
|
|
|
+ item.setUpdateTime(item.getCreateTime());
|
|
|
+ configItemDao.insert(item);
|
|
|
+ return item;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public ConfigItem findOne(Long appId, Long versionId, Long moduleId, Long envId, String key) {
|
|
|
+ return configItemDao.selectOne(new LambdaQueryWrapper<ConfigItem>().eq(ConfigItem::getAppId, appId)
|
|
|
+ .eq(ConfigItem::getVersionId, versionId).eq(ConfigItem::getModuleId, moduleId)
|
|
|
+ .eq(ConfigItem::getEnvId, envId).eq(ConfigItem::getKey, key));
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<ConfigItem> mergeConfigList(Long appId, Long versionId, Long moduleId, Long envId) {
|
|
|
+ List<ConfigItem> list = listBaseline(appId, versionId, moduleId);
|
|
|
+ //获取环境定义配置项
|
|
|
+ Map<String, ConfigItem> itemMap = listConfigItem(appId, versionId, moduleId, envId).stream()
|
|
|
+ .collect(Collectors.toMap(ConfigItem::getKey, Function.identity()));
|
|
|
+ //遍历基线
|
|
|
+ for (ConfigItem item : list) {
|
|
|
+ ConfigItem update = itemMap.get(item.getKey());
|
|
|
+ //非只读配置项更新
|
|
|
+ if (update != null && item.getMode() != ConfigMode.READONLY) {
|
|
|
+ item.setValue(update.getValue());
|
|
|
+ }
|
|
|
+ //需要覆盖的配置项不能校验
|
|
|
+ else if (update == null && item.getMode() == ConfigMode.OVERRIDE) {
|
|
|
+ throw new StatusException("配置项需要覆盖新值:" + item.getKey());
|
|
|
+ }
|
|
|
+ itemMap.remove(item.getKey());
|
|
|
+ }
|
|
|
+ //合并新增配置项
|
|
|
+ if (!itemMap.isEmpty()) {
|
|
|
+ list.addAll(itemMap.values());
|
|
|
+ list.sort(Comparator.comparing(ConfigItem::getKey));
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|