Search in sources :

Example 1 with SC_BAD_REQUEST

use of javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST in project gerrit by GerritCodeReview.

the class PostReview method apply.

public Response<ReviewResult> apply(BatchUpdate.Factory updateFactory, RevisionResource revision, ReviewInput input, Timestamp ts) throws RestApiException, UpdateException, OrmException, IOException, PermissionBackendException {
    // Respect timestamp, but truncate at change created-on time.
    ts = Ordering.natural().max(ts, revision.getChange().getCreatedOn());
    if (revision.getEdit().isPresent()) {
        throw new ResourceConflictException("cannot post review on edit");
    }
    if (input.onBehalfOf != null) {
        revision = onBehalfOf(revision, input);
    } else if (input.drafts == null) {
        input.drafts = DraftHandling.DELETE;
    }
    if (input.labels != null) {
        checkLabels(revision, input.strictLabels, input.labels);
    }
    if (input.comments != null) {
        cleanUpComments(input.comments);
        checkComments(revision, input.comments);
    }
    if (input.robotComments != null) {
        if (!migration.readChanges()) {
            throw new MethodNotAllowedException("robot comments not supported");
        }
        checkRobotComments(revision, input.robotComments);
    }
    if (input.notify == null) {
        log.warn("notify = null; assuming notify = NONE");
        input.notify = NotifyHandling.NONE;
    }
    ListMultimap<RecipientType, Account.Id> accountsToNotify = notifyUtil.resolveAccounts(input.notifyDetails);
    Map<String, AddReviewerResult> reviewerJsonResults = null;
    List<PostReviewers.Addition> reviewerResults = Lists.newArrayList();
    boolean hasError = false;
    boolean confirm = false;
    if (input.reviewers != null) {
        reviewerJsonResults = Maps.newHashMap();
        for (AddReviewerInput reviewerInput : input.reviewers) {
            // Prevent notifications because setting reviewers is batched.
            reviewerInput.notify = NotifyHandling.NONE;
            PostReviewers.Addition result = postReviewers.prepareApplication(revision.getChangeResource(), reviewerInput, true);
            reviewerJsonResults.put(reviewerInput.reviewer, result.result);
            if (result.result.error != null) {
                hasError = true;
                continue;
            }
            if (result.result.confirm != null) {
                confirm = true;
                continue;
            }
            reviewerResults.add(result);
        }
    }
    ReviewResult output = new ReviewResult();
    output.reviewers = reviewerJsonResults;
    if (hasError || confirm) {
        return Response.withStatusCode(SC_BAD_REQUEST, output);
    }
    output.labels = input.labels;
    try (BatchUpdate bu = updateFactory.create(db.get(), revision.getChange().getProject(), revision.getUser(), ts)) {
        Account.Id id = revision.getUser().getAccountId();
        boolean ccOrReviewer = false;
        if (input.labels != null && !input.labels.isEmpty()) {
            ccOrReviewer = input.labels.values().stream().filter(v -> v != 0).findFirst().isPresent();
        }
        if (!ccOrReviewer) {
            // Check if user was already CCed or reviewing prior to this review.
            ReviewerSet currentReviewers = approvalsUtil.getReviewers(db.get(), revision.getChangeResource().getNotes());
            ccOrReviewer = currentReviewers.all().contains(id);
        }
        // themselves as a reviewer or to the CC list.
        for (PostReviewers.Addition reviewerResult : reviewerResults) {
            bu.addOp(revision.getChange().getId(), reviewerResult.op);
            if (!ccOrReviewer && reviewerResult.result.reviewers != null) {
                for (ReviewerInfo reviewerInfo : reviewerResult.result.reviewers) {
                    if (Objects.equals(id.get(), reviewerInfo._accountId)) {
                        ccOrReviewer = true;
                        break;
                    }
                }
            }
            if (!ccOrReviewer && reviewerResult.result.ccs != null) {
                for (AccountInfo accountInfo : reviewerResult.result.ccs) {
                    if (Objects.equals(id.get(), accountInfo._accountId)) {
                        ccOrReviewer = true;
                        break;
                    }
                }
            }
        }
        if (!ccOrReviewer) {
            // User posting this review isn't currently in the reviewer or CC list,
            // isn't being explicitly added, and isn't voting on any label.
            // Automatically CC them on this change so they receive replies.
            PostReviewers.Addition selfAddition = postReviewers.ccCurrentUser(revision.getUser(), revision);
            bu.addOp(revision.getChange().getId(), selfAddition.op);
        }
        bu.addOp(revision.getChange().getId(), new Op(revision.getPatchSet().getId(), input, accountsToNotify));
        bu.execute();
        for (PostReviewers.Addition reviewerResult : reviewerResults) {
            reviewerResult.gatherResults();
        }
        emailReviewers(revision.getChange(), reviewerResults, input.notify, accountsToNotify);
    }
    return Response.ok(output);
}
Also used : ON_BEHALF_OF(com.google.gerrit.server.permissions.LabelPermission.ForUser.ON_BEHALF_OF) ListMultimap(com.google.common.collect.ListMultimap) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) PermissionBackend(com.google.gerrit.server.permissions.PermissionBackend) ReviewResult(com.google.gerrit.extensions.api.changes.ReviewResult) PatchSetApproval(com.google.gerrit.reviewdb.client.PatchSetApproval) ReviewerSet(com.google.gerrit.server.ReviewerSet) Config(org.eclipse.jgit.lib.Config) Map(java.util.Map) RetryHelper(com.google.gerrit.server.update.RetryHelper) DraftHandling(com.google.gerrit.extensions.api.changes.ReviewInput.DraftHandling) Side(com.google.gerrit.extensions.client.Side) GerritServerConfig(com.google.gerrit.server.config.GerritServerConfig) ChangeMessage(com.google.gerrit.reviewdb.client.ChangeMessage) Set(java.util.Set) Collectors.joining(java.util.stream.Collectors.joining) StandardCharsets(java.nio.charset.StandardCharsets) NotifyHandling(com.google.gerrit.extensions.api.changes.NotifyHandling) CommentAdded(com.google.gerrit.server.extensions.events.CommentAdded) AutoValue(com.google.auto.value.AutoValue) LabelId(com.google.gerrit.reviewdb.client.LabelId) NotesMigration(com.google.gerrit.server.notedb.NotesMigration) ChangeMessagesUtil(com.google.gerrit.server.ChangeMessagesUtil) Singleton(com.google.inject.Singleton) ReviewDb(com.google.gerrit.reviewdb.server.ReviewDb) PermissionBackendException(com.google.gerrit.server.permissions.PermissionBackendException) Change(com.google.gerrit.reviewdb.client.Change) UnprocessableEntityException(com.google.gerrit.extensions.restapi.UnprocessableEntityException) Collectors.groupingBy(java.util.stream.Collectors.groupingBy) CommentsUtil(com.google.gerrit.server.CommentsUtil) Response(com.google.gerrit.extensions.restapi.Response) ArrayList(java.util.ArrayList) Strings(com.google.common.base.Strings) Lists(com.google.common.collect.Lists) RestApiException(com.google.gerrit.extensions.restapi.RestApiException) REVIEWER(com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER) HashCode(com.google.common.hash.HashCode) PatchListCache(com.google.gerrit.server.patch.PatchListCache) TimeUtil(com.google.gerrit.common.TimeUtil) MoreObjects(com.google.common.base.MoreObjects) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) IOException(java.io.IOException) CommentsUtil.setCommentRevId(com.google.gerrit.server.CommentsUtil.setCommentRevId) RobotCommentInput(com.google.gerrit.extensions.api.changes.ReviewInput.RobotCommentInput) ChangeUpdate(com.google.gerrit.server.notedb.ChangeUpdate) IdentifiedUser(com.google.gerrit.server.IdentifiedUser) ReviewInput(com.google.gerrit.extensions.api.changes.ReviewInput) PatchSet(com.google.gerrit.reviewdb.client.PatchSet) LabelVote(com.google.gerrit.server.util.LabelVote) SC_BAD_REQUEST(javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST) ChangeControl(com.google.gerrit.server.project.ChangeControl) AddReviewerResult(com.google.gerrit.extensions.api.changes.AddReviewerResult) OrmException(com.google.gwtorm.server.OrmException) Inject(com.google.inject.Inject) LoggerFactory(org.slf4j.LoggerFactory) UpdateException(com.google.gerrit.server.update.UpdateException) Comment(com.google.gerrit.reviewdb.client.Comment) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) AccountInfo(com.google.gerrit.extensions.common.AccountInfo) Gson(com.google.gson.Gson) AuthException(com.google.gerrit.extensions.restapi.AuthException) Context(com.google.gerrit.server.update.Context) RetryingRestModifyView(com.google.gerrit.server.update.RetryingRestModifyView) Collectors.toSet(java.util.stream.Collectors.toSet) ReviewerInfo(com.google.gerrit.extensions.api.changes.ReviewerInfo) Timestamp(java.sql.Timestamp) Collection(java.util.Collection) LabelType(com.google.gerrit.common.data.LabelType) MethodNotAllowedException(com.google.gerrit.extensions.restapi.MethodNotAllowedException) Preconditions.checkState(com.google.common.base.Preconditions.checkState) Objects(java.util.Objects) ChangeData(com.google.gerrit.server.query.change.ChangeData) List(java.util.List) Nullable(com.google.gerrit.common.Nullable) Status(com.google.gerrit.reviewdb.client.PatchLineComment.Status) AccountsCollection(com.google.gerrit.server.account.AccountsCollection) LabelTypes(com.google.gerrit.common.data.LabelTypes) AddReviewerInput(com.google.gerrit.extensions.api.changes.AddReviewerInput) FixSuggestionInfo(com.google.gerrit.extensions.common.FixSuggestionInfo) Url(com.google.gerrit.extensions.restapi.Url) BatchUpdateOp(com.google.gerrit.server.update.BatchUpdateOp) RobotComment(com.google.gerrit.reviewdb.client.RobotComment) LabelPermission(com.google.gerrit.server.permissions.LabelPermission) FixSuggestion(com.google.gerrit.reviewdb.client.FixSuggestion) ChangePermission(com.google.gerrit.server.permissions.ChangePermission) Hashing(com.google.common.hash.Hashing) ReviewerState(com.google.gerrit.extensions.client.ReviewerState) Patch(com.google.gerrit.reviewdb.client.Patch) HashMap(java.util.HashMap) OptionalInt(java.util.OptionalInt) HashSet(java.util.HashSet) CommentInput(com.google.gerrit.extensions.api.changes.ReviewInput.CommentInput) Range(com.google.gerrit.extensions.client.Comment.Range) Account(com.google.gerrit.reviewdb.client.Account) ChangeUtil(com.google.gerrit.server.ChangeUtil) OutputFormat(com.google.gerrit.server.OutputFormat) ChangeContext(com.google.gerrit.server.update.ChangeContext) FixReplacementInfo(com.google.gerrit.extensions.common.FixReplacementInfo) CurrentUser(com.google.gerrit.server.CurrentUser) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) UTF_8(java.nio.charset.StandardCharsets.UTF_8) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) FixReplacement(com.google.gerrit.reviewdb.client.FixReplacement) Maps(com.google.common.collect.Maps) ApprovalsUtil(com.google.gerrit.server.ApprovalsUtil) Collectors.toList(java.util.stream.Collectors.toList) Address(com.google.gerrit.server.mail.Address) Provider(com.google.inject.Provider) Ordering(com.google.common.collect.Ordering) RecipientType(com.google.gerrit.extensions.api.changes.RecipientType) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) PatchSetUtil(com.google.gerrit.server.PatchSetUtil) Collections(java.util.Collections) Account(com.google.gerrit.reviewdb.client.Account) BatchUpdateOp(com.google.gerrit.server.update.BatchUpdateOp) MethodNotAllowedException(com.google.gerrit.extensions.restapi.MethodNotAllowedException) ReviewResult(com.google.gerrit.extensions.api.changes.ReviewResult) RecipientType(com.google.gerrit.extensions.api.changes.RecipientType) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) AddReviewerResult(com.google.gerrit.extensions.api.changes.AddReviewerResult) ReviewerSet(com.google.gerrit.server.ReviewerSet) LabelId(com.google.gerrit.reviewdb.client.LabelId) CommentsUtil.setCommentRevId(com.google.gerrit.server.CommentsUtil.setCommentRevId) AccountInfo(com.google.gerrit.extensions.common.AccountInfo) AddReviewerInput(com.google.gerrit.extensions.api.changes.AddReviewerInput) ReviewerInfo(com.google.gerrit.extensions.api.changes.ReviewerInfo)

Example 2 with SC_BAD_REQUEST

use of javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST in project cruise-control by linkedin.

the class KafkaCruiseControlServlet method getPartitionLoad.

private boolean getPartitionLoad(HttpServletRequest request, HttpServletResponse response) throws Exception {
    Resource resource;
    Long startMs;
    Long endMs;
    boolean json = wantJSON(request);
    try {
        String resourceString = request.getParameter(RESOURCE_PARAM);
        try {
            if (resourceString == null) {
                resourceString = DEFAULT_PARTITION_LOAD_RESOURCE;
            }
            resource = Resource.valueOf(resourceString.toUpperCase());
        } catch (IllegalArgumentException iae) {
            String errorMsg = String.format("Invalid resource type %s. The resource type must be one of the following: " + "CPU, DISK, NW_IN, NW_OUT", resourceString);
            StringWriter sw = new StringWriter();
            iae.printStackTrace(new PrintWriter(sw));
            setErrorResponse(response, sw.toString(), errorMsg, SC_BAD_REQUEST, json);
            // Close session
            return true;
        }
        String startMsString = request.getParameter(START_MS_PARAM);
        String endMsString = request.getParameter(END_MS_PARAM);
        startMs = startMsString == null ? -1L : Long.parseLong(startMsString);
        endMs = endMsString == null ? System.currentTimeMillis() : Long.parseLong(endMsString);
    } catch (Exception e) {
        StringWriter sw = new StringWriter();
        e.printStackTrace(new PrintWriter(sw));
        setErrorResponse(response, sw.toString(), e.getMessage(), SC_BAD_REQUEST, json);
        // Close session
        return true;
    }
    ModelCompletenessRequirements requirements = new ModelCompletenessRequirements(1, 0.0, false);
    // Get cluster model asynchronously.
    ClusterModel clusterModel = getAndMaybeReturnProgress(request, response, () -> _asyncKafkaCruiseControl.clusterModel(startMs, endMs, requirements));
    if (clusterModel == null) {
        return false;
    }
    List<Partition> sortedPartitions = clusterModel.replicasSortedByUtilization(resource);
    OutputStream out = response.getOutputStream();
    String entriesString = request.getParameter(ENTRIES);
    Integer entries = entriesString == null ? Integer.MAX_VALUE : Integer.parseInt(entriesString);
    int numEntries = 0;
    if (!json) {
        int topicNameLength = clusterModel.topics().stream().mapToInt(String::length).max().orElse(20) + 5;
        setResponseCode(response, SC_OK);
        out.write(String.format("%" + topicNameLength + "s%10s%30s%20s%20s%20s%20s%n", "PARTITION", "LEADER", "FOLLOWERS", "CPU (%)", "DISK (MB)", "NW_IN (KB/s)", "NW_OUT (KB/s)").getBytes(StandardCharsets.UTF_8));
        for (Partition p : sortedPartitions) {
            if (++numEntries > entries) {
                break;
            }
            List<Integer> followers = p.followers().stream().map((replica) -> replica.broker().id()).collect(Collectors.toList());
            out.write(String.format("%" + topicNameLength + "s%10s%30s%19.6f%19.3f%19.3f%19.3f%n", p.leader().topicPartition(), p.leader().broker().id(), followers, p.leader().load().expectedUtilizationFor(Resource.CPU), p.leader().load().expectedUtilizationFor(Resource.DISK), p.leader().load().expectedUtilizationFor(Resource.NW_IN), p.leader().load().expectedUtilizationFor(Resource.NW_OUT)).getBytes(StandardCharsets.UTF_8));
        }
    } else {
        Map<String, Object> partitionMap = new HashMap<>();
        List<Object> partitionList = new ArrayList<>();
        List<String> header = new ArrayList<>(Arrays.asList("topic", "partition", "leader", "followers", "CPU", "DISK", "NW_IN", "NW_OUT"));
        partitionMap.put("version", JSON_VERSION);
        partitionMap.put("header", header);
        for (Partition p : sortedPartitions) {
            if (++numEntries > entries) {
                break;
            }
            List<Integer> followers = p.followers().stream().map((replica) -> replica.broker().id()).collect(Collectors.toList());
            List<Object> record = new ArrayList<>();
            record.add(p.leader().topicPartition().topic());
            record.add(p.leader().topicPartition().partition());
            record.add(p.leader().broker().id());
            record.add(followers);
            record.add(p.leader().load().expectedUtilizationFor(Resource.CPU));
            record.add(p.leader().load().expectedUtilizationFor(Resource.DISK));
            record.add(p.leader().load().expectedUtilizationFor(Resource.NW_IN));
            record.add(p.leader().load().expectedUtilizationFor(Resource.NW_OUT));
            partitionList.add(record);
        }
        partitionMap.put("records", partitionList);
        Gson gson = new Gson();
        String g = gson.toJson(partitionMap);
        setJSONResponseCode(response, SC_OK);
        response.setContentLength(g.length());
        out.write(g.getBytes(StandardCharsets.UTF_8));
    }
    out.flush();
    return true;
}
Also used : Arrays(java.util.Arrays) SortedSet(java.util.SortedSet) LoggerFactory(org.slf4j.LoggerFactory) TimeoutException(java.util.concurrent.TimeoutException) GsonBuilder(com.google.gson.GsonBuilder) OperationFuture(com.linkedin.kafka.cruisecontrol.async.OperationFuture) Cluster(org.apache.kafka.common.Cluster) Gson(com.google.gson.Gson) Map(java.util.Map) ExecutorState(com.linkedin.kafka.cruisecontrol.executor.ExecutorState) KafkaClusterState(com.linkedin.kafka.cruisecontrol.KafkaClusterState) GoalOptimizer(com.linkedin.kafka.cruisecontrol.analyzer.GoalOptimizer) PrintWriter(java.io.PrintWriter) TopicPartition(org.apache.kafka.common.TopicPartition) HttpServlet(javax.servlet.http.HttpServlet) Time(org.apache.kafka.common.utils.Time) ExecutionTask(com.linkedin.kafka.cruisecontrol.executor.ExecutionTask) EndPoint(com.linkedin.kafka.cruisecontrol.servlet.KafkaCruiseControlServlet.EndPoint) Set(java.util.Set) PartitionInfo(org.apache.kafka.common.PartitionInfo) KafkaAssignerEvenRackAwareGoal(com.linkedin.kafka.cruisecontrol.analyzer.kafkaassigner.KafkaAssignerEvenRackAwareGoal) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) SC_NOT_FOUND(javax.servlet.http.HttpServletResponse.SC_NOT_FOUND) Goal(com.linkedin.kafka.cruisecontrol.analyzer.goals.Goal) List(java.util.List) AsyncKafkaCruiseControl(com.linkedin.kafka.cruisecontrol.async.AsyncKafkaCruiseControl) Resource(com.linkedin.kafka.cruisecontrol.common.Resource) ClusterModelStats(com.linkedin.kafka.cruisecontrol.model.ClusterModelStats) VALID_WINDOWS(com.linkedin.kafka.cruisecontrol.servlet.KafkaCruiseControlServlet.DataFrom.VALID_WINDOWS) SC_OK(javax.servlet.http.HttpServletResponse.SC_OK) Node(org.apache.kafka.common.Node) UnsupportedEncodingException(java.io.UnsupportedEncodingException) SortedMap(java.util.SortedMap) SC_INTERNAL_SERVER_ERROR(javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR) ClusterModel(com.linkedin.kafka.cruisecontrol.model.ClusterModel) HashMap(java.util.HashMap) Supplier(java.util.function.Supplier) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) HttpServletRequest(javax.servlet.http.HttpServletRequest) ServletOutputStream(javax.servlet.ServletOutputStream) OutputStreamWriter(java.io.OutputStreamWriter) Partition(com.linkedin.kafka.cruisecontrol.model.Partition) OutputStream(java.io.OutputStream) MetricRegistry(com.codahale.metrics.MetricRegistry) Logger(org.slf4j.Logger) KafkaCruiseControlState(com.linkedin.kafka.cruisecontrol.KafkaCruiseControlState) StringWriter(java.io.StringWriter) HttpServletResponse(javax.servlet.http.HttpServletResponse) IOException(java.io.IOException) SampleExtrapolation(com.linkedin.kafka.cruisecontrol.monitor.sampling.aggregator.SampleExtrapolation) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) URLEncoder(java.net.URLEncoder) TreeMap(java.util.TreeMap) StringJoiner(java.util.StringJoiner) SC_BAD_REQUEST(javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST) Comparator(java.util.Comparator) Collections(java.util.Collections) KafkaAssignerDiskUsageDistributionGoal(com.linkedin.kafka.cruisecontrol.analyzer.kafkaassigner.KafkaAssignerDiskUsageDistributionGoal) ModelCompletenessRequirements(com.linkedin.kafka.cruisecontrol.monitor.ModelCompletenessRequirements) TopicPartition(org.apache.kafka.common.TopicPartition) Partition(com.linkedin.kafka.cruisecontrol.model.Partition) HashMap(java.util.HashMap) ServletOutputStream(javax.servlet.ServletOutputStream) OutputStream(java.io.OutputStream) Resource(com.linkedin.kafka.cruisecontrol.common.Resource) ArrayList(java.util.ArrayList) Gson(com.google.gson.Gson) TimeoutException(java.util.concurrent.TimeoutException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) EndPoint(com.linkedin.kafka.cruisecontrol.servlet.KafkaCruiseControlServlet.EndPoint) ClusterModel(com.linkedin.kafka.cruisecontrol.model.ClusterModel) StringWriter(java.io.StringWriter) ModelCompletenessRequirements(com.linkedin.kafka.cruisecontrol.monitor.ModelCompletenessRequirements) PrintWriter(java.io.PrintWriter)

Example 3 with SC_BAD_REQUEST

use of javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST in project gerrit by GerritCodeReview.

the class RestApiServlet method service.

@Override
protected final void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
    final long startNanos = System.nanoTime();
    long auditStartTs = TimeUtil.nowMs();
    res.setHeader("Content-Disposition", "attachment");
    res.setHeader("X-Content-Type-Options", "nosniff");
    int statusCode = SC_OK;
    long responseBytes = -1;
    Optional<Exception> cause = Optional.empty();
    Response<?> response = null;
    QueryParams qp = null;
    Object inputRequestBody = null;
    RestResource rsrc = TopLevelResource.INSTANCE;
    ViewData viewData = null;
    try (TraceContext traceContext = enableTracing(req, res)) {
        String requestUri = requestUri(req);
        try (PerThreadCache ignored = PerThreadCache.create()) {
            List<IdString> path = splitPath(req);
            RequestInfo requestInfo = createRequestInfo(traceContext, requestUri, path);
            globals.requestListeners.runEach(l -> l.onRequest(requestInfo));
            // TraceIT#performanceLoggingForRestCall()).
            try (RequestStateContext requestStateContext = RequestStateContext.open().addRequestStateProvider(globals.deadlineCheckerFactory.create(requestInfo, req.getHeader(X_GERRIT_DEADLINE)));
                PerformanceLogContext performanceLogContext = new PerformanceLogContext(globals.config, globals.performanceLoggers)) {
                traceRequestData(req);
                if (isCorsPreflight(req)) {
                    doCorsPreflight(req, res);
                    return;
                }
                qp = ParameterParser.getQueryParams(req);
                checkCors(req, res, qp.hasXdOverride());
                if (qp.hasXdOverride()) {
                    req = applyXdOverrides(req, qp);
                }
                checkUserSession(req);
                RestCollection<RestResource, RestResource> rc = members.get();
                globals.permissionBackend.currentUser().checkAny(GlobalPermission.fromAnnotation(rc.getClass()));
                viewData = new ViewData(null, null);
                if (path.isEmpty()) {
                    globals.quotaChecker.enforce(req);
                    if (rc instanceof NeedsParams) {
                        ((NeedsParams) rc).setParams(qp.params());
                    }
                    if (isRead(req)) {
                        viewData = new ViewData(null, rc.list());
                    } else if (isPost(req)) {
                        RestView<RestResource> restCollectionView = rc.views().get(PluginName.GERRIT, "POST_ON_COLLECTION./");
                        if (restCollectionView != null) {
                            viewData = new ViewData(null, restCollectionView);
                        } else {
                            throw methodNotAllowed(req);
                        }
                    } else {
                        // DELETE on root collections is not supported
                        throw methodNotAllowed(req);
                    }
                } else {
                    IdString id = path.remove(0);
                    try {
                        rsrc = parseResourceWithRetry(req, traceContext, viewData.pluginName, rc, rsrc, id);
                        globals.quotaChecker.enforce(rsrc, req);
                        if (path.isEmpty()) {
                            checkPreconditions(req);
                        }
                    } catch (ResourceNotFoundException e) {
                        if (!path.isEmpty()) {
                            throw e;
                        }
                        globals.quotaChecker.enforce(req);
                        if (isPost(req) || isPut(req)) {
                            RestView<RestResource> createView = rc.views().get(PluginName.GERRIT, "CREATE./");
                            if (createView != null) {
                                viewData = new ViewData(null, createView);
                                path.add(id);
                            } else {
                                throw e;
                            }
                        } else if (isDelete(req)) {
                            RestView<RestResource> deleteView = rc.views().get(PluginName.GERRIT, "DELETE_MISSING./");
                            if (deleteView != null) {
                                viewData = new ViewData(null, deleteView);
                                path.add(id);
                            } else {
                                throw e;
                            }
                        } else {
                            throw e;
                        }
                    }
                    if (viewData.view == null) {
                        viewData = view(rc, req.getMethod(), path);
                    }
                }
                checkRequiresCapability(viewData);
                while (viewData.view instanceof RestCollection<?, ?>) {
                    @SuppressWarnings("unchecked") RestCollection<RestResource, RestResource> c = (RestCollection<RestResource, RestResource>) viewData.view;
                    if (path.isEmpty()) {
                        if (isRead(req)) {
                            viewData = new ViewData(null, c.list());
                        } else if (isPost(req)) {
                            // TODO: Here and on other collection methods: There is a bug that binds child views
                            // with pluginName="gerrit" instead of the real plugin name. This has never worked
                            // correctly and should be fixed where the binding gets created (DynamicMapProvider)
                            // and here.
                            RestView<RestResource> restCollectionView = c.views().get(PluginName.GERRIT, "POST_ON_COLLECTION./");
                            if (restCollectionView != null) {
                                viewData = new ViewData(null, restCollectionView);
                            } else {
                                throw methodNotAllowed(req);
                            }
                        } else if (isDelete(req)) {
                            RestView<RestResource> restCollectionView = c.views().get(PluginName.GERRIT, "DELETE_ON_COLLECTION./");
                            if (restCollectionView != null) {
                                viewData = new ViewData(null, restCollectionView);
                            } else {
                                throw methodNotAllowed(req);
                            }
                        } else {
                            throw methodNotAllowed(req);
                        }
                        break;
                    }
                    IdString id = path.remove(0);
                    try {
                        rsrc = parseResourceWithRetry(req, traceContext, viewData.pluginName, c, rsrc, id);
                        checkPreconditions(req);
                        viewData = new ViewData(null, null);
                    } catch (ResourceNotFoundException e) {
                        if (!path.isEmpty()) {
                            throw e;
                        }
                        if (isPost(req) || isPut(req)) {
                            RestView<RestResource> createView = c.views().get(PluginName.GERRIT, "CREATE./");
                            if (createView != null) {
                                viewData = new ViewData(viewData.pluginName, createView);
                                path.add(id);
                            } else {
                                throw e;
                            }
                        } else if (isDelete(req)) {
                            RestView<RestResource> deleteView = c.views().get(PluginName.GERRIT, "DELETE_MISSING./");
                            if (deleteView != null) {
                                viewData = new ViewData(viewData.pluginName, deleteView);
                                path.add(id);
                            } else {
                                throw e;
                            }
                        } else {
                            throw e;
                        }
                    }
                    if (viewData.view == null) {
                        viewData = view(c, req.getMethod(), path);
                    }
                    checkRequiresCapability(viewData);
                }
                if (notModified(req, traceContext, viewData, rsrc)) {
                    logger.atFinest().log("REST call succeeded: %d", SC_NOT_MODIFIED);
                    res.sendError(SC_NOT_MODIFIED);
                    return;
                }
                try (DynamicOptions pluginOptions = new DynamicOptions(globals.injector, globals.dynamicBeans)) {
                    if (!globals.paramParser.get().parse(viewData.view, pluginOptions, qp.params(), req, res)) {
                        return;
                    }
                    if (viewData.view instanceof RestReadView<?> && isRead(req)) {
                        response = invokeRestReadViewWithRetry(req, traceContext, viewData, (RestReadView<RestResource>) viewData.view, rsrc);
                    } else if (viewData.view instanceof RestModifyView<?, ?>) {
                        @SuppressWarnings("unchecked") RestModifyView<RestResource, Object> m = (RestModifyView<RestResource, Object>) viewData.view;
                        Type type = inputType(m);
                        inputRequestBody = parseRequest(req, type);
                        response = invokeRestModifyViewWithRetry(req, traceContext, viewData, m, rsrc, inputRequestBody);
                        if (inputRequestBody instanceof RawInput) {
                            try (InputStream is = req.getInputStream()) {
                                ServletUtils.consumeRequestBody(is);
                            }
                        }
                    } else if (viewData.view instanceof RestCollectionCreateView<?, ?, ?>) {
                        @SuppressWarnings("unchecked") RestCollectionCreateView<RestResource, RestResource, Object> m = (RestCollectionCreateView<RestResource, RestResource, Object>) viewData.view;
                        Type type = inputType(m);
                        inputRequestBody = parseRequest(req, type);
                        response = invokeRestCollectionCreateViewWithRetry(req, traceContext, viewData, m, rsrc, path.get(0), inputRequestBody);
                        if (inputRequestBody instanceof RawInput) {
                            try (InputStream is = req.getInputStream()) {
                                ServletUtils.consumeRequestBody(is);
                            }
                        }
                    } else if (viewData.view instanceof RestCollectionDeleteMissingView<?, ?, ?>) {
                        @SuppressWarnings("unchecked") RestCollectionDeleteMissingView<RestResource, RestResource, Object> m = (RestCollectionDeleteMissingView<RestResource, RestResource, Object>) viewData.view;
                        Type type = inputType(m);
                        inputRequestBody = parseRequest(req, type);
                        response = invokeRestCollectionDeleteMissingViewWithRetry(req, traceContext, viewData, m, rsrc, path.get(0), inputRequestBody);
                        if (inputRequestBody instanceof RawInput) {
                            try (InputStream is = req.getInputStream()) {
                                ServletUtils.consumeRequestBody(is);
                            }
                        }
                    } else if (viewData.view instanceof RestCollectionModifyView<?, ?, ?>) {
                        @SuppressWarnings("unchecked") RestCollectionModifyView<RestResource, RestResource, Object> m = (RestCollectionModifyView<RestResource, RestResource, Object>) viewData.view;
                        Type type = inputType(m);
                        inputRequestBody = parseRequest(req, type);
                        response = invokeRestCollectionModifyViewWithRetry(req, traceContext, viewData, m, rsrc, inputRequestBody);
                        if (inputRequestBody instanceof RawInput) {
                            try (InputStream is = req.getInputStream()) {
                                ServletUtils.consumeRequestBody(is);
                            }
                        }
                    } else {
                        throw new ResourceNotFoundException();
                    }
                    String isUpdatedRefEnabled = req.getHeader(X_GERRIT_UPDATED_REF_ENABLED);
                    if (!Strings.isNullOrEmpty(isUpdatedRefEnabled) && Boolean.valueOf(isUpdatedRefEnabled)) {
                        setXGerritUpdatedRefResponseHeaders(req, res);
                    }
                    if (response instanceof Response.Redirect) {
                        CacheHeaders.setNotCacheable(res);
                        String location = ((Response.Redirect) response).location();
                        res.sendRedirect(location);
                        logger.atFinest().log("REST call redirected to: %s", location);
                        return;
                    } else if (response instanceof Response.Accepted) {
                        CacheHeaders.setNotCacheable(res);
                        res.setStatus(response.statusCode());
                        res.setHeader(HttpHeaders.LOCATION, ((Response.Accepted) response).location());
                        logger.atFinest().log("REST call succeeded: %d", response.statusCode());
                        return;
                    }
                    statusCode = response.statusCode();
                    configureCaching(req, res, traceContext, rsrc, viewData, response.caching());
                    res.setStatus(statusCode);
                    logger.atFinest().log("REST call succeeded: %d", statusCode);
                }
                if (response != Response.none()) {
                    Object value = Response.unwrap(response);
                    if (value instanceof BinaryResult) {
                        responseBytes = replyBinaryResult(req, res, (BinaryResult) value);
                    } else {
                        responseBytes = replyJson(req, res, false, qp.config(), value);
                    }
                }
            }
        } catch (MalformedJsonException | JsonParseException e) {
            cause = Optional.of(e);
            logger.atFine().withCause(e).log("REST call failed on JSON parsing");
            responseBytes = replyError(req, res, statusCode = SC_BAD_REQUEST, "Invalid " + JSON_TYPE + " in request", e);
        } catch (BadRequestException e) {
            cause = Optional.of(e);
            responseBytes = replyError(req, res, statusCode = SC_BAD_REQUEST, messageOr(e, "Bad Request"), e.caching(), e);
        } catch (AuthException e) {
            cause = Optional.of(e);
            responseBytes = replyError(req, res, statusCode = SC_FORBIDDEN, messageOr(e, "Forbidden"), e.caching(), e);
        } catch (AmbiguousViewException e) {
            cause = Optional.of(e);
            responseBytes = replyError(req, res, statusCode = SC_NOT_FOUND, messageOr(e, "Ambiguous"), e);
        } catch (ResourceNotFoundException e) {
            cause = Optional.of(e);
            responseBytes = replyError(req, res, statusCode = SC_NOT_FOUND, messageOr(e, "Not Found"), e.caching(), e);
        } catch (MethodNotAllowedException e) {
            cause = Optional.of(e);
            responseBytes = replyError(req, res, statusCode = SC_METHOD_NOT_ALLOWED, messageOr(e, "Method Not Allowed"), e.caching(), e);
        } catch (ResourceConflictException e) {
            cause = Optional.of(e);
            responseBytes = replyError(req, res, statusCode = SC_CONFLICT, messageOr(e, "Conflict"), e.caching(), e);
        } catch (PreconditionFailedException e) {
            cause = Optional.of(e);
            responseBytes = replyError(req, res, statusCode = SC_PRECONDITION_FAILED, messageOr(e, "Precondition Failed"), e.caching(), e);
        } catch (UnprocessableEntityException e) {
            cause = Optional.of(e);
            responseBytes = replyError(req, res, statusCode = SC_UNPROCESSABLE_ENTITY, messageOr(e, "Unprocessable Entity"), e.caching(), e);
        } catch (NotImplementedException e) {
            cause = Optional.of(e);
            logger.atSevere().withCause(e).log("Error in %s %s", req.getMethod(), uriForLogging(req));
            responseBytes = replyError(req, res, statusCode = SC_NOT_IMPLEMENTED, messageOr(e, "Not Implemented"), e);
        } catch (QuotaException e) {
            cause = Optional.of(e);
            responseBytes = replyError(req, res, statusCode = SC_TOO_MANY_REQUESTS, messageOr(e, "Quota limit reached"), e.caching(), e);
        } catch (InvalidDeadlineException e) {
            cause = Optional.of(e);
            responseBytes = replyError(req, res, statusCode = SC_BAD_REQUEST, messageOr(e, "Bad Request"), e);
        } catch (Exception e) {
            cause = Optional.of(e);
            Optional<RequestCancelledException> requestCancelledException = RequestCancelledException.getFromCausalChain(e);
            if (requestCancelledException.isPresent()) {
                RequestStateProvider.Reason cancellationReason = requestCancelledException.get().getCancellationReason();
                globals.cancellationMetrics.countCancelledRequest(RequestInfo.RequestType.REST, requestUri, cancellationReason);
                statusCode = getCancellationStatusCode(cancellationReason);
                responseBytes = replyError(req, res, statusCode, getCancellationMessage(requestCancelledException.get()), e);
            } else {
                statusCode = SC_INTERNAL_SERVER_ERROR;
                Optional<ExceptionHook.Status> status = getStatus(e);
                statusCode = status.map(ExceptionHook.Status::statusCode).orElse(SC_INTERNAL_SERVER_ERROR);
                if (res.isCommitted()) {
                    responseBytes = 0;
                    if (statusCode == SC_INTERNAL_SERVER_ERROR) {
                        logger.atSevere().withCause(e).log("Error in %s %s, response already committed", req.getMethod(), uriForLogging(req));
                    } else {
                        logger.atWarning().log("Response for %s %s already committed, wanted to set status %d", req.getMethod(), uriForLogging(req), statusCode);
                    }
                } else {
                    res.reset();
                    TraceContext.getTraceId().ifPresent(traceId -> res.addHeader(X_GERRIT_TRACE, traceId));
                    if (status.isPresent()) {
                        responseBytes = reply(req, res, e, status.get(), getUserMessages(e));
                    } else {
                        responseBytes = replyInternalServerError(req, res, e, getUserMessages(e));
                    }
                }
            }
        } finally {
            String metric = getViewName(viewData);
            String formattedCause = cause.map(globals.retryHelper::formatCause).orElse("_none");
            globals.metrics.count.increment(metric);
            if (statusCode >= SC_BAD_REQUEST) {
                globals.metrics.errorCount.increment(metric, statusCode, formattedCause);
            }
            if (responseBytes != -1) {
                globals.metrics.responseBytes.record(metric, responseBytes);
            }
            globals.metrics.serverLatency.record(metric, System.nanoTime() - startNanos, TimeUnit.NANOSECONDS);
            globals.auditService.dispatch(new ExtendedHttpAuditEvent(globals.webSession.get().getSessionId(), globals.currentUser.get(), req, auditStartTs, qp != null ? qp.params() : ImmutableListMultimap.of(), inputRequestBody, statusCode, response, rsrc, viewData == null ? null : viewData.view));
        }
    }
}
Also used : ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) PluginName(com.google.gerrit.extensions.registration.PluginName) ListMultimap(com.google.common.collect.ListMultimap) DynamicItem(com.google.gerrit.extensions.registration.DynamicItem) DeadlineChecker(com.google.gerrit.server.DeadlineChecker) OptionUtil(com.google.gerrit.server.OptionUtil) RequestStateProvider(com.google.gerrit.server.cancellation.RequestStateProvider) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) PermissionBackend(com.google.gerrit.server.permissions.PermissionBackend) ActionType(com.google.gerrit.server.update.RetryableAction.ActionType) GsonBuilder(com.google.gson.GsonBuilder) InvalidDeadlineException(com.google.gerrit.server.InvalidDeadlineException) Config(org.eclipse.jgit.lib.Config) IntMath(com.google.common.math.IntMath) OutputFormat(com.google.gerrit.json.OutputFormat) ISO_8859_1(java.nio.charset.StandardCharsets.ISO_8859_1) HttpHeaders(com.google.common.net.HttpHeaders) Map(java.util.Map) CEILING(java.math.RoundingMode.CEILING) RawInput(com.google.gerrit.extensions.restapi.RawInput) RetryHelper(com.google.gerrit.server.update.RetryHelper) AnonymousUser(com.google.gerrit.server.AnonymousUser) ExclusionStrategy(com.google.gson.ExclusionStrategy) GroupAuditService(com.google.gerrit.server.group.GroupAuditService) Metadata(com.google.gerrit.server.logging.Metadata) RestReadView(com.google.gerrit.extensions.restapi.RestReadView) GerritServerConfig(com.google.gerrit.server.config.GerritServerConfig) HttpServlet(javax.servlet.http.HttpServlet) TraceContext(com.google.gerrit.server.logging.TraceContext) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) PerThreadCache(com.google.gerrit.server.cache.PerThreadCache) Set(java.util.Set) FilterOutputStream(java.io.FilterOutputStream) Collectors.joining(java.util.stream.Collectors.joining) InvocationTargetException(java.lang.reflect.InvocationTargetException) RequestListener(com.google.gerrit.server.RequestListener) SC_NOT_FOUND(javax.servlet.http.HttpServletResponse.SC_NOT_FOUND) Stream(java.util.stream.Stream) ChangesCollection(com.google.gerrit.server.restapi.change.ChangesCollection) SC_CONFLICT(javax.servlet.http.HttpServletResponse.SC_CONFLICT) ImmutableListMultimap(com.google.common.collect.ImmutableListMultimap) PluginSetContext(com.google.gerrit.server.plugincontext.PluginSetContext) GZIPOutputStream(java.util.zip.GZIPOutputStream) LazyArgs.lazy(com.google.common.flogger.LazyArgs.lazy) TypeLiteral(com.google.inject.TypeLiteral) ACCESS_CONTROL_ALLOW_HEADERS(com.google.common.net.HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS) FluentLogger(com.google.common.flogger.FluentLogger) ACCESS_CONTROL_ALLOW_CREDENTIALS(com.google.common.net.HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS) Joiner(com.google.common.base.Joiner) Iterables(com.google.common.collect.Iterables) PermissionBackendException(com.google.gerrit.server.permissions.PermissionBackendException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) UnprocessableEntityException(com.google.gerrit.extensions.restapi.UnprocessableEntityException) CountingOutputStream(com.google.common.io.CountingOutputStream) RawInputUtil(com.google.gerrit.common.RawInputUtil) Action(com.google.gerrit.server.update.RetryableAction.Action) Response(com.google.gerrit.extensions.restapi.Response) TraceTimer(com.google.gerrit.server.logging.TraceContext.TraceTimer) CONTENT_TYPE(com.google.common.net.HttpHeaders.CONTENT_TYPE) Constructor(java.lang.reflect.Constructor) DefaultInput(com.google.gerrit.extensions.restapi.DefaultInput) CancellationMetrics(com.google.gerrit.server.CancellationMetrics) FieldAttributes(com.google.gson.FieldAttributes) JsonReader(com.google.gson.stream.JsonReader) PerformanceLogger(com.google.gerrit.server.logging.PerformanceLogger) ArrayList(java.util.ArrayList) Strings(com.google.common.base.Strings) HttpServletRequest(javax.servlet.http.HttpServletRequest) VARY(com.google.common.net.HttpHeaders.VARY) SC_NOT_IMPLEMENTED(javax.servlet.http.HttpServletResponse.SC_NOT_IMPLEMENTED) Lists(com.google.common.collect.Lists) RestCollectionDeleteMissingView(com.google.gerrit.extensions.restapi.RestCollectionDeleteMissingView) RestCollectionCreateView(com.google.gerrit.extensions.restapi.RestCollectionCreateView) RestApiException(com.google.gerrit.extensions.restapi.RestApiException) CacheHeaders(com.google.gerrit.util.http.CacheHeaders) JsonWriter(com.google.gson.stream.JsonWriter) NeedsParams(com.google.gerrit.extensions.restapi.NeedsParams) RequestUtil(com.google.gerrit.util.http.RequestUtil) PreconditionFailedException(com.google.gerrit.extensions.restapi.PreconditionFailedException) BaseEncoding(com.google.common.io.BaseEncoding) QueryParams(com.google.gerrit.httpd.restapi.ParameterParser.QueryParams) ExperimentFeatures(com.google.gerrit.server.experiments.ExperimentFeatures) BufferedWriter(java.io.BufferedWriter) Throwables(com.google.common.base.Throwables) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) IOException(java.io.IOException) Field(java.lang.reflect.Field) ETagView(com.google.gerrit.extensions.restapi.ETagView) MalformedJsonException(com.google.gson.stream.MalformedJsonException) JsonToken(com.google.gson.stream.JsonToken) ParameterizedType(java.lang.reflect.ParameterizedType) TreeMap(java.util.TreeMap) SC_NOT_MODIFIED(javax.servlet.http.HttpServletResponse.SC_NOT_MODIFIED) DynamicMap(com.google.gerrit.extensions.registration.DynamicMap) Project(com.google.gerrit.entities.Project) DynamicSet(com.google.gerrit.extensions.registration.DynamicSet) SC_BAD_REQUEST(javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST) DynamicOptions(com.google.gerrit.server.DynamicOptions) TimeUtil(com.google.gerrit.server.util.time.TimeUtil) BufferedReader(java.io.BufferedReader) RequestCancelledException(com.google.gerrit.server.cancellation.RequestCancelledException) RequestId(com.google.gerrit.server.logging.RequestId) ChangeFinder(com.google.gerrit.server.change.ChangeFinder) ACCESS_CONTROL_ALLOW_METHODS(com.google.common.net.HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS) ServletException(javax.servlet.ServletException) Inject(com.google.inject.Inject) HttpServletRequestWrapper(javax.servlet.http.HttpServletRequestWrapper) AUTHORIZATION(com.google.common.net.HttpHeaders.AUTHORIZATION) AccessPath(com.google.gerrit.server.AccessPath) CacheControl(com.google.gerrit.extensions.restapi.CacheControl) RestModifyView(com.google.gerrit.extensions.restapi.RestModifyView) RestResource(com.google.gerrit.extensions.restapi.RestResource) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) ACCESS_CONTROL_ALLOW_ORIGIN(com.google.common.net.HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN) Gson(com.google.gson.Gson) Locale(java.util.Locale) AuthException(com.google.gerrit.extensions.restapi.AuthException) GERRIT_BACKEND_REQUEST_FEATURE_REMOVE_REVISION_ETAG(com.google.gerrit.server.experiments.ExperimentFeaturesConstants.GERRIT_BACKEND_REQUEST_FEATURE_REMOVE_REVISION_ETAG) PerformanceLogContext(com.google.gerrit.server.logging.PerformanceLogContext) Splitter(com.google.common.base.Splitter) ORIGIN(com.google.common.net.HttpHeaders.ORIGIN) GlobalPermission(com.google.gerrit.server.permissions.GlobalPermission) ImmutableSet(com.google.common.collect.ImmutableSet) RestCollectionView(com.google.gerrit.extensions.restapi.RestCollectionView) Timestamp(java.sql.Timestamp) ACCESS_CONTROL_REQUEST_HEADERS(com.google.common.net.HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS) SC_REQUEST_TIMEOUT(javax.servlet.http.HttpServletResponse.SC_REQUEST_TIMEOUT) RequestInfo(com.google.gerrit.server.RequestInfo) MethodNotAllowedException(com.google.gerrit.extensions.restapi.MethodNotAllowedException) EOFException(java.io.EOFException) Preconditions.checkState(com.google.common.base.Preconditions.checkState) TopLevelResource(com.google.gerrit.extensions.restapi.TopLevelResource) RestCollectionModifyView(com.google.gerrit.extensions.restapi.RestCollectionModifyView) List(java.util.List) Nullable(com.google.gerrit.common.Nullable) Type(java.lang.reflect.Type) ACCESS_CONTROL_MAX_AGE(com.google.common.net.HttpHeaders.ACCESS_CONTROL_MAX_AGE) SC_OK(javax.servlet.http.HttpServletResponse.SC_OK) Url(com.google.gerrit.extensions.restapi.Url) Writer(java.io.Writer) Optional(java.util.Optional) Providers(com.google.inject.util.Providers) Pattern(java.util.regex.Pattern) SC_METHOD_NOT_ALLOWED(javax.servlet.http.HttpServletResponse.SC_METHOD_NOT_ALLOWED) RestCollection(com.google.gerrit.extensions.restapi.RestCollection) RequestStateContext(com.google.gerrit.server.cancellation.RequestStateContext) JsonParseException(com.google.gson.JsonParseException) NotImplementedException(com.google.gerrit.extensions.restapi.NotImplementedException) SC_PRECONDITION_FAILED(javax.servlet.http.HttpServletResponse.SC_PRECONDITION_FAILED) ACCESS_CONTROL_REQUEST_METHOD(com.google.common.net.HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD) SC_INTERNAL_SERVER_ERROR(javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR) IdString(com.google.gerrit.extensions.restapi.IdString) HashMap(java.util.HashMap) AtomicReference(java.util.concurrent.atomic.AtomicReference) JsonElement(com.google.gson.JsonElement) HashSet(java.util.HashSet) GitReferenceUpdatedListener(com.google.gerrit.extensions.events.GitReferenceUpdatedListener) BinaryResult(com.google.gerrit.extensions.restapi.BinaryResult) FieldNamingPolicy(com.google.gson.FieldNamingPolicy) ImmutableList(com.google.common.collect.ImmutableList) ExceptionHook(com.google.gerrit.server.ExceptionHook) Objects.requireNonNull(java.util.Objects.requireNonNull) ExtendedHttpAuditEvent(com.google.gerrit.server.audit.ExtendedHttpAuditEvent) OutputStreamWriter(java.io.OutputStreamWriter) WebSession(com.google.gerrit.httpd.WebSession) OutputStream(java.io.OutputStream) CurrentUser(com.google.gerrit.server.CurrentUser) TemporaryBuffer(org.eclipse.jgit.util.TemporaryBuffer) UTF_8(java.nio.charset.StandardCharsets.UTF_8) ProjectsCollection(com.google.gerrit.server.restapi.project.ProjectsCollection) RestView(com.google.gerrit.extensions.restapi.RestView) HttpServletResponse(javax.servlet.http.HttpServletResponse) RetryableAction(com.google.gerrit.server.update.RetryableAction) Injector(com.google.inject.Injector) TimeUnit(java.util.concurrent.TimeUnit) Provider(com.google.inject.Provider) ServletUtils(org.eclipse.jgit.http.server.ServletUtils) Heap(org.eclipse.jgit.util.TemporaryBuffer.Heap) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) RevisionResource(com.google.gerrit.server.change.RevisionResource) SC_FORBIDDEN(javax.servlet.http.HttpServletResponse.SC_FORBIDDEN) QuotaException(com.google.gerrit.server.quota.QuotaException) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Collections(java.util.Collections) InputStream(java.io.InputStream) DynamicOptions(com.google.gerrit.server.DynamicOptions) RestCollection(com.google.gerrit.extensions.restapi.RestCollection) RestResource(com.google.gerrit.extensions.restapi.RestResource) RestView(com.google.gerrit.extensions.restapi.RestView) RawInput(com.google.gerrit.extensions.restapi.RawInput) IdString(com.google.gerrit.extensions.restapi.IdString) RestCollectionModifyView(com.google.gerrit.extensions.restapi.RestCollectionModifyView) JsonParseException(com.google.gson.JsonParseException) PerformanceLogContext(com.google.gerrit.server.logging.PerformanceLogContext) QuotaException(com.google.gerrit.server.quota.QuotaException) ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) UnprocessableEntityException(com.google.gerrit.extensions.restapi.UnprocessableEntityException) RestModifyView(com.google.gerrit.extensions.restapi.RestModifyView) Optional(java.util.Optional) RestReadView(com.google.gerrit.extensions.restapi.RestReadView) RestCollectionDeleteMissingView(com.google.gerrit.extensions.restapi.RestCollectionDeleteMissingView) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) RequestStateContext(com.google.gerrit.server.cancellation.RequestStateContext) NotImplementedException(com.google.gerrit.extensions.restapi.NotImplementedException) AuthException(com.google.gerrit.extensions.restapi.AuthException) ExtendedHttpAuditEvent(com.google.gerrit.server.audit.ExtendedHttpAuditEvent) RequestInfo(com.google.gerrit.server.RequestInfo) PerThreadCache(com.google.gerrit.server.cache.PerThreadCache) RestCollectionCreateView(com.google.gerrit.extensions.restapi.RestCollectionCreateView) InvalidDeadlineException(com.google.gerrit.server.InvalidDeadlineException) QueryParams(com.google.gerrit.httpd.restapi.ParameterParser.QueryParams) PreconditionFailedException(com.google.gerrit.extensions.restapi.PreconditionFailedException) MalformedJsonException(com.google.gson.stream.MalformedJsonException) MethodNotAllowedException(com.google.gerrit.extensions.restapi.MethodNotAllowedException) InputStream(java.io.InputStream) ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) InvalidDeadlineException(com.google.gerrit.server.InvalidDeadlineException) InvocationTargetException(java.lang.reflect.InvocationTargetException) PermissionBackendException(com.google.gerrit.server.permissions.PermissionBackendException) UnprocessableEntityException(com.google.gerrit.extensions.restapi.UnprocessableEntityException) RestApiException(com.google.gerrit.extensions.restapi.RestApiException) PreconditionFailedException(com.google.gerrit.extensions.restapi.PreconditionFailedException) IOException(java.io.IOException) MalformedJsonException(com.google.gson.stream.MalformedJsonException) RequestCancelledException(com.google.gerrit.server.cancellation.RequestCancelledException) ServletException(javax.servlet.ServletException) AuthException(com.google.gerrit.extensions.restapi.AuthException) MethodNotAllowedException(com.google.gerrit.extensions.restapi.MethodNotAllowedException) EOFException(java.io.EOFException) JsonParseException(com.google.gson.JsonParseException) NotImplementedException(com.google.gerrit.extensions.restapi.NotImplementedException) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) QuotaException(com.google.gerrit.server.quota.QuotaException) Response(com.google.gerrit.extensions.restapi.Response) HttpServletResponse(javax.servlet.http.HttpServletResponse) ExceptionHook(com.google.gerrit.server.ExceptionHook) ActionType(com.google.gerrit.server.update.RetryableAction.ActionType) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) IdString(com.google.gerrit.extensions.restapi.IdString) TraceContext(com.google.gerrit.server.logging.TraceContext) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) NeedsParams(com.google.gerrit.extensions.restapi.NeedsParams) BinaryResult(com.google.gerrit.extensions.restapi.BinaryResult)

Example 4 with SC_BAD_REQUEST

use of javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST in project gerrit by GerritCodeReview.

the class PostReview method apply.

public Response<ReviewResult> apply(RevisionResource revision, ReviewInput input, Instant ts) throws RestApiException, UpdateException, IOException, PermissionBackendException, ConfigInvalidException, PatchListNotAvailableException {
    // Respect timestamp, but truncate at change created-on time.
    ts = Ordering.natural().max(ts, revision.getChange().getCreatedOn());
    if (revision.getEdit().isPresent()) {
        throw new ResourceConflictException("cannot post review on edit");
    }
    ProjectState projectState = projectCache.get(revision.getProject()).orElseThrow(illegalState(revision.getProject()));
    LabelTypes labelTypes = projectState.getLabelTypes(revision.getNotes());
    logger.atFine().log("strict label checking is %s", (strictLabels ? "enabled" : "disabled"));
    metrics.draftHandling.increment(input.drafts == null ? "N/A" : input.drafts.name());
    input.drafts = firstNonNull(input.drafts, DraftHandling.KEEP);
    logger.atFine().log("draft handling = %s", input.drafts);
    if (input.onBehalfOf != null) {
        revision = onBehalfOf(revision, labelTypes, input);
    }
    if (input.labels != null) {
        checkLabels(revision, labelTypes, input.labels);
    }
    if (input.comments != null) {
        input.comments = cleanUpComments(input.comments);
        checkComments(revision, input.comments);
    }
    if (input.draftIdsToPublish != null) {
        checkDraftIds(revision, input.draftIdsToPublish, input.drafts);
    }
    if (input.robotComments != null) {
        input.robotComments = cleanUpComments(input.robotComments);
        checkRobotComments(revision, input.robotComments);
    }
    if (input.notify == null) {
        input.notify = defaultNotify(revision.getChange(), input);
    }
    logger.atFine().log("notify handling = %s", input.notify);
    Map<String, ReviewerResult> reviewerJsonResults = null;
    List<ReviewerModification> reviewerResults = Lists.newArrayList();
    boolean hasError = false;
    boolean confirm = false;
    if (input.reviewers != null) {
        reviewerJsonResults = Maps.newHashMap();
        for (ReviewerInput reviewerInput : input.reviewers) {
            ReviewerModification result = reviewerModifier.prepare(revision.getNotes(), revision.getUser(), reviewerInput, true);
            reviewerJsonResults.put(reviewerInput.reviewer, result.result);
            if (result.result.error != null) {
                logger.atFine().log("Adding %s as reviewer failed: %s", reviewerInput.reviewer, result.result.error);
                hasError = true;
                continue;
            }
            if (result.result.confirm != null) {
                logger.atFine().log("Adding %s as reviewer requires confirmation", reviewerInput.reviewer);
                confirm = true;
                continue;
            }
            logger.atFine().log("Adding %s as reviewer was prepared", reviewerInput.reviewer);
            reviewerResults.add(result);
        }
    }
    ReviewResult output = new ReviewResult();
    output.reviewers = reviewerJsonResults;
    if (hasError || confirm) {
        output.error = ERROR_ADDING_REVIEWER;
        return Response.withStatusCode(SC_BAD_REQUEST, output);
    }
    output.labels = input.labels;
    try (BatchUpdate bu = updateFactory.create(revision.getChange().getProject(), revision.getUser(), ts)) {
        Account account = revision.getUser().asIdentifiedUser().getAccount();
        boolean ccOrReviewer = false;
        if (input.labels != null && !input.labels.isEmpty()) {
            ccOrReviewer = input.labels.values().stream().anyMatch(v -> v != 0);
            if (ccOrReviewer) {
                logger.atFine().log("calling user is cc/reviewer on the change due to voting on a label");
            }
        }
        if (!ccOrReviewer) {
            // Check if user was already CCed or reviewing prior to this review.
            ReviewerSet currentReviewers = approvalsUtil.getReviewers(revision.getChangeResource().getNotes());
            ccOrReviewer = currentReviewers.all().contains(account.id());
            if (ccOrReviewer) {
                logger.atFine().log("calling user is already cc/reviewer on the change");
            }
        }
        // Apply reviewer changes first. Revision emails should be sent to the
        // updated set of reviewers. Also keep track of whether the user added
        // themselves as a reviewer or to the CC list.
        logger.atFine().log("adding reviewer additions");
        for (ReviewerModification reviewerResult : reviewerResults) {
            // Send a single batch email below.
            reviewerResult.op.suppressEmail();
            // Send events below, if possible as batch.
            reviewerResult.op.suppressEvent();
            bu.addOp(revision.getChange().getId(), reviewerResult.op);
            if (!ccOrReviewer && reviewerResult.reviewers.contains(account)) {
                logger.atFine().log("calling user is explicitly added as reviewer or CC");
                ccOrReviewer = true;
            }
        }
        if (!ccOrReviewer) {
            // User posting this review isn't currently in the reviewer or CC list,
            // isn't being explicitly added, and isn't voting on any label.
            // Automatically CC them on this change so they receive replies.
            logger.atFine().log("CCing calling user");
            ReviewerModification selfAddition = reviewerModifier.ccCurrentUser(revision.getUser(), revision);
            selfAddition.op.suppressEmail();
            selfAddition.op.suppressEvent();
            bu.addOp(revision.getChange().getId(), selfAddition.op);
        }
        // Add WorkInProgressOp if requested.
        if ((input.ready || input.workInProgress) && didWorkInProgressChange(revision.getChange().isWorkInProgress(), input)) {
            if (input.ready && input.workInProgress) {
                output.error = ERROR_WIP_READY_MUTUALLY_EXCLUSIVE;
                return Response.withStatusCode(SC_BAD_REQUEST, output);
            }
            revision.getChangeResource().permissions().check(ChangePermission.TOGGLE_WORK_IN_PROGRESS_STATE);
            if (input.ready) {
                output.ready = true;
            }
            logger.atFine().log("setting work-in-progress to %s", input.workInProgress);
            WorkInProgressOp wipOp = workInProgressOpFactory.create(input.workInProgress, new WorkInProgressOp.Input());
            wipOp.suppressEmail();
            bu.addOp(revision.getChange().getId(), wipOp);
        }
        // Add the review op.
        logger.atFine().log("posting review");
        bu.addOp(revision.getChange().getId(), new Op(projectState, revision.getPatchSet().id(), input));
        // Notify based on ReviewInput, ignoring the notify settings from any ReviewerInputs.
        NotifyResolver.Result notify = notifyResolver.resolve(input.notify, input.notifyDetails);
        bu.setNotify(notify);
        // Adjust the attention set based on the input
        replyAttentionSetUpdates.updateAttentionSet(bu, revision.getNotes(), input, revision.getUser());
        bu.execute();
        // Re-read change to take into account results of the update.
        ChangeData cd = changeDataFactory.create(revision.getProject(), revision.getChange().getId());
        for (ReviewerModification reviewerResult : reviewerResults) {
            reviewerResult.gatherResults(cd);
        }
        // Sending emails and events from ReviewersOps was suppressed so we can send a single batch
        // email/event here.
        batchEmailReviewers(revision.getUser(), revision.getChange(), reviewerResults, notify);
        batchReviewerEvents(revision.getUser(), cd, revision.getPatchSet(), reviewerResults, ts);
    }
    return Response.ok(output);
}
Also used : ON_BEHALF_OF(com.google.gerrit.server.permissions.LabelPermission.ForUser.ON_BEHALF_OF) Whitespace(com.google.gerrit.extensions.client.DiffPreferencesInfo.Whitespace) ProjectCache(com.google.gerrit.server.project.ProjectCache) Comment(com.google.gerrit.entities.Comment) FixSuggestion(com.google.gerrit.entities.FixSuggestion) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) PermissionBackend(com.google.gerrit.server.permissions.PermissionBackend) ReviewResult(com.google.gerrit.extensions.api.changes.ReviewResult) ReviewerSet(com.google.gerrit.server.ReviewerSet) DiffSummaryKey(com.google.gerrit.server.patch.DiffSummaryKey) Config(org.eclipse.jgit.lib.Config) Map(java.util.Map) FixReplacement(com.google.gerrit.entities.FixReplacement) DraftHandling(com.google.gerrit.extensions.api.changes.ReviewInput.DraftHandling) Side(com.google.gerrit.extensions.client.Side) Metadata(com.google.gerrit.server.logging.Metadata) GerritServerConfig(com.google.gerrit.server.config.GerritServerConfig) TraceContext(com.google.gerrit.server.logging.TraceContext) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Set(java.util.Set) Collectors.joining(java.util.stream.Collectors.joining) NotifyHandling(com.google.gerrit.extensions.api.changes.NotifyHandling) Stream(java.util.stream.Stream) CommentAdded(com.google.gerrit.server.extensions.events.CommentAdded) AutoValue(com.google.auto.value.AutoValue) DiffSummary(com.google.gerrit.server.patch.DiffSummary) PluginSetContext(com.google.gerrit.server.plugincontext.PluginSetContext) Counter1(com.google.gerrit.metrics.Counter1) MetricMaker(com.google.gerrit.metrics.MetricMaker) PatchListKey(com.google.gerrit.server.patch.PatchListKey) FluentLogger(com.google.common.flogger.FluentLogger) Joiner(com.google.common.base.Joiner) ChangeMessagesUtil(com.google.gerrit.server.ChangeMessagesUtil) Singleton(com.google.inject.Singleton) AccountCache(com.google.gerrit.server.account.AccountCache) PermissionBackendException(com.google.gerrit.server.permissions.PermissionBackendException) ConfigInvalidException(org.eclipse.jgit.errors.ConfigInvalidException) ReviewerResult(com.google.gerrit.extensions.api.changes.ReviewerResult) UnprocessableEntityException(com.google.gerrit.extensions.restapi.UnprocessableEntityException) Collectors.groupingBy(java.util.stream.Collectors.groupingBy) CommentsUtil(com.google.gerrit.server.CommentsUtil) CommentForValidation(com.google.gerrit.extensions.validators.CommentForValidation) Response(com.google.gerrit.extensions.restapi.Response) ArrayList(java.util.ArrayList) PATCHSET_LEVEL(com.google.gerrit.entities.Patch.PATCHSET_LEVEL) Strings(com.google.common.base.Strings) ReviewerInput(com.google.gerrit.extensions.api.changes.ReviewerInput) Lists(com.google.common.collect.Lists) ReviewerModification(com.google.gerrit.server.change.ReviewerModifier.ReviewerModification) Description(com.google.gerrit.metrics.Description) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) PatchSet(com.google.gerrit.entities.PatchSet) RestApiException(com.google.gerrit.extensions.restapi.RestApiException) Address(com.google.gerrit.entities.Address) REVIEWER(com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER) ProjectCache.illegalState(com.google.gerrit.server.project.ProjectCache.illegalState) NotifyResolver(com.google.gerrit.server.change.NotifyResolver) HashCode(com.google.common.hash.HashCode) Result(com.google.gerrit.server.change.ReviewerOp.Result) PatchListCache(com.google.gerrit.server.patch.PatchListCache) StorageException(com.google.gerrit.exceptions.StorageException) CommentValidationFailure(com.google.gerrit.extensions.validators.CommentValidationFailure) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) IOException(java.io.IOException) RobotCommentInput(com.google.gerrit.extensions.api.changes.ReviewInput.RobotCommentInput) ChangeUpdate(com.google.gerrit.server.notedb.ChangeUpdate) IdentifiedUser(com.google.gerrit.server.IdentifiedUser) ReviewInput(com.google.gerrit.extensions.api.changes.ReviewInput) LabelVote(com.google.gerrit.server.util.LabelVote) SC_BAD_REQUEST(javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST) TimeUtil(com.google.gerrit.server.util.time.TimeUtil) CommentValidator(com.google.gerrit.extensions.validators.CommentValidator) AccountState(com.google.gerrit.server.account.AccountState) Patch(com.google.gerrit.entities.Patch) Inject(com.google.inject.Inject) HumanComment(com.google.gerrit.entities.HumanComment) UpdateException(com.google.gerrit.server.update.UpdateException) RestModifyView(com.google.gerrit.extensions.restapi.RestModifyView) PatchSetApproval(com.google.gerrit.entities.PatchSetApproval) LabelTypes(com.google.gerrit.entities.LabelTypes) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) LabelType(com.google.gerrit.entities.LabelType) AuthException(com.google.gerrit.extensions.restapi.AuthException) ReviewerModifier(com.google.gerrit.server.change.ReviewerModifier) Collectors.toSet(java.util.stream.Collectors.toSet) Timestamp(java.sql.Timestamp) Collection(java.util.Collection) Account(com.google.gerrit.entities.Account) Streams(com.google.common.collect.Streams) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) ApprovalsUtil(com.google.gerrit.server.approval.ApprovalsUtil) Objects(java.util.Objects) ChangeData(com.google.gerrit.server.query.change.ChangeData) List(java.util.List) Nullable(com.google.gerrit.common.Nullable) FixSuggestionInfo(com.google.gerrit.extensions.common.FixSuggestionInfo) Url(com.google.gerrit.extensions.restapi.Url) Optional(java.util.Optional) MoreObjects.firstNonNull(com.google.common.base.MoreObjects.firstNonNull) BatchUpdateOp(com.google.gerrit.server.update.BatchUpdateOp) LabelPermission(com.google.gerrit.server.permissions.LabelPermission) PatchListNotAvailableException(com.google.gerrit.server.patch.PatchListNotAvailableException) WorkInProgressOp(com.google.gerrit.server.change.WorkInProgressOp) CommentValidationContext(com.google.gerrit.extensions.validators.CommentValidationContext) PublishCommentUtil(com.google.gerrit.server.PublishCommentUtil) ChangePermission(com.google.gerrit.server.permissions.ChangePermission) Hashing(com.google.common.hash.Hashing) ReviewerState(com.google.gerrit.extensions.client.ReviewerState) HashMap(java.util.HashMap) HashSet(java.util.HashSet) CommentsRejectedException(com.google.gerrit.server.update.CommentsRejectedException) ImmutableList(com.google.common.collect.ImmutableList) ChangeResource(com.google.gerrit.server.change.ChangeResource) PostUpdateContext(com.google.gerrit.server.update.PostUpdateContext) CommentInput(com.google.gerrit.extensions.api.changes.ReviewInput.CommentInput) Range(com.google.gerrit.extensions.client.Comment.Range) RobotComment(com.google.gerrit.entities.RobotComment) Field(com.google.gerrit.metrics.Field) Change(com.google.gerrit.entities.Change) ChangeUtil(com.google.gerrit.server.ChangeUtil) ChangeContext(com.google.gerrit.server.update.ChangeContext) ModifyReviewersEmail(com.google.gerrit.server.change.ModifyReviewersEmail) FixReplacementInfo(com.google.gerrit.extensions.common.FixReplacementInfo) CurrentUser(com.google.gerrit.server.CurrentUser) AccountResolver(com.google.gerrit.server.account.AccountResolver) Iterator(java.util.Iterator) UTF_8(java.nio.charset.StandardCharsets.UTF_8) ReviewerAdded(com.google.gerrit.server.extensions.events.ReviewerAdded) ProjectState(com.google.gerrit.server.project.ProjectState) Maps(com.google.common.collect.Maps) ObjectId(org.eclipse.jgit.lib.ObjectId) Collectors.toList(java.util.stream.Collectors.toList) Ordering(com.google.common.collect.Ordering) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) RevisionResource(com.google.gerrit.server.change.RevisionResource) PatchSetUtil(com.google.gerrit.server.PatchSetUtil) EmailReviewComments(com.google.gerrit.server.change.EmailReviewComments) Collections(java.util.Collections) Account(com.google.gerrit.entities.Account) BatchUpdateOp(com.google.gerrit.server.update.BatchUpdateOp) WorkInProgressOp(com.google.gerrit.server.change.WorkInProgressOp) LabelTypes(com.google.gerrit.entities.LabelTypes) NotifyResolver(com.google.gerrit.server.change.NotifyResolver) ReviewerResult(com.google.gerrit.extensions.api.changes.ReviewerResult) ReviewResult(com.google.gerrit.extensions.api.changes.ReviewResult) WorkInProgressOp(com.google.gerrit.server.change.WorkInProgressOp) ChangeData(com.google.gerrit.server.query.change.ChangeData) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) ReviewerSet(com.google.gerrit.server.ReviewerSet) ProjectState(com.google.gerrit.server.project.ProjectState) ReviewerModification(com.google.gerrit.server.change.ReviewerModifier.ReviewerModification) ReviewerInput(com.google.gerrit.extensions.api.changes.ReviewerInput)

Aggregations

IOException (java.io.IOException)4 ArrayList (java.util.ArrayList)4 Collections (java.util.Collections)4 HashMap (java.util.HashMap)4 HashSet (java.util.HashSet)4 List (java.util.List)4 Map (java.util.Map)4 Set (java.util.Set)4 SC_BAD_REQUEST (javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST)4 Strings (com.google.common.base.Strings)3 Lists (com.google.common.collect.Lists)3 Nullable (com.google.gerrit.common.Nullable)3 Joiner (com.google.common.base.Joiner)2 ImmutableList (com.google.common.collect.ImmutableList)2 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)2 FluentLogger (com.google.common.flogger.FluentLogger)2 AuthException (com.google.gerrit.extensions.restapi.AuthException)2 BadRequestException (com.google.gerrit.extensions.restapi.BadRequestException)2 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)2 Response (com.google.gerrit.extensions.restapi.Response)2