Search in sources :

Example 1 with RequestInfo

use of com.google.gerrit.server.RequestInfo in project gerrit by GerritCodeReview.

the class RestApiServlet method createRequestInfo.

private RequestInfo createRequestInfo(TraceContext traceContext, String requestUri, List<IdString> path) {
    RequestInfo.Builder requestInfo = RequestInfo.builder(RequestInfo.RequestType.REST, globals.currentUser.get(), traceContext).requestUri(requestUri);
    if (path.size() < 1) {
        return requestInfo.build();
    }
    RestCollection<?, ?> rootCollection = members.get();
    String resourceId = path.get(0).get();
    if (rootCollection instanceof ProjectsCollection) {
        requestInfo.project(Project.nameKey(resourceId));
    } else if (rootCollection instanceof ChangesCollection) {
        Optional<ChangeNotes> changeNotes = globals.changeFinder.findOne(resourceId);
        if (changeNotes.isPresent()) {
            requestInfo.project(changeNotes.get().getProjectName());
        }
    }
    return requestInfo.build();
}
Also used : Optional(java.util.Optional) ChangesCollection(com.google.gerrit.server.restapi.change.ChangesCollection) IdString(com.google.gerrit.extensions.restapi.IdString) ProjectsCollection(com.google.gerrit.server.restapi.project.ProjectsCollection) RequestInfo(com.google.gerrit.server.RequestInfo)

Example 2 with RequestInfo

use of com.google.gerrit.server.RequestInfo in project gerrit by GerritCodeReview.

the class SshCommand method start.

@Override
public void start(ChannelSession channel, Environment env) throws IOException {
    startThread(() -> {
        try (DynamicOptions pluginOptions = new DynamicOptions(injector, dynamicBeans)) {
            parseCommandLine(pluginOptions);
            stdout = toPrintWriter(out);
            stderr = toPrintWriter(err);
            try (TraceContext traceContext = enableTracing();
                PerformanceLogContext performanceLogContext = new PerformanceLogContext(config, performanceLoggers)) {
                RequestInfo requestInfo = RequestInfo.builder(RequestInfo.RequestType.SSH, user, traceContext).build();
                try (RequestStateContext requestStateContext = RequestStateContext.open().addRequestStateProvider(deadlineCheckerFactory.create(requestInfo, deadline))) {
                    requestListeners.runEach(l -> l.onRequest(requestInfo));
                    SshCommand.this.run();
                } catch (InvalidDeadlineException e) {
                    stderr.println(e.getMessage());
                } catch (RuntimeException e) {
                    Optional<RequestCancelledException> requestCancelledException = RequestCancelledException.getFromCausalChain(e);
                    if (!requestCancelledException.isPresent()) {
                        Throwables.throwIfUnchecked(e);
                    }
                    cancellationMetrics.countCancelledRequest(requestInfo, requestCancelledException.get().getCancellationReason());
                    StringBuilder msg = new StringBuilder(requestCancelledException.get().formatCancellationReason());
                    if (requestCancelledException.get().getCancellationMessage().isPresent()) {
                        msg.append(String.format(" (%s)", requestCancelledException.get().getCancellationMessage().get()));
                    }
                    stderr.println(msg.toString());
                }
            } finally {
                stdout.flush();
                stderr.flush();
            }
        }
    }, AccessPath.SSH_COMMAND);
}
Also used : DynamicOptions(com.google.gerrit.server.DynamicOptions) RequestStateContext(com.google.gerrit.server.cancellation.RequestStateContext) InvalidDeadlineException(com.google.gerrit.server.InvalidDeadlineException) Optional(java.util.Optional) TraceContext(com.google.gerrit.server.logging.TraceContext) RequestInfo(com.google.gerrit.server.RequestInfo) PerformanceLogContext(com.google.gerrit.server.logging.PerformanceLogContext)

Example 3 with RequestInfo

use of com.google.gerrit.server.RequestInfo in project gerrit by GerritCodeReview.

the class ReceiveCommits method processCommands.

ReceiveCommitsResult processCommands(Collection<ReceiveCommand> commands, MultiProgressMonitor progress) throws StorageException {
    checkState(!used, "Tried to re-use a ReceiveCommits objects that is single-use only");
    long start = TimeUtil.nowNanos();
    parsePushOptions();
    String clientProvidedDeadlineValue = Iterables.getLast(pushOptions.get("deadline"), /* defaultValue= */
    null);
    int commandCount = commands.size();
    try (TraceContext traceContext = TraceContext.newTrace(tracePushOption.isPresent(), tracePushOption.orElse(null), (tagName, traceId) -> addMessage(tagName + ": " + traceId));
        PerformanceLogContext performanceLogContext = new PerformanceLogContext(config, performanceLoggers);
        TraceTimer traceTimer = newTimer("processCommands", Metadata.builder().resourceCount(commandCount))) {
        RequestInfo requestInfo = RequestInfo.builder(RequestInfo.RequestType.GIT_RECEIVE, user, traceContext).project(project.getNameKey()).build();
        requestListeners.runEach(l -> l.onRequest(requestInfo));
        traceContext.addTag(RequestId.Type.RECEIVE_ID, new RequestId(project.getNameKey().get()));
        // Log the push options here, rather than in parsePushOptions(), so that they are included
        // into the trace if tracing is enabled.
        logger.atFine().log("push options: %s", receivePack.getPushOptions());
        Task commandProgress = progress.beginSubTask("refs", UNKNOWN);
        commands = commands.stream().map(c -> wrapReceiveCommand(c, commandProgress)).collect(toList());
        try (RequestStateContext requestStateContext = RequestStateContext.open().addRequestStateProvider(progress).addRequestStateProvider(deadlineCheckerFactory.create(start, requestInfo, clientProvidedDeadlineValue))) {
            processCommandsUnsafe(commands, progress);
            rejectRemaining(commands, INTERNAL_SERVER_ERROR);
        } catch (InvalidDeadlineException e) {
            rejectRemaining(commands, e.getMessage());
        } catch (RuntimeException e) {
            Optional<RequestCancelledException> requestCancelledException = RequestCancelledException.getFromCausalChain(e);
            if (!requestCancelledException.isPresent()) {
                Throwables.throwIfUnchecked(e);
            }
            cancellationMetrics.countCancelledRequest(requestInfo, requestCancelledException.get().getCancellationReason());
            StringBuilder msg = new StringBuilder(requestCancelledException.get().formatCancellationReason());
            if (requestCancelledException.get().getCancellationMessage().isPresent()) {
                msg.append(String.format(" (%s)", requestCancelledException.get().getCancellationMessage().get()));
            }
            rejectRemaining(commands, msg.toString());
        }
        // This sends error messages before the 'done' string of the progress monitor is sent.
        // Currently, the test framework relies on this ordering to understand if pushes completed
        // successfully.
        sendErrorMessages();
        commandProgress.end();
        loggingTags = traceContext.getTags();
        logger.atFine().log("Processing commands done.");
    }
    progress.end();
    return result.build();
}
Also used : Task(com.google.gerrit.server.git.MultiProgressMonitor.Task) RequestStateContext(com.google.gerrit.server.cancellation.RequestStateContext) RequestId(com.google.gerrit.server.logging.RequestId) Optional(java.util.Optional) RequestInfo(com.google.gerrit.server.RequestInfo) PerformanceLogContext(com.google.gerrit.server.logging.PerformanceLogContext) InvalidDeadlineException(com.google.gerrit.server.InvalidDeadlineException) TraceTimer(com.google.gerrit.server.logging.TraceContext.TraceTimer) TraceContext(com.google.gerrit.server.logging.TraceContext)

Example 4 with RequestInfo

use of com.google.gerrit.server.RequestInfo in project gerrit by GerritCodeReview.

the class Upload method runImpl.

@Override
protected void runImpl() throws IOException, Failure {
    PermissionBackend.ForProject perm = permissionBackend.user(user).project(projectState.getNameKey());
    try {
        perm.check(ProjectPermission.RUN_UPLOAD_PACK);
    } catch (AuthException e) {
        throw new Failure(1, "fatal: upload-pack not permitted on this server", e);
    } catch (PermissionBackendException e) {
        throw new Failure(1, "fatal: unable to check permissions ", e);
    }
    Repository permissionAwareRepo = PermissionAwareRepositoryManager.wrap(repo, perm);
    UploadPack up = new UploadPack(permissionAwareRepo);
    up.setPackConfig(config.getPackConfig());
    up.setTimeout(config.getTimeout());
    up.setPostUploadHook(PostUploadHookChain.newChain(Lists.newArrayList(postUploadHooks)));
    if (projectState.isAllUsers()) {
        up.setAdvertiseRefsHook(usersSelfAdvertiseRefsHook);
    }
    if (extraParameters != null) {
        up.setExtraParameters(ImmutableList.copyOf(extraParameters));
    }
    List<PreUploadHook> allPreUploadHooks = Lists.newArrayList(preUploadHooks);
    allPreUploadHooks.add(uploadValidatorsFactory.create(project, permissionAwareRepo, session.getRemoteAddressAsString()));
    up.setPreUploadHook(PreUploadHookChain.newChain(allPreUploadHooks));
    for (UploadPackInitializer initializer : uploadPackInitializers) {
        initializer.init(projectState.getNameKey(), up);
    }
    try (TraceContext traceContext = TraceContext.open();
        TracingHook tracingHook = new TracingHook()) {
        RequestInfo requestInfo = RequestInfo.builder(RequestInfo.RequestType.GIT_UPLOAD, user, traceContext).project(projectState.getNameKey()).build();
        requestListeners.runEach(l -> l.onRequest(requestInfo));
        up.setProtocolV2Hook(tracingHook);
        up.upload(in, out, err);
        session.setPeerAgent(up.getPeerUserAgent());
        stats = up.getStatistics();
    } catch (UploadValidationException e) {
        // internal server error to the client.
        if (!e.isOutput()) {
            up.sendMessage(e.getMessage());
        }
    }
}
Also used : PermissionBackend(com.google.gerrit.server.permissions.PermissionBackend) UploadPackInitializer(com.google.gerrit.server.git.UploadPackInitializer) UploadPack(org.eclipse.jgit.transport.UploadPack) AuthException(com.google.gerrit.extensions.restapi.AuthException) PermissionBackendException(com.google.gerrit.server.permissions.PermissionBackendException) RequestInfo(com.google.gerrit.server.RequestInfo) PreUploadHook(org.eclipse.jgit.transport.PreUploadHook) Repository(org.eclipse.jgit.lib.Repository) UploadValidationException(com.google.gerrit.server.git.validators.UploadValidationException) TracingHook(com.google.gerrit.server.git.TracingHook) TraceContext(com.google.gerrit.server.logging.TraceContext)

Example 5 with RequestInfo

use of com.google.gerrit.server.RequestInfo 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)

Aggregations

RequestInfo (com.google.gerrit.server.RequestInfo)5 TraceContext (com.google.gerrit.server.logging.TraceContext)4 Optional (java.util.Optional)3 AuthException (com.google.gerrit.extensions.restapi.AuthException)2 InvalidDeadlineException (com.google.gerrit.server.InvalidDeadlineException)2 RequestStateContext (com.google.gerrit.server.cancellation.RequestStateContext)2 PerformanceLogContext (com.google.gerrit.server.logging.PerformanceLogContext)2 PermissionBackend (com.google.gerrit.server.permissions.PermissionBackend)2 PermissionBackendException (com.google.gerrit.server.permissions.PermissionBackendException)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 Joiner (com.google.common.base.Joiner)1 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)1 Preconditions.checkState (com.google.common.base.Preconditions.checkState)1 Splitter (com.google.common.base.Splitter)1 Strings (com.google.common.base.Strings)1 Throwables (com.google.common.base.Throwables)1 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)1 ImmutableListMultimap (com.google.common.collect.ImmutableListMultimap)1 ImmutableSet (com.google.common.collect.ImmutableSet)1