123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- package com.qmth.ops.biz.service;
- import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
- import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
- import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
- import com.qmth.boot.core.exception.ParameterException;
- import com.qmth.boot.core.exception.StatusException;
- import com.qmth.ops.biz.dao.PropertyItemDao;
- 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 PropertyService extends ServiceImpl<PropertyItemDao, PropertyItem> {
- private static final long BASELINE_ENV_ID = 0L;
- private static final String APP_VERSION_KEY = "com.qmth.solar.app-version";
- private static final String APP_CODE_KEY = "com.qmth.solar.app-code";
- @Resource
- private EnvService envService;
- @Resource
- private PropertyGroupService propertyGroupService;
- @Resource
- private PropertyItemDao propertyItemDao;
- public List<PropertyItem> listBaseline(Long versionId, Long moduleId) {
- return propertyItemDao.selectList(
- new LambdaQueryWrapper<PropertyItem>().eq(PropertyItem::getVersionId, versionId)
- .eq(PropertyItem::getModuleId, moduleId).eq(PropertyItem::getEnvId, BASELINE_ENV_ID)
- .orderByAsc(PropertyItem::getKey));
- }
- @Transactional
- public List<PropertyItem> updateBaseline(@NotNull Version version, @NotNull Module module,
- @NotNull InputStream file, @NotNull FileFormat format, Version inheritVersion) throws IOException {
- if (!version.getAppId().equals(module.getAppId())) {
- throw new ParameterException("指定版本与模块不匹配");
- }
- if (version.getArchived()) {
- throw new ParameterException("指定版本已归档不能操作");
- }
- if (format != FileFormat.PROPERTY) {
- throw new ParameterException("暂不支持非properties类型文件");
- }
- long time = System.currentTimeMillis();
- final Map<String, PropertyItem> baseMap = new HashMap<>();
- if (inheritVersion != null) {
- listBaseline(inheritVersion.getId(), module.getId()).forEach(item -> baseMap.put(item.getKey(), item));
- } else {
- listBaseline(version.getId(), module.getId()).forEach(item -> baseMap.put(item.getKey(), item));
- }
- propertyItemDao.delete(new LambdaUpdateWrapper<PropertyItem>().eq(PropertyItem::getVersionId, version.getId())
- .eq(PropertyItem::getModuleId, module.getId()).eq(PropertyItem::getEnvId, BASELINE_ENV_ID));
- List<PropertyItem> list = PropertyFileUtil.read(file);
- for (PropertyItem item : list) {
- item.setVersionId(version.getId());
- item.setModuleId(module.getId());
- item.setEnvId(BASELINE_ENV_ID);
- item.setCreateTime(time);
- item.setUpdateTime(time);
- PropertyItem base = baseMap.get(item.getKey());
- if (base != null) {
- item.setMode(base.getMode());
- item.setComment(base.getComment());
- } else {
- item.setMode(PropertyMode.MUTABLE);
- }
- }
- saveBatch(list);
- List<PropertyItem> baseline = listBaseline(version.getId(), module.getId());
- baseMap.clear();
- baseline.forEach(item -> baseMap.put(item.getKey(), item));
- List<Env> envList = envService.list(version.getAppId());
- for (Env env : envList) {
- resetEnvProperty(version, module, env, inheritVersion, baseMap);
- }
- return baseline;
- }
- /**
- * 根据指定版本和最新基线,继承环境自定义配置
- *
- * @param version
- * @param module
- * @param env
- * @param inheritVersion
- * @param baseMap
- */
- private void resetEnvProperty(Version version, Module module, Env env, Version inheritVersion,
- Map<String, PropertyItem> baseMap) {
- List<PropertyItem> currentList = listPropertyItem(version.getId(), module.getId(), env.getId());
- propertyItemDao.delete(new LambdaUpdateWrapper<PropertyItem>().eq(PropertyItem::getVersionId, version.getId())
- .eq(PropertyItem::getModuleId, module.getId()).eq(PropertyItem::getEnvId, env.getId()));
- long time = System.currentTimeMillis();
- Map<String, PropertyItem> saveMap = new HashMap<>();
- for (PropertyItem item : currentList) {
- if (accept(item, baseMap)) {
- saveMap.put(item.getKey(), item);
- }
- }
- if (inheritVersion != null) {
- List<PropertyItem> inheritList = listPropertyItem(inheritVersion.getId(), module.getId(), env.getId());
- for (PropertyItem item : inheritList) {
- if (!saveMap.containsKey(item.getKey()) && accept(item, baseMap)) {
- item.setVersionId(version.getId());
- item.setCreateTime(time);
- item.setUpdateTime(time);
- saveMap.put(item.getKey(), item);
- }
- }
- }
- saveBatch(saveMap.values());
- }
- /**
- * 继承版本的环境自定义配置,是否可以在当前版本保留
- *
- * @param item
- * @return
- */
- private boolean accept(PropertyItem item, Map<String, PropertyItem> baseMap) {
- //当前基线包含且非只读,可以保留
- PropertyItem base = baseMap.get(item.getKey());
- if (base != null && base.getMode() != PropertyMode.READONLY) {
- return true;
- }
- //配置分组判断是否保留
- if (propertyGroupService.accept(item.getKey(), item.getValue())) {
- return true;
- }
- //应用自定义且不在基线内,不能保留
- return false;
- }
- @Transactional
- public PropertyItem updateBaselineItem(PropertyItem item) {
- propertyItemDao.update(item, new LambdaUpdateWrapper<PropertyItem>()
- .set(item.getMode() != null, PropertyItem::getMode, item.getMode())
- .set(item.getComment() != null, PropertyItem::getComment, item.getComment())
- .eq(PropertyItem::getVersionId, item.getVersionId()).eq(PropertyItem::getModuleId, item.getModuleId())
- .eq(PropertyItem::getEnvId, BASELINE_ENV_ID).eq(PropertyItem::getKey, item.getKey()));
- return findOne(item.getVersionId(), item.getModuleId(), BASELINE_ENV_ID, item.getKey());
- }
- public List<PropertyItem> listPropertyItem(Long versionId, Long moduleId, Long envId) {
- return propertyItemDao.selectList(
- new LambdaQueryWrapper<PropertyItem>().eq(PropertyItem::getVersionId, versionId)
- .eq(PropertyItem::getModuleId, moduleId).eq(PropertyItem::getEnvId, envId)
- .orderByAsc(PropertyItem::getKey));
- }
- @Transactional
- public PropertyItem updatePropertyItem(PropertyItem item) {
- PropertyItem base = findOne(item.getVersionId(), item.getModuleId(), BASELINE_ENV_ID, item.getKey());
- PropertyItem previous = findOne(item.getVersionId(), item.getModuleId(), item.getEnvId(), item.getKey());
- if (base != null && base.getMode() == PropertyMode.READONLY) {
- throw new ParameterException("配置项只读");
- }
- if (item.getValue() == null) {
- throw new ParameterException("配置值不能为空");
- }
- if (previous != null) {
- propertyItemDao.update(previous,
- new LambdaUpdateWrapper<PropertyItem>().set(PropertyItem::getValue, item.getValue())
- .set(item.getComment() != null, PropertyItem::getComment, item.getComment())
- .set(PropertyItem::getUpdateTime, System.currentTimeMillis())
- .eq(PropertyItem::getVersionId, item.getVersionId())
- .eq(PropertyItem::getModuleId, item.getModuleId())
- .eq(PropertyItem::getEnvId, item.getEnvId()).eq(PropertyItem::getKey, item.getKey()));
- return findOne(item.getVersionId(), item.getModuleId(), item.getEnvId(), item.getKey());
- } else {
- item.setMode(PropertyMode.MUTABLE);
- item.setCreateTime(System.currentTimeMillis());
- item.setUpdateTime(item.getCreateTime());
- propertyItemDao.insert(item);
- return item;
- }
- }
- @Transactional
- public void deletePropertyItem(PropertyItem item) {
- PropertyItem base = findOne(item.getVersionId(), item.getModuleId(), BASELINE_ENV_ID, item.getKey());
- if (base != null) {
- throw new ParameterException("存在基线配置项时不能删除");
- }
- PropertyItem current = findOne(item.getVersionId(), item.getModuleId(), item.getEnvId(), item.getKey());
- if (current == null) {
- throw new ParameterException("配置项不存在");
- }
- propertyItemDao
- .delete(new LambdaQueryWrapper<PropertyItem>().eq(PropertyItem::getVersionId, item.getVersionId())
- .eq(PropertyItem::getModuleId, item.getModuleId()).eq(PropertyItem::getEnvId, item.getEnvId())
- .eq(PropertyItem::getKey, item.getKey()));
- }
- public PropertyItem findOne(Long versionId, Long moduleId, Long envId, String key) {
- return propertyItemDao.selectOne(
- new LambdaQueryWrapper<PropertyItem>().eq(PropertyItem::getVersionId, versionId)
- .eq(PropertyItem::getModuleId, moduleId).eq(PropertyItem::getEnvId, envId)
- .eq(PropertyItem::getKey, key));
- }
- public List<PropertyItem> mergePropertyList(String appCode, Version version, Long moduleId, Long envId) {
- List<PropertyItem> list = listBaseline(version.getId(), moduleId);
- //获取环境定义配置项
- Map<String, PropertyItem> itemMap = listPropertyItem(version.getId(), moduleId, envId).stream()
- .collect(Collectors.toMap(PropertyItem::getKey, Function.identity()));
- //遍历基线
- for (PropertyItem item : list) {
- PropertyItem update = itemMap.get(item.getKey());
- //非只读配置项更新
- if (update != null && item.getMode() != PropertyMode.READONLY) {
- item.setValue(update.getValue());
- }
- //需要覆盖的配置项不能校验
- else if (update == null && item.getMode() == PropertyMode.OVERRIDE) {
- throw new StatusException("配置项需要覆盖新值:" + item.getKey());
- }
- itemMap.remove(item.getKey());
- }
- //合并新增配置项
- if (!itemMap.isEmpty()) {
- list.addAll(itemMap.values());
- }
- //强制增加appCode与appVersion配置项,自动根据当前app和version填充
- boolean hasCode = false;
- boolean hasVersion = false;
- for (PropertyItem item : list) {
- if (item.getKey().equals(APP_CODE_KEY)) {
- item.setValue(appCode);
- hasCode = true;
- } else if (item.getKey().equals(APP_VERSION_KEY)) {
- item.setValue(version.getName());
- hasVersion = true;
- }
- }
- if (!hasCode) {
- PropertyItem item = new PropertyItem();
- item.setKey(APP_CODE_KEY);
- item.setValue(appCode);
- list.add(item);
- }
- if (!hasVersion) {
- PropertyItem item = new PropertyItem();
- item.setKey(APP_VERSION_KEY);
- item.setValue(version.getName());
- list.add(item);
- }
- list.sort(Comparator.comparing(PropertyItem::getKey));
- return list;
- }
- }
|