Search in sources :

Example 6 with TraceContext

use of com.google.gerrit.server.logging.TraceContext in project gerrit by GerritCodeReview.

the class MergeSuperSet method completeChangeSet.

/**
 * Gets the ChangeSet of this {@code change} based on visiblity of the {@code user}. if
 * change.submitWholeTopic is true, we return the topic closure as well as the dependent changes
 * of the topic closure. Otherwise, we return just the dependent changes.
 *
 * @param change the change for which we get the dependent changes / topic closure.
 * @param user the current user for visibility purposes.
 * @param includingTopicClosure when true, return as if change.submitWholeTopic = true, so we
 *     return the topic closure.
 * @return {@link ChangeSet} object that represents the dependent changes and/or topic closure of
 *     the requested change.
 */
public ChangeSet completeChangeSet(Change change, CurrentUser user, boolean includingTopicClosure) throws IOException, PermissionBackendException {
    try {
        if (orm == null) {
            orm = repoManagerProvider.get();
            closeOrm = true;
        }
        ChangeData cd = changeDataFactory.create(change.getProject(), change.getId());
        boolean visible = false;
        if (cd != null) {
            if (projectCache.get(cd.project()).map(ProjectState::statePermitsRead).orElse(false)) {
                try {
                    permissionBackend.user(user).change(cd).check(ChangePermission.READ);
                    visible = true;
                } catch (AuthException e) {
                // Do nothing.
                }
            }
        }
        ChangeSet changeSet = new ChangeSet(cd, visible);
        if (wholeTopicEnabled(cfg) || includingTopicClosure) {
            return completeChangeSetIncludingTopics(changeSet, user);
        }
        try (TraceContext traceContext = PluginContext.newTrace(mergeSuperSetComputation)) {
            return mergeSuperSetComputation.get().completeWithoutTopic(orm, changeSet, user);
        }
    } finally {
        if (closeOrm && orm != null) {
            orm.close();
            orm = null;
        }
    }
}
Also used : AuthException(com.google.gerrit.extensions.restapi.AuthException) TraceContext(com.google.gerrit.server.logging.TraceContext) ChangeData(com.google.gerrit.server.query.change.ChangeData)

Example 7 with TraceContext

use of com.google.gerrit.server.logging.TraceContext 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 8 with TraceContext

use of com.google.gerrit.server.logging.TraceContext 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 9 with TraceContext

use of com.google.gerrit.server.logging.TraceContext in project gerrit by GerritCodeReview.

the class RestApiServlet method enableTracing.

private TraceContext enableTracing(HttpServletRequest req, HttpServletResponse res) {
    // There are 2 ways to enable tracing for REST calls:
    // 1. by using the 'trace' or 'trace=<trace-id>' request parameter
    // 2. by setting the 'X-Gerrit-Trace:' or 'X-Gerrit-Trace:<trace-id>' header
    String traceValueFromHeader = req.getHeader(X_GERRIT_TRACE);
    String traceValueFromRequestParam = req.getParameter(ParameterParser.TRACE_PARAMETER);
    boolean doTrace = traceValueFromHeader != null || traceValueFromRequestParam != null;
    // Check whether no trace ID, one trace ID or 2 different trace IDs have been specified.
    String traceId1;
    String traceId2;
    if (!Strings.isNullOrEmpty(traceValueFromHeader)) {
        traceId1 = traceValueFromHeader;
        if (!Strings.isNullOrEmpty(traceValueFromRequestParam) && !traceValueFromHeader.equals(traceValueFromRequestParam)) {
            traceId2 = traceValueFromRequestParam;
        } else {
            traceId2 = null;
        }
    } else {
        traceId1 = Strings.emptyToNull(traceValueFromRequestParam);
        traceId2 = null;
    }
    // Use the first trace ID to start tracing. If this trace ID is null, a trace ID will be
    // generated.
    TraceContext traceContext = TraceContext.newTrace(doTrace, traceId1, (tagName, traceId) -> res.setHeader(X_GERRIT_TRACE, traceId));
    // If a second trace ID was specified, add a tag for it as well.
    if (traceId2 != null) {
        traceContext.addTag(RequestId.Type.TRACE_ID, traceId2);
        res.addHeader(X_GERRIT_TRACE, traceId2);
    }
    return traceContext;
}
Also used : TraceContext(com.google.gerrit.server.logging.TraceContext) IdString(com.google.gerrit.extensions.restapi.IdString)

Example 10 with TraceContext

use of com.google.gerrit.server.logging.TraceContext in project gerrit by GerritCodeReview.

the class CheckAccess method apply.

public Response<AccessCheckInfo> apply(ProjectResource rsrc, AccessCheckInput input) throws PermissionBackendException, RestApiException, IOException, ConfigInvalidException {
    permissionBackend.user(rsrc.getUser()).check(GlobalPermission.VIEW_ACCESS);
    rsrc.getProjectState().checkStatePermitsRead();
    if (input == null) {
        throw new BadRequestException("input is required");
    }
    if (Strings.isNullOrEmpty(input.account)) {
        throw new BadRequestException("input requires 'account'");
    }
    try (TraceContext traceContext = TraceContext.open()) {
        traceContext.enableAclLogging();
        Account.Id match = accountResolver.resolve(input.account).asUnique().account().id();
        try {
            permissionBackend.absentUser(match).project(rsrc.getNameKey()).check(ProjectPermission.ACCESS);
        } catch (AuthException e) {
            return Response.ok(createInfo(HttpServletResponse.SC_FORBIDDEN, String.format("user %s cannot see project %s", match, rsrc.getName())));
        }
        RefPermission refPerm;
        if (!Strings.isNullOrEmpty(input.permission)) {
            if (Strings.isNullOrEmpty(input.ref)) {
                throw new BadRequestException("must set 'ref' when specifying 'permission'");
            }
            Optional<RefPermission> rp = DefaultPermissionMappings.refPermission(input.permission);
            if (!rp.isPresent()) {
                throw new BadRequestException(String.format("'%s' is not recognized as ref permission", input.permission));
            }
            refPerm = rp.get();
        } else {
            refPerm = RefPermission.READ;
        }
        String message = null;
        if (!Strings.isNullOrEmpty(input.ref)) {
            try {
                permissionBackend.absentUser(match).ref(BranchNameKey.create(rsrc.getNameKey(), input.ref)).check(refPerm);
            } catch (AuthException e) {
                return Response.ok(createInfo(HttpServletResponse.SC_FORBIDDEN, String.format("user %s lacks permission %s for %s in project %s", match, input.permission, input.ref, rsrc.getName())));
            }
        } else {
            // as access denied looks the same as no branches to the user.
            try (Repository repo = gitRepositoryManager.openRepository(rsrc.getNameKey())) {
                if (repo.getRefDatabase().getRefsByPrefix(REFS_HEADS).isEmpty()) {
                    message = "access is OK, but repository has no branches under refs/heads/";
                }
            }
        }
        return Response.ok(createInfo(HttpServletResponse.SC_OK, message));
    }
}
Also used : Account(com.google.gerrit.entities.Account) Repository(org.eclipse.jgit.lib.Repository) RefPermission(com.google.gerrit.server.permissions.RefPermission) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) TraceContext(com.google.gerrit.server.logging.TraceContext) AuthException(com.google.gerrit.extensions.restapi.AuthException)

Aggregations

TraceContext (com.google.gerrit.server.logging.TraceContext)12 AuthException (com.google.gerrit.extensions.restapi.AuthException)5 RequestInfo (com.google.gerrit.server.RequestInfo)4 RequestId (com.google.gerrit.server.logging.RequestId)4 ImmutableSet (com.google.common.collect.ImmutableSet)3 Optional (java.util.Optional)3 Joiner (com.google.common.base.Joiner)2 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)2 ImmutableList (com.google.common.collect.ImmutableList)2 ListMultimap (com.google.common.collect.ListMultimap)2 FluentLogger (com.google.common.flogger.FluentLogger)2 BadRequestException (com.google.gerrit.extensions.restapi.BadRequestException)2 IdString (com.google.gerrit.extensions.restapi.IdString)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 ChangeData (com.google.gerrit.server.query.change.ChangeData)2 HashSet (java.util.HashSet)2