Search in sources :

Example 6 with TaskCloseable

use of io.perfmark.TaskCloseable in project zuul by Netflix.

the class BaseZuulFilterRunner method filter.

protected final O filter(final ZuulFilter<I, O> filter, final I inMesg) {
    final long startTime = System.nanoTime();
    final ZuulMessage snapshot = inMesg.getContext().debugRouting() ? inMesg.clone() : null;
    FilterChainResumer resumer = null;
    try (TaskCloseable ignored = traceTask(filter, f -> f.filterName() + ".filter")) {
        addPerfMarkTags(inMesg);
        ExecutionStatus filterRunStatus = null;
        if (filter.filterType() == INBOUND && inMesg.getContext().shouldSendErrorResponse()) {
            // Pass request down the pipeline, all the way to error endpoint if error response needs to be generated
            filterRunStatus = SKIPPED;
        }
        ;
        try (TaskCloseable ignored2 = traceTask(filter, f -> f.filterName() + ".shouldSkipFilter")) {
            if (shouldSkipFilter(inMesg, filter)) {
                filterRunStatus = SKIPPED;
            }
        }
        if (filter.isDisabled()) {
            filterRunStatus = DISABLED;
        }
        if (filterRunStatus != null) {
            recordFilterCompletion(filterRunStatus, filter, startTime, inMesg, snapshot);
            return filter.getDefaultOutput(inMesg);
        }
        if (!isMessageBodyReadyForFilter(filter, inMesg)) {
            setFilterAwaitingBody(inMesg, true);
            logger.debug("Filter {} waiting for body, UUID {}", filter.filterName(), inMesg.getContext().getUUID());
            // wait for whole body to be buffered
            return null;
        }
        setFilterAwaitingBody(inMesg, false);
        if (snapshot != null) {
            Debug.addRoutingDebug(inMesg.getContext(), "Filter " + filter.filterType().toString() + " " + filter.filterOrder() + " " + filter.filterName());
        }
        // run body contents accumulated so far through this filter
        inMesg.runBufferedBodyContentThroughFilter(filter);
        if (filter.getSyncType() == FilterSyncType.SYNC) {
            final SyncZuulFilter<I, O> syncFilter = (SyncZuulFilter) filter;
            final O outMesg;
            try (TaskCloseable ignored2 = traceTask(filter, f -> f.filterName() + ".apply")) {
                addPerfMarkTags(inMesg);
                outMesg = syncFilter.apply(inMesg);
            }
            recordFilterCompletion(SUCCESS, filter, startTime, inMesg, snapshot);
            return (outMesg != null) ? outMesg : filter.getDefaultOutput(inMesg);
        }
        // async filter
        try (TaskCloseable ignored2 = traceTask(filter, f -> f.filterName() + ".applyAsync")) {
            final Link nettyToSchedulerLink = linkOut();
            filter.incrementConcurrency();
            resumer = new FilterChainResumer(inMesg, filter, snapshot, startTime);
            filter.applyAsync(inMesg).doOnSubscribe(() -> {
                try (TaskCloseable ignored3 = traceTask(filter, f -> f.filterName() + ".onSubscribeAsync")) {
                    linkIn(nettyToSchedulerLink);
                }
            }).doOnNext(resumer.onNextStarted(nettyToSchedulerLink)).doOnError(resumer.onErrorStarted(nettyToSchedulerLink)).doOnCompleted(resumer.onCompletedStarted(nettyToSchedulerLink)).observeOn(Schedulers.from(getChannelHandlerContext(inMesg).executor())).doOnUnsubscribe(resumer::decrementConcurrency).subscribe(resumer);
        }
        // wait for the async filter to finish
        return null;
    } catch (Throwable t) {
        if (resumer != null) {
            resumer.decrementConcurrency();
        }
        final O outMesg = handleFilterException(inMesg, filter, t);
        outMesg.finishBufferedBodyIfIncomplete();
        recordFilterCompletion(FAILED, filter, startTime, inMesg, snapshot);
        return outMesg;
    }
}
Also used : ZuulMessage(com.netflix.zuul.message.ZuulMessage) ExecutionStatus(com.netflix.zuul.ExecutionStatus) SyncZuulFilter(com.netflix.zuul.filters.SyncZuulFilter) Link(io.perfmark.Link) TaskCloseable(io.perfmark.TaskCloseable)

Example 7 with TaskCloseable

use of io.perfmark.TaskCloseable in project zuul by Netflix.

the class BaseZuulFilterRunner method invokeNextStage.

protected final void invokeNextStage(final O zuulMesg) {
    if (nextStage != null) {
        try (TaskCloseable ignored = traceTask(this, s -> s.getClass().getSimpleName() + ".invokeNextStage")) {
            addPerfMarkTags(zuulMesg);
            nextStage.filter(zuulMesg);
        }
    } else {
        // Next stage is Netty channel handler
        try (TaskCloseable ignored = traceTask(this, s -> s.getClass().getSimpleName() + ".fireChannelRead")) {
            addPerfMarkTags(zuulMesg);
            getChannelHandlerContext(zuulMesg).fireChannelRead(zuulMesg);
        }
    }
}
Also used : TaskCloseable(io.perfmark.TaskCloseable)

Example 8 with TaskCloseable

use of io.perfmark.TaskCloseable in project zuul by Netflix.

the class ZuulEndPointRunner method filter.

@Override
public void filter(final HttpRequestMessage zuulReq, final HttpContent chunk) {
    if (zuulReq.getContext().isCancelled()) {
        chunk.release();
        return;
    }
    String endpointName = "-";
    try (TaskCloseable ignored = PerfMark.traceTask(this, s -> s.getClass().getSimpleName() + ".filterChunk")) {
        addPerfMarkTags(zuulReq);
        ZuulFilter<HttpRequestMessage, HttpResponseMessage> endpoint = Preconditions.checkNotNull(getEndpoint(zuulReq), "endpoint");
        endpointName = endpoint.filterName();
        final HttpContent newChunk = endpoint.processContentChunk(zuulReq, chunk);
        if (newChunk != null) {
            // Endpoints do not directly forward content chunks to next stage in the filter chain.
            zuulReq.bufferBodyContents(newChunk);
            // deallocate original chunk if necessary
            if (newChunk != chunk) {
                chunk.release();
            }
            if (isFilterAwaitingBody(zuulReq) && zuulReq.hasCompleteBody() && !(endpoint instanceof ProxyEndpoint)) {
                // whole body has arrived, resume filter chain
                invokeNextStage(filter(endpoint, zuulReq));
            }
        }
    } catch (Exception ex) {
        handleException(zuulReq, endpointName, ex);
    }
}
Also used : HttpResponseMessage(com.netflix.zuul.message.http.HttpResponseMessage) HttpRequestMessage(com.netflix.zuul.message.http.HttpRequestMessage) ProxyEndpoint(com.netflix.zuul.filters.endpoint.ProxyEndpoint) HttpContent(io.netty.handler.codec.http.HttpContent) TaskCloseable(io.perfmark.TaskCloseable)

Example 9 with TaskCloseable

use of io.perfmark.TaskCloseable in project zuul by Netflix.

the class ZuulFilterChainRunner method filter.

@Override
public void filter(T inMesg, HttpContent chunk) {
    String filterName = "-";
    try (TaskCloseable ignored = PerfMark.traceTask(this, s -> s.getClass().getSimpleName() + ".filterChunk")) {
        addPerfMarkTags(inMesg);
        Preconditions.checkNotNull(inMesg, "input message");
        final AtomicInteger runningFilterIdx = getRunningFilterIndex(inMesg);
        final int limit = runningFilterIdx.get();
        for (int i = 0; i < limit; i++) {
            final ZuulFilter<T, T> filter = filters[i];
            filterName = filter.filterName();
            if ((!filter.isDisabled()) && (!shouldSkipFilter(inMesg, filter))) {
                final HttpContent newChunk = filter.processContentChunk(inMesg, chunk);
                if (newChunk == null) {
                    // Filter wants to break the chain and stop propagating this chunk any further
                    return;
                }
                // deallocate original chunk if necessary
                if ((newChunk != chunk) && (chunk.refCnt() > 0)) {
                    chunk.release(chunk.refCnt());
                }
                chunk = newChunk;
            }
        }
        if (limit >= filters.length) {
            // Filter chain has run to end, pass down the channel pipeline
            invokeNextStage(inMesg, chunk);
        } else {
            inMesg.bufferBodyContents(chunk);
            boolean isAwaitingBody = isFilterAwaitingBody(inMesg);
            // Record passport states for start and end of buffering bodies.
            if (isAwaitingBody) {
                CurrentPassport passport = CurrentPassport.fromSessionContext(inMesg.getContext());
                if (inMesg.hasCompleteBody()) {
                    if (inMesg instanceof HttpRequestMessage) {
                        passport.addIfNotAlready(PassportState.FILTERS_INBOUND_BUF_END);
                    } else if (inMesg instanceof HttpResponseMessage) {
                        passport.addIfNotAlready(PassportState.FILTERS_OUTBOUND_BUF_END);
                    }
                } else {
                    if (inMesg instanceof HttpRequestMessage) {
                        passport.addIfNotAlready(PassportState.FILTERS_INBOUND_BUF_START);
                    } else if (inMesg instanceof HttpResponseMessage) {
                        passport.addIfNotAlready(PassportState.FILTERS_OUTBOUND_BUF_START);
                    }
                }
            }
            if (isAwaitingBody && inMesg.hasCompleteBody()) {
                // whole body has arrived, resume filter chain
                runFilters(inMesg, runningFilterIdx);
            }
        }
    } catch (Exception ex) {
        handleException(inMesg, filterName, ex);
    }
}
Also used : CurrentPassport(com.netflix.zuul.passport.CurrentPassport) HttpResponseMessage(com.netflix.zuul.message.http.HttpResponseMessage) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) HttpRequestMessage(com.netflix.zuul.message.http.HttpRequestMessage) HttpContent(io.netty.handler.codec.http.HttpContent) TaskCloseable(io.perfmark.TaskCloseable)

Example 10 with TaskCloseable

use of io.perfmark.TaskCloseable in project zuul by Netflix.

the class ProxyEndpoint method responseFromOrigin.

public void responseFromOrigin(final HttpResponse originResponse) {
    try (TaskCloseable ignore = PerfMark.traceTask("ProxyEndpoint.responseFromOrigin")) {
        PerfMark.attachTag("uuid", zuulRequest, r -> r.getContext().getUUID());
        PerfMark.attachTag("path", zuulRequest, HttpRequestInfo::getPath);
        methodBinding.bind(() -> processResponseFromOrigin(originResponse));
    } catch (Exception ex) {
        unlinkFromOrigin();
        LOG.error("Error in responseFromOrigin", ex);
        channelCtx.fireExceptionCaught(ex);
    }
}
Also used : HttpRequestInfo(com.netflix.zuul.message.http.HttpRequestInfo) ClientException(com.netflix.client.ClientException) ZuulException(com.netflix.zuul.exception.ZuulException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) OutboundException(com.netflix.zuul.exception.OutboundException) TaskCloseable(io.perfmark.TaskCloseable)

Aggregations

TaskCloseable (io.perfmark.TaskCloseable)10 HttpRequestMessage (com.netflix.zuul.message.http.HttpRequestMessage)4 HttpResponseMessage (com.netflix.zuul.message.http.HttpResponseMessage)4 HttpContent (io.netty.handler.codec.http.HttpContent)3 ZuulException (com.netflix.zuul.exception.ZuulException)2 ProxyEndpoint (com.netflix.zuul.filters.endpoint.ProxyEndpoint)2 CurrentPassport (com.netflix.zuul.passport.CurrentPassport)2 ClientException (com.netflix.client.ClientException)1 CompleteEvent (com.netflix.netty.common.HttpLifecycleChannelHandler.CompleteEvent)1 CompleteReason (com.netflix.netty.common.HttpLifecycleChannelHandler.CompleteReason)1 SESSION_COMPLETE (com.netflix.netty.common.HttpLifecycleChannelHandler.CompleteReason.SESSION_COMPLETE)1 SourceAddressChannelHandler (com.netflix.netty.common.SourceAddressChannelHandler)1 SslHandshakeInfo (com.netflix.netty.common.ssl.SslHandshakeInfo)1 RejectionUtils (com.netflix.netty.common.throttle.RejectionUtils)1 Spectator (com.netflix.spectator.api.Spectator)1 ExecutionStatus (com.netflix.zuul.ExecutionStatus)1 CommonContextKeys (com.netflix.zuul.context.CommonContextKeys)1 Debug (com.netflix.zuul.context.Debug)1 SessionContext (com.netflix.zuul.context.SessionContext)1 SessionContextDecorator (com.netflix.zuul.context.SessionContextDecorator)1