Search in sources :

Example 21 with MergeRequest

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

the class GitLabReviewApi method commitReview.

@Override
public Review commitReview(String projectId, String reviewId, String message) {
    LegendSDLCServerException.validateNonNull(projectId, "projectId may not be null");
    LegendSDLCServerException.validateNonNull(reviewId, "reviewId may not be null");
    LegendSDLCServerException.validateNonNull(message, "message may not be null");
    GitLabProjectId gitLabProjectId = parseProjectId(projectId);
    MergeRequestApi mergeRequestApi = getGitLabApi(gitLabProjectId.getGitLabMode()).getMergeRequestApi();
    // Find the merge request
    MergeRequest mergeRequest = getReviewMergeRequest(mergeRequestApi, gitLabProjectId, reviewId);
    // Validate that the merge request is ready to be merged
    // Check that the state is open
    validateMergeRequestReviewState(mergeRequest, ReviewState.OPEN);
    // Check that there are no approvals still required
    Integer approvalsLeft = mergeRequest.getApprovalsLeft();
    if ((approvalsLeft != null) && (approvalsLeft > 0)) {
        throw new LegendSDLCServerException("Review " + reviewId + " in project " + projectId + " still requires " + approvalsLeft + " approvals", Status.CONFLICT);
    }
    // Accept
    try {
        return fromGitLabMergeRequest(projectId, mergeRequestApi.acceptMergeRequest(gitLabProjectId.getGitLabId(), mergeRequest.getIid(), message, true, null, null));
    } catch (GitLabApiException e) {
        switch(e.getHttpStatus()) {
            // Status 401 (Unauthorized) can indicate either that the user is not properly authenticated or that the user is not allowed to merge the request.
            case 401:
            case 403:
                {
                    // This shouldn't happen, but just in case ...
                    throw new LegendSDLCServerException("User " + getCurrentUser() + " is not allowed to commit changes from review " + reviewId + " in project " + projectId, Status.FORBIDDEN, e);
                }
            case 404:
                {
                    // This shouldn't happen, as we already verified the review exists
                    throw new LegendSDLCServerException("Unknown review in project " + projectId + ": " + reviewId, Status.NOT_FOUND, e);
                }
            case 405:
                {
                    // Status 405 (Method Not Allowed) indicates the merge request could not be accepted because it's not in an appropriate state (i.e., work in progress, closed, pipeline pending completion, or failed while requiring success)
                    throw new LegendSDLCServerException("Review " + reviewId + " in project " + projectId + " is not in a committable state; for more details, see: " + mergeRequest.getWebUrl(), Status.CONFLICT, e);
                }
            case 406:
                {
                    // Status 406 (Not Acceptable) indicates the merge could not occur because of a conflict
                    throw new LegendSDLCServerException("Could not commit review " + reviewId + " in project " + projectId + " because of a conflict; for more details, see: " + mergeRequest.getWebUrl(), Status.CONFLICT, e);
                }
            default:
                {
                    StringBuilder builder = new StringBuilder("Error committing changes from review ").append(reviewId).append(" to project ").append(projectId);
                    StringTools.appendThrowableMessageIfPresent(builder, e);
                    LOGGER.warn("Unexpected response status committing changes from review {} to project {}; status {}; message: {}", reviewId, projectId, e.getHttpStatus(), e.getMessage());
                    throw new LegendSDLCServerException(builder.toString(), e);
                }
        }
    } catch (LegendSDLCServerException e) {
        throw e;
    } catch (Exception e) {
        StringBuilder builder = new StringBuilder("Error committing changes from review ").append(reviewId).append(" to project ").append(projectId);
        StringTools.appendThrowableMessageIfPresent(builder, e);
        throw new LegendSDLCServerException(builder.toString(), e);
    }
}
Also used : LegendSDLCServerException(org.finos.legend.sdlc.server.error.LegendSDLCServerException) MergeRequest(org.gitlab4j.api.models.MergeRequest) GitLabProjectId(org.finos.legend.sdlc.server.gitlab.GitLabProjectId) MergeRequestApi(org.gitlab4j.api.MergeRequestApi) GitLabApiException(org.gitlab4j.api.GitLabApiException) LegendSDLCServerException(org.finos.legend.sdlc.server.error.LegendSDLCServerException) GitLabApiException(org.gitlab4j.api.GitLabApiException)

Example 22 with MergeRequest

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

the class GitLabReviewApi method reopenReview.

@Override
public Review reopenReview(String projectId, String reviewId) {
    LegendSDLCServerException.validateNonNull(projectId, "projectId may not be null");
    LegendSDLCServerException.validateNonNull(reviewId, "reviewId may not be null");
    GitLabProjectId gitLabProjectId = parseProjectId(projectId);
    MergeRequestApi mergeRequestApi = getGitLabApi(gitLabProjectId.getGitLabMode()).getMergeRequestApi();
    MergeRequest mergeRequest = getReviewMergeRequest(mergeRequestApi, gitLabProjectId, reviewId);
    validateMergeRequestReviewState(mergeRequest, ReviewState.CLOSED);
    try {
        MergeRequest reopenMergeRequest = updateMergeRequestState(mergeRequestApi, gitLabProjectId, mergeRequest, StateEvent.REOPEN);
        return fromGitLabMergeRequest(projectId, reopenMergeRequest);
    } catch (Exception e) {
        throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to reopen review " + reviewId + " in project " + projectId, () -> "Unknown review in project " + projectId + ": " + reviewId, () -> "Error reopening review " + reviewId + " in project " + projectId);
    }
}
Also used : MergeRequest(org.gitlab4j.api.models.MergeRequest) GitLabProjectId(org.finos.legend.sdlc.server.gitlab.GitLabProjectId) MergeRequestApi(org.gitlab4j.api.MergeRequestApi) LegendSDLCServerException(org.finos.legend.sdlc.server.error.LegendSDLCServerException) GitLabApiException(org.gitlab4j.api.GitLabApiException)

Example 23 with MergeRequest

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

the class GitLabReviewApi method revokeReviewApproval.

@Override
public Review revokeReviewApproval(String projectId, String reviewId) {
    LegendSDLCServerException.validateNonNull(projectId, "projectId may not be null");
    LegendSDLCServerException.validateNonNull(reviewId, "reviewId may not be null");
    GitLabProjectId gitLabProjectId = parseProjectId(projectId);
    MergeRequestApi mergeRequestApi = getGitLabApi(gitLabProjectId.getGitLabMode()).getMergeRequestApi();
    MergeRequest mergeRequest = getReviewMergeRequest(mergeRequestApi, gitLabProjectId, reviewId);
    try {
        MergeRequest revokeApprovalMergeRequest = mergeRequestApi.unapproveMergeRequest(gitLabProjectId.getGitLabId(), mergeRequest.getIid());
        // The MergeRequest that comes back from the unapproveMergeRequest call is not adequate
        // for creating a Review, as most relevant properties are null. The only useful thing we
        // get from it is the last update time.
        mergeRequest.setUpdatedAt(revokeApprovalMergeRequest.getUpdatedAt());
        return fromGitLabMergeRequest(projectId, mergeRequest);
    } catch (Exception e) {
        throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to revoke approval of review " + reviewId + " in project " + projectId, () -> "Unknown review in project " + projectId + ": " + reviewId, () -> "Error revoking review approval " + reviewId + " in project " + projectId);
    }
}
Also used : MergeRequest(org.gitlab4j.api.models.MergeRequest) GitLabProjectId(org.finos.legend.sdlc.server.gitlab.GitLabProjectId) MergeRequestApi(org.gitlab4j.api.MergeRequestApi) LegendSDLCServerException(org.finos.legend.sdlc.server.error.LegendSDLCServerException) GitLabApiException(org.gitlab4j.api.GitLabApiException)

Example 24 with MergeRequest

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

the class GitLabReviewApi method getReview.

@Override
public Review getReview(String projectId, String reviewId) {
    LegendSDLCServerException.validateNonNull(projectId, "projectId may not be null");
    LegendSDLCServerException.validateNonNull(reviewId, "reviewId may not be null");
    try {
        GitLabProjectId gitLabProjectId = parseProjectId(projectId);
        MergeRequest mergeRequest = getReviewMergeRequest(getGitLabApi(gitLabProjectId.getGitLabMode()).getMergeRequestApi(), gitLabProjectId, reviewId);
        return fromGitLabMergeRequest(projectId, mergeRequest);
    } catch (Exception e) {
        throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to get review " + reviewId + " for project " + projectId, () -> "Unknown review (" + reviewId + ") or project (" + projectId + ")", () -> "Error getting review " + reviewId + " for project " + projectId);
    }
}
Also used : MergeRequest(org.gitlab4j.api.models.MergeRequest) GitLabProjectId(org.finos.legend.sdlc.server.gitlab.GitLabProjectId) LegendSDLCServerException(org.finos.legend.sdlc.server.error.LegendSDLCServerException) GitLabApiException(org.gitlab4j.api.GitLabApiException)

Example 25 with MergeRequest

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

the class GitLabReviewApi method getReviews.

@Override
public List<Review> getReviews(String projectId, ReviewState state, Iterable<String> revisionIds, Instant since, Instant until, Integer limit) {
    LegendSDLCServerException.validateNonNull(projectId, "projectId may not be null");
    Set<String> revisionIdSet;
    if (revisionIds == null) {
        revisionIdSet = Collections.emptySet();
    } else if (revisionIds instanceof Set) {
        revisionIdSet = (Set<String>) revisionIds;
    } else {
        revisionIdSet = Sets.mutable.withAll(revisionIds);
    }
    Stream<MergeRequest> mergeRequestStream;
    try {
        GitLabProjectId gitLabProjectId = parseProjectId(projectId);
        if (!revisionIdSet.isEmpty()) {
            // TODO: we might want to do this differently since the number of revision IDs can be huge
            // we can have a threshold for which we change our strategy to  to make a single call for
            // merge requests by the other criteria and then filter by revisionIds.
            MutableIntSet mergeRequestIds = IntSets.mutable.empty();
            CommitsApi commitsApi = getGitLabApi(gitLabProjectId.getGitLabMode()).getCommitsApi();
            // Combine all MRs associated with each revision
            mergeRequestStream = revisionIdSet.stream().flatMap(revisionId -> {
                try {
                    return PagerTools.stream(withRetries(() -> commitsApi.getMergeRequests(gitLabProjectId.getGitLabId(), revisionId, ITEMS_PER_PAGE)));
                } catch (Exception e) {
                    throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to get reviews associated with revision " + revisionId + " for project " + projectId, () -> "Unknown revision (" + revisionId + ") or project (" + projectId + ")", () -> "Error getting reviews associated with revision " + revisionId + " for project " + projectId);
                }
            }).filter(// remove duplicates
            mr -> (mr.getIid() != null) && mergeRequestIds.add(mr.getIid()));
            MergeRequestState mergeRequestState = getMergeRequestState(state);
            if (mergeRequestState != MergeRequestState.ALL) {
                String mergeRequestStateString = mergeRequestState.toString();
                mergeRequestStream = mergeRequestStream.filter(mr -> mergeRequestStateString.equalsIgnoreCase(mr.getState()));
            }
        } else {
            // if no revision ID is specified we will use the default merge request API from Gitlab to take advantage of the filter
            MergeRequestFilter mergeRequestFilter = withMergeRequestFilters(new MergeRequestFilter(), state, since, until).withProjectId(gitLabProjectId.getGitLabId());
            mergeRequestStream = PagerTools.stream(withRetries(() -> getGitLabApi(gitLabProjectId.getGitLabMode()).getMergeRequestApi().getMergeRequests(mergeRequestFilter, ITEMS_PER_PAGE)));
        }
        Stream<Review> stream = mergeRequestStream.filter(BaseGitLabApi::isReviewMergeRequest).map(mr -> fromGitLabMergeRequest(projectId, mr));
        return addReviewFilters(stream, state, since, until, limit).collect(Collectors.toList());
    } catch (Exception e) {
        throw buildException(e, () -> "User " + getCurrentUser() + " is not allowed to get reviews for project " + projectId + ((state == null) ? "" : (" with state " + state)), () -> "Unknown project (" + projectId + ")", () -> "Error getting reviews for project " + projectId + ((state == null) ? "" : (" with state " + state)));
    }
}
Also used : ProjectType(org.finos.legend.sdlc.domain.model.project.ProjectType) CommitsApi(org.gitlab4j.api.CommitsApi) Arrays(java.util.Arrays) Branch(org.gitlab4j.api.models.Branch) MergeRequestScope(org.gitlab4j.api.Constants.MergeRequestScope) Date(java.util.Date) AbstractUser(org.gitlab4j.api.models.AbstractUser) LoggerFactory(org.slf4j.LoggerFactory) GitLabUserContext(org.finos.legend.sdlc.server.gitlab.auth.GitLabUserContext) StateEvent(org.gitlab4j.api.Constants.StateEvent) ReviewApi(org.finos.legend.sdlc.server.domain.api.review.ReviewApi) IntSets(org.eclipse.collections.impl.factory.primitive.IntSets) StringTools(org.finos.legend.sdlc.server.tools.StringTools) MergeRequestState(org.gitlab4j.api.Constants.MergeRequestState) Function(java.util.function.Function) Inject(javax.inject.Inject) ReviewState(org.finos.legend.sdlc.domain.model.review.ReviewState) MutableIntSet(org.eclipse.collections.api.set.primitive.MutableIntSet) MergeRequestParams(org.gitlab4j.api.models.MergeRequestParams) Review(org.finos.legend.sdlc.domain.model.review.Review) LegendSDLCServerException(org.finos.legend.sdlc.server.error.LegendSDLCServerException) MergeRequest(org.gitlab4j.api.models.MergeRequest) PagerTools(org.finos.legend.sdlc.server.gitlab.tools.PagerTools) DiffRef(org.gitlab4j.api.models.DiffRef) Status(javax.ws.rs.core.Response.Status) Commit(org.gitlab4j.api.models.Commit) EnumSet(java.util.EnumSet) Sets(org.eclipse.collections.api.factory.Sets) MergeRequestApi(org.gitlab4j.api.MergeRequestApi) RepositoryApi(org.gitlab4j.api.RepositoryApi) Logger(org.slf4j.Logger) GitLabMode(org.finos.legend.sdlc.server.gitlab.mode.GitLabMode) ProjectFileAccessProvider(org.finos.legend.sdlc.server.project.ProjectFileAccessProvider) Predicate(java.util.function.Predicate) Set(java.util.Set) MergeRequestFilter(org.gitlab4j.api.models.MergeRequestFilter) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) WorkspaceType(org.finos.legend.sdlc.domain.model.project.workspace.WorkspaceType) GitLabProjectId(org.finos.legend.sdlc.server.gitlab.GitLabProjectId) CallUntil(org.finos.legend.sdlc.server.tools.CallUntil) List(java.util.List) Stream(java.util.stream.Stream) User(org.finos.legend.sdlc.domain.model.user.User) GitLabApiException(org.gitlab4j.api.GitLabApiException) Collections(java.util.Collections) GitLabApi(org.gitlab4j.api.GitLabApi) MutableIntSet(org.eclipse.collections.api.set.primitive.MutableIntSet) EnumSet(java.util.EnumSet) Set(java.util.Set) Review(org.finos.legend.sdlc.domain.model.review.Review) MergeRequestState(org.gitlab4j.api.Constants.MergeRequestState) CommitsApi(org.gitlab4j.api.CommitsApi) LegendSDLCServerException(org.finos.legend.sdlc.server.error.LegendSDLCServerException) GitLabApiException(org.gitlab4j.api.GitLabApiException) MutableIntSet(org.eclipse.collections.api.set.primitive.MutableIntSet) MergeRequest(org.gitlab4j.api.models.MergeRequest) MergeRequestFilter(org.gitlab4j.api.models.MergeRequestFilter) GitLabProjectId(org.finos.legend.sdlc.server.gitlab.GitLabProjectId)

Aggregations

MergeRequest (org.gitlab4j.api.models.MergeRequest)32 GitLabProjectId (org.finos.legend.sdlc.server.gitlab.GitLabProjectId)25 LegendSDLCServerException (org.finos.legend.sdlc.server.error.LegendSDLCServerException)22 GitLabApiException (org.gitlab4j.api.GitLabApiException)17 MergeRequestApi (org.gitlab4j.api.MergeRequestApi)15 RepositoryApi (org.gitlab4j.api.RepositoryApi)9 ProjectFileAccessProvider (org.finos.legend.sdlc.server.project.ProjectFileAccessProvider)7 DiffRef (org.gitlab4j.api.models.DiffRef)7 Response (javax.ws.rs.core.Response)6 GitLabApi (org.gitlab4j.api.GitLabApi)6 List (java.util.List)5 Form (javax.ws.rs.core.Form)5 Project (org.finos.legend.sdlc.domain.model.project.Project)5 ProjectType (org.finos.legend.sdlc.domain.model.project.ProjectType)5 Review (org.finos.legend.sdlc.domain.model.review.Review)5 Entity (org.finos.legend.sdlc.domain.model.entity.Entity)4 Workspace (org.finos.legend.sdlc.domain.model.project.workspace.Workspace)4 ProjectStructure (org.finos.legend.sdlc.server.project.ProjectStructure)2 Branch (org.gitlab4j.api.models.Branch)2 MergeRequestParams (org.gitlab4j.api.models.MergeRequestParams)2