Search in sources :

Example 16 with Branch

use of org.gitlab4j.api.models.Branch in project legend-sdlc by finos.

the class GitLabWorkspaceApi method attemptToSquashAndRebaseWorkspace.

/**
 * This method is called when we failed to rebase the workspace branch on top of master branch. This implies that either
 * the whole change is causing a merge conflict or one of the intermediate commits have conflicts with the change in master branch
 * <p>
 * To handle the latter case, this method will squash all commits on the workspace branch and attempt rebase again.
 * If this fails, it implies that rebase fails because of merge conflicts, which means we have to enter conflict resolution route.
 * <p>
 * NOTE: based on the nature of this method, we have an optimization here where we check for the number of commits on the current
 * branch, if it is less than 2 (not counting the base), it means no squashing is needed and we can just immediately tell that there
 * is merge conflict and the workspace update should enter conflict resolution route
 * <p>
 * So following is the summary of this method:
 * 1. Create a temp branch to do the squashing on that branch
 * 3. Attempt to rebase the temp branch on master:
 * - If succeeded: re-create current workspace branch on top of the temp branch
 * - If failed -> implies conflict resolution is needed
 *
 * @return a workspace update report that might have status as UPDATED or CONFLICT.
 */
private WorkspaceUpdateReport attemptToSquashAndRebaseWorkspace(String projectId, String workspaceId, WorkspaceType workspaceType, String masterRevisionId, String currentWorkspaceRevisionId, String workspaceCreationRevisionId) {
    GitLabProjectId gitLabProjectId = parseProjectId(projectId);
    RepositoryApi repositoryApi = getGitLabApi(gitLabProjectId.getGitLabMode()).getRepositoryApi();
    // Create temp branch for rebasing
    String tempBranchName = newUserTemporaryBranchName();
    Branch tempBranch;
    try {
        tempBranch = GitLabApiTools.createBranchAndVerify(repositoryApi, gitLabProjectId.getGitLabId(), tempBranchName, workspaceCreationRevisionId, 30, 1_000);
    } catch (Exception e) {
        throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to create temporary workspace " + tempBranchName + " in project " + projectId, () -> "Unknown project: " + projectId, () -> "Error creating temporary workspace " + tempBranchName + " in project " + projectId);
    }
    if (tempBranch == null) {
        throw new LegendSDLCServerException("Failed to create temporary workspace " + tempBranchName + " in project " + projectId + " from revision " + workspaceCreationRevisionId);
    }
    CompareResults comparisonResult;
    try {
        comparisonResult = withRetries(() -> repositoryApi.compare(gitLabProjectId.getGitLabId(), workspaceCreationRevisionId, currentWorkspaceRevisionId, true));
    } catch (Exception e) {
        throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to get comparison information from revision " + workspaceCreationRevisionId + "  to revision " + currentWorkspaceRevisionId + " on project" + projectId, () -> "Could not find revisions " + workspaceCreationRevisionId + " ," + currentWorkspaceRevisionId + " on project" + projectId, () -> "Failed to fetch comparison information from revision " + workspaceCreationRevisionId + "  to revision " + currentWorkspaceRevisionId + " on project" + projectId);
    }
    // Create a new commit on temp branch that squashes all changes on the concerned workspace branch
    CommitsApi commitsApi = getGitLabApi(gitLabProjectId.getGitLabMode()).getCommitsApi();
    ProjectFileAccessProvider.WorkspaceAccessType workspaceAccessType = ProjectFileAccessProvider.WorkspaceAccessType.WORKSPACE;
    ProjectFileAccessProvider.FileAccessContext workspaceFileAccessContext = getProjectFileAccessProvider().getWorkspaceFileAccessContext(projectId, workspaceId, workspaceType, workspaceAccessType);
    Commit squashedCommit;
    try {
        List<CommitAction> commitActions = Lists.mutable.empty();
        comparisonResult.getDiffs().forEach(diff -> {
            if (diff.getDeletedFile()) {
                // DELETE
                commitActions.add(new CommitAction().withAction(CommitAction.Action.DELETE).withFilePath(diff.getOldPath()));
            } else if (diff.getRenamedFile()) {
                // MOVE
                // 
                // tl;dr;
                // split this into a delete and a create to make sure the moved entity has the content of the entity
                // in workspace HEAD revision
                // 
                // Since we use comparison API to compute the diff, Git has a smart algorithm to calculate file move
                // as it is a heuristics such that if file content is only slightly different, Git can conclude that the
                // diff was of type RENAME.
                // 
                // The problem with this is when we compare the workspace BASE revision and workspace HEAD revision
                // Assume that we actually renamed an entity, we also want to update the entity path, not just its location
                // the location part is correctly identified by Git, and the change in content is captured as a diff string
                // in comparison result (which shows the change in the path)
                // but when we create CommitAction, there is no way for us to apply this patch on top of the entity content
                // so if we just create action of type MOVE for CommitAction, we will have the content of the old entity
                // which has the wrong path, and thus this entity if continue to exist in the workspace will throw off
                // our path and entity location validation check
                commitActions.add(new CommitAction().withAction(CommitAction.Action.DELETE).withFilePath(diff.getOldPath()));
                commitActions.add(new CommitAction().withAction(CommitAction.Action.CREATE).withFilePath(diff.getNewPath()).withEncoding(Constants.Encoding.BASE64).withContent(encodeBase64(workspaceFileAccessContext.getFile(diff.getNewPath()).getContentAsBytes())));
            } else if (diff.getNewFile()) {
                // CREATE
                commitActions.add(new CommitAction().withAction(CommitAction.Action.CREATE).withFilePath(diff.getNewPath()).withEncoding(Constants.Encoding.BASE64).withContent(encodeBase64(workspaceFileAccessContext.getFile(diff.getNewPath()).getContentAsBytes())));
            } else {
                // UPDATE
                commitActions.add(new CommitAction().withAction(CommitAction.Action.UPDATE).withFilePath(diff.getOldPath()).withEncoding(Constants.Encoding.BASE64).withContent(encodeBase64(workspaceFileAccessContext.getFile(diff.getOldPath()).getContentAsBytes())));
            }
        });
        squashedCommit = commitsApi.createCommit(gitLabProjectId.getGitLabId(), tempBranchName, "aggregated changes for workspace " + workspaceId, null, null, getCurrentUser(), commitActions);
    } catch (Exception e) {
        throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to create commit on temporary workspace " + tempBranchName + " of project " + projectId, () -> "Unknown project: " + projectId + " or temporary workspace " + tempBranchName, () -> "Failed to create commit in temporary workspace " + tempBranchName + " of project " + projectId);
    }
    // Attempt to rebase the temporary branch on top of master
    boolean attemptRebaseResult = this.attemptToRebaseWorkspaceUsingTemporaryBranch(projectId, workspaceId, workspaceType, tempBranchName, masterRevisionId);
    // If rebasing failed, this implies there are conflicts, otherwise, the workspace should be updated
    if (!attemptRebaseResult) {
        return createWorkspaceUpdateReport(WorkspaceUpdateReportStatus.CONFLICT, null, null);
    }
    return createWorkspaceUpdateReport(WorkspaceUpdateReportStatus.UPDATED, masterRevisionId, squashedCommit.getId());
}
Also used : CompareResults(org.gitlab4j.api.models.CompareResults) LegendSDLCServerException(org.finos.legend.sdlc.server.error.LegendSDLCServerException) GitLabApiException(org.gitlab4j.api.GitLabApiException) CommitsApi(org.gitlab4j.api.CommitsApi) ProjectFileAccessProvider(org.finos.legend.sdlc.server.project.ProjectFileAccessProvider) LegendSDLCServerException(org.finos.legend.sdlc.server.error.LegendSDLCServerException) Commit(org.gitlab4j.api.models.Commit) GitLabProjectId(org.finos.legend.sdlc.server.gitlab.GitLabProjectId) Branch(org.gitlab4j.api.models.Branch) RepositoryApi(org.gitlab4j.api.RepositoryApi) CommitAction(org.gitlab4j.api.models.CommitAction)

Example 17 with Branch

use of org.gitlab4j.api.models.Branch 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);
    }
}
Also used : ProjectFileAccessProvider(org.finos.legend.sdlc.server.project.ProjectFileAccessProvider) LegendSDLCServerException(org.finos.legend.sdlc.server.error.LegendSDLCServerException) GitLabProjectId(org.finos.legend.sdlc.server.gitlab.GitLabProjectId) Branch(org.gitlab4j.api.models.Branch) RepositoryApi(org.gitlab4j.api.RepositoryApi) LegendSDLCServerException(org.finos.legend.sdlc.server.error.LegendSDLCServerException)

Example 18 with Branch

use of org.gitlab4j.api.models.Branch 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);
    }
}
Also used : ProjectFileAccessProvider(org.finos.legend.sdlc.server.project.ProjectFileAccessProvider) LegendSDLCServerException(org.finos.legend.sdlc.server.error.LegendSDLCServerException) GitLabProjectId(org.finos.legend.sdlc.server.gitlab.GitLabProjectId) Branch(org.gitlab4j.api.models.Branch) RepositoryApi(org.gitlab4j.api.RepositoryApi) GitLabApiException(org.gitlab4j.api.GitLabApiException) LegendSDLCServerException(org.finos.legend.sdlc.server.error.LegendSDLCServerException) GitLabApiException(org.gitlab4j.api.GitLabApiException)

Aggregations

Branch (org.gitlab4j.api.models.Branch)18 LegendSDLCServerException (org.finos.legend.sdlc.server.error.LegendSDLCServerException)15 GitLabApiException (org.gitlab4j.api.GitLabApiException)15 GitLabProjectId (org.finos.legend.sdlc.server.gitlab.GitLabProjectId)14 RepositoryApi (org.gitlab4j.api.RepositoryApi)14 ProjectFileAccessProvider (org.finos.legend.sdlc.server.project.ProjectFileAccessProvider)12 CommitsApi (org.gitlab4j.api.CommitsApi)6 GitLabApi (org.gitlab4j.api.GitLabApi)6 Revision (org.finos.legend.sdlc.domain.model.revision.Revision)4 Commit (org.gitlab4j.api.models.Commit)4 CommitAction (org.gitlab4j.api.models.CommitAction)4 CommitRef (org.gitlab4j.api.models.CommitRef)4 CompareResults (org.gitlab4j.api.models.CompareResults)4 MergeRequest (org.gitlab4j.api.models.MergeRequest)4 MergeRequestApi (org.gitlab4j.api.MergeRequestApi)3 Diff (org.gitlab4j.api.models.Diff)3 Arrays (java.util.Arrays)2 List (java.util.List)2 Objects (java.util.Objects)2 Set (java.util.Set)2