use of org.gitlab4j.api.RepositoryApi in project legend-sdlc by finos.
the class GitLabBackupApi method recoverBackupWorkspace.
/**
* This method will recover a backup workspace by doing the following step:
* 1. Verify that the backup workspace exists
* 2. Delete the existing workspace
* 3. Create
*/
@Override
public void recoverBackupWorkspace(String projectId, String workspaceId, WorkspaceType workspaceType, boolean forceRecovery) {
LegendSDLCServerException.validateNonNull(projectId, "projectId may not be null");
LegendSDLCServerException.validateNonNull(workspaceId, "workspaceId may not be null");
GitLabProjectId gitLabProjectId = parseProjectId(projectId);
RepositoryApi repositoryApi = getGitLabApi(gitLabProjectId.getGitLabMode()).getRepositoryApi();
ProjectFileAccessProvider.WorkspaceAccessType backupWorkspaceType = ProjectFileAccessProvider.WorkspaceAccessType.BACKUP;
// Verify the backup exists
try {
withRetries(() -> repositoryApi.getBranch(gitLabProjectId.getGitLabId(), getWorkspaceBranchName(workspaceId, workspaceType, backupWorkspaceType)));
} catch (Exception e) {
if (GitLabApiTools.isNotFoundGitLabApiException(e)) {
LOGGER.error("No backup for workspace {} in project {}, so recovery is not possible", workspaceId, projectId);
}
throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to get " + workspaceType.getLabel() + " " + backupWorkspaceType.getLabel() + " " + workspaceId + " in project " + projectId, () -> "Unknown " + workspaceType.getLabel() + " " + backupWorkspaceType.getLabel() + " with (" + workspaceId + ") or project (" + projectId + "). " + "This implies that a backup does not exist for the specified workspace, hence recovery is not possible", () -> "Error getting " + workspaceType.getLabel() + " " + backupWorkspaceType.getLabel() + " " + workspaceId + " in project " + projectId);
}
Branch existingBranch = null;
ProjectFileAccessProvider.WorkspaceAccessType workspaceAccessType = ProjectFileAccessProvider.WorkspaceAccessType.WORKSPACE;
// Check if branch exists
try {
existingBranch = withRetries(() -> repositoryApi.getBranch(gitLabProjectId.getGitLabId(), getWorkspaceBranchName(workspaceId, workspaceType, workspaceAccessType)));
} catch (Exception e) {
if (!GitLabApiTools.isNotFoundGitLabApiException(e)) {
LOGGER.error("Error getting {} {} in project {}", workspaceType.getLabel() + " " + workspaceAccessType.getLabel(), workspaceId, projectId, e);
}
}
if (existingBranch != null) {
if (!forceRecovery) {
throw new LegendSDLCServerException("Workspace " + workspaceId + " of project " + projectId + " already existed and the recovery is not forced, so recovery from backup is not possible", Response.Status.METHOD_NOT_ALLOWED);
}
// Delete the existing branch
boolean workspaceDeleted;
try {
workspaceDeleted = GitLabApiTools.deleteBranchAndVerify(repositoryApi, gitLabProjectId.getGitLabId(), getWorkspaceBranchName(workspaceId, workspaceType, workspaceAccessType), 20, 1_000);
} catch (Exception e) {
throw buildException(e, () -> "Error while attempting to recover backup for " + workspaceType.getLabel() + " " + workspaceAccessType.getLabel() + " " + workspaceId + " in project " + projectId + ": User " + getCurrentUser() + " is not allowed to delete workspace", () -> "Error while attempting to recover backup for " + workspaceType.getLabel() + " " + workspaceAccessType.getLabel() + " " + workspaceId + " in project " + projectId + ": Unknown project: " + projectId, () -> "Error while attempting to recover backup for " + workspaceType.getLabel() + " " + workspaceAccessType.getLabel() + " " + workspaceId + " in project " + projectId + ": Error deleting workspace");
}
if (!workspaceDeleted) {
throw new LegendSDLCServerException("Failed to delete " + workspaceType.getLabel() + " " + workspaceAccessType.getLabel() + " " + workspaceId + " in project " + projectId);
}
}
// Create new workspace branch off the backup branch head
Branch workspaceBranch;
try {
workspaceBranch = GitLabApiTools.createBranchFromSourceBranchAndVerify(repositoryApi, gitLabProjectId.getGitLabId(), getWorkspaceBranchName(workspaceId, workspaceType, workspaceAccessType), getWorkspaceBranchName(workspaceId, workspaceType, backupWorkspaceType), 30, 1_000);
} catch (Exception e) {
throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to create " + workspaceType.getLabel() + " " + workspaceAccessType.getLabel() + " " + workspaceId + " in project " + projectId, () -> "Unknown project: " + projectId, () -> "Error creating " + workspaceType.getLabel() + " " + workspaceAccessType.getLabel() + " " + workspaceId + " in project " + projectId);
}
if (workspaceBranch == null) {
throw new LegendSDLCServerException("Failed to create " + workspaceType.getLabel() + " " + workspaceAccessType.getLabel() + " " + workspaceId + " in project " + projectId + " from " + workspaceType.getLabel() + " " + backupWorkspaceType.getLabel() + " " + workspaceId);
}
// Delete backup branch
try {
boolean deleted = GitLabApiTools.deleteBranchAndVerify(repositoryApi, gitLabProjectId.getGitLabId(), getWorkspaceBranchName(workspaceId, workspaceType, backupWorkspaceType), 20, 1_000);
if (!deleted) {
LOGGER.error("Failed to delete {} {} in project {}", workspaceType.getLabel() + " " + backupWorkspaceType.getLabel(), workspaceId, projectId);
}
} catch (Exception e) {
// unfortunate, but this should not throw error
LOGGER.error("Error deleting {} {} in project {} after recovery is completed", workspaceType.getLabel() + " " + backupWorkspaceType.getLabel(), workspaceId, projectId, e);
}
}
use of org.gitlab4j.api.RepositoryApi in project legend-sdlc by finos.
the class GitLabComparisonApi method getReviewComparison.
@Override
public Comparison getReviewComparison(String projectId, String reviewId) {
LegendSDLCServerException.validateNonNull(projectId, "projectId may not be null");
LegendSDLCServerException.validateNonNull(reviewId, "reviewId may not be null");
GitLabProjectId gitLabProjectId = parseProjectId(projectId);
RepositoryApi repositoryApi = getGitLabApi(gitLabProjectId.getGitLabMode()).getRepositoryApi();
MergeRequest mergeRequest = getReviewMergeRequest(getGitLabApi(gitLabProjectId.getGitLabMode()).getMergeRequestApi(), gitLabProjectId, reviewId);
WorkspaceInfo workspaceInfo = parseWorkspaceBranchName(mergeRequest.getSourceBranch());
if (workspaceInfo == null) {
throw new LegendSDLCServerException("Unknown review in project " + projectId + ": " + reviewId, Response.Status.NOT_FOUND);
}
DiffRef diffRef = mergeRequest.getDiffRefs();
if ((diffRef == null) || (diffRef.getStartSha() == null) || (diffRef.getHeadSha() == null)) {
throw new LegendSDLCServerException("Unable to get revision info for review " + reviewId + " in project " + projectId);
}
String fromRevisionId = diffRef.getStartSha();
String toRevisionId = diffRef.getHeadSha();
ProjectStructure fromProjectStructure = getProjectStructure(projectId, workspaceInfo.getWorkspaceId(), fromRevisionId, workspaceInfo.getWorkspaceType(), workspaceInfo.getWorkspaceAccessType());
ProjectStructure toProjectStructure = getProjectStructure(gitLabProjectId.toString(), null, toRevisionId, null, null);
return getComparisonResult(gitLabProjectId, repositoryApi, fromRevisionId, toRevisionId, fromProjectStructure, toProjectStructure);
}
use of org.gitlab4j.api.RepositoryApi in project legend-sdlc by finos.
the class GitLabComparisonApi method getWorkspaceCreationComparison.
@Override
public Comparison getWorkspaceCreationComparison(String projectId, String workspaceId, WorkspaceType workspaceType) {
LegendSDLCServerException.validateNonNull(projectId, "projectId may not be null");
LegendSDLCServerException.validateNonNull(workspaceId, "workspaceId may not be null");
GitLabProjectId gitLabProjectId = parseProjectId(projectId);
RepositoryApi repositoryApi = getGitLabApi(gitLabProjectId.getGitLabMode()).getRepositoryApi();
String currentWorkspaceRevisionId = this.revisionApi.getWorkspaceRevisionContext(projectId, workspaceId, workspaceType).getCurrentRevision().getId();
ProjectFileAccessProvider.WorkspaceAccessType workspaceAccessType = ProjectFileAccessProvider.WorkspaceAccessType.WORKSPACE;
ProjectStructure toProjectStructure = getProjectStructure(gitLabProjectId.toString(), workspaceId, currentWorkspaceRevisionId, workspaceType, workspaceAccessType);
String workspaceCreationRevisionId;
try {
Commit commit = repositoryApi.getMergeBase(gitLabProjectId.getGitLabId(), Arrays.asList(MASTER_BRANCH, currentWorkspaceRevisionId));
workspaceCreationRevisionId = commit.getId();
} catch (Exception e) {
throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to get merged based revision for revisions " + MASTER_BRANCH + ", " + currentWorkspaceRevisionId + " from project " + gitLabProjectId.toString(), () -> "Could not find revisions " + MASTER_BRANCH + ", " + currentWorkspaceRevisionId + " from project " + gitLabProjectId.toString(), () -> "Failed to fetch Merged Base Information for revisions " + MASTER_BRANCH + ", " + currentWorkspaceRevisionId + " from project " + gitLabProjectId.toString());
}
ProjectStructure fromProjectStructure = getProjectStructure(gitLabProjectId.toString(), workspaceId, workspaceCreationRevisionId, workspaceType, workspaceAccessType);
return getComparisonResult(gitLabProjectId, repositoryApi, workspaceCreationRevisionId, currentWorkspaceRevisionId, fromProjectStructure, toProjectStructure);
}
use of org.gitlab4j.api.RepositoryApi in project legend-sdlc by finos.
the class GitLabConflictResolutionApi method acceptConflictResolution.
/**
* This method will apply conflict resolution changes and mark a conflict resolution as done.
* Assume we have workspace branch `w1`, this method will:
* 1. Perform entity changes to resolve conflicts
* 2. Remove backup branch for `w1` if exists
* 3. Create backup branch for `w1`
* 4. Remove workspace branch `w1`
* 5. Create new workspace branch `w1` from conflict resolution branch `w1`
* 6. Remove conflict resolution branch `w1`
* 7. Remove backup branch `w1`
*/
@Override
public void acceptConflictResolution(String projectId, String workspaceId, WorkspaceType workspaceType, PerformChangesCommand command) {
LegendSDLCServerException.validateNonNull(projectId, "projectId may not be null");
LegendSDLCServerException.validateNonNull(workspaceId, "workspaceId may not be null");
GitLabProjectId gitLabProjectId = parseProjectId(projectId);
RepositoryApi repositoryApi = getGitLabApi(gitLabProjectId.getGitLabMode()).getRepositoryApi();
ProjectFileAccessProvider.WorkspaceAccessType conflictResolutionWorkspaceType = ProjectFileAccessProvider.WorkspaceAccessType.CONFLICT_RESOLUTION;
// Verify conflict resolution is happening
try {
withRetries(() -> repositoryApi.getBranch(gitLabProjectId.getGitLabId(), getWorkspaceBranchName(workspaceId, workspaceType, conflictResolutionWorkspaceType)));
} catch (Exception e) {
if (e instanceof GitLabApiException && GitLabApiTools.isNotFoundGitLabApiException((GitLabApiException) e)) {
LOGGER.error("Conflict resolution is not happening on workspace {} in project {}, so accepting conflict resolution is not actionable", workspaceId, projectId);
}
throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to get " + workspaceType.getLabel() + " " + conflictResolutionWorkspaceType.getLabel() + " " + workspaceId + " in project " + projectId, () -> "Unknown " + workspaceType.getLabel() + " " + conflictResolutionWorkspaceType.getLabel() + " (" + workspaceId + ") or project (" + projectId + "). " + "This implies that conflict resolution is not taking place, hence accepting conflict resolution is not actionable", () -> "Error getting " + workspaceType.getLabel() + " " + conflictResolutionWorkspaceType.getLabel() + " " + workspaceId + " in project " + projectId);
}
// Perform entity changes to resolve conflicts
try {
this.entityApi.getWorkspaceWithConflictResolutionEntityModificationContext(projectId, workspaceId).performChanges(command.getEntityChanges(), command.getRevisionId(), command.getMessage());
} catch (Exception e) {
throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to apply conflict resolution changes in " + workspaceType.getLabel() + " " + conflictResolutionWorkspaceType.getLabel() + " " + workspaceId + " in project " + projectId, () -> "Unknown " + workspaceType.getLabel() + " " + conflictResolutionWorkspaceType.getLabel() + " (" + workspaceId + ") or project (" + projectId + "). " + "This implies that conflict resolution is not taking place, hence accept is not actionable", () -> "Error applying conflict resolution changes in " + workspaceType.getLabel() + " " + conflictResolutionWorkspaceType.getLabel() + " " + workspaceId + " in project " + projectId);
}
// Delete backup branch if already exists
boolean backupWorkspaceDeleted;
ProjectFileAccessProvider.WorkspaceAccessType backupWorkspaceType = ProjectFileAccessProvider.WorkspaceAccessType.BACKUP;
try {
backupWorkspaceDeleted = GitLabApiTools.deleteBranchAndVerify(repositoryApi, gitLabProjectId.getGitLabId(), getWorkspaceBranchName(workspaceId, workspaceType, backupWorkspaceType), 20, 1_000);
} catch (Exception e) {
// If we fail to delete the residual backup workspace, we cannot proceed anyway, so we will throw the error here
throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to delete " + workspaceType.getLabel() + " " + backupWorkspaceType.getLabel() + " " + workspaceId + " in project " + projectId, () -> "Unknown " + workspaceType.getLabel() + " " + backupWorkspaceType.getLabel() + " (" + workspaceId + ") or project (" + projectId + ")", () -> "Error deleting " + workspaceType.getLabel() + " " + backupWorkspaceType.getLabel() + " " + workspaceId + " in project " + projectId);
}
if (!backupWorkspaceDeleted) {
throw new LegendSDLCServerException("Failed to delete " + workspaceType.getLabel() + " " + backupWorkspaceType.getLabel() + " " + workspaceId + " in project " + projectId);
}
// Create backup branch from original branch
Branch newBackupBranch;
ProjectFileAccessProvider.WorkspaceAccessType workspaceAccessType = ProjectFileAccessProvider.WorkspaceAccessType.WORKSPACE;
try {
// Wait to allow nodes to synchronize that backup branch is already deleted
Thread.sleep(1000);
} catch (InterruptedException e) {
LOGGER.warn("Interrupted while waiting for nodes to synchronize that backup branch was deleted.", e);
Thread.currentThread().interrupt();
}
try {
newBackupBranch = GitLabApiTools.createBranchFromSourceBranchAndVerify(repositoryApi, gitLabProjectId.getGitLabId(), getWorkspaceBranchName(workspaceId, workspaceType, backupWorkspaceType), getWorkspaceBranchName(workspaceId, workspaceType, workspaceAccessType), 30, 1_000);
} catch (Exception e) {
throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to create " + workspaceType.getLabel() + " " + backupWorkspaceType.getLabel() + " " + workspaceId + " in project " + projectId, () -> "Unknown project: " + projectId, () -> "Error creating " + workspaceType.getLabel() + " " + backupWorkspaceType.getLabel() + " " + workspaceId + " in project " + projectId);
}
if (newBackupBranch == null) {
throw new LegendSDLCServerException("Failed to create " + workspaceType.getLabel() + " " + backupWorkspaceType.getLabel() + " " + workspaceId + " from " + workspaceType.getLabel() + " " + workspaceAccessType.getLabel() + " " + workspaceId + " in project " + projectId);
}
// Delete original branch
boolean originalBranchDeleted;
try {
originalBranchDeleted = GitLabApiTools.deleteBranchAndVerify(repositoryApi, gitLabProjectId.getGitLabId(), getWorkspaceBranchName(workspaceId, workspaceType, workspaceAccessType), 20, 1_000);
} catch (Exception e) {
throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to delete " + workspaceType.getLabel() + " " + workspaceAccessType.getLabel() + " " + workspaceId + " in project " + projectId, () -> "Unknown " + workspaceType.getLabel() + " " + workspaceAccessType.getLabel() + " (" + workspaceId + ") or project (" + projectId + ")", () -> "Error deleting " + workspaceType.getLabel() + " " + workspaceAccessType.getLabel() + " " + workspaceId + " in project " + projectId);
}
if (!originalBranchDeleted) {
throw new LegendSDLCServerException("Failed to delete " + workspaceType.getLabel() + " " + workspaceAccessType.getLabel() + " " + workspaceId + " in project " + projectId);
}
// Create new workspace branch off the conflict workspace head
Branch newWorkspaceBranch;
try {
// Wait to allow nodes to synchronize that original branch is already deleted.
Thread.sleep(1000);
} catch (InterruptedException e) {
LOGGER.warn("Interrupted while waiting for nodes to synchronize that original branch was deleted.", e);
Thread.currentThread().interrupt();
}
try {
newWorkspaceBranch = GitLabApiTools.createBranchFromSourceBranchAndVerify(repositoryApi, gitLabProjectId.getGitLabId(), getWorkspaceBranchName(workspaceId, workspaceType, workspaceAccessType), getWorkspaceBranchName(workspaceId, workspaceType, conflictResolutionWorkspaceType), 30, 1_000);
} catch (Exception e) {
throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to create " + workspaceType.getLabel() + " " + workspaceAccessType.getLabel() + " " + workspaceId + " in project " + projectId, () -> "Unknown " + workspaceType.getLabel() + " " + conflictResolutionWorkspaceType.getLabel() + " (" + workspaceId + ") or project (" + projectId + ")", () -> "Error creating " + workspaceType.getLabel() + " " + workspaceAccessType.getLabel() + " " + workspaceId + " in project " + projectId);
}
if (newWorkspaceBranch == null) {
throw new LegendSDLCServerException("Failed to create " + workspaceType.getLabel() + " " + workspaceAccessType.getLabel() + " " + workspaceId + " from " + workspaceType.getLabel() + " " + conflictResolutionWorkspaceType.getLabel() + " " + workspaceId + " in project " + projectId);
}
// Delete conflict resolution branch
boolean conflictResolutionWorkspaceDeleted;
try {
// No need to waste wait time here since conflict resolution branch was long created during update
conflictResolutionWorkspaceDeleted = GitLabApiTools.deleteBranchAndVerify(repositoryApi, gitLabProjectId.getGitLabId(), getWorkspaceBranchName(workspaceId, workspaceType, conflictResolutionWorkspaceType), 20, 1_000);
} catch (Exception e) {
throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to delete " + workspaceType.getLabel() + " " + conflictResolutionWorkspaceType.getLabel() + " " + workspaceId + " in project " + projectId, () -> "Unknown " + workspaceType.getLabel() + " " + conflictResolutionWorkspaceType.getLabel() + " (" + workspaceId + ") or project (" + projectId + ")", () -> "Error deleting " + workspaceType.getLabel() + " " + conflictResolutionWorkspaceType.getLabel() + " " + workspaceId + " in project " + projectId);
}
if (!conflictResolutionWorkspaceDeleted) {
throw new LegendSDLCServerException("Failed to delete " + workspaceType.getLabel() + " " + conflictResolutionWorkspaceType.getLabel() + " " + workspaceId + " in project " + projectId);
}
// Delete backup branch
try {
// Wait extra 500 ms to allow nodes to synchronize that backup branch was recreated
Thread.sleep(500);
} catch (InterruptedException e) {
LOGGER.warn("Interrupted while waiting for nodes to synchronize that backup branch was recreated.", e);
Thread.currentThread().interrupt();
}
try {
boolean deleted = GitLabApiTools.deleteBranchAndVerify(repositoryApi, gitLabProjectId.getGitLabId(), getWorkspaceBranchName(workspaceId, workspaceType, backupWorkspaceType), 20, 1_000);
if (!deleted) {
LOGGER.error("Failed to delete {} {} in project {}", workspaceType.getLabel() + " " + backupWorkspaceType.getLabel(), workspaceId, projectId);
}
} catch (Exception e) {
// unfortunate, but this should not throw error
LOGGER.error("Error deleting {} {} in project {}", workspaceType.getLabel() + " " + backupWorkspaceType.getLabel(), workspaceId, projectId, e);
}
}
Aggregations