Search in sources :

Example 16 with GitLabApiException

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

the class GitLabWorkspaceApi method attemptToRebaseWorkspaceUsingTemporaryBranch.

/**
 * This method attempts to rebase the workspace branch on top of master by using a temp branch. Detailed procedure outlined below:
 * 1. Create a new merge request (MR) that merges temp branch into master branch so that we can use gitlab rebase functionality
 * 2. Call rebase.
 * 3. Continuously check the rebase status of the merge request:
 * - If failed -> return `false`
 * - If succeeded, proceed
 * 4. Re-create workspace branch on top of the rebased temp branch.
 * 5. Cleanup: remove the temp branch and the MR
 * 6. Return `true`
 *
 * @return a boolean flag indicating if the attempted rebase succeeded.
 */
private boolean attemptToRebaseWorkspaceUsingTemporaryBranch(String projectId, String workspaceId, WorkspaceType workspaceType, String tempBranchName, String masterRevisionId) {
    GitLabProjectId gitLabProjectId = parseProjectId(projectId);
    GitLabApi gitLabApi = getGitLabApi(gitLabProjectId.getGitLabMode());
    RepositoryApi repositoryApi = gitLabApi.getRepositoryApi();
    // Create merge request to rebase
    MergeRequestApi mergeRequestApi = getGitLabApi(gitLabProjectId.getGitLabMode()).getMergeRequestApi();
    String title = "Update workspace " + workspaceId;
    String message = "Update workspace " + workspaceId + " up to revision " + masterRevisionId;
    MergeRequest mergeRequest;
    try {
        mergeRequest = mergeRequestApi.createMergeRequest(gitLabProjectId.getGitLabId(), tempBranchName, MASTER_BRANCH, title, message, null, null, null, null, false, false);
    } catch (Exception e) {
        throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to create merge request in project " + projectId, () -> "Unknown branch in project " + projectId + ": " + tempBranchName, () -> "Error creating merge request in project " + projectId);
    }
    // Attempt to rebase the merge request
    try {
        mergeRequestApi.rebaseMergeRequest(gitLabProjectId.getGitLabId(), mergeRequest.getIid());
        // Check rebase status
        // This only throws when we have 403, so we need to keep polling till we know the result
        // See https://docs.gitlab.com/ee/api/merge_requests.html#rebase-a-merge-request
        CallUntil<MergeRequest, GitLabApiException> rebaseStatusCallUntil = CallUntil.callUntil(() -> withRetries(() -> mergeRequestApi.getRebaseStatus(gitLabProjectId.getGitLabId(), mergeRequest.getIid())), mr -> !mr.getRebaseInProgress(), 600, 1000L);
        if (!rebaseStatusCallUntil.succeeded()) {
            LOGGER.warn("Timeout waiting for merge request " + mergeRequest.getIid() + " in project " + projectId + " to finish rebasing");
            return false;
        }
        // Check if there is merge conflict
        if (rebaseStatusCallUntil.getResult().getMergeError() != null) {
            return false;
        } else // if there are no merge conflicts, proceed with the update
        {
            // Create backup branch
            Branch backupBranch;
            ProjectFileAccessProvider.WorkspaceAccessType backupWorkspaceAccessType = ProjectFileAccessProvider.WorkspaceAccessType.BACKUP;
            ProjectFileAccessProvider.WorkspaceAccessType workspaceAccessType = ProjectFileAccessProvider.WorkspaceAccessType.WORKSPACE;
            try {
                backupBranch = GitLabApiTools.createBranchFromSourceBranchAndVerify(repositoryApi, gitLabProjectId.getGitLabId(), getWorkspaceBranchName(workspaceId, workspaceType, backupWorkspaceAccessType), getWorkspaceBranchName(workspaceId, workspaceType, workspaceAccessType), 30, 1_000);
            } catch (Exception e) {
                throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to create " + workspaceType.getLabel() + " " + backupWorkspaceAccessType.getLabel() + " " + workspaceAccessType.getLabel() + " " + workspaceId + " in project " + projectId, () -> "Unknown project: " + projectId, () -> "Error creating " + workspaceType.getLabel() + " " + backupWorkspaceAccessType.getLabel() + " " + workspaceAccessType.getLabel() + " " + workspaceId + " in project " + projectId);
            }
            if (backupBranch == null) {
                throw new LegendSDLCServerException("Failed to create " + workspaceType.getLabel() + " " + backupWorkspaceAccessType.getLabel() + " " + workspaceAccessType.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, () -> "Error while attempting to update the workspace " + workspaceId + " in project " + projectId + ": user " + getCurrentUser() + " is not allowed to delete workspace", () -> "Error while attempting to update the workspace " + workspaceId + " in project " + projectId + ": unknown workspace or project", () -> "Error while attempting to update the workspace " + workspaceId + " in project " + projectId + ": error deleting workspace");
            }
            if (!originalBranchDeleted) {
                throw new LegendSDLCServerException("Failed to delete " + workspaceType.getLabel() + " " + workspaceAccessType.getLabel() + " " + workspaceId + " in project " + projectId);
            }
            // Create new workspace branch off the temp branch head
            Branch newWorkspaceBranch;
            try {
                newWorkspaceBranch = GitLabApiTools.createBranchFromSourceBranchAndVerify(repositoryApi, gitLabProjectId.getGitLabId(), getWorkspaceBranchName(workspaceId, workspaceType, workspaceAccessType), tempBranchName, 30, 1_000);
            } catch (Exception e) {
                throw buildException(e, () -> "Error while attempting to update the workspace " + workspaceId + " in project " + projectId + ": user " + getCurrentUser() + " is not allowed to create workspace", () -> "Error while attempting to update the workspace " + workspaceId + " in project " + projectId + ": unknown project: " + projectId, () -> "Error while attempting to update the workspace " + workspaceId + " in project " + projectId + ": error creating workspace");
            }
            if (newWorkspaceBranch == null) {
                throw new LegendSDLCServerException("Failed to create " + workspaceType.getLabel() + " " + workspaceAccessType.getLabel() + " " + workspaceId + " from temporary workspace " + tempBranchName + " in project " + projectId);
            }
            // Delete backup branch
            try {
                boolean deleted = GitLabApiTools.deleteBranchAndVerify(repositoryApi, gitLabProjectId.getGitLabId(), getWorkspaceBranchName(workspaceId, workspaceType, backupWorkspaceAccessType), 20, 1_000);
                if (!deleted) {
                    LOGGER.error("Failed to delete {} {} in project {}", workspaceType.getLabel() + " " + backupWorkspaceAccessType.getLabel() + " " + workspaceAccessType.getLabel(), workspaceId, projectId);
                }
            } catch (Exception e) {
                // unfortunate, but this should not throw error
                LOGGER.error("Error deleting {} {} in project {}", workspaceType.getLabel() + " " + backupWorkspaceAccessType.getLabel() + " " + workspaceAccessType.getLabel(), workspaceId, projectId);
            }
        }
    } catch (Exception e) {
        throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to rebase merge request " + mergeRequest.getIid() + " in project " + projectId, () -> "Unknown merge request ( " + mergeRequest.getIid() + " ) or project ( " + projectId + " )", () -> "Error rebasing merge request " + mergeRequest.getIid() + " in project " + projectId);
    } finally {
        // Try to close merge request
        try {
            mergeRequestApi.updateMergeRequest(gitLabProjectId.getGitLabId(), mergeRequest.getIid(), null, title, null, null, StateEvent.CLOSE, null, null, null, null, null, null);
        } catch (Exception closeEx) {
            // if we fail, log the error but we don't throw it
            LOGGER.error("Could not close merge request {} for project {}: {}", mergeRequest.getIid(), projectId, mergeRequest.getWebUrl(), closeEx);
        }
        // Delete temporary branch in the background
        submitBackgroundRetryableTask(() -> waitForPipelinesDeleteBranchAndVerify(gitLabApi, gitLabProjectId, tempBranchName), 5000L, "delete " + tempBranchName);
    }
    return true;
}
Also used : GitLabApi(org.gitlab4j.api.GitLabApi) GitLabApiException(org.gitlab4j.api.GitLabApiException) LegendSDLCServerException(org.finos.legend.sdlc.server.error.LegendSDLCServerException) GitLabApiException(org.gitlab4j.api.GitLabApiException) ProjectFileAccessProvider(org.finos.legend.sdlc.server.project.ProjectFileAccessProvider) LegendSDLCServerException(org.finos.legend.sdlc.server.error.LegendSDLCServerException) MergeRequest(org.gitlab4j.api.models.MergeRequest) GitLabProjectId(org.finos.legend.sdlc.server.gitlab.GitLabProjectId) Branch(org.gitlab4j.api.models.Branch) MergeRequestApi(org.gitlab4j.api.MergeRequestApi) RepositoryApi(org.gitlab4j.api.RepositoryApi)

Example 17 with GitLabApiException

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

the class GitLabApiTools method callWithRetries.

public static <T> T callWithRetries(ThrowingSupplier<T, ? extends GitLabApiException> apiCall, int maxRetries, long initialWaitIntervalMillis, LongUnaryOperator waitIntervalUpdater) throws GitLabApiException {
    if (maxRetries <= 0) {
        return apiCall.get();
    }
    List<GitLabApiException> exceptions;
    try {
        return apiCall.get();
    } catch (GitLabApiException e) {
        if (!isRetryableGitLabApiException(e)) {
            throw e;
        }
        noteRetryableException();
        exceptions = Lists.mutable.ofInitialCapacity(maxRetries + 1);
        exceptions.add(e);
        LOGGER.error(getRetryableExceptionLogMessage(e, 1), e);
    }
    long waitInterval = initialWaitIntervalMillis;
    for (int i = 0; i < maxRetries; i++) {
        // Wait
        if (waitInterval > 0) {
            LOGGER.debug("Waiting {} millis for attempt #{}", waitInterval, i + 2);
            try {
                Thread.sleep(waitInterval);
            } catch (InterruptedException e) {
                LOGGER.warn("Interrupted while waiting", e);
                Thread.currentThread().interrupt();
            }
        }
        // Try to execute API call
        try {
            return apiCall.get();
        } catch (GitLabApiException e) {
            if (!isRetryableGitLabApiException(e)) {
                addSuppressedExceptions(e, exceptions);
                throw e;
            }
            noteRetryableException();
            exceptions.add(e);
            LOGGER.error(getRetryableExceptionLogMessage(e, i + 2), e);
        } catch (Exception e) {
            addSuppressedExceptions(e, exceptions);
            throw e;
        }
        // Update wait interval
        if (waitIntervalUpdater != null) {
            try {
                waitInterval = waitIntervalUpdater.applyAsLong(waitInterval);
            } catch (Exception e) {
                // log exceptions trying to update the wait interval, but otherwise ignore them
                LOGGER.error("Exception while updating the wait interval (from {}  millis)", waitInterval, e);
            }
        }
    }
    GitLabApiException lastException = exceptions.get(exceptions.size() - 1);
    if (exceptions.size() > 1) {
        addSuppressedExceptions(lastException, exceptions.subList(0, exceptions.size() - 1));
    }
    throw lastException;
}
Also used : GitLabApiException(org.gitlab4j.api.GitLabApiException) GitLabApiException(org.gitlab4j.api.GitLabApiException)

Example 18 with GitLabApiException

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

the class TestGitLabApiTools method testFindGitLabApiException.

@Test
public void testFindGitLabApiException() {
    GitLabApiException innerException = new GitLabApiException("");
    GitLabApiException expected = new GitLabApiException(innerException);
    Assert.assertSame(innerException, GitLabApiTools.findGitLabApiException(innerException));
    Assert.assertSame(expected, GitLabApiTools.findGitLabApiException(expected));
    Assert.assertSame(expected, GitLabApiTools.findGitLabApiException(new RuntimeException(expected)));
    Assert.assertSame(expected, GitLabApiTools.findGitLabApiException(new RuntimeException(new Exception(expected))));
    Assert.assertNull(GitLabApiTools.findGitLabApiException(null));
    Assert.assertNull(GitLabApiTools.findGitLabApiException(new RuntimeException()));
    Assert.assertNull(GitLabApiTools.findGitLabApiException(new Exception(new RuntimeException(new Exception()))));
}
Also used : GitLabApiException(org.gitlab4j.api.GitLabApiException) GitLabApiException(org.gitlab4j.api.GitLabApiException) Test(org.junit.Test)

Example 19 with GitLabApiException

use of org.gitlab4j.api.GitLabApiException in project choerodon-starters by open-hand.

the class CommitAction method withFileContent.

public CommitAction withFileContent(File file, String filePath, Encoding encoding) throws GitLabApiException {
    this.encoding = (encoding != null ? encoding : Encoding.TEXT);
    this.filePath = filePath;
    try {
        content = FileUtils.getFileContentAsString(file, this.encoding);
    } catch (IOException e) {
        throw new GitLabApiException(e);
    }
    return (this);
}
Also used : GitLabApiException(org.gitlab4j.api.GitLabApiException) IOException(java.io.IOException)

Example 20 with GitLabApiException

use of org.gitlab4j.api.GitLabApiException in project catma by forTEXT.

the class GitlabManagerRestricted method getResourcePermissions.

private Map<String, AccessLevel> getResourcePermissions(Integer groupId) throws GitLabApiException {
    Map<String, AccessLevel> resultMap = Maps.newHashMap();
    ProjectApi projectApi = new ProjectApi(restrictedGitLabApi);
    logger.info("Loading project permissions");
    List<Project> resourceAndContainerProjects = projectApi.getProjects(new ProjectFilter().withMembership(true));
    logger.info(String.format("Filtering %1$d resources on group #%2$d", resourceAndContainerProjects.size(), groupId));
    Set<Project> filteredOnGroupProjects = resourceAndContainerProjects.stream().filter(p -> p.getNamespace().getId().equals(groupId)).collect(Collectors.toSet());
    logger.info(String.format("Updating accesslevel registry for %1$d resources", filteredOnGroupProjects.size()));
    for (Project p : filteredOnGroupProjects) {
        Permissions permission = p.getPermissions();
        if (permission.getGroupAccess() != null) {
            resultMap.put(p.getName(), permission.getGroupAccess().getAccessLevel());
        }
        if (permission.getProjectAccess() != null && (!resultMap.containsKey(p.getName()) || resultMap.get(p.getName()).value.intValue() < permission.getProjectAccess().getAccessLevel().value.intValue())) {
            resultMap.put(p.getName(), permission.getProjectAccess().getAccessLevel());
        }
    }
    return resultMap;
}
Also used : NotesApi(org.gitlab4j.api.NotesApi) JsonObject(com.google.gson.JsonObject) Reply(de.catma.document.comment.Reply) AccessLevel(org.gitlab4j.api.models.AccessLevel) ProjectFilter(org.gitlab4j.api.models.ProjectFilter) StringUtils(org.apache.commons.lang3.StringUtils) Author(org.gitlab4j.api.models.Author) IssuesApi(org.gitlab4j.api.IssuesApi) ChangeUserAttributeEvent(de.catma.ui.events.ChangeUserAttributeEvent) Map(java.util.Map) Group(org.gitlab4j.api.models.Group) IssueState(org.gitlab4j.api.Constants.IssueState) GroupApi(org.gitlab4j.api.GroupApi) Visibility(org.gitlab4j.api.models.Visibility) CATMAPropertyKey(de.catma.properties.CATMAPropertyKey) IGitUserInformation(de.catma.repository.git.interfaces.IGitUserInformation) GitMember(de.catma.repository.git.GitMember) Pager(org.gitlab4j.api.Pager) GitlabUtils(de.catma.repository.git.GitlabUtils) Set(java.util.Set) Logger(java.util.logging.Logger) SerializationHelper(de.catma.repository.git.serialization.SerializationHelper) Collectors(java.util.stream.Collectors) ProjectReference(de.catma.project.ProjectReference) Objects(java.util.Objects) List(java.util.List) ProjectApi(org.gitlab4j.api.ProjectApi) Optional(java.util.Optional) GitLabApiException(org.gitlab4j.api.GitLabApiException) Status(org.gitlab4j.api.models.ImportStatus.Status) CacheBuilder(com.google.common.cache.CacheBuilder) GitLabApi(org.gitlab4j.api.GitLabApi) RBACPermission(de.catma.rbac.RBACPermission) Permissions(org.gitlab4j.api.models.Permissions) GroupFilter(org.gitlab4j.api.models.GroupFilter) Namespace(org.gitlab4j.api.models.Namespace) HashMap(java.util.HashMap) RBACRole(de.catma.rbac.RBACRole) JsonParser(com.google.gson.JsonParser) User(de.catma.user.User) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) EventBus(com.google.common.eventbus.EventBus) IRemoteGitManagerRestricted(de.catma.repository.git.interfaces.IRemoteGitManagerRestricted) Comment(de.catma.document.comment.Comment) ForkStatus(de.catma.project.ForkStatus) GitProjectManager(de.catma.repository.git.GitProjectManager) Note(org.gitlab4j.api.models.Note) IDGenerator(de.catma.util.IDGenerator) Subscribe(com.google.common.eventbus.Subscribe) CreateRepositoryResponse(de.catma.repository.git.CreateRepositoryResponse) Issue(org.gitlab4j.api.models.Issue) IOException(java.io.IOException) Project(org.gitlab4j.api.models.Project) Maps(com.google.common.collect.Maps) IssueFilter(org.gitlab4j.api.models.IssueFilter) TimeUnit(java.util.concurrent.TimeUnit) Member(org.gitlab4j.api.models.Member) Cache(com.google.common.cache.Cache) Collections(java.util.Collections) BackgroundService(de.catma.backgroundservice.BackgroundService) GitUser(de.catma.repository.git.GitUser) Project(org.gitlab4j.api.models.Project) ProjectFilter(org.gitlab4j.api.models.ProjectFilter) ProjectApi(org.gitlab4j.api.ProjectApi) Permissions(org.gitlab4j.api.models.Permissions) AccessLevel(org.gitlab4j.api.models.AccessLevel)

Aggregations

GitLabApiException (org.gitlab4j.api.GitLabApiException)77 IOException (java.io.IOException)35 GitLabApi (org.gitlab4j.api.GitLabApi)18 Project (org.gitlab4j.api.models.Project)18 Group (org.gitlab4j.api.models.Group)14 List (java.util.List)12 GitLabProjectId (org.finos.legend.sdlc.server.gitlab.GitLabProjectId)9 MergeRequest (org.gitlab4j.api.models.MergeRequest)9 GitMember (de.catma.repository.git.GitMember)8 ArrayList (java.util.ArrayList)8 LegendSDLCServerException (org.finos.legend.sdlc.server.error.LegendSDLCServerException)8 MergeRequestApi (org.gitlab4j.api.MergeRequestApi)8 UserApi (org.gitlab4j.api.UserApi)8 ProvisioningException (com.tremolosecurity.provisioning.core.ProvisioningException)7 Workflow (com.tremolosecurity.provisioning.core.Workflow)7 GroupApi (org.gitlab4j.api.GroupApi)7 IssuesApi (org.gitlab4j.api.IssuesApi)7 AccessLevel (org.gitlab4j.api.models.AccessLevel)7 Issue (org.gitlab4j.api.models.Issue)7 Comment (de.catma.document.comment.Comment)6