Search in sources :

Example 1 with HttpContentProducer

use of co.cask.cdap.api.service.http.HttpContentProducer in project cdap by caskdata.

the class DelayedHttpServiceResponder method execute.

/**
 * Calls to other responder methods in this class only cache the response to be sent. The response is actually
 * sent only when this method is called.
 *
 * @param keepAlive {@code true} to keep the connection open; {@code false} otherwise
 */
public void execute(boolean keepAlive) {
    Preconditions.checkState(bufferedResponse != null, "Can not call execute before one of the other responder methods are called.");
    try {
        HttpContentProducer contentProducer = bufferedResponse.getContentProducer();
        HttpHeaders headers = new DefaultHttpHeaders().add(bufferedResponse.getHeaders());
        headers.set(HttpHeaderNames.CONNECTION, keepAlive ? HttpHeaderValues.KEEP_ALIVE : HttpHeaderValues.CLOSE);
        if (!headers.contains(HttpHeaderNames.CONTENT_TYPE)) {
            headers.set(HttpHeaderNames.CONTENT_TYPE, bufferedResponse.getContentType());
        }
        if (contentProducer != null) {
            responder.sendContent(HttpResponseStatus.valueOf(bufferedResponse.getStatus()), bodyProducerFactory.create(contentProducer, taskExecutor), headers);
        } else {
            responder.sendContent(HttpResponseStatus.valueOf(bufferedResponse.getStatus()), bufferedResponse.getContentBuffer(), headers);
        }
        emitMetrics(bufferedResponse.getStatus());
    } finally {
        close();
    }
}
Also used : HttpHeaders(io.netty.handler.codec.http.HttpHeaders) EmptyHttpHeaders(io.netty.handler.codec.http.EmptyHttpHeaders) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) HttpContentProducer(co.cask.cdap.api.service.http.HttpContentProducer)

Example 2 with HttpContentProducer

use of co.cask.cdap.api.service.http.HttpContentProducer in project cdap by caskdata.

the class AbstractHttpHandlerDelegator method wrapResponder.

/**
   * Returns a new instance of {@link DelayedHttpServiceResponder} that wraps around the given {@link HttpResponder}
   * object. This method is called from handler class generated by {@link HttpHandlerGenerator}.
   */
@SuppressWarnings("unused")
protected final DelayedHttpServiceResponder wrapResponder(HttpResponder responder) {
    MetricsContext collector = this.metricsContext;
    HttpServiceContext serviceContext = context.getServiceContext();
    Preconditions.checkState(serviceContext instanceof TransactionalHttpServiceContext, "This instance of HttpServiceContext does not support transactions.");
    if (serviceContext.getSpecification() != null) {
        collector = metricsContext.childContext(Constants.Metrics.Tag.HANDLER, serviceContext.getSpecification().getName());
    }
    return new DelayedHttpServiceResponder(responder, new BodyProducerFactory() {

        @Override
        public BodyProducer create(HttpContentProducer contentProducer, TransactionalHttpServiceContext serviceContext) {
            final ClassLoader programContextClassLoader = new CombineClassLoader(null, ImmutableList.of(contentProducer.getClass().getClassLoader(), getClass().getClassLoader()));
            // Capture the context since we need to keep it until the end of the content producing.
            // We don't need to worry about double capturing of the context when HttpContentConsumer is used.
            // This is because when HttpContentConsumer is used, the responder constructed here will get closed and this
            // BodyProducerFactory won't be used.
            final Cancellable contextReleaser = context.capture();
            return new BodyProducerAdapter(contentProducer, serviceContext, programContextClassLoader, contextReleaser);
        }
    }, (TransactionalHttpServiceContext) serviceContext, collector);
}
Also used : BodyProducer(co.cask.http.BodyProducer) CombineClassLoader(co.cask.cdap.common.lang.CombineClassLoader) HttpServiceContext(co.cask.cdap.api.service.http.HttpServiceContext) Cancellable(org.apache.twill.common.Cancellable) MetricsContext(co.cask.cdap.api.metrics.MetricsContext) HttpContentProducer(co.cask.cdap.api.service.http.HttpContentProducer) CombineClassLoader(co.cask.cdap.common.lang.CombineClassLoader)

Example 3 with HttpContentProducer

use of co.cask.cdap.api.service.http.HttpContentProducer in project cdap by caskdata.

the class AbstractHttpHandlerDelegator method wrapContentConsumer.

/**
   * Returns a new instance of {@link BodyConsumer} that wraps around the given {@link HttpContentConsumer}
   * and {@link DelayedHttpServiceResponder}.
   *
   * IMPORTANT: This method will also capture the context associated with the current thread, hence after
   * this method is called, no other methods on this class should be called from the current thread.
   *
   * This method is called from handler class generated by {@link HttpHandlerGenerator}.
   */
@SuppressWarnings("unused")
protected final BodyConsumer wrapContentConsumer(HttpContentConsumer consumer, DelayedHttpServiceResponder responder) {
    Preconditions.checkState(!responder.hasBufferedResponse(), "HttpContentConsumer may not be used after a response has already been sent.");
    // Close the provided responder since a new one will be created for the BodyConsumerAdapter to use.
    responder.close();
    final HttpServiceContext serviceContext = context.getServiceContext();
    Preconditions.checkState(serviceContext instanceof TransactionalHttpServiceContext, "This instance of HttpServiceContext does not support transactions.");
    final Cancellable contextReleaser = context.capture();
    final ClassLoader programContextClassLoader = new CombineClassLoader(null, ImmutableList.of(consumer.getClass().getClassLoader(), getClass().getClassLoader()));
    return new BodyConsumerAdapter(new DelayedHttpServiceResponder(responder, new BodyProducerFactory() {

        @Override
        public BodyProducer create(HttpContentProducer contentProducer, TransactionalHttpServiceContext serviceContext) {
            // Transfer the captured context from the content consumer to the content producer
            return new BodyProducerAdapter(contentProducer, serviceContext, programContextClassLoader, contextReleaser);
        }
    }), consumer, serviceContext, programContextClassLoader, contextReleaser);
}
Also used : CombineClassLoader(co.cask.cdap.common.lang.CombineClassLoader) HttpServiceContext(co.cask.cdap.api.service.http.HttpServiceContext) Cancellable(org.apache.twill.common.Cancellable) HttpContentProducer(co.cask.cdap.api.service.http.HttpContentProducer) CombineClassLoader(co.cask.cdap.common.lang.CombineClassLoader)

Aggregations

HttpContentProducer (co.cask.cdap.api.service.http.HttpContentProducer)3 HttpServiceContext (co.cask.cdap.api.service.http.HttpServiceContext)2 CombineClassLoader (co.cask.cdap.common.lang.CombineClassLoader)2 Cancellable (org.apache.twill.common.Cancellable)2 MetricsContext (co.cask.cdap.api.metrics.MetricsContext)1 BodyProducer (co.cask.http.BodyProducer)1 DefaultHttpHeaders (io.netty.handler.codec.http.DefaultHttpHeaders)1 EmptyHttpHeaders (io.netty.handler.codec.http.EmptyHttpHeaders)1 HttpHeaders (io.netty.handler.codec.http.HttpHeaders)1