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();
}
}
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);
}
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);
}
Aggregations