Commit 5754ded9 authored by 黎博's avatar 黎博

合并master

parents 3faeeda1 d0c7a412
...@@ -161,6 +161,12 @@ ...@@ -161,6 +161,12 @@
<version>3.1.305</version> <version>3.1.305</version>
</dependency> </dependency>
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
......
...@@ -3,26 +3,61 @@ package cn.qg.holmes.aspect; ...@@ -3,26 +3,61 @@ package cn.qg.holmes.aspect;
import cn.qg.holmes.common.JsonResult; import cn.qg.holmes.common.JsonResult;
import cn.qg.holmes.exception.TokenInvalidException; import cn.qg.holmes.exception.TokenInvalidException;
import cn.qg.holmes.exception.UnauthorizedException; import cn.qg.holmes.exception.UnauthorizedException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
/**
* 全局异常处理
* @author libo
*/
@ControllerAdvice @ControllerAdvice
@ResponseBody @ResponseBody
public class ExceptionHandlerAdvice { public class ExceptionHandlerAdvice {
/**
* 权限不足
*/
@ExceptionHandler(UnauthorizedException.class) @ExceptionHandler(UnauthorizedException.class)
public JsonResult handleException(UnauthorizedException e) { public JsonResult handleException(UnauthorizedException e) {
e.printStackTrace(); e.printStackTrace();
return JsonResult.buildErrorStateResult("权限不足!", false); return JsonResult.buildErrorStateResult("权限不足!", false);
} }
/**
* Token无效
*/
@ExceptionHandler(TokenInvalidException.class) @ExceptionHandler(TokenInvalidException.class)
public JsonResult handleException(TokenInvalidException e) { public JsonResult handleException(TokenInvalidException e) {
e.printStackTrace(); e.printStackTrace();
return JsonResult.buildErrorStateResult("登录已失效,请重新登录!", false); return JsonResult.buildErrorStateResult("登录已失效,请重新登录!", false);
} }
/**
* 参数验证失败
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public JsonResult handleException(MethodArgumentNotValidException e) {
e.printStackTrace();
ObjectError objectError = e.getBindingResult().getAllErrors().get(0);
return JsonResult.buildErrorStateResult(objectError.getDefaultMessage(), false);
}
/**
* 参数必须性处理
*/
@ExceptionHandler(MissingServletRequestParameterException.class)
public JsonResult handleException(MissingServletRequestParameterException e) {
e.printStackTrace();
return JsonResult.buildErrorStateResult(e.getMessage(), false);
}
/**
* 其他所有异常
*/
@ExceptionHandler(Exception.class) @ExceptionHandler(Exception.class)
public JsonResult handleException(Exception e) { public JsonResult handleException(Exception e) {
e.printStackTrace(); e.printStackTrace();
......
package cn.qg.holmes.controller.effect;
import cn.qg.holmes.common.JsonResult;
import cn.qg.holmes.config.annotation.RequiresPermissions;
import cn.qg.holmes.entity.effect.BuildData;
import cn.qg.holmes.entity.effect.BuildDataDetail;
import cn.qg.holmes.service.effect.BuildDataDetailService;
import cn.qg.holmes.service.effect.BuildDataService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 造数据文档controller
* @author libo
*/
@CrossOrigin
@RestController
@RequestMapping("/build/data")
public class BuildDataController {
@Autowired
BuildDataService buildDataService;
@Autowired
BuildDataDetailService buildDataDetailService;
/**
* 获取造数据页面展示
* @return
*/
@GetMapping("/index")
public JsonResult getBuildDataIndex() {
List<Map<String, Object>> resultList = new ArrayList<>();
List<BuildData> buildDataList = buildDataService.list();
QueryWrapper<BuildDataDetail> queryWrapper = new QueryWrapper<>();
for (BuildData buildData: buildDataList) {
Map<String, Object> map = new HashMap<>();
Integer moduleId = buildData.getId();
queryWrapper.eq("module", moduleId);
List<BuildDataDetail> buildDataDetails = buildDataDetailService.list(queryWrapper);
map.put("moduleId", moduleId);
map.put("moduleName", buildData.getName());
map.put("type", buildData.getColor());
map.put("list", buildDataDetails);
resultList.add(map);
queryWrapper.clear();
}
return JsonResult.buildSuccessResult(resultList);
}
/**
* 获取详情列表
* @param name 造数据详情名称
* @param module 模块id
* @return
*/
@GetMapping("/list")
public JsonResult getBuildDataDetailList(String name, Integer module) {
QueryWrapper<BuildDataDetail> queryWrapper = new QueryWrapper<>();
if (!StringUtils.isEmpty(name)) {
queryWrapper.eq("name", name);
}
if (module != null) {
queryWrapper.eq("module", module);
}
queryWrapper.orderByDesc("id");
List<BuildDataDetail> buildDataDetailList = buildDataDetailService.list(queryWrapper);
Map<Integer, String> moduleMap = buildDataService.list().stream().collect(Collectors.toMap(BuildData::getId, BuildData::getName));
for (BuildDataDetail buildDataDetail: buildDataDetailList) {
buildDataDetail.setModuleName(moduleMap.get(buildDataDetail.getModule()));
}
return JsonResult.buildSuccessResult(buildDataDetailList);
}
/**
* 返回造数据模块,不分页
* @return
*/
@GetMapping("/modules")
public JsonResult getBuildDataModules() {
return JsonResult.buildSuccessResult(buildDataService.list());
}
/**
* 新增造数据详情
* @param buildDataDetail
* @return
*/
@RequiresPermissions("build:data:add")
@PostMapping("/add")
public JsonResult addBuildDataDetail(@Valid @RequestBody BuildDataDetail buildDataDetail) {
QueryWrapper<BuildDataDetail> queryWrapper = new QueryWrapper<>();
queryWrapper
.eq("name", buildDataDetail.getName())
.eq("module", buildDataDetail.getModule());
if (buildDataDetailService.getOne(queryWrapper) != null) {
return JsonResult.buildErrorStateResult("数据已存在,不能重复添加!", false);
}
return JsonResult.buildSuccessResult(buildDataDetailService.save(buildDataDetail));
}
/**
* 更新造数据详情
* @param buildDataDetail
* @return
*/
@RequiresPermissions("build:data:update")
@PostMapping("/update")
public JsonResult updateBuildDataDetail(@Valid @RequestBody BuildDataDetail buildDataDetail) {
return JsonResult.buildSuccessResult(buildDataDetailService.updateById(buildDataDetail));
}
/**
* 删除造数据详情
* @param buildDataDetail
* @return
*/
@RequiresPermissions("build:data:delete")
@PostMapping("/delete")
public JsonResult deleteBuildDataDetail(@Valid @RequestBody BuildDataDetail buildDataDetail) {
return JsonResult.buildSuccessResult(buildDataDetailService.removeById(buildDataDetail.getId()));
}
}
...@@ -2,8 +2,11 @@ package cn.qg.holmes.controller.effect; ...@@ -2,8 +2,11 @@ package cn.qg.holmes.controller.effect;
import cn.qg.holmes.common.JsonResult; import cn.qg.holmes.common.JsonResult;
import cn.qg.holmes.service.effect.DatabaseSyncService; import cn.qg.holmes.service.effect.DatabaseSyncService;
import cn.qg.holmes.service.k8s.K8sService;
import cn.qg.holmes.utils.JenkinsService; import cn.qg.holmes.utils.JenkinsService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.JdbcNamedParameter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
...@@ -35,22 +38,43 @@ public class DbSyncController { ...@@ -35,22 +38,43 @@ public class DbSyncController {
@Value("${dbsync.mysql.password}") @Value("${dbsync.mysql.password}")
private String password; private String password;
@Autowired
K8sService k8sService;
/**
* 同步数据库
* @param namespace 环境
* @param dbName 数据库名称
* @param tableName 表名称
* @param businessData 是否保留业务数据
* @return
*/
@GetMapping("/one") @GetMapping("/one")
public JsonResult syncSingleTable(@RequestParam String namespace, @RequestParam String dbName, @RequestParam String tableName) { public JsonResult syncDatabase(@RequestParam String namespace, @RequestParam String dbName, @RequestParam String tableName, @RequestParam boolean businessData) {
try { try {
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
Map<String, String> map = databaseSyncService.getMysqlInfoByNamespace(namespace); Map<String, String> map = k8sService.getMysqlAddressByNamespace(namespace);
String destIp = map.get("ip"); String destIp = map.get("host");
String destPort = map.get("port"); String destPort = map.get("port");
log.info("获取到{}环境的Mysql地址为:{}", namespace, destIp + ":" + destPort); log.info("获取到{}环境的Mysql地址为:{}", namespace, destIp + ":" + destPort);
if (!StringUtils.isEmpty(dbName)) {
// 同步所有数据库
if (dbName.equalsIgnoreCase("all")) {
List<String> dbList = databaseSyncService.getDatabaseList(ip, port, username, password);
databaseSyncService.getDbInfoFromSource(ip, port, username, password, dbName);
databaseSyncService.syncDbToDest(destIp, destPort, "qa", "qatest", dbName, namespace, businessData);
} else {
// 同步单个数据库或单张表
if (tableName.equalsIgnoreCase("all") || tableName.equals("")) { if (tableName.equalsIgnoreCase("all") || tableName.equals("")) {
log.info("开始同步{}库下所有的表", dbName); log.info("开始同步{}库下所有表到{}环境,保留业务数据:{}", dbName, namespace, businessData);
databaseSyncService.getDbInfoFromSource(ip, port, username, password, dbName); databaseSyncService.getDbInfoFromSource(ip, port, username, password, dbName);
databaseSyncService.syncDbToDest(destIp, destPort, "qa", "qatest", dbName, namespace); databaseSyncService.syncDbToDest(destIp, destPort, "qa", "qatest", dbName, namespace, businessData);
} else { } else {
log.info("开始同步{}库下{}表", dbName, tableName); log.info("开始同步{}库下{}表到{}环境,保留业务数据:{}", dbName, tableName, namespace, businessData);
databaseSyncService.getSingleTableFromSource(ip, port, username, password, dbName, tableName); databaseSyncService.getSingleTableFromSource(ip, port, username, password, dbName, tableName);
databaseSyncService.syncSingleTableToDest(destIp, destPort, "qa", "qatest", dbName, tableName); databaseSyncService.syncSingleTableToDest(destIp, destPort, "qa", "qatest", dbName, tableName, businessData);
}
}
} }
long endTime = System.currentTimeMillis(); long endTime = System.currentTimeMillis();
long elapsedTime = (endTime - startTime) / 1000; long elapsedTime = (endTime - startTime) / 1000;
...@@ -77,11 +101,79 @@ public class DbSyncController { ...@@ -77,11 +101,79 @@ public class DbSyncController {
*/ */
@GetMapping("/tables") @GetMapping("/tables")
public JsonResult getTableList(@RequestParam String dbName) { public JsonResult getTableList(@RequestParam String dbName) {
List<Object> tableList = databaseSyncService.getTableListByDb(ip, port, username, password, dbName); List<String> tableList = databaseSyncService.getTableListByDb(ip, port, username, password, dbName);
tableList.add(0, "all"); tableList.add(0, "all");
return JsonResult.buildSuccessResult(tableList); return JsonResult.buildSuccessResult(tableList);
} }
/**
* 给数据库同步脚本使用的接口
* @param database 数据库名
* @return
*/
@GetMapping("/tableList")
public String getTableListForSync(@RequestParam String database) {
List<String> tableList = databaseSyncService.getTableListByDb(ip, port, username, password, database);
return StringUtils.join(tableList, " ");
}
/**
* 获取同步库所有的数据库
* 给数据库同步脚本使用的接口
* @return
*/
@GetMapping("/dbList")
public String getDbListForSync() {
List<String> dbList = databaseSyncService.getDatabaseList(ip, port, username, password);
return StringUtils.join(dbList, " ");
}
/**
* 同步表结构
* @param targetIp
* @param targetPort
* @param database
* @param table
* @return
*/
@GetMapping("/table/structure")
public JsonResult handleTableStructure(@RequestParam String targetIp, @RequestParam String targetPort, @RequestParam String database, @RequestParam String table) {
try {
log.info("开始同步表结构到测试环境,地址:{}:{}, 数据库:{}, 表:{}", targetIp, targetPort, database, table);
databaseSyncService.getSourceDbStructure(ip, port, username, password, database, table);
databaseSyncService.syncDbStructureToDest(targetIp, targetPort, "qa", "qatest", database, table);
} catch (Exception e) {
e.printStackTrace();
return JsonResult.buildErrorStateResult("创建表结构失败!", false);
}
return JsonResult.buildSuccessResult("创建" + targetIp + ":" + targetPort + "环境表结构成功!");
}
/**
* 新-同步数据库,构建jenkins job db_sync
* @param namespace 环境
* @param targetHost 目标环境ip
* @param targetPort 目标环境端口
* @param database 数据库名称
* @param table 表名
* @param businessData 是否保留业务数据
* @return
*/
@PostMapping("new")
public JsonResult dbSyncNew(@RequestParam String namespace,
@RequestParam String targetHost,
@RequestParam String targetPort,
@RequestParam String database,
@RequestParam String table,
@RequestParam boolean businessData) {
int buildNum = jenkinsService.buildDbSyncJobNew(namespace, targetHost, targetPort, database, table, businessData);
if (buildNum == 0) {
return JsonResult.buildErrorStateResult("数据库同步失败!", 0);
} else {
return JsonResult.buildSuccessResult("开始同步数据库!", buildNum);
}
}
/** /**
* 老数据库同步,调用Jenkins job sync_database_schema * 老数据库同步,调用Jenkins job sync_database_schema
* @param dbName 数据库名 * @param dbName 数据库名
......
...@@ -30,7 +30,7 @@ public class JenkinsController { ...@@ -30,7 +30,7 @@ public class JenkinsController {
@RequestParam String namespace) { @RequestParam String namespace) {
try { try {
log.info("开始构建jenkins项目:项目类型:{}, 项目名:{}, 分支:{}, 部署至环境:{}", type, project, branch, namespace); log.info("开始构建jenkins项目:项目类型:{}, 项目名:{}, 分支:{}, 部署至环境:{}", type, project, branch, namespace);
jenkinsService.buildJenkinsJob(type, project, branch, namespace); jenkinsService.buildTkeJob(type, project, branch, namespace);
return JsonResult.buildSuccessResult(true); return JsonResult.buildSuccessResult(true);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
......
...@@ -2,9 +2,11 @@ package cn.qg.holmes.controller.gitlab; ...@@ -2,9 +2,11 @@ package cn.qg.holmes.controller.gitlab;
import cn.qg.holmes.common.JsonResult; import cn.qg.holmes.common.JsonResult;
import cn.qg.holmes.config.annotation.RequiresPermissions; import cn.qg.holmes.config.annotation.RequiresPermissions;
import cn.qg.holmes.entity.auth.UserInfoVo;
import cn.qg.holmes.entity.gitlab.DingRobotPipelineVo; import cn.qg.holmes.entity.gitlab.DingRobotPipelineVo;
import cn.qg.holmes.entity.gitlab.Pipeline; import cn.qg.holmes.entity.gitlab.Pipeline;
import cn.qg.holmes.entity.jira.DingRobot; import cn.qg.holmes.entity.jira.DingRobot;
import cn.qg.holmes.service.auth.TokenService;
import cn.qg.holmes.service.gitlab.PipelineService; import cn.qg.holmes.service.gitlab.PipelineService;
import cn.qg.holmes.service.jira.DingRobotService; import cn.qg.holmes.service.jira.DingRobotService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
...@@ -35,6 +37,12 @@ public class PipelineController { ...@@ -35,6 +37,12 @@ public class PipelineController {
@Autowired @Autowired
DingRobotService dingRobotService; DingRobotService dingRobotService;
@Autowired
HttpServletRequest servletRequest;
@Autowired
TokenService tokenService;
/** /**
* gitlab webhook * gitlab webhook
* @param request * @param request
...@@ -57,7 +65,7 @@ public class PipelineController { ...@@ -57,7 +65,7 @@ public class PipelineController {
} }
@GetMapping("/list") @GetMapping("/list")
public JsonResult getDingRobotAndPipelineList(String jiraProjectKey, String projectName, String namespace, public JsonResult getDingRobotAndPipelineList(String jiraProjectKey, String projectName, String namespace, Integer status,
@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) { @RequestParam(defaultValue = "10") Integer pageSize) {
IPage<DingRobot> page = new Page<>(pageNum, pageSize); IPage<DingRobot> page = new Page<>(pageNum, pageSize);
...@@ -71,6 +79,9 @@ public class PipelineController { ...@@ -71,6 +79,9 @@ public class PipelineController {
if (!StringUtils.isEmpty(namespace)) { if (!StringUtils.isEmpty(namespace)) {
dingRobotQueryWrapper.eq("namespace", namespace); dingRobotQueryWrapper.eq("namespace", namespace);
} }
if (status != null) {
dingRobotQueryWrapper.eq("status", status);
}
dingRobotQueryWrapper.orderByDesc("id"); dingRobotQueryWrapper.orderByDesc("id");
IPage<DingRobot> projectRobotIPage = dingRobotService.page(page, dingRobotQueryWrapper); IPage<DingRobot> projectRobotIPage = dingRobotService.page(page, dingRobotQueryWrapper);
List<DingRobot> dingRobotList = projectRobotIPage.getRecords(); List<DingRobot> dingRobotList = projectRobotIPage.getRecords();
...@@ -99,6 +110,10 @@ public class PipelineController { ...@@ -99,6 +110,10 @@ public class PipelineController {
public JsonResult addRobotAndPipeline(@RequestBody DingRobotPipelineVo dingRobotPipelineVo) { public JsonResult addRobotAndPipeline(@RequestBody DingRobotPipelineVo dingRobotPipelineVo) {
try { try {
DingRobot dingRobot = dingRobotPipelineVo.getDingRobot(); DingRobot dingRobot = dingRobotPipelineVo.getDingRobot();
// 设置创建人
String token = servletRequest.getHeader("token");
UserInfoVo userInfoVo = tokenService.getUserInfoFromCache(token);
dingRobot.setCreator(userInfoVo.getChineseName());
String projectName = dingRobot.getProjectName(); String projectName = dingRobot.getProjectName();
String jiraProjectKey = dingRobot.getJiraProjectKey(); String jiraProjectKey = dingRobot.getJiraProjectKey();
QueryWrapper<DingRobot> dingRobotQueryWrapper = new QueryWrapper<>(); QueryWrapper<DingRobot> dingRobotQueryWrapper = new QueryWrapper<>();
...@@ -205,4 +220,29 @@ public class PipelineController { ...@@ -205,4 +220,29 @@ public class PipelineController {
} }
} }
/**
* 更新状态
* @param dingRobotId 机器人id
* @param status 状态,1-进行中,2-已完成
* @return
*/
@RequiresPermissions("qa:process:finish")
@PostMapping("/finish")
public JsonResult finishPipeline(@RequestParam Integer dingRobotId, @RequestParam Integer status) {
try {
DingRobot dingRobot = dingRobotService.getById(dingRobotId);
if (dingRobot == null) {
return JsonResult.buildErrorStateResult("该测试流程不存在!", false);
}
// 设置状态为已完成
dingRobot.setStatus(status);
if (!dingRobotService.updateById(dingRobot)) {
return JsonResult.buildErrorStateResult("更新状态失败!", false);
}
return JsonResult.buildSuccessResult("更新状态成功!", true);
} catch (Exception e) {
return JsonResult.buildErrorStateResult("更新状态失败!", false);
}
}
} }
...@@ -29,10 +29,10 @@ public class DockerProjectController { ...@@ -29,10 +29,10 @@ public class DockerProjectController {
* @return * @return
*/ */
@GetMapping("/list") @GetMapping("/list")
public JsonResult getDockerProjectList(String projectName, String projectType, Integer isActive, public JsonResult getDockerProjectList(String projectName, String projectType, Integer isActive, String hostName,
@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) { @RequestParam(defaultValue = "10") Integer pageSize) {
IPage projectIPage = dockerProjectService.getDockerProjectList(projectName, projectType, isActive, pageNum, pageSize); IPage projectIPage = dockerProjectService.getDockerProjectList(projectName, projectType, isActive, hostName, pageNum, pageSize);
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
map.put("total", projectIPage.getTotal()); map.put("total", projectIPage.getTotal());
map.put("list", projectIPage.getRecords()); map.put("list", projectIPage.getRecords());
...@@ -169,4 +169,18 @@ public class DockerProjectController { ...@@ -169,4 +169,18 @@ public class DockerProjectController {
return dockerProject.getGitPath(); return dockerProject.getGitPath();
} }
@GetMapping("/get_info")
public String getStartCommand(@RequestParam String projectName, @RequestParam String key) {
QueryWrapper<DockerProject> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("project_name", projectName);
DockerProject dockerProject = dockerProjectService.getOne(queryWrapper);
if (key.equals("start_command")) {
return dockerProject.getStartCommand();
}
if (key.equals("host_name")) {
return dockerProject.getHostName();
}
return "";
}
} }
package cn.qg.holmes.controller.k8s;
import cn.qg.holmes.common.JsonResult;
import cn.qg.holmes.config.annotation.RequiresPermissions;
import cn.qg.holmes.entity.k8s.EnvTemplate;
import cn.qg.holmes.entity.k8s.EnvTemplateDetail;
import cn.qg.holmes.entity.k8s.EnvTemplateVo;
import cn.qg.holmes.service.k8s.EnvTemplateDetailService;
import cn.qg.holmes.service.k8s.EnvTemplateService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@CrossOrigin
@RestController
@RequestMapping("/env/template")
public class EnvTemplateController {
@Autowired
EnvTemplateService envTemplateService;
@Autowired
EnvTemplateDetailService envTemplateDetailService;
@GetMapping("/list")
public JsonResult getTemplateList(@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
IPage<EnvTemplate> envTemplateIPage = new Page<>(pageNum, pageSize);
IPage<EnvTemplate> IPage = envTemplateService.page(envTemplateIPage);
List<EnvTemplate> envTemplateList = IPage.getRecords();
List<EnvTemplateVo> envTemplateVoList = new ArrayList<>();
QueryWrapper<EnvTemplateDetail> queryWrapper = new QueryWrapper<>();
for (EnvTemplate envTemplate: envTemplateList) {
EnvTemplateVo envTemplateVo = new EnvTemplateVo();
envTemplateVo.setEnvTemplate(envTemplate);
queryWrapper.eq("template_id", envTemplate.getId());
List<EnvTemplateDetail> envTemplateDetailList = envTemplateDetailService.list(queryWrapper);
envTemplateVo.setEnvTemplateDetailList(envTemplateDetailList);
envTemplateVoList.add(envTemplateVo);
queryWrapper.clear();
}
Map<String, Object> map = new HashMap<>();
map.put("total", IPage.getTotal());
map.put("list", envTemplateVoList);
return JsonResult.buildSuccessResult(map);
}
/**
* 获取所有的模板及其关联的服务
* @return
*/
@GetMapping("/getAll")
public JsonResult getTemplateByName() {
List<Map<String, Object>> resultList = new ArrayList<>();
List<EnvTemplate> envTemplateList = envTemplateService.list();
QueryWrapper<EnvTemplateDetail> queryWrapper = new QueryWrapper<>();
for (EnvTemplate envTemplate: envTemplateList) {
Map<String, Object> map = new HashMap<>();
map.put("id", envTemplate.getId());
map.put("name", envTemplate.getName());
map.put("updateTime", envTemplate.getUpdateTime());
queryWrapper.eq("template_id", envTemplate.getId());
List<EnvTemplateDetail> envTemplateDetailList = envTemplateDetailService.list(queryWrapper);
for (EnvTemplateDetail envTemplateDetail: envTemplateDetailList) {
List<EnvTemplateDetail> envTemplateDetailListTemp;
if (map.containsKey(envTemplateDetail.getLabel())) {
envTemplateDetailListTemp = (List<EnvTemplateDetail>) map.get(envTemplateDetail.getLabel());
} else {
envTemplateDetailListTemp = new ArrayList<>();
}
envTemplateDetailListTemp.add(envTemplateDetail);
map.put(envTemplateDetail.getLabel(), envTemplateDetailListTemp);
}
queryWrapper.clear();
resultList.add(map);
}
return JsonResult.buildSuccessResult(resultList);
}
/**
* 新建模板
* @param envTemplateVo 模板虚拟实体类
* @return
*/
@RequiresPermissions("docker:envTemplate:create")
@PostMapping("/create")
public JsonResult saveEnvTemplate(@RequestBody EnvTemplateVo envTemplateVo) {
EnvTemplate envTemplate = envTemplateVo.getEnvTemplate();
QueryWrapper<EnvTemplate> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", envTemplate.getName());
if (envTemplateService.getOne(queryWrapper) != null) {
return JsonResult.buildErrorStateResult("模板已存在!", false);
}
// 保存模板
if (!envTemplateService.save(envTemplate)) {
return JsonResult.buildErrorStateResult("模板创建失败!", false);
}
// 模板详情列表设置模板id
Integer templateId = envTemplateService.getOne(queryWrapper).getId();
List<EnvTemplateDetail> envTemplateDetailList = envTemplateVo.getEnvTemplateDetailList();
for (EnvTemplateDetail envTemplateDetail: envTemplateDetailList) {
envTemplateDetail.setTemplateId(templateId);
}
// 保存模板详情
if (!envTemplateDetailService.saveBatch(envTemplateDetailList)) {
return JsonResult.buildErrorStateResult("模板详情保存失败!", false);
}
return JsonResult.buildSuccessResult(true);
}
/**
* 编辑模板及模板详情
* @param envTemplateVo 模板列表
* @return
*/
@RequiresPermissions("docker:envTemplate:modify")
@PostMapping("/modify")
public JsonResult modifyEnvTemplate(@RequestBody EnvTemplateVo envTemplateVo) {
EnvTemplate envTemplate = envTemplateVo.getEnvTemplate();
if (!envTemplateService.updateById(envTemplate)) {
return JsonResult.buildErrorStateResult("模板更新失败!", false);
}
// 参数传过来的列表
List<EnvTemplateDetail> envTemplateDetailList = envTemplateVo.getEnvTemplateDetailList();
// 查询出数据库里该模板的所有条目
QueryWrapper<EnvTemplateDetail> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("template_id", envTemplate.getId());
List<EnvTemplateDetail> envTemplateDetailListDb = envTemplateDetailService.list(queryWrapper);
// 删除传参里没有的
for (EnvTemplateDetail envTemplateDetailDb: envTemplateDetailListDb) {
boolean delete = true;
for (EnvTemplateDetail envTemplateDetail: envTemplateDetailList) {
if (envTemplateDetail.getId() != null) {
if (envTemplateDetail.getId().equals(envTemplateDetailDb.getId())) {
delete = false;
break;
}
}
}
if (delete) {
envTemplateDetailService.removeById(envTemplateDetailDb.getId());
}
}
// 设置一下templateId
envTemplateDetailList.forEach(envTemplateDetail -> {
envTemplateDetail.setTemplateId(envTemplate.getId());
});
// 剩余的批量新增/修改
if (!envTemplateDetailService.saveOrUpdateBatch(envTemplateDetailList)) {
return JsonResult.buildErrorStateResult("更新模板详情失败!", false);
}
return JsonResult.buildSuccessResult("模板更新成功");
}
/**
*
* @param templateId 模板id
* @return
*/
@RequiresPermissions("docker:envTemplate:delete")
@PostMapping("/delete")
public JsonResult deleteEnvTemplate(@RequestParam Integer templateId) {
if (!envTemplateService.removeById(templateId)) {
return JsonResult.buildErrorStateResult("模板删除失败!", false);
}
QueryWrapper<EnvTemplateDetail> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("template_id", templateId);
if (!envTemplateDetailService.remove(queryWrapper)) {
return JsonResult.buildErrorStateResult("模板详情删除失败", false);
}
return JsonResult.buildSuccessResult("模板删除成功!");
}
}
package cn.qg.holmes.controller.k8s; package cn.qg.holmes.controller.k8s;
import cn.qg.holmes.common.JsonResult; import cn.qg.holmes.common.JsonResult;
import cn.qg.holmes.config.annotation.RecordOperation;
import cn.qg.holmes.entity.auth.UserInfoVo; import cn.qg.holmes.entity.auth.UserInfoVo;
import cn.qg.holmes.entity.behavior.UserBehaviorRecord;
import cn.qg.holmes.entity.k8s.DockerProject; import cn.qg.holmes.entity.k8s.DockerProject;
import cn.qg.holmes.entity.k8s.EnvTemplateDetail;
import cn.qg.holmes.entity.k8s.ServiceCreateVo; import cn.qg.holmes.entity.k8s.ServiceCreateVo;
import cn.qg.holmes.service.auth.TokenService; import cn.qg.holmes.service.auth.TokenService;
import cn.qg.holmes.service.behavior.UserBehaviorRecordService;
import cn.qg.holmes.service.k8s.*; import cn.qg.holmes.service.k8s.*;
import cn.qg.holmes.utils.RedisUtils;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tencentcloudapi.tcr.v20190924.models.RepoInfo; import com.tencentcloudapi.tcr.v20190924.models.RepoInfo;
import com.tencentcloudapi.tcr.v20190924.models.TagInfo;
import io.fabric8.kubernetes.api.model.*;
import io.fabric8.kubernetes.api.model.apps.Deployment; import io.fabric8.kubernetes.api.model.apps.Deployment;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.*; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* k8及容器操作相关接口 * k8及容器操作相关接口
...@@ -48,7 +52,13 @@ public class K8sController { ...@@ -48,7 +52,13 @@ public class K8sController {
TokenService tokenService; TokenService tokenService;
@Autowired @Autowired
UserBehaviorRecordService userBehaviorRecordService; EnvTemplateService envTemplateService;
@Autowired
EnvTemplateDetailService envTemplateDetailService;
@Autowired
RedisUtils redisUtils;
/** /**
* 获取namespace列表 * 获取namespace列表
...@@ -92,7 +102,6 @@ public class K8sController { ...@@ -92,7 +102,6 @@ public class K8sController {
* @param serviceCreateVo 创建实体类 * @param serviceCreateVo 创建实体类
* @return * @return
*/ */
@RecordOperation("新增服务")
@PostMapping("/service/create") @PostMapping("/service/create")
public JsonResult createPod(@RequestBody ServiceCreateVo serviceCreateVo) { public JsonResult createPod(@RequestBody ServiceCreateVo serviceCreateVo) {
try { try {
...@@ -173,15 +182,15 @@ public class K8sController { ...@@ -173,15 +182,15 @@ public class K8sController {
} }
} else if (label.equals("java")) { } else if (label.equals("java")) {
DockerProject dockerProject = dockerProjectService.getOne(queryWrapper); DockerProject dockerProject = dockerProjectService.getOne(queryWrapper);
// 直接创建Java Deployment
k8sService.createJavaDeployment(serviceCreateVo, dockerProject);
// 如果存在Service,则首先删除,再创建新的 // 如果存在Service,则首先删除,再创建新的
if (k8sService.queryIfServiceExistByName(namespace, serviceName)) { if (k8sService.queryIfServiceExistByName(namespace, serviceName)) {
k8sService.deleteService(namespace, serviceName); k8sService.deleteService(namespace, serviceName);
} }
k8sService.createJavaService(namespace, serviceName, serviceCreateVo.getDebug()); k8sService.createJavaService(namespace, serviceName, serviceCreateVo.getDebug());
// 直接创建Java Deployment
k8sService.createJavaDeployment(serviceCreateVo, dockerProject);
// 如果存在Ingress,则首先删除Ingress,再创建新的 // 如果存在Ingress,则首先删除Ingress,再创建新的
if (k8sService.queryIfIngressExistByName(namespace, serviceName)) { if (k8sService.queryIfIngressExistByName(namespace, serviceName)) {
k8sService.deleteIngress(namespace, serviceName); k8sService.deleteIngress(namespace, serviceName);
...@@ -217,13 +226,12 @@ public class K8sController { ...@@ -217,13 +226,12 @@ public class K8sController {
/** /**
* 重置pod * 重置pod
* @param namespace 环境 * @param namespace 环境
* @param serviceName podName * @param podName podName
* @return * @return
*/ */
@RecordOperation("重置服务")
@PostMapping("/service/redeploy") @PostMapping("/service/redeploy")
public JsonResult resetPodByName(String namespace, String serviceName) { public JsonResult resetPodByName(String namespace, String podName) {
return JsonResult.buildSuccessResult(k8sService.resetPod(namespace, serviceName)); return JsonResult.buildSuccessResult(k8sService.resetPod(namespace, podName));
} }
/** /**
...@@ -231,7 +239,6 @@ public class K8sController { ...@@ -231,7 +239,6 @@ public class K8sController {
* @param serviceCreateVo * @param serviceCreateVo
* @return * @return
*/ */
@RecordOperation("jenkins打包")
@PostMapping("/service/modify") @PostMapping("/service/modify")
public JsonResult modifyPod(@RequestBody ServiceCreateVo serviceCreateVo) { public JsonResult modifyPod(@RequestBody ServiceCreateVo serviceCreateVo) {
log.info("接口/k8s/service/modify收到请求,请求参数为:{}", JSON.toJSONString(serviceCreateVo)); log.info("接口/k8s/service/modify收到请求,请求参数为:{}", JSON.toJSONString(serviceCreateVo));
...@@ -252,18 +259,33 @@ public class K8sController { ...@@ -252,18 +259,33 @@ public class K8sController {
if (label.equals("java")) { if (label.equals("java")) {
// JAVA // JAVA
DockerProject dockerProject = dockerProjectService.getOne(queryWrapper); DockerProject dockerProject = dockerProjectService.getOne(queryWrapper);
// 如果不存在Service,则重新创建Service
if (!k8sService.queryIfServiceExistByName(namespace, serviceName)) {
k8sService.createJavaService(namespace, serviceName, serviceCreateVo.getDebug());
}
// 创建Deployment // 创建Deployment
if (k8sService.queryIfDeploymentExistByName(namespace, serviceName)) { if (k8sService.queryIfDeploymentExistByName(namespace, serviceName)) {
Deployment deployment = k8sService.getDeployment(namespace, serviceName);
List<Container> containers = deployment.getSpec().getTemplate().getSpec().getContainers();
if (containers != null && containers.size() > 0) {
List<EnvVar> envVarList = containers.get(0).getEnv();
// 根据原来的debug和mock值,来设置debug和mock
for (EnvVar envVar: envVarList) {
if (envVar.getName().equals("DEBUG")) {
serviceCreateVo.setDebug(Integer.valueOf(envVar.getValue()));
}
if (envVar.getName().equals("MOCK")) {
serviceCreateVo.setMock(Integer.valueOf((envVar.getValue())));
}
}
}
log.info("{}环境{}服务的Deployment已存在,首先删除该Deployment.", namespace, serviceName); log.info("{}环境{}服务的Deployment已存在,首先删除该Deployment.", namespace, serviceName);
k8sService.deleteDeployment(namespace, serviceName); k8sService.deleteDeployment(namespace, serviceName);
} }
k8sService.createJavaDeployment(serviceCreateVo, dockerProject); k8sService.createJavaDeployment(serviceCreateVo, dockerProject);
// 如果不存在Service,则重新创建Service
if (!k8sService.queryIfServiceExistByName(namespace, serviceName)) {
k8sService.createJavaService(namespace, serviceName, serviceCreateVo.getDebug());
}
// 如果不存在ingress则创建ingress // 如果不存在ingress则创建ingress
if (!k8sService.queryIfIngressExistByName(namespace, serviceName)) { if (!k8sService.queryIfIngressExistByName(namespace, serviceName)) {
k8sService.createIngress(namespace, serviceName, serviceCreateVo.getDomain()); k8sService.createIngress(namespace, serviceName, serviceCreateVo.getDomain());
...@@ -271,6 +293,12 @@ public class K8sController { ...@@ -271,6 +293,12 @@ public class K8sController {
} else if (label.equals("ui") || label.equals("node")) { } else if (label.equals("ui") || label.equals("node")) {
// UI // UI
DockerProject dockerProject = dockerProjectService.getOne(queryWrapper); DockerProject dockerProject = dockerProjectService.getOne(queryWrapper);
// 如果不存在Service,则重新创建Service
if (!k8sService.queryIfServiceExistByName(namespace, serviceName)) {
k8sService.createUIAndNodeService(namespace, serviceName, type, label);
}
// 创建Deployment // 创建Deployment
if (k8sService.queryIfDeploymentExistByName(namespace, serviceName)) { if (k8sService.queryIfDeploymentExistByName(namespace, serviceName)) {
log.info("{}环境{}服务的Deployment已存在,首先删除该Deployment.", namespace, serviceName); log.info("{}环境{}服务的Deployment已存在,首先删除该Deployment.", namespace, serviceName);
...@@ -278,11 +306,6 @@ public class K8sController { ...@@ -278,11 +306,6 @@ public class K8sController {
} }
k8sService.createUIAndNodeDeployment(serviceCreateVo, dockerProject); k8sService.createUIAndNodeDeployment(serviceCreateVo, dockerProject);
// 如果不存在Service,则重新创建Service
if (!k8sService.queryIfServiceExistByName(namespace, serviceName)) {
k8sService.createUIAndNodeService(namespace, serviceName, type, label);
}
// 如果不存在ingress则创建ingress // 如果不存在ingress则创建ingress
if (!k8sService.queryIfIngressExistByName(namespace, serviceName)) { if (!k8sService.queryIfIngressExistByName(namespace, serviceName)) {
k8sService.createIngress(namespace, serviceName, serviceCreateVo.getDomain()); k8sService.createIngress(namespace, serviceName, serviceCreateVo.getDomain());
...@@ -298,7 +321,6 @@ public class K8sController { ...@@ -298,7 +321,6 @@ public class K8sController {
* @param serviceCreateVo * @param serviceCreateVo
* @return * @return
*/ */
@RecordOperation("更新服务")
@PostMapping("/service/update") @PostMapping("/service/update")
public JsonResult updatePod(@RequestBody ServiceCreateVo serviceCreateVo) { public JsonResult updatePod(@RequestBody ServiceCreateVo serviceCreateVo) {
String namespace = serviceCreateVo.getNamespace(); String namespace = serviceCreateVo.getNamespace();
...@@ -311,6 +333,7 @@ public class K8sController { ...@@ -311,6 +333,7 @@ public class K8sController {
.eq("project_name", serviceName) .eq("project_name", serviceName)
.eq("project_type", type); .eq("project_type", type);
DockerProject dockerProject = dockerProjectService.getOne(dockerProjectQueryWrapper); DockerProject dockerProject = dockerProjectService.getOne(dockerProjectQueryWrapper);
// 先删除原有pod // 先删除原有pod
if (!k8sService.deleteDeployment(namespace, serviceName)) { if (!k8sService.deleteDeployment(namespace, serviceName)) {
return JsonResult.buildErrorStateResult("更新服务失败!", false); return JsonResult.buildErrorStateResult("更新服务失败!", false);
...@@ -323,13 +346,13 @@ public class K8sController { ...@@ -323,13 +346,13 @@ public class K8sController {
} }
// 类型为Java // 类型为Java
if (label.equals("java")) { if (label.equals("java")) {
deployment = k8sService.createJavaDeployment(serviceCreateVo, dockerProject);
k8sService.createJavaService(namespace, serviceName, serviceCreateVo.getDebug()); k8sService.createJavaService(namespace, serviceName, serviceCreateVo.getDebug());
deployment = k8sService.createJavaDeployment(serviceCreateVo, dockerProject);
} }
// 类型为UI或Node // 类型为UI或Node
if (label.equals("ui") || label.equals("node")) { if (label.equals("ui") || label.equals("node")) {
deployment = k8sService.createUIAndNodeDeployment(serviceCreateVo, dockerProject);
k8sService.createUIAndNodeService(namespace, serviceName, type, label); k8sService.createUIAndNodeService(namespace, serviceName, type, label);
deployment = k8sService.createUIAndNodeDeployment(serviceCreateVo, dockerProject);
} }
// 删除原有Ingress // 删除原有Ingress
if (k8sService.queryIfIngressExistByName(namespace, serviceName)) { if (k8sService.queryIfIngressExistByName(namespace, serviceName)) {
...@@ -350,7 +373,6 @@ public class K8sController { ...@@ -350,7 +373,6 @@ public class K8sController {
* @param serviceName 服务名称 * @param serviceName 服务名称
* @return * @return
*/ */
@RecordOperation("删除服务")
@PostMapping("/service/delete") @PostMapping("/service/delete")
public JsonResult deletePodByName(String namespace, String serviceName) { public JsonResult deletePodByName(String namespace, String serviceName) {
return JsonResult.buildSuccessResult(k8sService.deleteDeployment(namespace, serviceName)); return JsonResult.buildSuccessResult(k8sService.deleteDeployment(namespace, serviceName));
...@@ -400,30 +422,28 @@ public class K8sController { ...@@ -400,30 +422,28 @@ public class K8sController {
* @return * @return
*/ */
@PostMapping("/sync/mq") @PostMapping("/sync/mq")
public JsonResult syncOnlineMqToTest(@RequestHeader String token, @RequestParam String namespace, @RequestParam String host) { public JsonResult syncOnlineMqToTest(@RequestParam String host) {
UserInfoVo userInfoVo = tokenService.getUserInfoFromCache(token);
UserBehaviorRecord userBehaviorRecord = new UserBehaviorRecord();
userBehaviorRecord.setUsername(userInfoVo.getChineseName());
userBehaviorRecord.setNamespace(namespace);
userBehaviorRecord.setAction("同步mq");
userBehaviorRecordService.save(userBehaviorRecord);
return JsonResult.buildSuccessResult(mqService.setDefinitions(host)); return JsonResult.buildSuccessResult(mqService.setDefinitions(host));
} }
/**
* 比较线上和测试mq
* @param host
* @return
*/
@GetMapping("/mq/diff")
public JsonResult getMqDiffResult(@RequestParam String host) {
return JsonResult.buildSuccessResult(mqService.getMqDiff(host));
}
/** /**
* 情况测试环境redis * 情况测试环境redis
* @param namespace 环境 * @param namespace 环境
* @return * @return
*/ */
@PostMapping("/redis/flush") @PostMapping("/redis/flush")
public JsonResult flushRedis(@RequestHeader String token, @RequestParam String namespace) { public JsonResult flushRedis(@RequestParam String namespace) {
try { try {
UserInfoVo userInfoVo = tokenService.getUserInfoFromCache(token);
UserBehaviorRecord userBehaviorRecord = new UserBehaviorRecord();
userBehaviorRecord.setUsername(userInfoVo.getChineseName());
userBehaviorRecord.setNamespace(namespace);
userBehaviorRecord.setAction("清空redis");
userBehaviorRecordService.save(userBehaviorRecord);
Map<String, Object> redisInfo = k8sService.getPodAndServiceInfo(namespace, "base", "redis"); Map<String, Object> redisInfo = k8sService.getPodAndServiceInfo(namespace, "base", "redis");
String lanIp = redisInfo.get("lanIp").toString(); String lanIp = redisInfo.get("lanIp").toString();
List<Map<String, Object>> portMappings = (List<Map<String, Object>>) redisInfo.get("portMappings"); List<Map<String, Object>> portMappings = (List<Map<String, Object>>) redisInfo.get("portMappings");
...@@ -443,8 +463,109 @@ public class K8sController { ...@@ -443,8 +463,109 @@ public class K8sController {
@PostMapping("/namespace/create") @PostMapping("/namespace/create")
public JsonResult createNewNamespace(@RequestParam String name, public JsonResult createNewNamespace(@RequestParam String name,
@RequestParam String desc, @RequestParam String desc,
@RequestParam String owner) { @RequestParam String owner,
return JsonResult.buildSuccessResult(k8sService.createNewNamespace(name, desc, owner)); @RequestParam String templateId) {
boolean createNamespace = k8sService.createNewNamespace(name, desc, owner);
if (!createNamespace) {
return JsonResult.buildErrorStateResult("环境创建失败!", false);
}
QueryWrapper<EnvTemplateDetail> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("template_id", templateId);
List<EnvTemplateDetail> envTemplateDetailList = envTemplateDetailService.list(queryWrapper);
for (EnvTemplateDetail envTemplateDetail: envTemplateDetailList) {
String label = envTemplateDetail.getLabel();
String image = envTemplateDetail.getTag();
String serviceName = envTemplateDetail.getServiceName();
String serviceType = envTemplateDetail.getServiceType();
String domain = envTemplateDetail.getDomain();
// 处理基础服务
if (label.equals("base")) {
switch (serviceType) {
case "mysql":
k8sService.createMysqlPvc(name);
k8sService.createMysqlDeployment(name, image);
k8sService.createMysqlService(name);
break;
case "mongodb":
k8sService.createMongodbPvc(name);
k8sService.createMongoDbDeployment(name, image);
k8sService.createMongodbService(name);
break;
case "redis":
k8sService.createRedisDeployment(name, image);
k8sService.createRedisService(name);
break;
case "rabbitmq":
k8sService.createRabbitmqPvc(name);
k8sService.createRabbitmqDeployment(name, image);
k8sService.createRabbitmqService(name);
break;
case "zookeeper":
k8sService.createZookeeperPvc(name);
k8sService.createZookeeperDeployment(name, image);
k8sService.createZookeeperService(name);
break;
default:
break;
}
}
if (label.equals("java")) {
ServiceCreateVo serviceCreateVo = new ServiceCreateVo();
serviceCreateVo.setServiceName(serviceName);
serviceCreateVo.setNamespace(name);
serviceCreateVo.setImage(image);
serviceCreateVo.setType(serviceType);
serviceCreateVo.setDebug(0);
serviceCreateVo.setMock(0);
serviceCreateVo.setLabel(label);
serviceCreateVo.setDomain(domain);
QueryWrapper<DockerProject> dockerProjectQueryWrapper = new QueryWrapper<>();
dockerProjectQueryWrapper
.eq("project_name", serviceName)
.eq("project_type", serviceType)
.eq("is_active", 1)
.eq("deploy_to_docker", 1);
DockerProject dockerProject = dockerProjectService.getOne(dockerProjectQueryWrapper);
dockerProjectQueryWrapper.clear();
if (dockerProject != null) {
k8sService.createJavaDeployment(serviceCreateVo, dockerProject);
k8sService.createJavaService(name, serviceName, serviceCreateVo.getDebug());
k8sService.createIngress(name, serviceName, domain);
}
}
if (label.equals("ui") || label.equals("node")) {
ServiceCreateVo serviceCreateVo = new ServiceCreateVo();
serviceCreateVo.setServiceName(serviceName);
serviceCreateVo.setNamespace(name);
serviceCreateVo.setImage(image);
serviceCreateVo.setType(serviceType);
serviceCreateVo.setDebug(0);
serviceCreateVo.setMock(0);
serviceCreateVo.setLabel(label);
serviceCreateVo.setDomain(domain);
QueryWrapper<DockerProject> dockerProjectQueryWrapper = new QueryWrapper<>();
dockerProjectQueryWrapper
.eq("project_name", serviceName)
.eq("project_type", serviceType)
.eq("is_active", 1)
.eq("deploy_to_docker", 1);
DockerProject dockerProject = dockerProjectService.getOne(dockerProjectQueryWrapper);
dockerProjectQueryWrapper.clear();
if (dockerProject != null) {
k8sService.createUIAndNodeDeployment(serviceCreateVo, dockerProject);
k8sService.createUIAndNodeService(name, serviceName, serviceType, label);
k8sService.createIngress(name, serviceName, domain);
}
}
}
// 删除相关缓存
redisUtils.del("k8s:namespace:all");
redisUtils.del("k8s:namespace:test");
redisUtils.del("k8s:namespace:dev");
return JsonResult.buildSuccessResult("环境创建成功");
} }
/** /**
...@@ -483,4 +604,117 @@ public class K8sController { ...@@ -483,4 +604,117 @@ public class K8sController {
resultList.sort(String::compareTo); resultList.sort(String::compareTo);
return String.join("\n", resultList); return String.join("\n", resultList);
} }
/**
* 按照类型获取所有的服务
* @return
*/
@GetMapping("/repo/getAll")
public JsonResult getAllRepos() {
List<Map<String, Object>> resultMapList = new ArrayList<>();
List<RepoInfo> repoInfoList = imageService.getRepoInfoList("qa-base");
Map<String, Object> base = new HashMap<>();
List<Map<String, String>> baseList = new ArrayList<>();
for (RepoInfo repoInfo: repoInfoList) {
String serviceName = repoInfo.getRepoName().split("/")[1];
TagInfo[] tagInfos = imageService.getImageListByService(repoInfo.getRepoName()).getTagInfo();
for (TagInfo tagInfo: tagInfos) {
Map<String, String> map = new HashMap<>();
map.put("serviceName", serviceName + ":" + tagInfo.getTagName());
map.put("serviceType", serviceName);
map.put("label", "base");
map.put("tag", "qa-base/" + serviceName + ":" + tagInfo.getTagName());
map.put("domain", serviceName + tagInfo.getTagName());
baseList.add(map);
}
}
base.put("type", "base");
base.put("repos", baseList);
resultMapList.add(base);
QueryWrapper<DockerProject> queryWrapper = new QueryWrapper<>();
queryWrapper.groupBy("project_type").select("project_type");
List<DockerProject> projectList = dockerProjectService.list(queryWrapper);
queryWrapper.clear();
for (DockerProject dp: projectList) {
String type = dp.getProjectType();
Map<String, Object> serviceMap = new HashMap<>();
List<Map<String, String>> serviceMapList = new ArrayList<>();
queryWrapper
.eq("project_type", type)
.eq("is_active", 1)
.eq("deploy_to_docker", 1);
List<DockerProject> dockerProjectList = dockerProjectService.list(queryWrapper);
for (DockerProject dockerProject: dockerProjectList) {
Map<String, String> map = new HashMap<>();
map.put("serviceType", type);
map.put("label", type);
map.put("serviceName", dockerProject.getProjectName());
map.put("domain", dockerProject.getHostName().split("\\.")[0]);
map.put("tag", "qa-test/" + dockerProject.getProjectName() + ":latest");
serviceMapList.add(map);
}
serviceMap.put("type", type);
serviceMap.put("repos", serviceMapList);
resultMapList.add(serviceMap);
queryWrapper.clear();
}
return JsonResult.buildSuccessResult(resultMapList);
}
/**
* 给打包用的,获取dubbo接口
* @param namespace 环境
* @param serviceType 服务类型
* @param serviceName 服务名称
* @param key port_20880
* @return
*/
@GetMapping("/dubbo/port")
public String getDubboPort(@RequestParam String namespace,
@RequestParam String serviceType,
@RequestParam String serviceName,
@RequestParam String key) {
List<ServicePort> servicePortList = k8sService.getServiceDetail(namespace, serviceName).getSpec().getPorts();
Map<String, Object> serviceMap = new HashMap<>();
List<Map<String, Object>> portMappingList = new ArrayList<>();
if (servicePortList.size() > 0) {
for (ServicePort servicePort : servicePortList) {
if (servicePort.getNodePort() != null) {
serviceMap.put("port_" + servicePort.getName(), servicePort.getNodePort());
}
Map<String, Object> portMap = new HashMap<>();
portMap.put("name", servicePort.getName());
portMap.put("nodePort", servicePort.getNodePort());
portMap.put("port", servicePort.getPort());
portMap.put("protocol", servicePort.getProtocol());
portMap.put("targetPort", servicePort.getTargetPort());
portMappingList.add(portMap);
}
}
serviceMap.put("portMappings", portMappingList);
serviceMap.put("serviceName", serviceName);
serviceMap.put("namespace", namespace);
if (serviceMap.containsKey(key)) {
return serviceMap.get(key).toString();
} else {
return JSON.toJSONString(serviceMap);
}
}
/**
* 获取k8s环境变量
* @param namespace 环境
* @return
*/
@GetMapping("/listEnvVars")
public Map getListEnvVars(@RequestParam String namespace) {
Map<String, Object> detailMap = k8sService.getListEnvVars(namespace);
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("details", detailMap);
resultMap.put("success", true);
return resultMap;
}
} }
...@@ -69,19 +69,10 @@ public class NavigateController { ...@@ -69,19 +69,10 @@ public class NavigateController {
Map<Integer, String> moduleMap =navigateModuleList.stream().collect(Collectors.toMap(NavigateModule::getId, NavigateModule::getName)); Map<Integer, String> moduleMap =navigateModuleList.stream().collect(Collectors.toMap(NavigateModule::getId, NavigateModule::getName));
// 获取导航列表 // 获取导航列表
List<NavigateDetail> navigateDetailList = navigateDetailService.list(detailQueryWrapper); List<NavigateDetail> navigateDetailList = navigateDetailService.list(detailQueryWrapper);
List<Map<String, Object>> resultList = new ArrayList<>();
for (NavigateDetail navigateDetail: navigateDetailList) { for (NavigateDetail navigateDetail: navigateDetailList) {
Map<String, Object> map = new HashMap<>(); navigateDetail.setModuleName(moduleMap.get(navigateDetail.getModule()));
map.put("id", navigateDetail.getId());
map.put("name", navigateDetail.getName());
map.put("url", navigateDetail.getUrl());
map.put("module", navigateDetail.getModule());
map.put("moduleName", moduleMap.get(navigateDetail.getModule()));
map.put("createTime", navigateDetail.getCreateTime());
map.put("updateTime", navigateDetail.getUpdateTime());
resultList.add(map);
} }
return JsonResult.buildSuccessResult(resultList); return JsonResult.buildSuccessResult(navigateDetailList);
} }
/** /**
......
package cn.qg.holmes.entity.effect;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.util.Date;
/**
* 造数据文档模块类
*/
@TableName(value = "build_data")
@Data
public class BuildData {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 模块名称
*/
@TableField(value = "name")
@NotBlank(message = "模块名称不能为空")
private String name;
/**
* 模块颜色
*/
@TableField(value = "color")
@NotBlank(message = "模块颜色不能为空")
private String color;
/**
* 更新时间
*/
@TableField(value = "update_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
package cn.qg.holmes.entity.effect;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
* 造数据详情实体类
*/
@TableName(value = "build_data_detail")
@Data
public class BuildDataDetail {
/**
* 主键id
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 造数据说明
*/
@TableField(value = "name")
@NotBlank(message = "名称不能为空")
private String name;
/**
* 链接地址
*/
@TableField(value = "url")
@NotBlank(message = "链接名称不能为空")
private String url;
/**
* 模块id
*/
@TableField(value = "module")
@NotNull(message = "模块id不能为空")
private Integer module;
/**
* 更新时间
*/
@TableField(value = "update_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
@TableField(exist = false)
private String moduleName;
}
...@@ -13,11 +13,30 @@ import java.util.Date; ...@@ -13,11 +13,30 @@ import java.util.Date;
public class DingRobot { public class DingRobot {
@TableId(type = IdType.AUTO) @TableId(type = IdType.AUTO)
private Integer id; private Integer id;
/**
* 项目名称,与提BUG时【】里的内容进行匹配
*/
private String projectName; private String projectName;
/**
* jira项目关键字
*/
private String jiraProjectKey; private String jiraProjectKey;
/**
* 钉钉机器人webhook
*/
private String dingUrl; private String dingUrl;
/**
* 创建人
*/
private String creator; private String creator;
/**
* 环境
*/
private String namespace; private String namespace;
/**
* 1-进行中,2-已完成
*/
private Integer status;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime; private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
......
...@@ -44,10 +44,16 @@ public class JiraBugPool { ...@@ -44,10 +44,16 @@ public class JiraBugPool {
* 钉钉robot * 钉钉robot
*/ */
private String dingUrl; private String dingUrl;
/**
* 对应项目id
*/
private Integer dingRobotId;
/** /**
* 是否有效,1-有效,0-无效 * 是否有效,1-有效,0-无效
*/ */
private Integer enable; private Integer enable;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime; private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
......
package cn.qg.holmes.entity.k8s;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
/**
* 环境模板实体类
* @author libo
*/
@TableName(value = "env_template")
@Data
public class EnvTemplate {
@TableId(type = IdType.AUTO)
private Integer id;
private String name;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
package cn.qg.holmes.entity.k8s;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
@Data
@TableName(value = "env_template_detail")
public class EnvTemplateDetail {
@TableId(type = IdType.AUTO)
private Integer id;
private String serviceName;
private String serviceType;
private String label;
private String domain;
private String tag;
private Integer templateId;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
package cn.qg.holmes.entity.k8s;
import lombok.Data;
import java.util.List;
/**
* 创建环境模板虚拟实体类
*/
@Data
public class EnvTemplateVo {
private EnvTemplate envTemplate;
private List<EnvTemplateDetail> envTemplateDetailList;
}
package cn.qg.holmes.entity.navigate; package cn.qg.holmes.entity.navigate;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
...@@ -45,4 +46,7 @@ public class NavigateDetail { ...@@ -45,4 +46,7 @@ public class NavigateDetail {
*/ */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime; private Date updateTime;
@TableField(exist = false)
private String moduleName;
} }
package cn.qg.holmes.mapper.effect;
import cn.qg.holmes.entity.effect.BuildDataDetail;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface BuildDataDetailMapper extends BaseMapper<BuildDataDetail> {
}
package cn.qg.holmes.mapper.effect;
import cn.qg.holmes.entity.effect.BuildData;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface BuildDataMapper extends BaseMapper<BuildData> {
}
...@@ -6,5 +6,5 @@ import com.baomidou.mybatisplus.core.metadata.IPage; ...@@ -6,5 +6,5 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
public interface DockerProjectMapper extends BaseMapper<DockerProject> { public interface DockerProjectMapper extends BaseMapper<DockerProject> {
IPage<DockerProject> getDockerProjectList(IPage<DockerProject> page, String projectName, String projectType, Integer isActive); IPage<DockerProject> getDockerProjectList(IPage<DockerProject> page, String projectName, String projectType, Integer isActive, String hostName);
} }
package cn.qg.holmes.mapper.k8s;
import cn.qg.holmes.entity.k8s.EnvTemplateDetail;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface EnvTemplateDetailMapper extends BaseMapper<EnvTemplateDetail> {
}
package cn.qg.holmes.mapper.k8s;
import cn.qg.holmes.entity.k8s.EnvTemplate;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface EnvTemplateMapper extends BaseMapper<EnvTemplate> {
}
package cn.qg.holmes.service.effect;
import cn.qg.holmes.entity.effect.BuildDataDetail;
import com.baomidou.mybatisplus.extension.service.IService;
public interface BuildDataDetailService extends IService<BuildDataDetail> {
}
package cn.qg.holmes.service.effect;
import cn.qg.holmes.entity.effect.BuildData;
import com.baomidou.mybatisplus.extension.service.IService;
public interface BuildDataService extends IService<BuildData> {
}
package cn.qg.holmes.service.effect; package cn.qg.holmes.service.effect;
import java.util.List; import java.util.List;
import java.util.Map;
public interface DatabaseSyncService { public interface DatabaseSyncService {
boolean getDbInfoFromSource(String ip, String port, String username, String password, String dbName); boolean getDbInfoFromSource(String ip, String port, String username, String password, String dbName);
boolean syncDbToDest(String ip, String port, String username, String password, String dbName, String namespace); boolean syncDbToDest(String ip, String port, String username, String password, String dbName, String namespace, boolean businessData);
boolean getSingleTableFromSource(String ip, String port, String username, String password, String dbName, String tableName); boolean getSingleTableFromSource(String ip, String port, String username, String password, String dbName, String tableName);
boolean syncSingleTableToDest(String ip, String port, String username, String password, String dbName, String tableName); boolean syncSingleTableToDest(String ip, String port, String username, String password, String dbName, String tableName, boolean businessData);
List<Object> getDatabaseList(String ip, String port, String username, String password); List<String> getDatabaseList(String ip, String port, String username, String password);
Map<String, String> getMysqlInfoByNamespace(String namespace); List<String> getTableListByDb(String ip, String port, String username, String password, String dbName);
List<Object> getTableListByDb(String ip, String port, String username, String password, String dbName); // 从同步库获取表结构
boolean getSourceDbStructure(String ip, String port, String username, String password, String dbName, String tableName);
// 将同步库的表结构同步到环境
boolean syncDbStructureToDest(String ip, String port, String username, String password, String dbName, String tableName);
} }
\ No newline at end of file
package cn.qg.holmes.service.effect.impl;
import cn.qg.holmes.entity.effect.BuildDataDetail;
import cn.qg.holmes.mapper.effect.BuildDataDetailMapper;
import cn.qg.holmes.service.effect.BuildDataDetailService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service
public class BuildDataDetailServiceImpl extends ServiceImpl<BuildDataDetailMapper, BuildDataDetail>
implements BuildDataDetailService {
}
package cn.qg.holmes.service.effect.impl;
import cn.qg.holmes.entity.effect.BuildData;
import cn.qg.holmes.mapper.effect.BuildDataMapper;
import cn.qg.holmes.service.effect.BuildDataService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service
public class BuildDataServiceImpl extends ServiceImpl<BuildDataMapper, BuildData> implements BuildDataService {
}
package cn.qg.holmes.service.effect.impl; package cn.qg.holmes.service.effect.impl;
import cn.qg.holmes.service.effect.DatabaseSyncService; import cn.qg.holmes.service.effect.DatabaseSyncService;
import cn.qg.holmes.utils.HttpClientUtils;
import cn.qg.holmes.utils.RedisUtils; import cn.qg.holmes.utils.RedisUtils;
import com.alibaba.fastjson.JSON;
import com.jayway.jsonpath.JsonPath;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.*; import java.sql.*;
import java.util.*; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Slf4j @Slf4j
@Service @Service
...@@ -21,9 +21,6 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService { ...@@ -21,9 +21,6 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService {
@Autowired @Autowired
RedisUtils redisUtils; RedisUtils redisUtils;
@Value("${tke.host}")
private String tkeHost;
@Value("${cash_loan_flow.sql}") @Value("${cash_loan_flow.sql}")
private String cashLoanFlowSql; private String cashLoanFlowSql;
...@@ -35,6 +32,29 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService { ...@@ -35,6 +32,29 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService {
private final String dbSyncPrefix = "dbsync:"; private final String dbSyncPrefix = "dbsync:";
/**
* 实现StringBuilder的replaceAll
*
* @param stb
* @param oldStr 被替换的字符串
* @param newStr 替换oldStr
* @return
*/
public StringBuilder replaceAll(StringBuilder stb, String oldStr, String newStr) {
if (stb == null || oldStr == null || newStr == null || stb.length() == 0 || oldStr.length() == 0)
return stb;
int index = stb.indexOf(oldStr);
if (index > -1 && !oldStr.equals(newStr)) {
int lastIndex = 0;
while (index > -1) {
stb.replace(index, index + oldStr.length(), newStr);
lastIndex = index + newStr.length();
index = stb.indexOf(oldStr, lastIndex);
}
}
return stb;
}
/** /**
* 从中间库获取数据库相关信息 * 从中间库获取数据库相关信息
* @param ip 中间库 ip * @param ip 中间库 ip
...@@ -56,11 +76,11 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService { ...@@ -56,11 +76,11 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService {
// 创建数据库的redis值 // 创建数据库的redis值
String dbRedisValue = ""; String dbRedisValue = "";
// 表数据redis值 // 表数据redis值
String insertRedisValue = ""; StringBuilder insertRedisValue = new StringBuilder();
// 建表语句redis值 // 建表语句redis值
String createTableRedisValue = ""; String createTableRedisValue = "";
// 表名列表redis值 // 表名列表redis值
String tableListStr = ""; StringBuilder tableListStr = new StringBuilder();
List<String> columnNameList = new ArrayList<>(); List<String> columnNameList = new ArrayList<>();
List<String> columnTypeList = new ArrayList<>(); List<String> columnTypeList = new ArrayList<>();
...@@ -76,24 +96,26 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService { ...@@ -76,24 +96,26 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService {
while (dbResultSet.next()) { while (dbResultSet.next()) {
dbRedisValue = dbResultSet.getString(2); dbRedisValue = dbResultSet.getString(2);
} }
dbResultSet.close();
// 设置建库语句的redis值 // 设置建库语句的redis值
redisUtils.set(dbRedisKey, dbRedisValue, 86400); redisUtils.set(dbRedisKey, dbRedisValue, 86400);
} }
DatabaseMetaData databaseMetaData = connection.getMetaData(); DatabaseMetaData databaseMetaData = connection.getMetaData();
// 获取所有表名 // 获取所有表名
ResultSet tableResultSet = databaseMetaData.getTables(null, null, null, new String[]{"TABLE"}); ResultSet tableResultSet = databaseMetaData.getTables(null, null, null, new String[]{"TABLE"});
// 遍历表,一个表一个表处理
while (tableResultSet.next()) { while (tableResultSet.next()) {
String tableName = tableResultSet.getString("TABLE_NAME"); String tableName = tableResultSet.getString("TABLE_NAME");
tableListStr += tableName; tableListStr.append(tableName);
tableListStr += "\n"; tableListStr.append("\n");
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
log.info("开始获取表{}的数据", tableName); log.info("开始获取表{}的数据", tableName);
String createTableKey = dbSyncPrefix + dbName + ":" + tableName + ":create" ; String createTableKey = dbSyncPrefix + dbName + ":" + tableName + ":create" ;
String insertTableKey = dbSyncPrefix + dbName + ":" + tableName + ":insert" ; String insertTableKey = dbSyncPrefix + dbName + ":" + tableName + ":insert" ;
// 表结构
if (!redisUtils.hasKey(createTableKey)) { if (!redisUtils.hasKey(createTableKey)) {
// 获取所有建表语句 // 获取所有建表语句
String sql = String.format("SHOW CREATE TABLE %s", tableName); String sql = String.format("SHOW CREATE TABLE %s", tableName);
...@@ -102,10 +124,13 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService { ...@@ -102,10 +124,13 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService {
while (pResultSet.next()) { while (pResultSet.next()) {
createTableRedisValue = pResultSet.getString(2); createTableRedisValue = pResultSet.getString(2);
} }
pResultSet.close();
redisUtils.set(createTableKey, createTableRedisValue, 86400); redisUtils.set(createTableKey, createTableRedisValue, 86400);
createTableRedisValue = ""; createTableRedisValue = "";
} }
// 表数据
if (!redisUtils.hasKey(insertTableKey)) { if (!redisUtils.hasKey(insertTableKey)) {
ResultSet columnResultSet = databaseMetaData.getColumns(null, "%", tableName, "%"); ResultSet columnResultSet = databaseMetaData.getColumns(null, "%", tableName, "%");
while (columnResultSet.next()) { while (columnResultSet.next()) {
...@@ -117,34 +142,50 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService { ...@@ -117,34 +142,50 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService {
columnNameList.add(columnName); columnNameList.add(columnName);
columnTypeList.add(columnType); columnTypeList.add(columnType);
} }
String columnArrayStr = null; columnResultSet.close();
StringBuilder columnArrayStr = new StringBuilder();
for (String column : columnNameList) { for (String column : columnNameList) {
if (null == columnArrayStr) { if (columnArrayStr.length() == 0) {
columnArrayStr = "`" + column + "`"; columnArrayStr.append("`").append(column).append("`");
} else { } else {
columnArrayStr = columnArrayStr + "," + "`" + column + "`"; columnArrayStr.append(",`").append(column).append("`");
} }
} }
String selectSQL = String.format("select %s from %s", columnArrayStr, tableName); preparedStatement = connection.prepareStatement("select " + columnArrayStr + " from " + tableName);
preparedStatement = connection.prepareStatement(selectSQL);
ResultSet selectResultSet = preparedStatement.executeQuery(); ResultSet selectResultSet = preparedStatement.executeQuery();
StringBuilder insertSql = new StringBuilder();
while (selectResultSet.next()) { while (selectResultSet.next()) {
String rowValues = getRowValues(selectResultSet, columnNameList.size(), columnTypeList); String rowValues = getRowValues(selectResultSet, columnNameList.size(), columnTypeList);
String insertSql = String.format("insert into %s (%s) values(%s);", tableName, columnArrayStr, rowValues); insertSql
insertSql = insertSql.replaceAll("\n", "<br/>"); .append("insert into ")
insertSql = insertSql + "\n"; .append(tableName)
insertRedisValue += insertSql; .append(" (")
} .append(columnArrayStr)
.append(") ")
.append("values (")
.append(rowValues)
.append(");");
insertSql = replaceAll(insertSql, "\n", "<br/>");
insertSql.append("\n");
insertRedisValue.append(insertSql);
// 清空insertSql
insertSql.delete(0, insertSql.length());
}
selectResultSet.close();
columnNameList.clear(); columnNameList.clear();
columnTypeList.clear(); columnTypeList.clear();
redisUtils.set(insertTableKey, insertRedisValue, 86400);
redisUtils.set(insertTableKey, insertRedisValue.toString(), 86400);
long endTime = System.currentTimeMillis(); long endTime = System.currentTimeMillis();
log.info("{}表数据获取完成,共花费{}秒", tableName, (endTime - startTime) / 1000); log.info("{}表数据获取完成,共花费{}秒", tableName, (endTime - startTime) / 1000);
insertRedisValue = ""; // 清空insertRedisValue
insertRedisValue.delete(0, insertRedisValue.length());
} }
} }
redisUtils.set(tableListKey, tableListStr, 86400); tableResultSet.close();
redisUtils.set(tableListKey, tableListStr.toString(), 86400);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
...@@ -172,120 +213,42 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService { ...@@ -172,120 +213,42 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService {
* @return * @return
*/ */
@Override @Override
public boolean syncDbToDest(String ip, String port, String username, String password, String dbName, String namespace) { public boolean syncDbToDest(String ip, String port, String username, String password, String dbName, String namespace, boolean businessData) {
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://" + ip + ":" + port;
String dbRedisKey = dbSyncPrefix + dbName;
String tableListKey = dbSyncPrefix + dbName + ":tables";
Connection connection = null;
Connection newConnection = null;
PreparedStatement preparedStatement = null;
try { try {
Class.forName(driver); String tableListKey = dbSyncPrefix + dbName + ":tables";
connection = DriverManager.getConnection(url, username, password);
// 删除原有数据库
String dropDbSql = String.format("DROP DATABASE IF EXISTS %s", dbName);
log.info("删除原有数据库:{}", dropDbSql);
preparedStatement = connection.prepareStatement(dropDbSql);
preparedStatement.execute();
// 重新创建数据库
String createDbSql = redisUtils.get(dbRedisKey).toString();
log.info("重新创建数据库:{}", createDbSql);
preparedStatement = connection.prepareStatement(createDbSql);
preparedStatement.execute();
connection.close();
// 重新设置连接,并指定数据库
newConnection = DriverManager.getConnection(url + "/" + dbName, username, password);
newConnection.setAutoCommit(false);
List<String> tableList = Arrays.asList(redisUtils.get(tableListKey).toString().split("\n")); List<String> tableList = Arrays.asList(redisUtils.get(tableListKey).toString().split("\n"));
Statement statement = newConnection.createStatement(); if (tableList.size() > 0) {
// 循环处理每个表
for (String tableName: tableList) { for (String tableName: tableList) {
log.info("开始同步表:{}", tableName); syncSingleTableToDest(ip, port, username, password, dbName, tableName, businessData);
long dataStartTime = System.currentTimeMillis();
String createTableKey = dbSyncPrefix + dbName + ":" + tableName + ":create" ;
String insertTableKey = dbSyncPrefix + dbName + ":" + tableName + ":insert" ;
String createTableValue = redisUtils.get(createTableKey).toString();
String insertTableValue = redisUtils.get(insertTableKey).toString();
// 不为空时才执行建表语句
if (!createTableValue.isEmpty()) {
statement.execute(createTableValue);
}
// 不为空时才插入数据
if (!insertTableValue.isEmpty()) {
for (String insertSql: insertTableValue.split("\n")) {
statement.addBatch(insertSql);
}
statement.executeBatch();
statement.clearBatch();
}
long dataEndTime = System.currentTimeMillis();
log.info("{}表同步完成,共花费{}秒", tableName, (dataEndTime - dataStartTime) / 1000);
}
// 判断是否需要update
if (dbName.equals("cash_loan_flow")) {
for (String sql: cashLoanFlowSql.split("\n")) {
log.info("执行update sql: {}", sql);
statement.addBatch(sql);
}
statement.executeBatch();
statement.clearBatch();
}
if (dbName.equals("contract")) {
for (String sql: contractSql.split("\n")) {
log.info("执行update sql: {}", sql);
statement.addBatch(sql);
} }
statement.executeBatch();
statement.clearBatch();
}
if (dbName.equals("payment_center")) {
for (String sql: paymentCenterSql.split("\n")) {
log.info("执行update sql: {}", sql);
statement.addBatch(sql);
}
statement.executeBatch();
statement.clearBatch();
}
newConnection.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (connection != null) {
connection.close();
}
if (newConnection != null) {
newConnection.close();
}
if (preparedStatement != null) {
preparedStatement.close();
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} return false;
} }
return true; return true;
} }
/**
* 获取单个表
* @param ip 同步库ip
* @param port 同步库端口
* @param username 同步库用户名
* @param password 同步库密码
* @param dbName 数据库名
* @param tableName 表名
* @return
*/
@Override @Override
public boolean getSingleTableFromSource(String ip, String port, String username, String password, String dbName, String tableName) { public boolean getSingleTableFromSource(String ip, String port, String username, String password, String dbName, String tableName) {
String driver = "com.mysql.jdbc.Driver"; String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://" + ip + ":" + port + "/" + dbName; String url = "jdbc:mysql://" + ip + ":" + port + "/" + dbName;
String dbRedisKey = dbSyncPrefix + dbName;
String tableCreateKey = dbSyncPrefix + dbName + ":" + tableName + ":create"; String tableCreateKey = dbSyncPrefix + dbName + ":" + tableName + ":create";
String tableInsertKey = dbSyncPrefix + dbName + ":" + tableName + ":insert"; String tableInsertKey = dbSyncPrefix + dbName + ":" + tableName + ":insert";
String insertRedisValue = ""; String dbRedisValue = null;
StringBuilder insertRedisValue = new StringBuilder();
Connection connection = null; Connection connection = null;
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
...@@ -298,6 +261,19 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService { ...@@ -298,6 +261,19 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService {
connection.setAutoCommit(true); connection.setAutoCommit(true);
DatabaseMetaData databaseMetaData = connection.getMetaData(); DatabaseMetaData databaseMetaData = connection.getMetaData();
// 判断是否有创建数据库的redis值
if (!redisUtils.hasKey(dbRedisKey)) {
String dbSql = String.format("SHOW CREATE DATABASE %s", dbName);
preparedStatement = connection.prepareStatement(dbSql);
ResultSet dbResultSet = preparedStatement.executeQuery();
while (dbResultSet.next()) {
dbRedisValue = dbResultSet.getString(2);
}
dbResultSet.close();
// 设置建库语句的redis值
redisUtils.set(dbRedisKey, dbRedisValue, 86400);
}
if (!redisUtils.hasKey(tableCreateKey)) { if (!redisUtils.hasKey(tableCreateKey)) {
String sql = String.format("SHOW CREATE TABLE %s", tableName); String sql = String.format("SHOW CREATE TABLE %s", tableName);
preparedStatement = connection.prepareStatement(sql); preparedStatement = connection.prepareStatement(sql);
...@@ -305,9 +281,11 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService { ...@@ -305,9 +281,11 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService {
while (resultSet.next()) { while (resultSet.next()) {
redisUtils.set(tableCreateKey, resultSet.getString(2), 600); redisUtils.set(tableCreateKey, resultSet.getString(2), 600);
} }
resultSet.close();
} }
if (!redisUtils.hasKey(tableInsertKey)) { if (!redisUtils.hasKey(tableInsertKey)) {
log.info("redis中没有{}表的数据,开始获取表数据。", tableName);
ResultSet columnResultSet = databaseMetaData.getColumns(null, "%", tableName, "%"); ResultSet columnResultSet = databaseMetaData.getColumns(null, "%", tableName, "%");
while (columnResultSet.next()) { while (columnResultSet.next()) {
// 字段名称 // 字段名称
...@@ -318,26 +296,44 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService { ...@@ -318,26 +296,44 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService {
columnNameList.add(columnName); columnNameList.add(columnName);
columnTypeList.add(columnType);; columnTypeList.add(columnType);;
} }
String columnArrayStr = null; columnResultSet.close();
StringBuilder columnArrayStr = new StringBuilder();
for (String column : columnNameList) { for (String column : columnNameList) {
if (null == columnArrayStr) { if (columnArrayStr.length() == 0) {
columnArrayStr = "`" + column + "`"; columnArrayStr.append("`").append(column).append("`");
} else { } else {
columnArrayStr = columnArrayStr + "," + "`" + column + "`"; columnArrayStr.append(",`").append(column).append("`");
} }
} }
String selectSQL = String.format("select %s from %s", columnArrayStr, tableName); String selectSQL = String.format("select %s from %s", columnArrayStr, tableName);
preparedStatement = connection.prepareStatement(selectSQL); preparedStatement = connection.prepareStatement(selectSQL);
ResultSet selectResultSet = preparedStatement.executeQuery(); ResultSet selectResultSet = preparedStatement.executeQuery();
StringBuilder insertSql = new StringBuilder();
while (selectResultSet.next()) { while (selectResultSet.next()) {
String rowValues = getRowValues(selectResultSet, columnNameList.size(), columnTypeList); String rowValues = getRowValues(selectResultSet, columnNameList.size(), columnTypeList);
String insertSql = String.format("insert into %s (%s) values(%s);", tableName, columnArrayStr, rowValues); // String insertSql = String.format("insert into %s (%s) values(%s);", tableName, columnArrayStr, rowValues);
insertSql = insertSql.replaceAll("\n", "<br/>"); // insertSql = insertSql.replaceAll("\n", "<br/>");
insertSql = insertSql + "\n"; // insertSql = insertSql + "\n";
insertRedisValue += insertSql; insertSql
} .append("insert into ")
redisUtils.set(tableInsertKey, insertRedisValue, 600); .append(tableName)
.append(" (")
.append(columnArrayStr)
.append(") ")
.append("values (")
.append(rowValues)
.append(");");
insertSql = replaceAll(insertSql, "\n", "<br/>");
insertSql.append("\n");
insertRedisValue.append(insertSql);
insertSql.delete(0, insertSql.length());
}
selectResultSet.close();
redisUtils.set(tableInsertKey, insertRedisValue.toString(), 600);
insertRedisValue.delete(0, insertRedisValue.length());
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
...@@ -357,50 +353,200 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService { ...@@ -357,50 +353,200 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService {
return true; return true;
} }
/**
* 同步单张表
* @param ip
* @param port
* @param username
* @param password
* @param dbName
* @param tableName
* @param businessData 是否同步业务数据
* @return
*/
@Override @Override
public boolean syncSingleTableToDest(String ip, String port, String username, String password, String dbName, String tableName) { public boolean syncSingleTableToDest(String ip, String port, String username, String password, String dbName, String tableName, boolean businessData) {
String driver = "com.mysql.jdbc.Driver"; String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://" + ip + ":" + port + "/" + dbName; String url = "jdbc:mysql://" + ip + ":" + port + "/" + dbName;
String urlWithoutDb = "jdbc:mysql://" + ip + ":" + port;
String createDbKey = dbSyncPrefix + dbName;
String tableCreateKey = dbSyncPrefix + dbName + ":" + tableName + ":create"; String tableCreateKey = dbSyncPrefix + dbName + ":" + tableName + ":create";
String tableInsertKey = dbSyncPrefix + dbName + ":" + tableName + ":insert"; String tableInsertKey = dbSyncPrefix + dbName + ":" + tableName + ":insert";
Connection connection = null; Connection connection = null;
Connection connectionWithoutDb = null;
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
Statement statement = null; Statement statement = null;
List<String> columnNameList = new ArrayList<>();
List<String> columnTypeList = new ArrayList<>();
try { try {
Class.forName(driver); Class.forName(driver);
connection = DriverManager.getConnection(url, username, password);
connection.setAutoCommit(false);
String createDbSql = redisUtils.get(createDbKey).toString();
String createTableSql = redisUtils.get(tableCreateKey).toString(); String createTableSql = redisUtils.get(tableCreateKey).toString();
String insertTableSql = redisUtils.get(tableInsertKey).toString(); String insertTableSql = redisUtils.get(tableInsertKey).toString();
String dropTableSql = String.format("DROP TABLE if exists %s", tableName);
// 暂存原有数据
StringBuilder backupDataSql = new StringBuilder();
List<String> dbList = getDatabaseList(ip, port, username, password);
if (dbList.contains(dbName)) {
// 环境中数据库已存在
// 创建数据库连接
connection = DriverManager.getConnection(url, username, password);
connection.setAutoCommit(false);
DatabaseMetaData databaseMetaData = connection.getMetaData();
// 获取表列表
List<String> tableList = getTableListByDb(ip, port, username, password, dbName);
if (tableList.contains(tableName)) {
// 如果表存在
if (businessData) {
// 需要保留业务数据
log.info("因需要保留业务数据,因此先备份环境中{}.{}表的数据", dbName, tableName);
ResultSet columnResultSet = databaseMetaData.getColumns(null, "%", tableName, "%");
while (columnResultSet.next()) {
// 字段名称
String columnName = columnResultSet.getString("COLUMN_NAME");
// 数据类型
String columnType = columnResultSet.getString("TYPE_NAME");
columnNameList.add(columnName);
columnTypeList.add(columnType);;
}
columnResultSet.close();
StringBuilder columnArrayStr = new StringBuilder();
for (String column : columnNameList) {
if (columnArrayStr.length() == 0) {
columnArrayStr.append("`").append(column).append("`");
} else {
columnArrayStr.append(",`").append(column).append("`");
}
}
String selectSQL = String.format("select %s from %s", columnArrayStr, tableName);
preparedStatement = connection.prepareStatement(selectSQL);
ResultSet selectResultSet = preparedStatement.executeQuery();
StringBuilder insertSql = new StringBuilder();
while (selectResultSet.next()) {
String rowValues = getRowValues(selectResultSet, columnNameList.size(), columnTypeList);
insertSql
.append("insert into ")
.append(tableName)
.append(" (")
.append(columnArrayStr)
.append(") ")
.append("values (")
.append(rowValues)
.append(");");
insertSql = replaceAll(insertSql, "\n", "<br/>");
insertSql.append("\n");
backupDataSql.append(insertSql);
insertSql.delete(0, insertSql.length());
}
selectResultSet.close();
// 如果表存在,则首先删除表 // 如果表存在,则首先删除表
String dropTableSql = String.format("DROP TABLE if exists %s", tableName); log.info("表数据备份完成,删除环境中的{}.{}表", dbName, tableName);
preparedStatement = connection.prepareStatement(dropTableSql); preparedStatement = connection.prepareStatement(dropTableSql);
preparedStatement.execute(); preparedStatement.execute();
// 重新创建表 // 重新创建表
log.info("使用同步库中的表结构重新创建表: {}.{}", dbName, tableName);
preparedStatement = connection.prepareStatement(createTableSql); preparedStatement = connection.prepareStatement(createTableSql);
preparedStatement.execute(); preparedStatement.execute();
// 环境备份数据不为空,插入环境备份的数据
if (backupDataSql.length() > 0) {
log.info("开始插入环境中备份的数据!");
statement = connection.createStatement(); statement = connection.createStatement();
for (String insertSql: insertTableSql.split("\n")) { for (String sql: backupDataSql.toString().split("\n")) {
statement.addBatch(insertSql); statement.addBatch(sql);
}
} }
} else {
// 不需要保留业务数据
// 表存在,则首先删除表
preparedStatement = connection.prepareStatement(dropTableSql);
preparedStatement.execute();
// 重新创建表
log.info("使用同步库中的表结构重新创建表: {}.{}", dbName, tableName);
preparedStatement = connection.prepareStatement(createTableSql);
preparedStatement.execute();
// 同步库中数据不为空时,插入同步库中的数据
if (!StringUtils.isEmpty(insertTableSql)) {
log.info("开始插入同步库中的数据!");
statement = connection.createStatement();
for (String sql: insertTableSql.split("\n")) {
statement.addBatch(sql);
}
}
}
} else {
// 表不存在,创建表
log.info("使用同步库中的表结构创建表: {}.{}", dbName, tableName);
preparedStatement = connection.prepareStatement(createTableSql);
preparedStatement.execute();
// 同步库中数据不为空时,插入同步库中的数据
if (!StringUtils.isEmpty(insertTableSql)) {
log.info("开始插入同步库中的数据!");
statement = connection.createStatement();
for (String sql: insertTableSql.split("\n")) {
statement.addBatch(sql);
}
}
}
} else {
// 环境中数据库不存在, 此时无论是否保留业务数据
// 创建数据库
log.info("环境中不存在数据库,首先创建数据库:{}", dbName);
connectionWithoutDb = DriverManager.getConnection(urlWithoutDb, username, password);
connectionWithoutDb.setAutoCommit(false);
preparedStatement = connectionWithoutDb.prepareStatement(createDbSql);
preparedStatement.execute();
connection = DriverManager.getConnection(url, username, password);
connection.setAutoCommit(false);
// 创建表
log.info("使用同步库中的表结构创建表: {}.{}", dbName, tableName);
preparedStatement = connection.prepareStatement(createTableSql);
preparedStatement.execute();
// 同步库中数据不为空时,插入同步库中的数据
if (!StringUtils.isEmpty(insertTableSql)) {
log.info("开始插入同步库中的数据!");
statement = connection.createStatement();
for (String sql: insertTableSql.split("\n")) {
statement.addBatch(sql);
}
}
}
if (statement != null) {
statement.executeBatch(); statement.executeBatch();
statement.clearBatch(); statement.clearBatch();
}
connection.commit(); connection.commit();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
log.info("表{}.{}同步失败.", dbName, tableName);
return false; return false;
} finally { } finally {
try { try {
if (connection != null) { if (connection != null) {
connection.close(); connection.close();
} }
if (connectionWithoutDb != null) {
connectionWithoutDb.close();
}
if (preparedStatement != null) { if (preparedStatement != null) {
preparedStatement.close(); preparedStatement.close();
} }
...@@ -423,17 +569,11 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService { ...@@ -423,17 +569,11 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService {
* @return * @return
*/ */
@Override @Override
public List<Object> getDatabaseList(String ip, String port, String username, String password) { public List<String> getDatabaseList(String ip, String port, String username, String password) {
String driver = "com.mysql.jdbc.Driver"; String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://" + ip + ":" + port; String url = "jdbc:mysql://" + ip + ":" + port;
List<Object> databaseList = new ArrayList<>(); List<String> databaseList = new ArrayList<>();
String dbListRedisKey = dbSyncPrefix + ":db:list";
if (redisUtils.hasKey(dbListRedisKey)) {
databaseList = redisUtils.lGet(dbListRedisKey, 0, redisUtils.lGetListSize(dbListRedisKey));
log.info("从redis获取到的数据库列表为:{}", databaseList);
} else {
Connection connection = null; Connection connection = null;
try { try {
...@@ -445,12 +585,12 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService { ...@@ -445,12 +585,12 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService {
PreparedStatement preparedStatement = connection.prepareStatement(showDatabasesSql); PreparedStatement preparedStatement = connection.prepareStatement(showDatabasesSql);
ResultSet dbListResultSet = preparedStatement.executeQuery(); ResultSet dbListResultSet = preparedStatement.executeQuery();
while (dbListResultSet.next()) { while (dbListResultSet.next()) {
databaseList.add(dbListResultSet.getString(1)); String database = dbListResultSet.getString(1);
if (!database.equals("information_schema") && !database.equals("sys")) {
databaseList.add(database);
}
} }
preparedStatement.close(); preparedStatement.close();
// 设置数据库列表缓存,缓存24个小时
log.info("从同步库获取到的数据库列表为:{}", databaseList);
redisUtils.lSet(dbListRedisKey, databaseList, 86400);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
...@@ -462,32 +602,9 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService { ...@@ -462,32 +602,9 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService {
connection = null; connection = null;
} }
} }
}
return databaseList; return databaseList;
} }
/**
* 根据namespace获取对应的mysql ip和端口
* @param namespace
* @return
*/
@Override
public Map<String, String> getMysqlInfoByNamespace(String namespace) {
Map<String, String> headers = new HashMap<>();
Map<String, String> params = new HashMap<>();
headers.put("cluster", "qa");
params.put("namespace", namespace);
params.put("serviceName", "mysql");
params.put("type", "base");
String response = HttpClientUtils.doPostJson(tkeHost + "/service/details", headers, JSON.toJSONString(params));
String mysqlIp = JsonPath.read(response, "$.data.lanIp").toString();
String mysqlPort = JsonPath.read(response, "$.data.portMappings[0].nodePort").toString();
Map<String, String> result = new HashMap<>();
result.put("ip", mysqlIp);
result.put("port", mysqlPort);
return result;
}
/** /**
* 获取某个数据库下表列表 * 获取某个数据库下表列表
* @param ip mysql ip * @param ip mysql ip
...@@ -498,13 +615,13 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService { ...@@ -498,13 +615,13 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService {
* @return * @return
*/ */
@Override @Override
public List<Object> getTableListByDb(String ip, String port, String username, String password, String dbName) { public List<String> getTableListByDb(String ip, String port, String username, String password, String dbName) {
String driver = "com.mysql.jdbc.Driver"; String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://" + ip + ":" + port + "/" + dbName; String url = "jdbc:mysql://" + ip + ":" + port + "/" + dbName;
Connection connection = null; Connection connection = null;
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
List<Object> tableList = new ArrayList<>(); List<String> tableList = new ArrayList<>();
try { try {
Class.forName(driver); Class.forName(driver);
...@@ -536,6 +653,152 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService { ...@@ -536,6 +653,152 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService {
} }
} }
/**
* 从同步库获取表结构
* @param ip
* @param port
* @param username
* @param password
* @param dbName
* @param tableName
* @return
*/
@Override
public boolean getSourceDbStructure(String ip, String port, String username, String password, String dbName, String tableName) {
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://" + ip + ":" + port + "/" + dbName;
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
Class.forName(driver);
connection = DriverManager.getConnection(url, username, password);
connection.setAutoCommit(true);
if ("all".equals(tableName)) {
String tableListKey = dbSyncPrefix + dbName + ":tableList";
List<String> tableList = getTableListByDb(ip, port, username, password, dbName);
redisUtils.set(tableListKey, StringUtils.join(tableList, " "), 600);
for (String table: tableList) {
String tableRedisKey = dbSyncPrefix + dbName + ":" + table + ":create";
if (!redisUtils.hasKey(tableRedisKey)) {
String sql = String.format("SHOW CREATE TABLE %s", table);
preparedStatement = connection.prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
redisUtils.set(tableRedisKey, resultSet.getString(2), 600);
}
resultSet.close();
preparedStatement.clearBatch();
}
}
} else {
String tableRedisKey = dbSyncPrefix + dbName + ":" + tableName + ":create";
if (!redisUtils.hasKey(tableRedisKey)) {
String sql = String.format("SHOW CREATE TABLE %s", tableName);
preparedStatement = connection.prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
redisUtils.set(tableRedisKey, resultSet.getString(2), 600);
}
resultSet.close();
}
preparedStatement.clearBatch();
}
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
try {
if (connection != null) {
connection.close();
}
if (preparedStatement != null) {
preparedStatement.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return true;
}
/**
* 将同步库的表结构同步到环境中
* @param ip
* @param port
* @param username
* @param password
* @param dbName
* @param tableName
* @return
*/
@Override
public boolean syncDbStructureToDest(String ip, String port, String username, String password, String dbName, String tableName) {
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://" + ip + ":" + port + "/" + dbName;
Connection connection = null;
Statement statement = null;
try {
Class.forName(driver);
connection = DriverManager.getConnection(url, username, password);
connection.setAutoCommit(true);
statement = connection.createStatement();
if ("all".equals(tableName)) {
String tableListKey = dbSyncPrefix + dbName + ":tableList";
List<String> tableList = Arrays.asList(redisUtils.get(tableListKey).toString().split(" "));
// 删除key
redisUtils.del(tableListKey);
for (String table: tableList) {
// 首先删除表
String dropTableSql = "DROP TABLE IF EXISTS " + table;
statement.execute(dropTableSql);
statement.clearBatch();
// 然后同步表结构
String tableRedisKey = dbSyncPrefix + dbName + ":" + table + ":create";
String createTableSql = redisUtils.get(tableRedisKey).toString();
redisUtils.del(tableRedisKey);
statement.execute(createTableSql);
statement.clearBatch();
}
} else {
// 首先删除表
String dropTableSql = "DROP TABLE IF EXISTS " + tableName;
statement.execute(dropTableSql);
// 然后同步表结构
String tableRedisKey = dbSyncPrefix + dbName + ":" + tableName + ":create";
String createTableSql = redisUtils.get(tableRedisKey).toString();
redisUtils.del(tableRedisKey);
statement.execute(createTableSql);
statement.clearBatch();
}
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
try {
if (connection != null) {
connection.close();
}
if (statement != null) {
statement.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return true;
}
/** /**
* 获取表数据一行的所有值 * 获取表数据一行的所有值
* @param rs * @param rs
...@@ -545,7 +808,7 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService { ...@@ -545,7 +808,7 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService {
*/ */
private String getRowValues(ResultSet rs, int size, List<String> columnTypeList) { private String getRowValues(ResultSet rs, int size, List<String> columnTypeList) {
try { try {
String rowValues = null; StringBuilder rowValues = new StringBuilder();
for (int i = 1; i <= size; i++) { for (int i = 1; i <= size; i++) {
String columnValue = null; String columnValue = null;
...@@ -563,14 +826,14 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService { ...@@ -563,14 +826,14 @@ public class DatabaseSyncServiceImpl implements DatabaseSyncService {
columnValue = "'" + columnValue + "'"; columnValue = "'" + columnValue + "'";
} }
// 拼接字段值 // 拼接字段值
if (null == rowValues) { if (rowValues.length() == 0) {
rowValues = columnValue; rowValues.append(columnValue);
} else { } else {
rowValues = rowValues + "," + columnValue; rowValues.append(",").append(columnValue);
} }
} }
return rowValues; return rowValues.toString();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
System.out.println("获取表数据一行的所有值异常"); System.out.println("获取表数据一行的所有值异常");
......
...@@ -53,7 +53,7 @@ public class PipelineServiceImpl extends ServiceImpl<PipelineMapper, Pipeline> i ...@@ -53,7 +53,7 @@ public class PipelineServiceImpl extends ServiceImpl<PipelineMapper, Pipeline> i
if (pipeline != null) { if (pipeline != null) {
if (pipeline.getEnable() == 1) { if (pipeline.getEnable() == 1) {
log.info("pipeline中找到对应项目,且项目是启动状态,开始构建:{}", pipeline.toString()); log.info("pipeline中找到对应项目,且项目是启动状态,开始构建:{}", pipeline.toString());
Integer buildNum = jenkinsService.buildJenkinsJob(pipeline.getServiceType(), projectName, branch, pipeline.getNamespace()); Integer buildNum = jenkinsService.buildTkeJob(pipeline.getServiceType(), projectName, branch, pipeline.getNamespace());
String markdown = DingdingUtils.buildPipelineMarkdownMsg(projectName, branch, pipeline.getServiceType(), author, message, commitDate, pipeline.getNamespace(), buildNum.toString()); String markdown = DingdingUtils.buildPipelineMarkdownMsg(projectName, branch, pipeline.getServiceType(), author, message, commitDate, pipeline.getNamespace(), buildNum.toString());
DingdingUtils.sendToDingding(markdown, dingRobotService.getById(pipeline.getDingRobotId()).getDingUrl()); DingdingUtils.sendToDingding(markdown, dingRobotService.getById(pipeline.getDingRobotId()).getDingUrl());
} else { } else {
......
...@@ -42,16 +42,20 @@ public class DingRobotServiceImpl extends ServiceImpl<DingRobotMapper, DingRobot ...@@ -42,16 +42,20 @@ public class DingRobotServiceImpl extends ServiceImpl<DingRobotMapper, DingRobot
String priority = JsonPath.read(jiraData, "$.issue.fields.priority.name"); String priority = JsonPath.read(jiraData, "$.issue.fields.priority.name");
String module = JsonPath.read(jiraData, "$.issue.fields.components[0].name"); String module = JsonPath.read(jiraData, "$.issue.fields.components[0].name");
String robotUrl = null; String robotUrl = null;
Integer dingRobotId = null;
Integer status = null;
List<DingRobot> dingRobots = dingRobotMapper.selectList(null); List<DingRobot> dingRobots = dingRobotMapper.selectList(null);
for (DingRobot dingRobot : dingRobots) { for (DingRobot dingRobot : dingRobots) {
String projectName = "【" + dingRobot.getProjectName() + "】"; String projectName = "【" + dingRobot.getProjectName() + "】";
if (summary.contains(projectName)) { if (summary.contains(projectName)) {
robotUrl = dingRobot.getDingUrl(); robotUrl = dingRobot.getDingUrl();
dingRobotId = dingRobot.getId();
status = dingRobot.getStatus();
break; break;
} }
} }
// 只有创建了dingRobot的项目的BUG才会被放到BUG池子里 // 只有创建了dingRobot的项目的BUG才会被放到BUG池子里
if (robotUrl != null) { if (robotUrl != null && dingRobotId != null) {
// 首次提交的BUG放入bug池子 // 首次提交的BUG放入bug池子
JiraBugPool jiraBugPool = new JiraBugPool(); JiraBugPool jiraBugPool = new JiraBugPool();
jiraBugPool.setKey(key); jiraBugPool.setKey(key);
...@@ -61,9 +65,11 @@ public class DingRobotServiceImpl extends ServiceImpl<DingRobotMapper, DingRobot ...@@ -61,9 +65,11 @@ public class DingRobotServiceImpl extends ServiceImpl<DingRobotMapper, DingRobot
jiraBugPool.setAssignee(assignee); jiraBugPool.setAssignee(assignee);
jiraBugPool.setUrl("http://jira2.quantgroup.cn/browse/" + key); jiraBugPool.setUrl("http://jira2.quantgroup.cn/browse/" + key);
jiraBugPool.setDingUrl(robotUrl); jiraBugPool.setDingUrl(robotUrl);
jiraBugPool.setDingRobotId(dingRobotId);
jiraBugPoolService.save(jiraBugPool); jiraBugPoolService.save(jiraBugPool);
} }
if (robotUrl != null) { // 只有项目是进行中才会发送通知
if (robotUrl != null && status == 1) {
String markdownMsg = DingdingUtils.buildBugCommitMarkdownMsg(key, summary, creator, assignee, priority, module); String markdownMsg = DingdingUtils.buildBugCommitMarkdownMsg(key, summary, creator, assignee, priority, module);
return DingdingUtils.sendToDingding(markdownMsg, robotUrl); return DingdingUtils.sendToDingding(markdownMsg, robotUrl);
} }
......
...@@ -5,5 +5,5 @@ import com.baomidou.mybatisplus.core.metadata.IPage; ...@@ -5,5 +5,5 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
public interface DockerProjectService extends IService<DockerProject> { public interface DockerProjectService extends IService<DockerProject> {
IPage<DockerProject> getDockerProjectList(String projectName, String projectType, Integer isActive, Integer pageNum, Integer pageSize); IPage<DockerProject> getDockerProjectList(String projectName, String projectType, Integer isActive, String hostName, Integer pageNum, Integer pageSize);
} }
package cn.qg.holmes.service.k8s;
import cn.qg.holmes.entity.k8s.EnvTemplateDetail;
import com.baomidou.mybatisplus.extension.service.IService;
public interface EnvTemplateDetailService extends IService<EnvTemplateDetail> {
}
package cn.qg.holmes.service.k8s;
import cn.qg.holmes.entity.k8s.EnvTemplate;
import com.baomidou.mybatisplus.extension.service.IService;
public interface EnvTemplateService extends IService<EnvTemplate> {
}
...@@ -45,12 +45,13 @@ public class ImageService { ...@@ -45,12 +45,13 @@ public class ImageService {
* @param repoName 服务名 * @param repoName 服务名
* @return * @return
*/ */
public Map<String, Object> getImageListByService(String repoName) { public TagInfoResp getImageListByService(String repoName) {
try { try {
DescribeImagePersonalRequest request = new DescribeImagePersonalRequest(); DescribeImagePersonalRequest request = new DescribeImagePersonalRequest();
request.setRepoName(repoName); request.setRepoName(repoName);
DescribeImagePersonalResponse response = tcrClient.DescribeImagePersonal(request); DescribeImagePersonalResponse response = tcrClient.DescribeImagePersonal(request);
return JSON.parseObject(DescribeImagePersonalResponse.toJsonString(response.getData()), Map.class); // return JSON.parseObject(DescribeImagePersonalResponse.toJsonString(response.getData()), Map.class);
return response.getData();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return null; return null;
...@@ -97,7 +98,8 @@ public class ImageService { ...@@ -97,7 +98,8 @@ public class ImageService {
public static void main(String[] args) { public static void main(String[] args) {
ImageService imageService = new ImageService(); ImageService imageService = new ImageService();
System.out.println(JSON.toJSONString(imageService.getRepoInfoList("qa-test"))); // System.out.println(JSON.toJSONString(imageService.getRepoInfoList("qa-base")));
System.out.println(JSON.toJSONString(imageService.getImageListByService("qa-base/mongodb")));
} }
} }
...@@ -141,9 +141,17 @@ public class K8sService { ...@@ -141,9 +141,17 @@ public class K8sService {
if (service != null) { if (service != null) {
port = service.getSpec().getPorts().get(0).getNodePort(); port = service.getSpec().getPorts().get(0).getNodePort();
} }
if (podList.size() > 0) { if (podList.size() == 1) {
host = podList.get(0).getStatus().getHostIP(); host = podList.get(0).getStatus().getHostIP();
} }
if (podList.size() >= 2) {
for (Pod pod: podList) {
if (pod.getStatus().getHostIP() != null) {
host = pod.getStatus().getHostIP();
break;
}
}
}
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
df.setTimeZone(TimeZone.getTimeZone("UTC")); df.setTimeZone(TimeZone.getTimeZone("UTC"));
SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
...@@ -176,9 +184,17 @@ public class K8sService { ...@@ -176,9 +184,17 @@ public class K8sService {
if (service != null) { if (service != null) {
port = service.getSpec().getPorts().get(0).getNodePort(); port = service.getSpec().getPorts().get(0).getNodePort();
} }
if (podList.size() > 0) { if (podList.size() == 1) {
host = podList.get(0).getStatus().getHostIP(); host = podList.get(0).getStatus().getHostIP();
} }
if (podList.size() >= 2) {
for (Pod pod: podList) {
if (pod.getStatus().getHostIP() != null) {
host = pod.getStatus().getHostIP();
break;
}
}
}
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
df.setTimeZone(TimeZone.getTimeZone("UTC")); df.setTimeZone(TimeZone.getTimeZone("UTC"));
SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
...@@ -211,88 +227,33 @@ public class K8sService { ...@@ -211,88 +227,33 @@ public class K8sService {
* @param namespace 环境 * @param namespace 环境
* @return * @return
*/ */
public List<Map<String, Object>> getPodList(String namespace) { public Map<String, String> getMysqlAddressByNamespace(String namespace) {
List<Pod> podList = kubernetesClient.pods().inNamespace(namespace).list().getItems(); // 获取Service
List<Map<String, Object>> result = new ArrayList<>(); Service service = kubernetesClient.services().inNamespace(namespace).withName("mysql").get();
for (Pod pod : podList) { Map<String, String> labels = new HashMap<>();
System.out.println(pod); labels.put("qcloud-app", "mysql");
if (pod.getStatus().getPhase().equals("Running") || pod.getStatus().getPhase().equals("Pending")) { labels.put("type", "base");
Map<String, Object> map = new HashMap<>(); List<Pod> podList = kubernetesClient.pods().inNamespace(namespace).withLabels(labels).list().getItems();
// 端口映射 String port = null;
List<Map<String, Object>> portMappingList = new ArrayList<>(); String host = null;
ObjectMeta podMetadata = pod.getMetadata();
String serviceName = podMetadata.getLabels().get("qcloud-app");
// 端口暴露在Service
Service service = kubernetesClient.services().inNamespace(namespace).withName(serviceName).get();
if (service != null) { if (service != null) {
map.put("serviceType", service.getSpec().getType()); port = String.valueOf(service.getSpec().getPorts().get(0).getNodePort());
List<ServicePort> servicePortList = service.getSpec().getPorts();
if (servicePortList.size() > 0) {
for (ServicePort servicePort : servicePortList) {
if (servicePort.getNodePort() != null) {
map.put("port_" + servicePort.getName(), servicePort.getNodePort());
}
Map<String, Object> portMap = new HashMap<>();
portMap.put("name", servicePort.getName());
portMap.put("nodePort", servicePort.getNodePort());
portMap.put("port", servicePort.getPort());
portMap.put("protocol", servicePort.getProtocol());
portMap.put("targetPort", servicePort.getTargetPort());
portMappingList.add(portMap);
}
}
if (portMappingList.size() > 0) {
map.put("portMappings", portMappingList);
}
}
// 格式化创建时间
try {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
map.put("createdAt", df.parse(podMetadata.getCreationTimestamp()));
} catch (Exception e) {
e.printStackTrace();
log.info("时间转换异常!");
map.put("createdAt", podMetadata.getCreationTimestamp());
} }
// 从Ingress里获取host if (podList.size() == 1) {
Ingress ingress = kubernetesClient.extensions().ingresses().inNamespace(namespace).withName(serviceName).get(); host = podList.get(0).getStatus().getHostIP();
if (ingress != null) {
map.put("host", ingress.getSpec().getRules().get(0).getHost());
}
map.put("serviceName", serviceName);
map.put("podName", podMetadata.getName());
map.put("labels", podMetadata.getLabels());
map.put("image", pod.getStatus().getContainerStatuses().get(0).getImage());
map.put("imageId", pod.getStatus().getContainerStatuses().get(0).getImageID());
map.put("lanIp", pod.getStatus().getHostIP());
map.put("podIp", pod.getStatus().getPodIP());
map.put("startTime", pod.getStatus().getStartTime());
// 状态判断
List<ContainerStatus> containerStatuses = pod.getStatus().getContainerStatuses();
String status = "";
if (pod.getMetadata().getDeletionTimestamp() != null) {
status = "Terminating";
} else {
if (containerStatuses.size() == 0) {
status = "Pending";
} else {
if (containerStatuses.get(0).getState().getWaiting() != null) {
status = "ContainerCreating";
}
if (containerStatuses.get(0).getState().getRunning() != null && !containerStatuses.get(0).getReady()) {
status = "Waiting";
}
if (containerStatuses.get(0).getState().getRunning() != null && containerStatuses.get(0).getReady()) {
status = "Normal";
} }
if (podList.size() >= 2) {
for (Pod pod: podList) {
if (pod.getStatus().getHostIP() != null) {
host = pod.getStatus().getHostIP();
break;
} }
} }
map.put("status", status);
result.add(map);
} }
} Map<String, String> resultMap = new HashMap<>();
return result; resultMap.put("host", host);
resultMap.put("port", port);
return resultMap;
} }
...@@ -324,7 +285,7 @@ public class K8sService { ...@@ -324,7 +285,7 @@ public class K8sService {
// 对象转列表 // 对象转列表
List<Map<String, Object>> resultList = new ArrayList<>(); List<Map<String, Object>> resultList = new ArrayList<>();
for (Map<String, Object> map: podServiceMap.values()) { for (Map<String, Object> map: podServiceMap.values()) {
if (map != null) { if ((map != null) && (map.get("serviceName") != null)) {
resultList.add(map); resultList.add(map);
} }
} }
...@@ -604,7 +565,7 @@ public class K8sService { ...@@ -604,7 +565,7 @@ public class K8sService {
envVar3.setName("CLUSTER"); envVar3.setName("CLUSTER");
envVar3.setValue(cluster); envVar3.setValue(cluster);
EnvVar envVar4 = new EnvVar(); EnvVar envVar4 = new EnvVar();
envVar4.setName("CLUSTER"); envVar4.setName("SYSTEM_NAME");
envVar4.setValue(serviceName); envVar4.setValue(serviceName);
EnvVar envVar5 = new EnvVar(); EnvVar envVar5 = new EnvVar();
envVar5.setName("HOSTS"); envVar5.setName("HOSTS");
...@@ -650,6 +611,8 @@ public class K8sService { ...@@ -650,6 +611,8 @@ public class K8sService {
memoryLimit.setFormat("Mi"); memoryLimit.setFormat("Mi");
requests.put("cpu", cpuQuantity); requests.put("cpu", cpuQuantity);
requests.put("memory", memoryQuantity); requests.put("memory", memoryQuantity);
limits.put("cpu", cpuLimit);
limits.put("memory", memoryLimit);
resourceRequirements.setRequests(requests); resourceRequirements.setRequests(requests);
resourceRequirements.setLimits(limits); resourceRequirements.setLimits(limits);
container.setResources(resourceRequirements); container.setResources(resourceRequirements);
...@@ -666,15 +629,15 @@ public class K8sService { ...@@ -666,15 +629,15 @@ public class K8sService {
livenessProbe.setExec(execAction); livenessProbe.setExec(execAction);
livenessProbe.setInitialDelaySeconds(200); livenessProbe.setInitialDelaySeconds(200);
livenessProbe.setSuccessThreshold(1); livenessProbe.setSuccessThreshold(1);
livenessProbe.setFailureThreshold(5); livenessProbe.setFailureThreshold(40);
container.setLivenessProbe(livenessProbe); container.setLivenessProbe(livenessProbe);
//readinessProbe //readinessProbe
Probe readinessProbe = new Probe(); Probe readinessProbe = new Probe();
readinessProbe.setExec(execAction); readinessProbe.setExec(execAction);
readinessProbe.setInitialDelaySeconds(30); readinessProbe.setInitialDelaySeconds(200);
readinessProbe.setTimeoutSeconds(2); readinessProbe.setTimeoutSeconds(2);
readinessProbe.setPeriodSeconds(5); readinessProbe.setPeriodSeconds(40);
container.setReadinessProbe(readinessProbe); container.setReadinessProbe(readinessProbe);
} }
...@@ -876,6 +839,8 @@ public class K8sService { ...@@ -876,6 +839,8 @@ public class K8sService {
memoryLimit.setFormat("Mi"); memoryLimit.setFormat("Mi");
requests.put("cpu", cpuQuantity); requests.put("cpu", cpuQuantity);
requests.put("memory", memoryQuantity); requests.put("memory", memoryQuantity);
limits.put("cpu", cpuLimit);
limits.put("memory", memoryLimit);
resourceRequirements.setRequests(requests); resourceRequirements.setRequests(requests);
resourceRequirements.setLimits(limits); resourceRequirements.setLimits(limits);
container.setResources(resourceRequirements); container.setResources(resourceRequirements);
...@@ -1035,7 +1000,7 @@ public class K8sService { ...@@ -1035,7 +1000,7 @@ public class K8sService {
memoryQuantity.setFormat("Mi"); memoryQuantity.setFormat("Mi");
cpuLimit.setAmount("100"); cpuLimit.setAmount("100");
cpuLimit.setFormat("m"); cpuLimit.setFormat("m");
memoryLimit.setAmount("1000"); memoryLimit.setAmount("4000");
memoryLimit.setFormat("Mi"); memoryLimit.setFormat("Mi");
requests.put("cpu", cpuQuantity); requests.put("cpu", cpuQuantity);
requests.put("memory", memoryQuantity); requests.put("memory", memoryQuantity);
...@@ -1282,6 +1247,8 @@ public class K8sService { ...@@ -1282,6 +1247,8 @@ public class K8sService {
memoryLimit.setFormat("Gi"); memoryLimit.setFormat("Gi");
requests.put("cpu", cpuQuantity); requests.put("cpu", cpuQuantity);
requests.put("memory", memoryQuantity); requests.put("memory", memoryQuantity);
limits.put("cpu", cpuLimit);
limits.put("memory", memoryLimit);
resourceRequirements.setRequests(requests); resourceRequirements.setRequests(requests);
resourceRequirements.setLimits(limits); resourceRequirements.setLimits(limits);
container.setResources(resourceRequirements); container.setResources(resourceRequirements);
...@@ -1396,7 +1363,7 @@ public class K8sService { ...@@ -1396,7 +1363,7 @@ public class K8sService {
public Service createMongodbService(String namespace) { public Service createMongodbService(String namespace) {
Service mongodbService = new Service(); Service mongodbService = new Service();
ObjectMeta objectMeta = buildObjectMeta("fe", "mongodb", "base"); ObjectMeta objectMeta = buildObjectMeta(namespace, "mongodb", "base");
ServiceSpec serviceSpec = new ServiceSpec(); ServiceSpec serviceSpec = new ServiceSpec();
serviceSpec.setType("NodePort"); serviceSpec.setType("NodePort");
...@@ -1501,12 +1468,14 @@ public class K8sService { ...@@ -1501,12 +1468,14 @@ public class K8sService {
cpuRequest.setFormat("m"); cpuRequest.setFormat("m");
memoryRequest.setAmount("256"); memoryRequest.setAmount("256");
memoryRequest.setFormat("Mi"); memoryRequest.setFormat("Mi");
cpuLimit.setAmount("250"); cpuLimit.setAmount("1024");
cpuLimit.setFormat("m"); cpuLimit.setFormat("m");
memoryLimit.setAmount("512"); memoryLimit.setAmount("512");
memoryLimit.setFormat("Mi"); memoryLimit.setFormat("Mi");
requests.put("cpu", cpuRequest); requests.put("cpu", cpuRequest);
requests.put("memory", memoryRequest); requests.put("memory", memoryRequest);
limits.put("cpu", cpuLimit);
limits.put("memory", memoryLimit);
resourceRequirements.setRequests(requests); resourceRequirements.setRequests(requests);
resourceRequirements.setLimits(limits); resourceRequirements.setLimits(limits);
container.setResources(resourceRequirements); container.setResources(resourceRequirements);
...@@ -1971,7 +1940,14 @@ public class K8sService { ...@@ -1971,7 +1940,14 @@ public class K8sService {
List<Volume> volumeList = new ArrayList<>(); List<Volume> volumeList = new ArrayList<>();
// imagePullSecrets
List<LocalObjectReference> localObjectReferenceList = new ArrayList<>(); List<LocalObjectReference> localObjectReferenceList = new ArrayList<>();
LocalObjectReference localObjectReference1 = new LocalObjectReference();
LocalObjectReference localObjectReference2 = new LocalObjectReference();
localObjectReference1.setName("qcloudregistrykey");
localObjectReference2.setName("tencenthubkey");
localObjectReferenceList.add(localObjectReference1);
localObjectReferenceList.add(localObjectReference2);
PodSpec podSpec = new PodSpec(); PodSpec podSpec = new PodSpec();
podSpec.setHostname("rabbitmq-" + namespace); podSpec.setHostname("rabbitmq-" + namespace);
...@@ -2192,7 +2168,8 @@ public class K8sService { ...@@ -2192,7 +2168,8 @@ public class K8sService {
* @param owner * @param owner
* @return * @return
*/ */
public Namespace createNewNamespace(String name, String desc, String owner) { public boolean createNewNamespace(String name, String desc, String owner) {
try {
Namespace namespace = new Namespace(); Namespace namespace = new Namespace();
ObjectMeta objectMeta = new ObjectMeta(); ObjectMeta objectMeta = new ObjectMeta();
Map<String, String> annotations = new HashMap<>(); Map<String, String> annotations = new HashMap<>();
...@@ -2215,7 +2192,57 @@ public class K8sService { ...@@ -2215,7 +2192,57 @@ public class K8sService {
namespace.setSpec(namespaceSpec); namespace.setSpec(namespaceSpec);
namespace.setStatus(namespaceStatus); namespace.setStatus(namespaceStatus);
log.info("创建新的环境: {}", namespace.toString()); log.info("创建新的环境: {}", namespace.toString());
return kubernetesClient.namespaces().create(namespace); kubernetesClient.namespaces().create(namespace);
createQcloudRegistryKeySecret(name);
createTencenthHubKeySecret(name);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
public Secret createQcloudRegistryKeySecret(String namespace) {
Secret secret = new Secret();
ObjectMeta objectMeta = new ObjectMeta();
Map<String, String> labels = new HashMap<>();
labels.put("qcloud-app", "qcloudregistrykey");
objectMeta.setLabels(labels);
objectMeta.setName("qcloudregistrykey");
objectMeta.setNamespace(namespace);
Map<String, String> data = new HashMap<>();
data.put(".dockercfg", "eyJjY3IuY2NzLnRlbmNlbnR5dW4uY29tIjp7InVzZXJuYW1lIjoiMTAwMDA4NjMyMjY5IiwicGFzc3dvcmQiOiJ7QXBwbGljYXRpb25Ub2tlbjo0MTM1NWY2OWQyY2U3ZWUyYmE2YjQxZmMxNzJlNzM0MH0iLCJlbWFpbCI6IjEwMDAwODYzMjI2OUBxcS5jb20iLCJhdXRoIjoiTVRBd01EQTROak15TWpZNU9udEJjSEJzYVdOaGRHbHZibFJ2YTJWdU9qUXhNelUxWmpZNVpESmpaVGRsWlRKaVlUWmlOREZtWXpFM01tVTNNelF3ZlE9PSJ9fQ==");
secret.setApiVersion("v1");
secret.setKind("Secret");
secret.setType("kubernetes.io/dockercfg");
secret.setMetadata(objectMeta);
secret.setData(data);
log.info("{}环境,创建新的secret:qcloudregistrykey", namespace);
return kubernetesClient.secrets().inNamespace(namespace).create(secret);
}
public Secret createTencenthHubKeySecret(String namespace) {
Secret secret = new Secret();
ObjectMeta objectMeta = new ObjectMeta();
Map<String, String> labels = new HashMap<>();
labels.put("qcloud-app", "tencenthubkey");
objectMeta.setLabels(labels);
objectMeta.setName("tencenthubkey");
objectMeta.setNamespace(namespace);
Map<String, String> data = new HashMap<>();
data.put(".dockercfg", "eyJodWIudGVuY2VudHl1bi5jb20iOnsidXNlcm5hbWUiOiIxMDAwMDg2MzIyNjkiLCJwYXNzd29yZCI6ImV5SmhiR2NpT2lKSVV6STFOaUlzSW5SNWNDSTZJa3BYVkNKOS5leUpsZUhBaU9qRTROell5T1RFME9EVXNJbXAwYVNJNklqVTVPVGRqTmpkaExUWmpaV1l0TkRGbE55MDVPRGsyTFdGaE16TTFPRGRpWW1ReE1TSXNJbWxoZENJNk1UVTJNRGt6TVRRNE5Td2libUptSWpveE5UWXdPVE14TkRnMUxDSnpkV0lpT2lJeE1EQXdNRGcyTXpJeU5qa2lmUS5ZWEl4TzBaWTg3QmNzSktLdW9lQ3gzYllLZ1RzMktNVElSeDd5dWVRdDZNIiwiZW1haWwiOiIxMDAwMDg2MzIyNjlAcXEuY29tIiwiYXV0aCI6Ik1UQXdNREE0TmpNeU1qWTVPbVY1U21oaVIyTnBUMmxLU1ZWNlNURk9hVWx6U1c1U05XTkRTVFpKYTNCWVZrTktPUzVsZVVwc1pVaEJhVTlxUlRST2VsbDVUMVJGTUU5RVZYTkpiWEF3WVZOSk5rbHFWVFZQVkdScVRtcGthRXhVV21wYVYxbDBUa1JHYkU1NU1EVlBSR3N5VEZkR2FFMTZUVEZQUkdScFdXMVJlRTFUU1hOSmJXeG9aRU5KTmsxVVZUSk5SR3Q2VFZSUk5FNVRkMmxpYlVwdFNXcHZlRTVVV1hkUFZFMTRUa1JuTVV4RFNucGtWMGxwVDJsSmVFMUVRWGROUkdjeVRYcEplVTVxYTJsbVVTNVpXRWw0VHpCYVdUZzNRbU56U2t0TGRXOWxRM2d6WWxsTFoxUnpNa3ROVkVsU2VEZDVkV1ZSZERaTiJ9fQ==");
secret.setApiVersion("v1");
secret.setKind("Secret");
secret.setType("kubernetes.io/dockercfg");
secret.setMetadata(objectMeta);
secret.setData(data);
log.info("{}环境,创建新的secret:qcloudregistrykey", namespace);
return kubernetesClient.secrets().inNamespace(namespace).create(secret);
} }
/** /**
...@@ -2240,22 +2267,94 @@ public class K8sService { ...@@ -2240,22 +2267,94 @@ public class K8sService {
return kubernetesClient.services().inNamespace(namespace).withName(serviceName).delete(); return kubernetesClient.services().inNamespace(namespace).withName(serviceName).delete();
} }
/**
* 获取Deployment
* @param namespace
* @param serviceName
* @return
*/
public Deployment getDeployment(String namespace, String serviceName) {
return kubernetesClient.apps().deployments().inNamespace(namespace).withName(serviceName).get();
}
/**
* 获取环境的所有k8s变量
* @param namespace 环境
*/
public Map<String, Object> getListEnvVars(String namespace) {
Map<String, Object> envMap = new TreeMap<>();
List<Pod> podList = kubernetesClient.pods().inNamespace(namespace).list().getItems();
List<Service> serviceList = kubernetesClient.services().inNamespace(namespace).list().getItems();
// 遍历Pod列表
for (Pod pod: podList) {
String serviceName = pod.getMetadata().getLabels().get("qcloud-app");
serviceName = serviceName.replace("-", "_").toUpperCase();
envMap.put(serviceName + "_SERVICE_HOST", pod.getStatus().getHostIP());
// MYSQL需要额外加个参数
if (serviceName.equals("MYSQL")) {
envMap.put("DB_SERVICE_HOST", pod.getStatus().getHostIP());
}
}
// 遍历Service列表
for (Service service: serviceList) {
String serviceName = service.getMetadata().getName().toUpperCase().replaceAll("-", "_");
List<ServicePort> servicePortList = service.getSpec().getPorts();
if (service.getMetadata().getLabels().get("type").equals("base")) {
if (servicePortList.get(0).getPort() != null) {
envMap.put(serviceName + "_SERVICE_PORT", servicePortList.get(0).getNodePort());
// MYSQL需要额外加个参数
if (serviceName.equals("MYSQL")) {
envMap.put("DB_SERVICE_PORT", servicePortList.get(0).getNodePort());
}
}
for (ServicePort servicePort: servicePortList) {
envMap.put(serviceName + "_SERVICE_PORT_" + servicePort.getPort(), servicePort.getNodePort());
// MYSQL需要额外加个参数
if (serviceName.equals("MYSQL")) {
envMap.put("DB_SERVICE_PORT_" + servicePort.getPort(), servicePort.getNodePort());
}
}
} else {
if (servicePortList.get(0).getNodePort() != null) {
envMap.put(serviceName + "_SERVICE_PORT", servicePortList.get(0).getNodePort());
}
for (ServicePort servicePort: servicePortList) {
if (service.getSpec().getType().equals("NodePort")) {
envMap.put(serviceName + "_SERVICE_PORT_" + servicePort.getPort(), servicePort.getNodePort());
} else if (service.getSpec().getType().equals("ClusterIP")) {
envMap.put(serviceName + "_SERVICE_PORT_" + servicePort.getName(), servicePort.getPort());
}
}
}
}
return envMap;
}
public void podTest() { public void podTest() {
Map<String, String> labels = new HashMap<>(); Map<String, String> labels = new HashMap<>();
labels.put("qcloud-app", "mysql"); labels.put("qcloud-app", "mysql");
labels.put("type", "base"); labels.put("type", "base");
Pod pod = kubernetesClient.pods().inNamespace("k8s").withLabels(labels).list().getItems().get(0); List<Pod> podList = kubernetesClient.pods().inNamespace("vcc").withLabels(labels).list().getItems();
System.out.println(pod); String host = null;
for (Pod pod: podList) {
if (pod.getStatus().getHostIP() != null) {
host = pod.getStatus().getHostIP();
break;
}
}
System.out.println(podList.size());
System.out.println(host);
} }
public static void main(String[] args) { public static void main(String[] args) {
// K8sService k8sService = new K8sService(); K8sService k8sService = new K8sService();
// k8sService.createNewNamespace("test6", "dev", "黎博"); // k8sService.createNewNamespace("test6", "dev", "黎博");
// k8sService.podTest(); k8sService.podTest();
// k8sService.getPodList("k8s"); // k8sService.getPodList("k8s");
// System.out.println(JSON.toJSONString(k8sService.getPodListNew("fe"))); // System.out.println(JSON.toJSONString(k8sService.getPodListNew("fe")));
// if (!k8sService.queryIfServiceExistByName("fe", "lxq-ui")) { // if (!k8sService.queryIfServiceExistByName("fe", "lxq-ui")) {
// k8sService.createUIAndNodeService("fe", "lxq-ui", "ui", "ui"); // k8sService.createUIAndNodeService("fe", "lxq-ui", "ui", "ui");
// } // }
} }
} }
...@@ -16,6 +16,7 @@ public class MqService { ...@@ -16,6 +16,7 @@ public class MqService {
/** /**
* 获取MQ信息 * 获取MQ信息
*
* @param host * @param host
* @param auth * @param auth
* @return * @return
...@@ -29,6 +30,7 @@ public class MqService { ...@@ -29,6 +30,7 @@ public class MqService {
/** /**
* 同步线上MQ到测试 * 同步线上MQ到测试
*
* @param host * @param host
* @return * @return
*/ */
...@@ -39,13 +41,14 @@ public class MqService { ...@@ -39,13 +41,14 @@ public class MqService {
Map<String, Object> onlineDefinitions = getDefinitionsOfHost(ONLINE_MQ_URL, ONLINE_MQ_AUTH); Map<String, Object> onlineDefinitions = getDefinitionsOfHost(ONLINE_MQ_URL, ONLINE_MQ_AUTH);
List<Map<String, String>> permissionList = (List<Map<String, String>>) onlineDefinitions.get("permissions"); List<Map<String, String>> permissionList = (List<Map<String, String>>) onlineDefinitions.get("permissions");
List<Map<String, String>> qaPermissionList = new ArrayList<>(); List<Map<String, String>> qaPermissionList = new ArrayList<>();
for (Map<String, String> permission: permissionList) { for (Map<String, String> permission : permissionList) {
if (permission.get("user").equals("rabbit_admin")) { if (permission.get("user").equals("rabbit_admin")) {
qaPermissionList.add(permission); Map<String, String> temp = new HashMap<>();
temp.putAll(permission);
qaPermissionList.add(temp);
permission.put("user", "qa"); permission.put("user", "qa");
qaPermissionList.add(permission); qaPermissionList.add(permission);
} } else if (!permission.get("user").equals("qa") && !permission.get("user").equals("rabbit_admin")) {
if (!permission.get("user").equals("qa") && !permission.get("user").equals("rabbit_admin")) {
qaPermissionList.add(permission); qaPermissionList.add(permission);
} }
} }
...@@ -65,8 +68,73 @@ public class MqService { ...@@ -65,8 +68,73 @@ public class MqService {
} }
} }
/**
* 获取 sourceMapList 比 targetMapList 多出的元素
*
* @param sourceMapList
* @param targetMapList
* @return
*/
public List<String> mqListCompare(List<Map<String, String>> sourceMapList, List<Map<String, String>> targetMapList) {
List<String> resultList = new ArrayList<>();
for (Map<String, String> sourceMap : sourceMapList) {
boolean flag = false;
for (Map<String, String> targetMap : targetMapList) {
if (sourceMap.get("name").equals(targetMap.get("name"))) {
flag = true;
}
}
if (!flag) {
resultList.add(sourceMap.get("name"));
}
}
return resultList;
}
/**
* 比较测试环境与线上mq
* @param host 测试环境mq地址:ip+端口
* @return
*/
public Map<String, Object> getMqDiff(String host) {
String ONLINE_MQ_URL = "http://172.30.3.140:15672";
String ONLINE_MQ_AUTH = "Basic cmFiYml0X2FkbWluOmFiYzEyMzQ=";
Map<String, Object> onlineDefinitions = getDefinitionsOfHost(ONLINE_MQ_URL, ONLINE_MQ_AUTH);
String qaMqUrl = "http://" + host;
String QA_MQ_AUTH = "Basic cWE6cWF0ZXN0";
Map<String, Object> qaDefinitions = getDefinitionsOfHost(qaMqUrl, QA_MQ_AUTH);
List<Map<String, String>> onlineHostList = (List<Map<String, String>>) onlineDefinitions.get("vhosts");
List<Map<String, String>> qaHostList = (List<Map<String, String>>) qaDefinitions.get("vhosts");
List<Map<String, String>> onlineQueueList = (List<Map<String, String>>) onlineDefinitions.get("queues");
List<Map<String, String>> qaQueueList = (List<Map<String, String>>) qaDefinitions.get("queues");
List<String> lostVhostList = mqListCompare(onlineHostList, qaHostList);
List<String> moreVhostList = mqListCompare(qaHostList, onlineHostList);
List<String> lostQueueList = mqListCompare(onlineQueueList, qaQueueList);
List<String> moreQueueList = mqListCompare(qaQueueList, onlineQueueList);
Map<String, Object> map = new HashMap<>();
Map<String, Object> lostMap = new HashMap<>();
lostMap.put("vhost", lostVhostList);
lostMap.put("queue", lostQueueList);
Map<String, Object> moreMap = new HashMap<>();
moreMap.put("vhost", moreVhostList);
moreMap.put("queue", moreQueueList);
if (lostVhostList.size() > 0 || lostQueueList.size() > 0) {
lostMap.put("show", true);
} else {
lostMap.put("show", false);
}
if (moreVhostList.size() > 0 || moreQueueList.size() > 0) {
moreMap.put("show", true);
} else {
moreMap.put("show", false);
}
map.put("lost", lostMap);
map.put("more", moreMap);
return map;
}
public static void main(String[] args) { public static void main(String[] args) {
MqService mqService = new MqService(); MqService mqService = new MqService();
mqService.setDefinitions("172.17.5.17:31426"); mqService.setDefinitions("172.17.5.46:32419");
} }
} }
...@@ -25,8 +25,8 @@ public class DockerProjectServiceImpl extends ServiceImpl<DockerProjectMapper, D ...@@ -25,8 +25,8 @@ public class DockerProjectServiceImpl extends ServiceImpl<DockerProjectMapper, D
* @return * @return
*/ */
@Override @Override
public IPage<DockerProject> getDockerProjectList(String projectName, String projectType, Integer isActive, Integer pageNum, Integer pageSize) { public IPage<DockerProject> getDockerProjectList(String projectName, String projectType, Integer isActive, String hostName, Integer pageNum, Integer pageSize) {
IPage<DockerProject> page = new Page<>(pageNum, pageSize); IPage<DockerProject> page = new Page<>(pageNum, pageSize);
return dockerProjectMapper.getDockerProjectList(page, projectName, projectType, isActive); return dockerProjectMapper.getDockerProjectList(page, projectName, projectType, isActive, hostName);
} }
} }
package cn.qg.holmes.service.k8s.impl;
import cn.qg.holmes.entity.k8s.EnvTemplateDetail;
import cn.qg.holmes.mapper.k8s.EnvTemplateDetailMapper;
import cn.qg.holmes.service.k8s.EnvTemplateDetailService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service
public class EnvTemplateDetailServiceImpl extends ServiceImpl<EnvTemplateDetailMapper, EnvTemplateDetail> implements EnvTemplateDetailService {
}
package cn.qg.holmes.service.k8s.impl;
import cn.qg.holmes.entity.k8s.EnvTemplate;
import cn.qg.holmes.mapper.k8s.EnvTemplateMapper;
import cn.qg.holmes.service.k8s.EnvTemplateService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service
public class EnvTemplateServiceImpl extends ServiceImpl<EnvTemplateMapper, EnvTemplate> implements EnvTemplateService {
}
package cn.qg.holmes.task.jira; package cn.qg.holmes.task;
import cn.qg.holmes.entity.jira.DingRobot;
import cn.qg.holmes.entity.jira.JiraBugPool; import cn.qg.holmes.entity.jira.JiraBugPool;
import cn.qg.holmes.service.jira.DingRobotService;
import cn.qg.holmes.service.jira.JiraBugPoolService; import cn.qg.holmes.service.jira.JiraBugPoolService;
import cn.qg.holmes.service.jira.JiraIssueService; import cn.qg.holmes.service.jira.JiraIssueService;
import cn.qg.holmes.utils.DingdingUtils; import cn.qg.holmes.utils.DingdingUtils;
...@@ -16,11 +18,11 @@ import org.springframework.stereotype.Component; ...@@ -16,11 +18,11 @@ import org.springframework.stereotype.Component;
import java.util.List; import java.util.List;
/** /**
* Jira BUG通知到钉钉定时任务类 * JIRA BUG相关定时任务
*/ */
@Component @Component
@Slf4j @Slf4j
public class JiraToDingding { public class BugNotifyTask {
@Autowired @Autowired
JiraIssueService jiraIssueService; JiraIssueService jiraIssueService;
...@@ -28,6 +30,9 @@ public class JiraToDingding { ...@@ -28,6 +30,9 @@ public class JiraToDingding {
@Autowired @Autowired
JiraBugPoolService jiraBugPoolService; JiraBugPoolService jiraBugPoolService;
@Autowired
DingRobotService dingRobotService;
@Value("${sjgd.ding.url}") @Value("${sjgd.ding.url}")
private String sjgdDingUrl; private String sjgdDingUrl;
...@@ -80,9 +85,13 @@ public class JiraToDingding { ...@@ -80,9 +85,13 @@ public class JiraToDingding {
log.info("{} BUG持续时间:{}小时", issue.getKey(), duration); log.info("{} BUG持续时间:{}小时", issue.getKey(), duration);
// 如果已超过4个小时,则发送钉钉通知 // 如果已超过4个小时,则发送钉钉通知
if (duration >= 4) { if (duration >= 4) {
DingRobot dingRobot = dingRobotService.getById(jiraBugPool.getDingRobotId());
// 项目进行中才发送通知
if (dingRobot.getStatus() == 1) {
DingdingUtils.sendToDingding(DingdingUtils.buildBugFixRemindMsg(issue, duration), jiraBugPool.getDingUrl()); DingdingUtils.sendToDingding(DingdingUtils.buildBugFixRemindMsg(issue, duration), jiraBugPool.getDingUrl());
} }
} }
}
} else { } else {
log.info("JIRA上未找到该issue,将BUG: {} 置为无效", jiraBugPool.getKey()); log.info("JIRA上未找到该issue,将BUG: {} 置为无效", jiraBugPool.getKey());
jiraBugPool.setEnable(0); jiraBugPool.setEnable(0);
......
package cn.qg.holmes.task;
import cn.qg.holmes.utils.JenkinsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* 数据库同步定时任务
*/
@Slf4j
@Component
public class DbSyncTask {
@Autowired
JenkinsService jenkinsService;
@Scheduled(cron = "0 0 23 * * ?")
public void getDbInfoFromSourceJob() {
jenkinsService.buildDbDailyBackupJob();
}
}
...@@ -118,7 +118,7 @@ public class DingdingUtils { ...@@ -118,7 +118,7 @@ public class DingdingUtils {
content += "今日测试进度:" + progress + " \n\n"; content += "今日测试进度:" + progress + " \n\n";
content = content + "剩余未解决BUG列表:" + "\n\n"; content = content + "剩余未解决BUG列表:" + "\n\n";
if (issueList.size() == 0) { if (issueList.size() == 0) {
content += "暂无未解决BUG!"; content += "暂无未解决BUG!\n\n";
} }
int count = 0; int count = 0;
for (Issue issue: issueList) { for (Issue issue: issueList) {
......
...@@ -171,7 +171,7 @@ public class HttpClientUtils { ...@@ -171,7 +171,7 @@ public class HttpClientUtils {
public static String doPostJson(String url, Map<String, String> headers, String json) { public static String doPostJson(String url, Map<String, String> headers, String json) {
CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse httpResponse = null; CloseableHttpResponse httpResponse = null;
String resultString = ""; String resultString = null;
try { try {
// 创建Http Post请求 // 创建Http Post请求
HttpPost httpPost = new HttpPost(url); HttpPost httpPost = new HttpPost(url);
...@@ -183,7 +183,9 @@ public class HttpClientUtils { ...@@ -183,7 +183,9 @@ public class HttpClientUtils {
setHeader(headers, httpPost); setHeader(headers, httpPost);
httpResponse = httpClient.execute(httpPost); httpResponse = httpClient.execute(httpPost);
if (httpResponse.getEntity() != null) {
resultString = EntityUtils.toString(httpResponse.getEntity(), ENCODING); resultString = EntityUtils.toString(httpResponse.getEntity(), ENCODING);
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
......
...@@ -51,7 +51,7 @@ public class JenkinsService { ...@@ -51,7 +51,7 @@ public class JenkinsService {
* @param namespace 部署的环境 * @param namespace 部署的环境
* @return * @return
*/ */
public int buildJenkinsJob(String type, String project, String branch, String namespace) { public int buildTkeJob(String type, String project, String branch, String namespace) {
Map<String, String> buildParams = new HashMap<>(); Map<String, String> buildParams = new HashMap<>();
buildParams.put("GIT_REPO", project); buildParams.put("GIT_REPO", project);
buildParams.put("BRANCH_NAME", branch); buildParams.put("BRANCH_NAME", branch);
...@@ -154,6 +154,16 @@ public class JenkinsService { ...@@ -154,6 +154,16 @@ public class JenkinsService {
} }
} }
/**
* 构建sync_database_schema
* @param dbName
* @param host
* @param port
* @param replaceDomain
* @param notDeleteBusinessData
* @param useCache
* @return build num
*/
public int buildDbSyncJob(String dbName, String host, String port, public int buildDbSyncJob(String dbName, String host, String port,
boolean replaceDomain, boolean notDeleteBusinessData, boolean useCache) { boolean replaceDomain, boolean notDeleteBusinessData, boolean useCache) {
Map<String, String> params = new HashMap<>(); Map<String, String> params = new HashMap<>();
...@@ -188,6 +198,51 @@ public class JenkinsService { ...@@ -188,6 +198,51 @@ public class JenkinsService {
return result; return result;
} }
/**
* 构建db_sync
* @param namespace
* @param host
* @param port
* @param database
* @param table
* @param businessData
* @return build num
*/
public int buildDbSyncJobNew(String namespace, String host, String port, String database, String table, boolean businessData) {
Map<String, String> params = new HashMap<>();
params.put("namespace", namespace);
params.put("target_db_host", host);
params.put("target_db_port", port);
params.put("database", database);
params.put("table", table);
params.put("business_data", String.valueOf(businessData));
try {
jenkinsServer.getJob("db_sync").build(params);
Build build = jenkinsServer.getJob("db_sync").getLastBuild();
return build.getNumber() + 1;
} catch (Exception e) {
log.info("执行数据库同步脚本失败,host:{}, port: {}, dbName: {}", host, port, database);
e.printStackTrace();
return 0;
}
}
/**
* 构建db_daily_backup
* @return
*/
public int buildDbDailyBackupJob() {
try {
jenkinsServer.getJob("db_daily_backup").build();
Build build = jenkinsServer.getJob("db_daily_backup").getLastBuild();
return build.getNumber() + 1;
} catch (Exception e) {
log.info("执行数据库备份失败!");
e.printStackTrace();
return 0;
}
}
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
JenkinsService jenkinsApi = new JenkinsService(); JenkinsService jenkinsApi = new JenkinsService();
// List<Build> buildList = jenkinsApi.getJobBuildList("tke-java", 1, "kdsp"); // List<Build> buildList = jenkinsApi.getJobBuildList("tke-java", 1, "kdsp");
......
...@@ -14,6 +14,9 @@ ...@@ -14,6 +14,9 @@
<if test="isActive != null"> <if test="isActive != null">
AND `is_active` = #{isActive} AND `is_active` = #{isActive}
</if> </if>
<if test="hostName != null and hostName !=''">
AND `host_name` like CONCAT('%', #{hostName}, '%')
</if>
ORDER BY `id` DESC ORDER BY `id` DESC
</select> </select>
......
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