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;
}
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;
}
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()))));
}
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);
}
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;
}
Aggregations