Commit b515f7e7 by jiaotianqi

灰度管理

parent a95a6b61
package com.gic.operation.web.controller.gray;
import com.gic.api.base.commons.Constant;
import com.gic.api.base.commons.Page;
import com.gic.commons.exception.BaseRuntimeException;
import com.gic.commons.exception.ExceptionManager;
import com.gic.commons.webapi.reponse.RestResponse;
import com.gic.dsmongo.api.dto.Criteria;
import com.gic.dsmongo.api.dto.MongoDelBatchDTO;
import com.gic.dsmongo.api.dto.MongoQueryDTO;
import com.gic.dsmongo.api.dto.MongoSaveDTO;
import com.gic.gray.config.dto.GrayConfig;
import com.gic.gray.config.dto.GrayModuleConfig;
import com.gic.gray.config.dto.JavaModuleDeployInfo;
import com.gic.gray.config.util.GrayConfigUtil;
import com.gic.gray.config.util.MongoOperaUtil;
import com.gic.operation.web.qo.GrayConfigQo;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
import java.util.stream.Collectors;
/**
* 灰度管理controller
*
* @author jiaotianqi
* @date 2021/7/26 10:39
*/
@RestController
@RequestMapping("/gray")
public class GrayManagerController {
@RequestMapping("/add-gray-config")
public RestResponse addGrayConfig(@Validated @RequestBody GrayConfigQo grayConfigQo) {
MongoQueryDTO mongoQueryDTO = new MongoQueryDTO();
mongoQueryDTO.setDataBaseAndCollectionName("gic-deploy-git-4", "gray_module_config", "id");
mongoQueryDTO.setCriteria(Criteria.where("_id").eq(GrayConfigUtil.getClusterName() + ":" + grayConfigQo.getModuleName()));
Map result = MongoOperaUtil.get(mongoQueryDTO).getResult();
if (result != null) {
ExceptionManager.throwException("模块已经存在", BaseRuntimeException.class);
}
GrayModuleConfig grayModuleConfig = new GrayModuleConfig();
grayModuleConfig.setId(GrayConfigUtil.getClusterName() + ":" + grayConfigQo.getModuleName());
grayModuleConfig.setCluster_name(GrayConfigUtil.getClusterName());
grayModuleConfig.setFront_end(grayConfigQo.getFrontEnd());
grayModuleConfig.setGray_enable(grayConfigQo.getGrayEnable());
grayModuleConfig.setGray_type(grayConfigQo.getGrayType());
grayModuleConfig.setModule_name(grayConfigQo.getModuleName());
MongoSaveDTO saveDto = new MongoSaveDTO();
saveDto.setDataBaseAndCollectionName("gic-deploy-git-4", "gray_module_config", "id");
saveDto.setData(grayModuleConfig);
boolean save = MongoOperaUtil.save(saveDto);
if (save) {
GrayConfigUtil.refreshGrayConfig(Arrays.asList(grayConfigQo.getModuleName()));
}
return RestResponse.success(save);
}
@RequestMapping("/update")
public RestResponse update(@Validated @RequestBody GrayConfigQo grayConfigQo) {
GrayConfig newGrayConfig = new GrayConfig();
newGrayConfig.setGrayEnable(grayConfigQo.getGrayEnable());
newGrayConfig.setGrayType(grayConfigQo.getGrayType());
if (CollectionUtils.isNotEmpty(grayConfigQo.getApplicationNameList())) {
GrayConfigUtil.updateGrayConfig(newGrayConfig, grayConfigQo.getApplicationNameList());
}
return RestResponse.success();
}
@RequestMapping("/delete")
public RestResponse delete(@RequestBody GrayConfigQo grayConfigQo) {
MongoDelBatchDTO delDto=new MongoDelBatchDTO();
MongoQueryDTO mongoQueryDTO = new MongoQueryDTO();
mongoQueryDTO.setCriteria(Criteria.where("_id").eq(GrayConfigUtil.getClusterName()+":"+grayConfigQo.getModuleName()));
delDto.setCriterias(mongoQueryDTO);
delDto.setDataBaseAndCollectionName("gic-deploy-git-4", "gray_module_config", "id");
boolean delete = MongoOperaUtil.delete(delDto);
return RestResponse.success(delete);
}
@RequestMapping("/query-by-page")
public RestResponse<Page<JavaModuleDeployInfo>> queryByPage(String moduleName, Boolean grayFlag, Integer currPage, Integer pageSize, Boolean frontEnd) {
Page<JavaModuleDeployInfo> javaModuleDeployInfoPage = GrayConfigUtil.queryModuleConfig(currPage, pageSize, moduleName, grayFlag, frontEnd);
return RestResponse.success(javaModuleDeployInfoPage);
}
@RequestMapping("/refresh-redis-gray-config")
public RestResponse refreshRedisGrayConfig() {
GrayConfigUtil.refreshGrayConfig(null, true, false);
GrayConfigUtil.refreshGrayConfigChangeTimeByZk();
return RestResponse.success();
}
/**
* 查询集群名称
*
* @return
*/
@RequestMapping("/query-cluster-name")
public RestResponse<List<String>> queryClusterName() {
MongoQueryDTO queryDto = new MongoQueryDTO();
queryDto.setShowField("_id");
queryDto.setDataBaseAndCollectionName("gic-deploy-git-4", "cluster_config", "id");
List<String> clusterNameList = MongoOperaUtil.query(queryDto).getResult().stream().map(d -> d.get("id").toString()).filter(d -> !d.endsWith("-gray")).collect(Collectors.toList());
return RestResponse.success(clusterNameList);
}
/**
* 查询模块名称
*
* @param type 1 灰度管理页面 2 路由管理页面
* @return
*/
@RequestMapping("/query-module-name")
public RestResponse<List<String>> queryModuleName(@RequestParam(defaultValue = "1") Integer type) {
MongoQueryDTO queryModuleConfig = new MongoQueryDTO();
queryModuleConfig.setShowField("_id,is_dubbo_service");
queryModuleConfig.setDataBaseAndCollectionName("gic-deploy-git-4", "java_module_config", "_id");
List<String> moduleNameList = null;
if (Objects.equals(type, Constant.NUMBER_1)) {
MongoQueryDTO queryDto = new MongoQueryDTO();
queryDto.setShowField("module_name");
queryDto.setCriteria(Arrays.asList(Criteria.where("cluster_name").eq(GrayConfigUtil.getClusterName()),
Criteria.where("front_end").eq(false)));
queryDto.setDataBaseAndCollectionName("gic-deploy-git-4", "gray_module_config", "_id");
Set<String> moduleNameSet = MongoOperaUtil.query(queryDto).getResult().stream().map(d -> d.get("module_name").toString()).collect(Collectors.toSet());
moduleNameList = MongoOperaUtil.query(queryModuleConfig).getResult().stream().map(d -> d.get("id").toString()).filter(d -> !moduleNameSet.contains(d)).collect(Collectors.toList());
} else {
MongoQueryDTO queryDto = new MongoQueryDTO();
queryDto.setShowField("_id");
queryDto.setCriteria(Criteria.where("front_end").eq(false));
queryDto.setDataBaseAndCollectionName("gic-deploy-git-4", "nginx_module_config", "_id");
Set<String> moduleNameSet = MongoOperaUtil.query(queryDto).getResult().stream().map(d -> d.get("id").toString()).collect(Collectors.toSet());
moduleNameList = MongoOperaUtil.query(queryModuleConfig).getResult().stream().filter(
d -> !moduleNameSet.contains(d.get("id").toString()) && Optional.ofNullable(d.get("is_dubbo_service")).orElse("").toString().endsWith("false")).map(d -> d.get("id").toString()).collect(Collectors.toList());
}
return RestResponse.success(moduleNameList);
}
}
package com.gic.operation.web.controller.gray;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.gic.api.base.commons.Page;
import com.gic.api.base.commons.ServiceResponse;
import com.gic.commons.exception.BaseRuntimeException;
import com.gic.commons.exception.ExceptionManager;
import com.gic.commons.webapi.reponse.RestResponse;
import com.gic.dsmongo.api.dto.*;
import com.gic.dsmongo.api.utils.MongoUtil;
import com.gic.gray.config.dto.NginxLocationConfig;
import com.gic.gray.config.util.MongoOperaUtil;
import com.gic.operation.web.qo.RouteConfigQo;
import com.gic.operation.web.vo.RouteConfigVo;
import com.google.common.base.Splitter;
import jodd.util.StringUtil;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
import java.util.stream.Collectors;
/**
* 路由管理
*
* @author jiaotianqi
* @date 2021/8/5 9:54
*/
@RestController
@RequestMapping("route")
public class RouteManagerController {
@RequestMapping("/add-route-config")
public RestResponse addRouteConfig(@RequestBody RouteConfigQo routeConfigQo) {
Map nginxModuleConfig = getNginxModuleConfig(routeConfigQo.getModuleName());
if(nginxModuleConfig!=null){
ExceptionManager.throwException("模块已存在", BaseRuntimeException.class);
}
MongoSaveDTO saveDto = new MongoSaveDTO();
saveDto.setDataBaseAndCollectionName("gic-deploy-git-4", "nginx_module_config", "id");
Map<String, Object> data = new HashMap<>();
data.put("id", routeConfigQo.getModuleName());
data.put("location_regex", routeConfigQo.getRegxSymbol());
data.put("location_route", routeConfigQo.getRouteRegx());
data.put("module_path", routeConfigQo.getModulePath());
data.put("front_end", routeConfigQo.getFrontEnd());
if (routeConfigQo.getLocationConfig() != null && StringUtil.isNotBlank(routeConfigQo.getLocationConfig())) {
data.put("location_config", Splitter.on(",").splitToList(routeConfigQo.getLocationConfig()));
}
saveDto.setData(data);
boolean save = MongoOperaUtil.save(saveDto);
return RestResponse.success(save);
}
@RequestMapping("/update-route-config")
public RestResponse updateRouteConfig(@RequestBody RouteConfigQo routeConfigQo) {
MongoUpdateBatchDTO updateDataDto = new MongoUpdateBatchDTO();
updateDataDto.setDataBaseAndCollectionName("gic-deploy-git-4", "nginx_module_config", "id");
Map<String, Object> data = new HashMap<>();
data.put("id", routeConfigQo.getModuleName());
data.put("location_regex", routeConfigQo.getRegxSymbol());
data.put("location_route", routeConfigQo.getRouteRegx());
data.put("module_path", routeConfigQo.getModulePath());
data.put("front_end", routeConfigQo.getFrontEnd());
updateDataDto.setJsonData(JSON.toJSONString(Arrays.asList(data), SerializerFeature.WriteMapNullValue));
boolean updateBatch = MongoOperaUtil.updateBatch(updateDataDto);
return RestResponse.success(updateBatch);
}
@RequestMapping("/delete")
public RestResponse delete(@RequestBody RouteConfigQo routeConfigQo) {
MongoDelBatchDTO delDto=new MongoDelBatchDTO();
MongoQueryDTO mongoQueryDTO = new MongoQueryDTO();
mongoQueryDTO.setCriteria(Criteria.where("_id").eq(routeConfigQo.getModuleName()));
delDto.setCriterias(mongoQueryDTO);
delDto.setDataBaseAndCollectionName("gic-deploy-git-4", "nginx_module_config", "id");
boolean delete = MongoOperaUtil.delete(delDto);
return RestResponse.success(delete);
}
@RequestMapping("/query-route-config")
public RestResponse<Page<RouteConfigVo>> queryRouteConfig(@RequestBody RouteConfigQo routeConfigQo) {
Page pageRes = new Page();
MongoQueryDTO queryDto = new MongoQueryDTO();
queryDto.setDataBaseAndCollectionName("gic-deploy-git-4", "nginx_module_config", "id");
queryDto.setCurrentPage(routeConfigQo.getPageNum());
queryDto.setPageSize(routeConfigQo.getPageSize());
queryDto.setSort("_id=asc");
List<Criteria> queryCriteriaList = new ArrayList<>();
Optional.ofNullable(routeConfigQo.getModuleName()).ifPresent(v -> queryCriteriaList.add(Criteria.where("_id").regex(v)));
Optional.ofNullable(routeConfigQo.getFrontEnd()).ifPresent(v -> queryCriteriaList.add(Criteria.where("front_end").eq(v)));
queryDto.setCriteria(queryCriteriaList);
ServiceResponse<Page<Map>> pageServiceResponse = MongoOperaUtil.queryPage(queryDto);
if (pageServiceResponse.isSuccess()&&pageServiceResponse.getResult()!=null) {
Page<Map> result = pageServiceResponse.getResult();
pageRes.setCurrentPage(result.getCurrentPage());
pageRes.setPageSize(result.getPageSize());
pageRes.setTotalPage(result.getTotalPage());
pageRes.setTotalCount(result.getTotalCount());
pageRes.setResult(result.getResult().stream().map(d -> {
RouteConfigVo routeConfigVo = new RouteConfigVo();
routeConfigVo.setFrontEnd((Boolean) d.get("front_end"));
routeConfigVo.setModuleName(d.get("id").toString());
routeConfigVo.setRegxSymbol(d.get("location_regex").toString());
routeConfigVo.setRouteRegx(d.get("location_route").toString());
routeConfigVo.setModulePath(d.get("module_path").toString());
return routeConfigVo;
}).collect(Collectors.toList()));
}
return RestResponse.success(pageRes);
}
/**
* 回显
* @param moduleName
* @return
*/
@RequestMapping("/preview")
public RestResponse preview(String moduleName) {
NginxLocationConfig nginxLocationConfig = MongoUtil.toBean(getNginxModuleConfig(moduleName), NginxLocationConfig.class);
StringBuilder nginxLocationConfigStr = new StringBuilder();
nginxLocationConfigStr.append("location ").append(nginxLocationConfig.getLocation_regex()).append(" ").append(nginxLocationConfig.getLocation_route()).append("{ \r\n");
if (nginxLocationConfig.getFront_end()) {
//前端
if (nginxLocationConfig.getLocation_config() != null) {
for (String locationConfig : nginxLocationConfig.getLocation_config()) {
nginxLocationConfigStr.append(" ").append(locationConfig).append(";\r\n");
}
}else {
nginxLocationConfigStr.append(" set_by_lua_file $target_upstream $grayRoute ").append(nginxLocationConfig.getId()).append(" ").append(nginxLocationConfig.getId()).append(" ").append(nginxLocationConfig.getId()).append(";\r\n");
nginxLocationConfigStr.append(" alias /mydata/gicweb/$target_upstream/;\r\n");
nginxLocationConfigStr.append(" try_files $uri $uri/ /");
if(StringUtil.isNotBlank(nginxLocationConfig.getModule_path())){
nginxLocationConfigStr.append(nginxLocationConfig.getModule_path());
}else {
nginxLocationConfigStr.append(nginxLocationConfig.getId());
}
nginxLocationConfigStr.append("/index.html;\r\n}\r\n\r\n\r\n");
}
} else {
//后端
List<String> locationConfigList = null;
if (nginxLocationConfig.getLocation_config() != null) {
locationConfigList = nginxLocationConfig.getLocation_config();
} else {
MongoQueryDTO otherConfigParam = new MongoQueryDTO();
otherConfigParam.setCriteria(Criteria.where("_id").eq("nginx_location_default_config"));
otherConfigParam.setDataBaseAndCollectionName("gic-deploy-git-4", "other_config", "id");
locationConfigList = (List<String>) MongoOperaUtil.get(otherConfigParam).getResult().get("location_config");
}
for (String locationConfig : locationConfigList) {
nginxLocationConfigStr.append(" ").append(locationConfig).append(";\r\n");
}
nginxLocationConfigStr.append(" set_by_lua_file $target_upstream $grayRoute ").append(nginxLocationConfig.getId()).append(" ").append(nginxLocationConfig.getId()).append(" ").append(nginxLocationConfig.getId()).append("-gray;\r\n")
.append(" rewrite ^").append(nginxLocationConfig.getLocation_route()).append("/(.*)$ ");
if(StringUtil.isNotBlank(nginxLocationConfig.getModule_path())){
nginxLocationConfigStr.append("/").append(nginxLocationConfig.getModule_path());
}
nginxLocationConfigStr.append("/$1 break;\r\n")
.append(" proxy_pass http://$target_upstream;\r\n}");
}
return RestResponse.success(nginxLocationConfigStr.toString());
}
private Map getNginxModuleConfig(String moduleName) {
MongoQueryDTO getDto = new MongoQueryDTO();
getDto.setCriteria(Criteria.where("_id").eq(moduleName));
getDto.setDataBaseAndCollectionName("gic-deploy-git-4", "nginx_module_config", "id");
return MongoOperaUtil.get(getDto).getResult();
}
}
package com.gic.operation.web.qo;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;
/**
* 灰度配置
* @author jiaotianqi
* @date 2021/7/15 15:55
*/
public class GrayConfigQo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 是否开启灰度
*/
@NotNull(message = "是否开启灰度不能为空")
private Boolean grayEnable;
/**
* 灰度类型
* 1 全部走灰度 2 指定企业走灰度 3 全部走非灰度
*/
@NotNull(message = "灰度类型不能为空")
private Integer grayType;
/**
* 模块名称 新增需要 更新不需要
*/
private String moduleName;
/**
* 是否是前端项目 新增需要 更新不需要
*/
private Boolean frontEnd;
/**
* 应用名称
*/
private List<String> applicationNameList;
public String getModuleName() {
return moduleName;
}
public Boolean getFrontEnd() {
return frontEnd;
}
public void setFrontEnd(Boolean frontEnd) {
this.frontEnd = frontEnd;
}
public void setModuleName(String moduleName) {
this.moduleName = moduleName;
}
public List<String> getApplicationNameList() {
return applicationNameList;
}
public void setApplicationNameList(List<String> applicationNameList) {
this.applicationNameList = applicationNameList;
}
public Boolean getGrayEnable() {
return grayEnable;
}
public void setGrayEnable(Boolean grayEnable) {
this.grayEnable = grayEnable;
}
public Integer getGrayType() {
return grayType;
}
public void setGrayType(Integer grayType) {
this.grayType = grayType;
}
}
package com.gic.operation.web.qo;
import com.gic.api.base.dto.PageSearchDTO;
/**
* 路由配置查询对象
* @author jiaotianqi
*/
public class RouteConfigQo extends PageSearchDTO {
/**
* 模块名称
*/
private String moduleName;
/**
* 匹配符
*/
private String regxSymbol;
/**
* 路由规则
*/
private String routeRegx;
/**
* 模块路径
*/
private String modulePath;
/**
* 是否是前端项目
*/
private Boolean frontEnd;
/**
* 指定的location配置 如果指定 则使用指定的 多个逗号隔开
*/
private String locationConfig;
public String getLocationConfig() {
return locationConfig;
}
public void setLocationConfig(String locationConfig) {
this.locationConfig = locationConfig;
}
public Boolean getFrontEnd() {
return frontEnd;
}
public void setFrontEnd(Boolean frontEnd) {
this.frontEnd = frontEnd;
}
public String getModuleName() {
return moduleName;
}
public void setModuleName(String moduleName) {
this.moduleName = moduleName;
}
public String getRegxSymbol() {
return regxSymbol;
}
public void setRegxSymbol(String regxSymbol) {
this.regxSymbol = regxSymbol;
}
public String getRouteRegx() {
return routeRegx;
}
public void setRouteRegx(String routeRegx) {
this.routeRegx = routeRegx;
}
public String getModulePath() {
return modulePath;
}
public void setModulePath(String modulePath) {
this.modulePath = modulePath;
}
}
package com.gic.operation.web.vo;
/**
* 路由配置查询对象
* @author jiaotianqi
*/
public class RouteConfigVo {
/**
* 模块名称
*/
private String moduleName;
/**
* 匹配符
*/
private String regxSymbol;
/**
* 路由规则
*/
private String routeRegx;
/**
* 模块路径
*/
private String modulePath;
/**
* 是否是前端项目
*/
private Boolean frontEnd;
public Boolean getFrontEnd() {
return frontEnd;
}
public void setFrontEnd(Boolean frontEnd) {
this.frontEnd = frontEnd;
}
public String getModuleName() {
return moduleName;
}
public void setModuleName(String moduleName) {
this.moduleName = moduleName;
}
public String getRegxSymbol() {
return regxSymbol;
}
public void setRegxSymbol(String regxSymbol) {
this.regxSymbol = regxSymbol;
}
public String getRouteRegx() {
return routeRegx;
}
public void setRouteRegx(String routeRegx) {
this.routeRegx = routeRegx;
}
public String getModulePath() {
return modulePath;
}
public void setModulePath(String modulePath) {
this.modulePath = modulePath;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment