大声道撒旦
This commit is contained in:
parent
914ad0d1a1
commit
5598468fab
@ -31,6 +31,12 @@ public class RepositoryBranch extends Entity<Long> {
|
||||
@Column(name = "commit_date")
|
||||
private LocalDateTime commitDate;
|
||||
|
||||
@Column(name = "last_update_time")
|
||||
private LocalDateTime lastUpdateTime;
|
||||
|
||||
@Column(name = "last_commit_time")
|
||||
private LocalDateTime lastCommitTime;
|
||||
|
||||
@Column(name = "is_protected")
|
||||
private Boolean isProtected = false;
|
||||
|
||||
@ -54,5 +60,4 @@ public class RepositoryBranch extends Entity<Long> {
|
||||
|
||||
@Column(name = "external_system_id")
|
||||
private Long externalSystemId;
|
||||
|
||||
}
|
||||
@ -6,6 +6,7 @@ import com.qqchen.deploy.backend.deploy.integration.response.GitGroupResponse;
|
||||
import com.qqchen.deploy.backend.deploy.integration.response.GitProjectResponse;
|
||||
import com.qqchen.deploy.backend.system.enums.ExternalSystemTypeEnum;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
||||
@ -11,10 +11,15 @@ import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Git服务集成实现
|
||||
@ -25,6 +30,7 @@ import java.util.List;
|
||||
public class GitServiceIntegrationImpl implements IGitServiceIntegration {
|
||||
|
||||
private final RestTemplate restTemplate = new RestTemplate();
|
||||
private static final DateTimeFormatter GITLAB_DATE_FORMATTER = DateTimeFormatter.ISO_DATE_TIME;
|
||||
|
||||
@Override
|
||||
public boolean testConnection(ExternalSystem system) {
|
||||
@ -117,6 +123,16 @@ public class GitServiceIntegrationImpl implements IGitServiceIntegration {
|
||||
HttpHeaders headers = createHeaders(system);
|
||||
HttpEntity<String> entity = new HttpEntity<>(headers);
|
||||
|
||||
// 先获取原始响应以便调试
|
||||
ResponseEntity<String> rawResponse = restTemplate.exchange(
|
||||
url,
|
||||
HttpMethod.GET,
|
||||
entity,
|
||||
String.class
|
||||
);
|
||||
log.info("GitLab API raw response for project {}: {}", projectId, rawResponse.getBody());
|
||||
|
||||
// 然后解析为对象
|
||||
ResponseEntity<List<GitBranchResponse>> response = restTemplate.exchange(
|
||||
url,
|
||||
HttpMethod.GET,
|
||||
@ -124,7 +140,12 @@ public class GitServiceIntegrationImpl implements IGitServiceIntegration {
|
||||
new ParameterizedTypeReference<>() {}
|
||||
);
|
||||
|
||||
return response.getBody() != null ? response.getBody() : Collections.emptyList();
|
||||
List<GitBranchResponse> branches = response.getBody();
|
||||
if (branches != null && !branches.isEmpty()) {
|
||||
log.info("First branch details: {}", branches.get(0));
|
||||
}
|
||||
|
||||
return branches != null ? branches : Collections.emptyList();
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to fetch git branches for system: {} and project: {}", system.getName(), projectId, e);
|
||||
return Collections.emptyList();
|
||||
@ -160,4 +181,90 @@ public class GitServiceIntegrationImpl implements IGitServiceIntegration {
|
||||
|
||||
return headers;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GitLab事件响应对象
|
||||
*/
|
||||
class GitlabEvent {
|
||||
private String action;
|
||||
private String targetType;
|
||||
private String targetBranch;
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
// Getters and setters
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public void setAction(String action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public String getTargetType() {
|
||||
return targetType;
|
||||
}
|
||||
|
||||
public void setTargetType(String targetType) {
|
||||
this.targetType = targetType;
|
||||
}
|
||||
|
||||
public String getTargetBranch() {
|
||||
return targetBranch;
|
||||
}
|
||||
|
||||
public void setTargetBranch(String targetBranch) {
|
||||
this.targetBranch = targetBranch;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(LocalDateTime createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GitLab仓库事件响应对象
|
||||
*/
|
||||
class GitlabRepositoryEvent {
|
||||
private String actionName;
|
||||
private String refType;
|
||||
private String ref;
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
// Getters and setters
|
||||
public String getActionName() {
|
||||
return actionName;
|
||||
}
|
||||
|
||||
public void setActionName(String actionName) {
|
||||
this.actionName = actionName;
|
||||
}
|
||||
|
||||
public String getRefType() {
|
||||
return refType;
|
||||
}
|
||||
|
||||
public void setRefType(String refType) {
|
||||
this.refType = refType;
|
||||
}
|
||||
|
||||
public String getRef() {
|
||||
return ref;
|
||||
}
|
||||
|
||||
public void setRef(String ref) {
|
||||
this.ref = ref;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(LocalDateTime createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,11 @@
|
||||
package com.qqchen.deploy.backend.deploy.integration.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneId;
|
||||
|
||||
/**
|
||||
* Git分支响应对象
|
||||
@ -12,23 +15,62 @@ public class GitBranchResponse {
|
||||
|
||||
private String name;
|
||||
|
||||
@JsonProperty("default")
|
||||
private Boolean isDefaultBranch;
|
||||
|
||||
private Boolean isProtected;
|
||||
|
||||
@JsonProperty("can_push")
|
||||
private Boolean canPush;
|
||||
|
||||
@JsonProperty("developers_can_push")
|
||||
private Boolean developersCanPush;
|
||||
|
||||
@JsonProperty("developers_can_merge")
|
||||
private Boolean developersCanMerge;
|
||||
|
||||
private String commitId;
|
||||
|
||||
private String commitMessage;
|
||||
|
||||
private String commitAuthor;
|
||||
|
||||
private LocalDateTime commitDate;
|
||||
@JsonProperty("commit")
|
||||
private GitCommitResponse commit;
|
||||
|
||||
@JsonProperty("web_url")
|
||||
private String webUrl;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class GitCommitResponse {
|
||||
private String id;
|
||||
private String message;
|
||||
private String author_name;
|
||||
|
||||
@JsonProperty("authored_date")
|
||||
private OffsetDateTime authoredDate;
|
||||
|
||||
@JsonProperty("committed_date")
|
||||
private OffsetDateTime committedDate;
|
||||
}
|
||||
|
||||
public String getCommitId() {
|
||||
return commit != null ? commit.id : null;
|
||||
}
|
||||
|
||||
public String getCommitMessage() {
|
||||
return commit != null ? commit.message : null;
|
||||
}
|
||||
|
||||
public String getCommitAuthor() {
|
||||
return commit != null ? commit.author_name : null;
|
||||
}
|
||||
|
||||
public LocalDateTime getCommitDate() {
|
||||
return commit != null && commit.authoredDate != null ?
|
||||
commit.authoredDate.atZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime() : null;
|
||||
}
|
||||
|
||||
public LocalDateTime getLastUpdateTime() {
|
||||
return commit != null && commit.committedDate != null ?
|
||||
commit.committedDate.atZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime() : null;
|
||||
}
|
||||
|
||||
public LocalDateTime getLastCommitTime() {
|
||||
return getLastUpdateTime();
|
||||
}
|
||||
}
|
||||
@ -38,6 +38,8 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* Git仓库分支服务实现
|
||||
*/
|
||||
@ -117,54 +119,41 @@ public class RepositoryBranchServiceImpl extends BaseServiceImpl<RepositoryBranc
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 4. 获取上次成功同步的历史记录
|
||||
RepositorySyncHistory lastSuccessSync = repositorySyncHistoryRepository
|
||||
.findTopByExternalSystemIdAndSyncTypeAndStatusOrderByStartTimeDesc(
|
||||
externalSystemId, RepositorySyncType.BRANCH, ExternalSystemSyncStatus.SUCCESS);
|
||||
|
||||
// 5. 筛选需要同步的项目
|
||||
List<RepositoryProject> projectsToSync = projects;
|
||||
if (lastSuccessSync != null) {
|
||||
projectsToSync = projects.stream()
|
||||
.filter(project -> project.getLastActivityAt() == null ||
|
||||
project.getLastActivityAt().isAfter(lastSuccessSync.getEndTime()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
if (projectsToSync.isEmpty()) {
|
||||
log.info("No projects need to be synchronized for external system: {}", externalSystem.getName());
|
||||
repositorySyncHistoryService.updateSyncHistory(syncHistory.getId(), ExternalSystemSyncStatus.SUCCESS, null);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AtomicInteger totalSyncedBranches = new AtomicInteger(0);
|
||||
List<CompletableFuture<Void>> futures = new ArrayList<>();
|
||||
List<RepositoryBranch> branchesToSave = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
// 6. 异步同步每个项目的分支
|
||||
for (RepositoryProject project : projectsToSync) {
|
||||
// 4. 异步处理每个项目
|
||||
for (RepositoryProject project : projects) {
|
||||
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
// 6.1 获取远程分支信息
|
||||
// 4.1 获取当前项目在GitLab上的所有分支
|
||||
List<GitBranchResponse> remoteBranches = gitServiceIntegration.branches(externalSystem, project.getProjectId());
|
||||
if (remoteBranches.isEmpty()) {
|
||||
log.info("No branches found for project: {}", project.getName());
|
||||
return;
|
||||
}
|
||||
Set<String> remoteBranchNames = remoteBranches.stream()
|
||||
.map(GitBranchResponse::getName)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 6.2 获取本地已存在的分支
|
||||
// 4.2 获取数据库中的所有分支
|
||||
Map<String, RepositoryBranch> existingBranchMap = repositoryBranchRepository
|
||||
.findByExternalSystemIdAndProjectIdAndDeletedFalse(externalSystemId, project.getId())
|
||||
.stream()
|
||||
.collect(Collectors.toMap(RepositoryBranch::getName, Function.identity()));
|
||||
|
||||
// 6.3 更新或创建分支
|
||||
// 4.3 处理所有远程分支(新增或更新)
|
||||
for (GitBranchResponse remoteBranch : remoteBranches) {
|
||||
RepositoryBranch branch = updateOrCreateBranch(externalSystemId, project.getId(), remoteBranch, existingBranchMap);
|
||||
branchesToSave.add(branch);
|
||||
totalSyncedBranches.incrementAndGet();
|
||||
existingBranchMap.remove(remoteBranch.getName());
|
||||
}
|
||||
|
||||
// 4.4 处理已删除的分支
|
||||
existingBranchMap.forEach((branchName, branch) -> {
|
||||
branch.setDeleted(true);
|
||||
branchesToSave.add(branch);
|
||||
totalSyncedBranches.incrementAndGet();
|
||||
});
|
||||
|
||||
log.info("Processed {} branches for project: {}", remoteBranches.size(), project.getName());
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to sync branches for project: {}", project.getName(), e);
|
||||
@ -188,16 +177,15 @@ public class RepositoryBranchServiceImpl extends BaseServiceImpl<RepositoryBranc
|
||||
}
|
||||
}
|
||||
|
||||
// 7. 更新同步历史为成功
|
||||
// 5. 更新同步历史为成功
|
||||
repositorySyncHistoryService.updateSyncHistory(syncHistory.getId(), ExternalSystemSyncStatus.SUCCESS, null);
|
||||
|
||||
log.info("Successfully synchronized total {} branches for external system: {}",
|
||||
totalSyncedBranches.get(), externalSystem.getName());
|
||||
return totalSyncedBranches.get();
|
||||
} catch (Exception e) {
|
||||
// 8. 更新同步历史为失败
|
||||
// 6. 更新同步历史为失败
|
||||
repositorySyncHistoryService.updateSyncHistory(syncHistory.getId(), ExternalSystemSyncStatus.FAILED, e.getMessage());
|
||||
log.error("Failed to sync branches for external system: {}", externalSystemId, e);
|
||||
throw new BusinessException(ResponseCode.REPOSITORY_BRANCH_SYNC_FAILED);
|
||||
}
|
||||
}
|
||||
@ -224,6 +212,8 @@ public class RepositoryBranchServiceImpl extends BaseServiceImpl<RepositoryBranc
|
||||
branch.setCommitAuthor(remoteBranch.getCommitAuthor());
|
||||
branch.setCommitDate(remoteBranch.getCommitDate());
|
||||
branch.setWebUrl(remoteBranch.getWebUrl());
|
||||
branch.setLastUpdateTime(remoteBranch.getLastUpdateTime());
|
||||
branch.setLastCommitTime(remoteBranch.getLastCommitTime());
|
||||
|
||||
return branch;
|
||||
}
|
||||
|
||||
@ -359,6 +359,8 @@ CREATE TABLE deploy_repo_branch
|
||||
commit_message TEXT NULL COMMENT '最新提交信息',
|
||||
commit_author VARCHAR(100) NULL COMMENT '最新提交作者',
|
||||
commit_date DATETIME(6) NULL COMMENT '最新提交时间',
|
||||
last_update_time DATETIME(6) NULL COMMENT '分支最后更新时间',
|
||||
last_commit_time DATETIME(6) NULL COMMENT '分支最后提交时间',
|
||||
web_url VARCHAR(255) NULL COMMENT '网页URL'
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='代码仓库分支表';
|
||||
|
||||
Loading…
Reference in New Issue
Block a user