大声道撒旦

This commit is contained in:
dengqichen 2024-12-30 11:39:07 +08:00
parent 05cc791af5
commit 6da8bcb072
7 changed files with 228 additions and 88 deletions

View File

@ -16,7 +16,7 @@ import java.util.List;
*/
@Slf4j
@RestController
@RequestMapping("/api/v1//api/v1/jenkins-sync-history")
@RequestMapping("/api/v1/jenkins-sync-history")
@Tag(name = "Jenkin同步日志管理", description = "Jenkin同步日志管理相关接口")
public class JenkinsSyncHistoryApiController extends BaseController<JenkinsSyncHistory, JenkinsSyncHistoryDTO, Long, JenkinsSyncHistoryQuery> {

View File

@ -18,6 +18,8 @@ public class JenkinsSyncHistoryDTO extends BaseDTO {
private String number;
private LocalDateTime startTime;
private LocalDateTime endTime;
private String errorMessage;

View File

@ -41,6 +41,6 @@ public class JenkinsSyncHistory extends Entity<Long> {
private String errorMessage;
@Column(name = "external_system_id", nullable = false)
private Long external_system_id;
private Long externalSystemId;
}

View File

@ -2,12 +2,15 @@ package com.qqchen.deploy.backend.deploy.service.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qqchen.deploy.backend.deploy.dto.JenkinsSyncHistoryDTO;
import com.qqchen.deploy.backend.deploy.entity.ExternalSystem;
import com.qqchen.deploy.backend.deploy.entity.JenkinsBuild;
import com.qqchen.deploy.backend.deploy.entity.JenkinsJob;
import com.qqchen.deploy.backend.deploy.entity.JenkinsView;
import com.qqchen.deploy.backend.deploy.dto.JenkinsBuildDTO;
import com.qqchen.deploy.backend.deploy.entity.QJenkinsBuild;
import com.qqchen.deploy.backend.deploy.enums.ExternalSystemSyncStatus;
import com.qqchen.deploy.backend.deploy.enums.JenkinsSyncType;
import com.qqchen.deploy.backend.deploy.query.JenkinsBuildQuery;
import com.qqchen.deploy.backend.deploy.integration.IJenkinsServiceIntegration;
import com.qqchen.deploy.backend.deploy.integration.response.JenkinsBuildResponse;
@ -16,6 +19,7 @@ import com.qqchen.deploy.backend.deploy.repository.IJenkinsBuildRepository;
import com.qqchen.deploy.backend.deploy.repository.IJenkinsJobRepository;
import com.qqchen.deploy.backend.deploy.repository.IJenkinsViewRepository;
import com.qqchen.deploy.backend.deploy.service.IJenkinsBuildService;
import com.qqchen.deploy.backend.deploy.service.IJenkinsSyncHistoryService;
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
import com.qqchen.deploy.backend.framework.exception.BusinessException;
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
@ -57,35 +61,66 @@ public class JenkinsBuildServiceImpl extends BaseServiceImpl<JenkinsBuild, Jenki
@Resource
private ObjectMapper objectMapper;
@Resource
private IJenkinsSyncHistoryService jenkinsSyncHistoryService;
@Override
@Transactional(rollbackFor = Exception.class)
public Integer syncAllBuilds(Long externalSystemId) {
// 1. 查询外部系统
ExternalSystem externalSystem = externalSystemRepository.findById(externalSystemId)
.orElseThrow(() -> new BusinessException(ResponseCode.EXTERNAL_SYSTEM_NOT_FOUND));
// 1. 创建同步历史记录
JenkinsSyncHistoryDTO syncHistory = new JenkinsSyncHistoryDTO();
syncHistory.setExternalSystemId(externalSystemId);
syncHistory.setSyncType(JenkinsSyncType.BUILD);
syncHistory.setStatus(ExternalSystemSyncStatus.RUNNING);
jenkinsSyncHistoryService.saveOrUpdateHistory(syncHistory);
// 2. 查询所有视图
try {
// 2. 查询外部系统
ExternalSystem externalSystem = externalSystemRepository.findById(externalSystemId).orElseThrow(() -> new BusinessException(ResponseCode.EXTERNAL_SYSTEM_NOT_FOUND));
// 3. 查询所有视图
List<JenkinsView> views = jenkinsViewRepository.findByExternalSystemId(externalSystemId);
if (views.isEmpty()) {
log.info("No views found for external system: {}", externalSystemId);
// 更新同步历史为成功
syncHistory.setStatus(ExternalSystemSyncStatus.SUCCESS);
jenkinsSyncHistoryService.saveOrUpdateHistory(syncHistory);
return 0;
}
// 3. 同步每个视图下的构建信息
// 4. 同步每个视图下的构建信息
int totalSyncedBuilds = 0;
StringBuilder errorMessages = new StringBuilder();
for (JenkinsView view : views) {
try {
Integer syncedBuilds = syncBuildsByView(externalSystem, view);
totalSyncedBuilds += syncedBuilds;
log.info("Successfully synchronized {} builds for view: {}", syncedBuilds, view.getViewName());
} catch (Exception e) {
log.error("Failed to sync builds for view: {}", view.getViewName(), e);
String errorMessage = String.format("Failed to sync builds for view %s: %s", view.getViewName(), e.getMessage());
log.error(errorMessage, e);
errorMessages.append(errorMessage).append("\n");
}
}
// 5. 更新同步历史状态
if (errorMessages.length() > 0) {
syncHistory.setStatus(ExternalSystemSyncStatus.FAILED);
syncHistory.setErrorMessage(errorMessages.toString());
} else {
syncHistory.setStatus(ExternalSystemSyncStatus.SUCCESS);
}
jenkinsSyncHistoryService.saveOrUpdateHistory(syncHistory);
log.info("Successfully synchronized total {} builds for external system: {}",
totalSyncedBuilds, externalSystemId);
return totalSyncedBuilds;
} catch (Exception e) {
log.error("Failed to sync Jenkins builds for external system: {}", externalSystemId, e);
// 更新同步历史为失败
syncHistory.setStatus(ExternalSystemSyncStatus.FAILED);
syncHistory.setErrorMessage(e.getMessage());
jenkinsSyncHistoryService.saveOrUpdateHistory(syncHistory);
throw e;
}
}
@Override

View File

@ -1,10 +1,13 @@
package com.qqchen.deploy.backend.deploy.service.impl;
import com.qqchen.deploy.backend.deploy.converter.JenkinsJobConverter;
import com.qqchen.deploy.backend.deploy.dto.JenkinsSyncHistoryDTO;
import com.qqchen.deploy.backend.deploy.entity.ExternalSystem;
import com.qqchen.deploy.backend.deploy.entity.JenkinsJob;
import com.qqchen.deploy.backend.deploy.entity.JenkinsView;
import com.qqchen.deploy.backend.deploy.dto.JenkinsJobDTO;
import com.qqchen.deploy.backend.deploy.enums.ExternalSystemSyncStatus;
import com.qqchen.deploy.backend.deploy.enums.JenkinsSyncType;
import com.qqchen.deploy.backend.deploy.integration.response.JenkinsHealthReportResponse;
import com.qqchen.deploy.backend.deploy.query.JenkinsJobQuery;
import com.qqchen.deploy.backend.deploy.integration.IJenkinsServiceIntegration;
@ -13,6 +16,7 @@ import com.qqchen.deploy.backend.deploy.repository.IExternalSystemRepository;
import com.qqchen.deploy.backend.deploy.repository.IJenkinsJobRepository;
import com.qqchen.deploy.backend.deploy.repository.IJenkinsViewRepository;
import com.qqchen.deploy.backend.deploy.service.IJenkinsJobService;
import com.qqchen.deploy.backend.deploy.service.IJenkinsSyncHistoryService;
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
import com.qqchen.deploy.backend.framework.exception.BusinessException;
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
@ -21,16 +25,15 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
/**
* Jenkins任务 Service实现
@ -51,9 +54,13 @@ public class JenkinsJobServiceImpl extends BaseServiceImpl<JenkinsJob, JenkinsJo
@Resource
private IJenkinsServiceIntegration jenkinsServiceIntegration;
@Resource
private JenkinsJobConverter jenkinsJobConverter;
@Resource
private IJenkinsSyncHistoryService jenkinsSyncHistoryService;
/**
* 同步外部系统下所有视图的Jenkins任务
*
@ -63,19 +70,30 @@ public class JenkinsJobServiceImpl extends BaseServiceImpl<JenkinsJob, JenkinsJo
@Override
@Transactional(rollbackFor = Exception.class)
public Integer syncJobs(Long externalSystemId) {
// 1. 查询外部系统
ExternalSystem externalSystem = externalSystemRepository.findById(externalSystemId)
.orElseThrow(() -> new BusinessException(ResponseCode.EXTERNAL_SYSTEM_NOT_FOUND));
// 1. 创建同步历史记录
JenkinsSyncHistoryDTO syncHistory = new JenkinsSyncHistoryDTO();
syncHistory.setExternalSystemId(externalSystemId);
syncHistory.setSyncType(JenkinsSyncType.JOB);
syncHistory.setStatus(ExternalSystemSyncStatus.RUNNING);
jenkinsSyncHistoryService.saveOrUpdateHistory(syncHistory);
// 2. 查询该外部系统下的所有视图
try {
// 2. 查询外部系统
ExternalSystem externalSystem = externalSystemRepository.findById(externalSystemId).orElseThrow(() -> new BusinessException(ResponseCode.EXTERNAL_SYSTEM_NOT_FOUND));
// 3. 查询该外部系统下的所有视图
List<JenkinsView> views = jenkinsViewRepository.findByExternalSystemId(externalSystemId);
if (views.isEmpty()) {
log.info("No views found for external system: {}", externalSystemId);
// 更新同步历史为成功
syncHistory.setStatus(ExternalSystemSyncStatus.SUCCESS);
jenkinsSyncHistoryService.saveOrUpdateHistory(syncHistory);
return 0;
}
// 3. 遍历所有视图同步每个视图下的任务
// 4. 遍历所有视图同步每个视图下的任务
int totalSyncedJobs = 0;
StringBuilder errorMessages = new StringBuilder();
for (JenkinsView view : views) {
try {
Integer syncedJobs = syncJobsByView(externalSystem, view);
@ -83,12 +101,31 @@ public class JenkinsJobServiceImpl extends BaseServiceImpl<JenkinsJob, JenkinsJo
log.info("Successfully synchronized {} jobs for view: {}", syncedJobs, view.getViewName());
} catch (Exception e) {
// 记录错误但继续同步其他视图
log.error("Failed to sync jobs for view: {}", view.getViewName(), e);
String errorMessage = String.format("Failed to sync jobs for view %s: %s", view.getViewName(), e.getMessage());
log.error(errorMessage, e);
errorMessages.append(errorMessage).append("\n");
}
}
// 5. 更新同步历史状态
if (errorMessages.length() > 0) {
syncHistory.setStatus(ExternalSystemSyncStatus.FAILED);
syncHistory.setErrorMessage(errorMessages.toString());
} else {
syncHistory.setStatus(ExternalSystemSyncStatus.SUCCESS);
}
jenkinsSyncHistoryService.saveOrUpdateHistory(syncHistory);
log.info("Successfully synchronized total {} jobs for external system: {}", totalSyncedJobs, externalSystemId);
return totalSyncedJobs;
} catch (Exception e) {
log.error("Failed to sync Jenkins jobs for external system: {}", externalSystemId, e);
// 更新同步历史为失败
syncHistory.setStatus(ExternalSystemSyncStatus.FAILED);
syncHistory.setErrorMessage(e.getMessage());
jenkinsSyncHistoryService.saveOrUpdateHistory(syncHistory);
throw e;
}
}
/**

View File

@ -13,6 +13,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* Jenkin同步日志 Service实现
@ -21,12 +22,48 @@ import java.time.LocalDateTime;
@Service
public class JenkinsSyncHistoryServiceImpl extends BaseServiceImpl<JenkinsSyncHistory, JenkinsSyncHistoryDTO, JenkinsSyncHistoryQuery, Long> implements IJenkinsSyncHistoryService {
@Resource
private IJenkinsSyncHistoryRepository jenkinsSyncHistoryRepository;
@Override
public void saveOrUpdateHistory(JenkinsSyncHistoryDTO syncHistory) {
LocalDateTime now = LocalDateTime.now();
// 如果是新建的同步历史记录开始同步时
if (syncHistory.getId() == null && syncHistory.getNumber() == null) {
syncHistory.setNumber(generateSyncHistoryNumber(syncHistory.getSyncType(), syncHistory.getExternalSystemId()));
syncHistory.setStartTime(now);
jenkinsSyncHistoryRepository.save(super.converter.toEntity(syncHistory));
return;
}
// 查找已存在的记录
JenkinsSyncHistory existingHistory = jenkinsSyncHistoryRepository.findByNumber(syncHistory.getNumber());
if (existingHistory != null) {
// 如果状态是SUCCESS或FAILED设置结束时间
if (ExternalSystemSyncStatus.SUCCESS.equals(syncHistory.getStatus())
|| ExternalSystemSyncStatus.FAILED.equals(syncHistory.getStatus())) {
existingHistory.setEndTime(now);
}
existingHistory.setStatus(syncHistory.getStatus());
existingHistory.setErrorMessage(syncHistory.getErrorMessage());
jenkinsSyncHistoryRepository.save(existingHistory);
}
}
/**
* 生成同步历史编号
* 格式{同步类型}_{年月日时分秒}_{系统ID}
* 例如VIEW_20231220123456_1
*
* @param syncType 同步类型
* @param externalSystemId 外部系统ID
* @return 生成的编号
*/
private String generateSyncHistoryNumber(JenkinsSyncType syncType, Long externalSystemId) {
return String.format("%s_%s_%d",
syncType.name(),
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")),
externalSystemId);
}
}

View File

@ -1,15 +1,19 @@
package com.qqchen.deploy.backend.deploy.service.impl;
import com.qqchen.deploy.backend.deploy.converter.JenkinsViewConverter;
import com.qqchen.deploy.backend.deploy.dto.JenkinsSyncHistoryDTO;
import com.qqchen.deploy.backend.deploy.entity.ExternalSystem;
import com.qqchen.deploy.backend.deploy.entity.JenkinsView;
import com.qqchen.deploy.backend.deploy.dto.JenkinsViewDTO;
import com.qqchen.deploy.backend.deploy.enums.ExternalSystemSyncStatus;
import com.qqchen.deploy.backend.deploy.enums.JenkinsSyncType;
import com.qqchen.deploy.backend.deploy.query.JenkinsViewQuery;
import com.qqchen.deploy.backend.deploy.integration.IJenkinsServiceIntegration;
import com.qqchen.deploy.backend.deploy.integration.response.JenkinsViewResponse;
import com.qqchen.deploy.backend.deploy.repository.IExternalSystemRepository;
import com.qqchen.deploy.backend.deploy.repository.IJenkinsSyncHistoryRepository;
import com.qqchen.deploy.backend.deploy.repository.IJenkinsViewRepository;
import com.qqchen.deploy.backend.deploy.service.IJenkinsSyncHistoryService;
import com.qqchen.deploy.backend.deploy.service.IJenkinsViewService;
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
import com.qqchen.deploy.backend.framework.exception.BusinessException;
@ -46,6 +50,9 @@ public class JenkinsViewServiceImpl extends BaseServiceImpl<JenkinsView, Jenkins
@Resource
private IJenkinsSyncHistoryRepository jenkinsSyncHistoryRepository;
@Resource
private IJenkinsSyncHistoryService jenkinsSyncHistoryService;
/**
* 同步Jenkins视图
*
@ -55,17 +62,28 @@ public class JenkinsViewServiceImpl extends BaseServiceImpl<JenkinsView, Jenkins
@Override
@Transactional(rollbackFor = Exception.class)
public Integer syncViews(Long externalSystemId) {
// 1. 查询外部系统
// 1. 创建同步历史记录
JenkinsSyncHistoryDTO syncHistory = new JenkinsSyncHistoryDTO();
syncHistory.setExternalSystemId(externalSystemId);
syncHistory.setSyncType(JenkinsSyncType.VIEW);
syncHistory.setStatus(ExternalSystemSyncStatus.RUNNING);
jenkinsSyncHistoryService.saveOrUpdateHistory(syncHistory);
try {
// 2. 查询外部系统
ExternalSystem externalSystem = externalSystemRepository.findById(externalSystemId).orElseThrow(() -> new BusinessException(ResponseCode.EXTERNAL_SYSTEM_NOT_FOUND));
// 2. 调用Jenkins API获取视图列表
// 3. 调用Jenkins API获取视图列表
List<JenkinsViewResponse> viewResponses = jenkinsServiceIntegration.listViews(externalSystem);
if (viewResponses.isEmpty()) {
log.info("No views found in Jenkins system: {}", externalSystemId);
// 更新同步历史为成功
syncHistory.setStatus(ExternalSystemSyncStatus.SUCCESS);
jenkinsSyncHistoryService.saveOrUpdateHistory(syncHistory);
return 0;
}
// 3. 转换并保存/更新视图数据
// 4. 转换并保存/更新视图数据
List<JenkinsView> jenkinsViews = new ArrayList<>();
for (JenkinsViewResponse viewResponse : viewResponses) {
// 查找是否存在相同的视图
@ -89,11 +107,22 @@ public class JenkinsViewServiceImpl extends BaseServiceImpl<JenkinsView, Jenkins
jenkinsViews.add(jenkinsView);
}
// 4. 批量保存或更新
// 5. 批量保存或更新
jenkinsViewRepository.saveAll(jenkinsViews);
log.info("Successfully synchronized {} Jenkins views for external system: {}", jenkinsViews.size(), externalSystemId);
// 6. 更新同步历史为成功
syncHistory.setStatus(ExternalSystemSyncStatus.SUCCESS);
jenkinsSyncHistoryService.saveOrUpdateHistory(syncHistory);
return jenkinsViews.size();
} catch (Exception e) {
log.error("Failed to sync Jenkins views for external system: {}", externalSystemId, e);
syncHistory.setStatus(ExternalSystemSyncStatus.FAILED);
syncHistory.setErrorMessage(e.getMessage());
jenkinsSyncHistoryService.saveOrUpdateHistory(syncHistory);
throw e;
}
}
/**