diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/entity/JenkinsBuildNotification.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/entity/JenkinsBuildNotification.java index 2e020654..4301b5c8 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/entity/JenkinsBuildNotification.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/entity/JenkinsBuildNotification.java @@ -3,6 +3,7 @@ package com.qqchen.deploy.backend.deploy.entity; import com.qqchen.deploy.backend.framework.domain.Entity; import jakarta.persistence.Column; import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; import lombok.Data; import lombok.EqualsAndHashCode; diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/impl/GitServiceIntegrationImpl.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/impl/GitServiceIntegrationImpl.java index e7ee1fa9..64281c73 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/impl/GitServiceIntegrationImpl.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/impl/GitServiceIntegrationImpl.java @@ -33,6 +33,10 @@ public class GitServiceIntegrationImpl extends BaseExternalSystemIntegration imp private static final Map SYSTEM_CACHE = new ConcurrentHashMap<>(); private static final long CACHE_EXPIRE_TIME = 30 * 60 * 1000; // 30分钟过期 + // GitLab API 分页配置 + private static final int PER_PAGE = 100; // GitLab API 最大值 + private static final int MAX_PAGES = 100; // 防止无限循环,最多获取 10000 条 + /** * Git系统缓存内部类 */ @@ -99,25 +103,43 @@ public class GitServiceIntegrationImpl extends BaseExternalSystemIntegration imp @Override public List groups(ExternalSystem system) { + List allGroups = new ArrayList<>(); + HttpHeaders headers = createHeaders(system); + HttpEntity entity = new HttpEntity<>(headers); + try { - // 直接使用原始系统信息构建URL(URL不需要解密) - String url = String.format("%s/api/v4/groups?per_page=100", system.getUrl()); - // 创建请求头(内部自动处理解密) - HttpHeaders headers = createHeaders(system); - HttpEntity entity = new HttpEntity<>(headers); + int page = 1; + while (page <= MAX_PAGES) { + String url = String.format("%s/api/v4/groups?per_page=%d&page=%d", + system.getUrl(), PER_PAGE, page); + + ResponseEntity> response = restTemplate.exchange( + url, + HttpMethod.GET, + entity, + new ParameterizedTypeReference<>() {} + ); - ResponseEntity> response = restTemplate.exchange( - url, - HttpMethod.GET, - entity, - new ParameterizedTypeReference<>() { + List groups = response.getBody(); + if (groups == null || groups.isEmpty()) { + break; } - ); - - return response.getBody() != null ? response.getBody() : Collections.emptyList(); + + allGroups.addAll(groups); + log.debug("Fetched {} groups from page {}", groups.size(), page); + + // 如果返回数量小于 per_page,说明已经是最后一页 + if (groups.size() < PER_PAGE) { + break; + } + page++; + } + + log.info("Total fetched {} groups for system: {}", allGroups.size(), system.getName()); + return allGroups; } catch (Exception e) { log.error("Failed to fetch git groups for system: {}", system.getName(), e); - return Collections.emptyList(); + return allGroups.isEmpty() ? Collections.emptyList() : allGroups; } } @@ -147,56 +169,91 @@ public class GitServiceIntegrationImpl extends BaseExternalSystemIntegration imp @Override public List projectsByGroup(ExternalSystem system, Long groupId) { + List allProjects = new ArrayList<>(); + HttpHeaders headers = createHeaders(system); + HttpEntity entity = new HttpEntity<>(headers); + try { - // 直接使用原始系统信息构建URL(URL不需要解密) - String url = String.format("%s/api/v4/groups/%d/projects?per_page=100", system.getUrl(), groupId); - // 创建请求头(内部自动处理解密) - HttpHeaders headers = createHeaders(system); - HttpEntity entity = new HttpEntity<>(headers); + int page = 1; + while (page <= MAX_PAGES) { + String url = String.format("%s/api/v4/groups/%d/projects?per_page=%d&page=%d", + system.getUrl(), groupId, PER_PAGE, page); + + ResponseEntity> response = restTemplate.exchange( + url, + HttpMethod.GET, + entity, + new ParameterizedTypeReference<>() {} + ); - ResponseEntity> response = restTemplate.exchange( - url, - HttpMethod.GET, - entity, - new ParameterizedTypeReference<>() { + List projects = response.getBody(); + if (projects == null || projects.isEmpty()) { + break; } - ); - - return response.getBody() != null ? response.getBody() : Collections.emptyList(); + + allProjects.addAll(projects); + log.debug("Fetched {} projects from page {} for group {}", projects.size(), page, groupId); + + // 如果返回数量小于 per_page,说明已经是最后一页 + if (projects.size() < PER_PAGE) { + break; + } + page++; + } + + log.info("Total fetched {} projects for system: {} and group: {}", allProjects.size(), system.getName(), groupId); + return allProjects; } catch (Exception e) { log.error("Failed to fetch git projects for system: {} and group: {}", system.getName(), groupId, e); - return Collections.emptyList(); + return allProjects.isEmpty() ? Collections.emptyList() : allProjects; } } @Override public List branches(ExternalSystem system, Long projectId) { + List allBranches = new ArrayList<>(); + HttpHeaders headers = createHeaders(system); + HttpEntity entity = new HttpEntity<>(headers); + try { - // 直接使用原始系统信息构建URL(URL不需要解密) - String url = String.format("%s/api/v4/projects/%d/repository/branches?per_page=100", system.getUrl(), projectId); - // 创建请求头(内部自动处理解密) - HttpHeaders headers = createHeaders(system); - HttpEntity entity = new HttpEntity<>(headers); - // 然后解析为对象 - ResponseEntity> response = restTemplate.exchange( - url, - HttpMethod.GET, - entity, - new ParameterizedTypeReference<>() { - } - ); + int page = 1; + while (page <= MAX_PAGES) { + String url = String.format("%s/api/v4/projects/%d/repository/branches?per_page=%d&page=%d", + system.getUrl(), projectId, PER_PAGE, page); + + ResponseEntity> response = restTemplate.exchange( + url, + HttpMethod.GET, + entity, + new ParameterizedTypeReference<>() {} + ); - List branches = response.getBody(); - if (branches != null && !branches.isEmpty()) { - log.info("Found {} branches, first branch: {}", branches.size(), branches.getFirst().getName()); + List branches = response.getBody(); + if (branches == null || branches.isEmpty()) { + break; + } + + allBranches.addAll(branches); + log.debug("Fetched {} branches from page {} for project {}", branches.size(), page, projectId); + + // 如果返回数量小于 per_page,说明已经是最后一页 + if (branches.size() < PER_PAGE) { + break; + } + page++; + } + + if (!allBranches.isEmpty()) { + log.info("Total fetched {} branches for project: {}, first branch: {}", + allBranches.size(), projectId, allBranches.getFirst().getName()); } else { log.warn("No branches found for project: {}", projectId); } - - return branches != null ? branches : Collections.emptyList(); + + return allBranches; } catch (Exception e) { log.error("Failed to fetch git branches for system: {} and project: {}", system.getName(), projectId, e); - return Collections.emptyList(); + return allBranches.isEmpty() ? Collections.emptyList() : allBranches; } }