大声道撒旦

This commit is contained in:
dengqichen 2025-01-07 13:36:47 +08:00
parent 5b2dc6145f
commit a2ccd9012c
3 changed files with 61 additions and 46 deletions

View File

@ -68,6 +68,13 @@ public interface IJenkinsServiceIntegration extends IExternalSystemIntegration {
*/
List<JenkinsJobResponse> listJobs(ExternalSystem externalSystem, String viewName);
/**
* 获取任务详情
*
* @param externalSystem Jenkins系统配置
* @param jobName 任务名称
* @return 任务详情
*/
JenkinsJobResponse job(ExternalSystem externalSystem, String jobName);
/**

View File

@ -30,6 +30,7 @@ import java.util.Base64;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
@Slf4j
@Service

View File

@ -3,22 +3,14 @@ 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.entity.*;
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.integration.response.JenkinsJobResponse;
import com.qqchen.deploy.backend.deploy.integration.response.*;
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;
import com.qqchen.deploy.backend.deploy.repository.IExternalSystemRepository;
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.repository.*;
import com.qqchen.deploy.backend.deploy.service.IJenkinsBuildService;
import com.qqchen.deploy.backend.deploy.service.IJenkinsSyncHistoryService;
import com.qqchen.deploy.backend.deploy.service.sync.JenkinsSyncContext;
@ -29,24 +21,16 @@ import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
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.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* Jenkins构建信息 Service实现
*/
@Slf4j
@Service
public class JenkinsBuildServiceImpl extends BaseServiceImpl<JenkinsBuild, JenkinsBuildDTO, JenkinsBuildQuery, Long>
@ -157,9 +141,23 @@ public class JenkinsBuildServiceImpl extends BaseServiceImpl<JenkinsBuild, Jenki
return 0;
}
// 2. 同步每个任务
// 2. 一次性获取视图下所有任务的最新状态
List<JenkinsJobResponse> jobResponses = jenkinsServiceIntegration.listJobs(externalSystem, view.getViewName());
if (jobResponses.isEmpty()) {
log.info("No job information available for view: {}", view.getViewName());
return 0;
}
// 3. 创建任务名称到响应的映射
Map<String, JenkinsJobResponse> jobResponseMap = jobResponses.stream()
.collect(Collectors.toMap(JenkinsJobResponse::getName, job -> job));
// 4. 同步每个任务的构建信息
return jobs.stream()
.map(job -> syncJob(externalSystem, job))
.map(job -> {
JenkinsJobResponse jobResponse = jobResponseMap.get(job.getJobName());
return syncJob(externalSystem, job, jobResponse);
})
.mapToInt(Integer::intValue)
.sum();
} catch (Exception e) {
@ -169,30 +167,28 @@ public class JenkinsBuildServiceImpl extends BaseServiceImpl<JenkinsBuild, Jenki
}
@Transactional
protected Integer syncJob(ExternalSystem externalSystem, JenkinsJob job) {
protected Integer syncJob(ExternalSystem externalSystem, JenkinsJob job, JenkinsJobResponse jobResponse) {
try {
// 1. 获取任务最新状态
JenkinsJobResponse jobResponse = jenkinsServiceIntegration.job(externalSystem, job.getJobName());
if (jobResponse == null || jobResponse.getLastBuild() == null) {
log.info("No build information available for job: {}", job.getJobName());
return 0;
}
// 2. 获取数据库中最后一次构建记录
// 1. 获取数据库中最后一次构建记录
Optional<JenkinsBuild> lastBuild = jenkinsBuildRepository.findTopByExternalSystemIdAndJobIdOrderByBuildNumberDesc(
externalSystem.getId(), job.getId());
// 3. 获取需要同步的构建信息
// 2. 获取需要同步的构建信息
List<JenkinsBuildResponse> newBuilds = getNewBuilds(externalSystem, job, jobResponse, lastBuild);
if (newBuilds.isEmpty()) {
log.info("No new builds to sync for job: {}", job.getJobName());
return 0;
}
// 4. 保存新的构建信息
// 3. 保存新的构建信息
saveNewBuilds(externalSystem, job, newBuilds);
// 5. 更新任务的最新构建信息
// 4. 更新任务的最新构建信息
updateJobLastBuild(job, jobResponse);
log.info("Successfully synchronized {} builds for job: {}", newBuilds.size(), job.getJobName());
@ -208,28 +204,42 @@ public class JenkinsBuildServiceImpl extends BaseServiceImpl<JenkinsBuild, Jenki
JenkinsJob job,
JenkinsJobResponse jobResponse,
Optional<JenkinsBuild> lastBuild) {
// 获取所有构建
List<JenkinsBuildResponse> allBuilds = jenkinsServiceIntegration.listBuilds(
externalSystem, job.getJobName());
if (allBuilds.isEmpty()) {
return allBuilds;
// 1. 获取最新构建号从jobResponse中获取避免额外的API调用
if (jobResponse.getLastBuild() == null) {
log.info("No builds found for job: {}", job.getJobName());
return Collections.emptyList();
}
Integer latestBuildNumber = jobResponse.getLastBuild().getNumber();
// 如果是首次同步获取所有构建
// 2. 确定同步范围
Integer fromBuildNumber;
if (lastBuild.isEmpty()) {
// 首次同步从第一个构建开始
log.info("First time sync for job: {}, will sync all builds", job.getJobName());
return allBuilds;
fromBuildNumber = 1;
} else {
// 增量同步从上次同步的下一个构建开始
fromBuildNumber = lastBuild.get().getBuildNumber() + 1;
}
// 获取新的构建
Integer lastBuildNumber = lastBuild.get().getBuildNumber();
List<JenkinsBuildResponse> newBuilds = allBuilds.stream()
.filter(build -> build.getNumber() > lastBuildNumber)
// 3. 如果没有新的构建直接返回
if (fromBuildNumber > latestBuildNumber) {
log.info("No new builds to sync for job: {} (last build: {}, latest build: {})",
job.getJobName(), lastBuild.map(JenkinsBuild::getBuildNumber).orElse(null), latestBuildNumber);
return Collections.emptyList();
}
// 4. 获取构建信息
List<JenkinsBuildResponse> builds = jenkinsServiceIntegration.listBuilds(externalSystem, job.getJobName());
// 5. 过滤出需要的构建
List<JenkinsBuildResponse> newBuilds = builds.stream()
.filter(build -> build.getNumber() >= fromBuildNumber && build.getNumber() <= latestBuildNumber)
.collect(Collectors.toList());
log.info("Found {} new builds for job: {} (last build number: {})",
newBuilds.size(), job.getJobName(), lastBuildNumber);
log.info("Found {} new builds for job: {} (from build: {}, to build: {})",
newBuilds.size(), job.getJobName(), fromBuildNumber, latestBuildNumber);
return newBuilds;
}
@ -277,9 +287,6 @@ public class JenkinsBuildServiceImpl extends BaseServiceImpl<JenkinsBuild, Jenki
jenkinsSyncHistoryService.saveOrUpdateHistory(syncHistory);
}
/**
* 从API响应更新构建信息
*/
private void updateBuildFromResponse(JenkinsBuild jenkinsBuild, JenkinsBuildResponse response) {
jenkinsBuild.setBuildUrl(response.getUrl());
jenkinsBuild.setBuildStatus(response.getResult());