use of org.apache.camel.AsyncCallback in project camel by apache.
the class S3Consumer method processBatch.
public int processBatch(Queue<Object> exchanges) throws Exception {
int total = exchanges.size();
for (int index = 0; index < total && isBatchAllowed(); index++) {
// only loop if we are started (allowed to run)
final Exchange exchange = ObjectHelper.cast(Exchange.class, exchanges.poll());
// add current index and total as properties
exchange.setProperty(Exchange.BATCH_INDEX, index);
exchange.setProperty(Exchange.BATCH_SIZE, total);
exchange.setProperty(Exchange.BATCH_COMPLETE, index == total - 1);
// update pending number of exchanges
pendingExchanges = total - index - 1;
// add on completion to handle after work when the exchange is done
exchange.addOnCompletion(new Synchronization() {
public void onComplete(Exchange exchange) {
processCommit(exchange);
}
public void onFailure(Exchange exchange) {
processRollback(exchange);
}
@Override
public String toString() {
return "S3ConsumerOnCompletion";
}
});
LOG.trace("Processing exchange [{}]...", exchange);
getAsyncProcessor().process(exchange, new AsyncCallback() {
@Override
public void done(boolean doneSync) {
LOG.trace("Processing exchange [{}] done.", exchange);
}
});
}
return total;
}
use of org.apache.camel.AsyncCallback in project camel by apache.
the class CamelContinuationServlet method doService.
@Override
protected void doService(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
log.trace("Service: {}", request);
// is there a consumer registered for the request.
HttpConsumer consumer = getServletResolveConsumerStrategy().resolve(request, getConsumers());
if (consumer == null) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
// figure out if continuation is enabled and what timeout to use
boolean useContinuation = false;
Long continuationTimeout = null;
HttpCommonEndpoint endpoint = consumer.getEndpoint();
if (endpoint instanceof JettyHttpEndpoint) {
JettyHttpEndpoint jettyEndpoint = (JettyHttpEndpoint) endpoint;
Boolean epUseContinuation = jettyEndpoint.getUseContinuation();
Long epContinuationTimeout = jettyEndpoint.getContinuationTimeout();
if (epUseContinuation != null) {
useContinuation = epUseContinuation;
} else {
useContinuation = jettyEndpoint.getComponent().isUseContinuation();
}
if (epContinuationTimeout != null) {
continuationTimeout = epContinuationTimeout;
} else {
continuationTimeout = jettyEndpoint.getComponent().getContinuationTimeout();
}
}
if (useContinuation) {
log.trace("Start request with continuation timeout of {}", continuationTimeout != null ? continuationTimeout : "jetty default");
} else {
log.trace("Usage of continuation is disabled, either by component or endpoint configuration, fallback to normal servlet processing instead");
super.doService(request, response);
return;
}
if (consumer.getEndpoint().getHttpMethodRestrict() != null) {
Iterator<?> it = ObjectHelper.createIterable(consumer.getEndpoint().getHttpMethodRestrict()).iterator();
boolean match = false;
while (it.hasNext()) {
String method = it.next().toString();
if (method.equalsIgnoreCase(request.getMethod())) {
match = true;
break;
}
}
if (!match) {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
}
if ("TRACE".equals(request.getMethod()) && !consumer.isTraceEnabled()) {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
// we do not support java serialized objects unless explicit enabled
String contentType = request.getContentType();
if (HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT.equals(contentType) && !consumer.getEndpoint().getComponent().isAllowJavaSerializedObject()) {
response.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
return;
}
final Exchange result = (Exchange) request.getAttribute(EXCHANGE_ATTRIBUTE_NAME);
if (result == null) {
// no asynchronous result so leverage continuation
final Continuation continuation = ContinuationSupport.getContinuation(request);
if (continuation.isInitial() && continuationTimeout != null) {
// set timeout on initial
continuation.setTimeout(continuationTimeout);
}
// are we suspended and a request is dispatched initially?
if (consumer.isSuspended() && continuation.isInitial()) {
response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
return;
}
if (continuation.isExpired()) {
String id = (String) continuation.getAttribute(EXCHANGE_ATTRIBUTE_ID);
// remember this id as expired
expiredExchanges.put(id, id);
log.warn("Continuation expired of exchangeId: {}", id);
consumer.getBinding().doWriteExceptionResponse(new TimeoutException(), response);
return;
}
// a new request so create an exchange
final Exchange exchange = new DefaultExchange(consumer.getEndpoint(), ExchangePattern.InOut);
if (consumer.getEndpoint().isBridgeEndpoint()) {
exchange.setProperty(Exchange.SKIP_GZIP_ENCODING, Boolean.TRUE);
exchange.setProperty(Exchange.SKIP_WWW_FORM_URLENCODED, Boolean.TRUE);
}
if (consumer.getEndpoint().isDisableStreamCache()) {
exchange.setProperty(Exchange.DISABLE_HTTP_STREAM_CACHE, Boolean.TRUE);
}
HttpHelper.setCharsetFromContentType(request.getContentType(), exchange);
exchange.setIn(new HttpMessage(exchange, request, response));
// set context path as header
String contextPath = consumer.getEndpoint().getPath();
exchange.getIn().setHeader("CamelServletContextPath", contextPath);
updateHttpPath(exchange, contextPath);
if (log.isTraceEnabled()) {
log.trace("Suspending continuation of exchangeId: {}", exchange.getExchangeId());
}
continuation.setAttribute(EXCHANGE_ATTRIBUTE_ID, exchange.getExchangeId());
// we want to handle the UoW
try {
consumer.createUoW(exchange);
} catch (Exception e) {
log.error("Error processing request", e);
throw new ServletException(e);
}
// must suspend before we process the exchange
continuation.suspend();
ClassLoader oldTccl = overrideTccl(exchange);
if (log.isTraceEnabled()) {
log.trace("Processing request for exchangeId: {}", exchange.getExchangeId());
}
// use the asynchronous API to process the exchange
consumer.getAsyncProcessor().process(exchange, new AsyncCallback() {
public void done(boolean doneSync) {
// check if the exchange id is already expired
boolean expired = expiredExchanges.remove(exchange.getExchangeId()) != null;
if (!expired) {
if (log.isTraceEnabled()) {
log.trace("Resuming continuation of exchangeId: {}", exchange.getExchangeId());
}
// resume processing after both, sync and async callbacks
continuation.setAttribute(EXCHANGE_ATTRIBUTE_NAME, exchange);
continuation.resume();
} else {
log.warn("Cannot resume expired continuation of exchangeId: {}", exchange.getExchangeId());
}
}
});
if (oldTccl != null) {
restoreTccl(exchange, oldTccl);
}
// method again when its resumed
return;
}
try {
// now lets output to the response
if (log.isTraceEnabled()) {
log.trace("Resumed continuation and writing response for exchangeId: {}", result.getExchangeId());
}
Integer bs = consumer.getEndpoint().getResponseBufferSize();
if (bs != null) {
log.trace("Using response buffer size: {}", bs);
response.setBufferSize(bs);
}
consumer.getBinding().writeResponse(result, response);
} catch (IOException e) {
log.error("Error processing request", e);
throw e;
} catch (Exception e) {
log.error("Error processing request", e);
throw new ServletException(e);
} finally {
consumer.doneUoW(result);
}
}
use of org.apache.camel.AsyncCallback in project camel by apache.
the class ReplyManagerSupport method processReply.
public void processReply(ReplyHolder holder) {
if (holder != null && isRunAllowed()) {
try {
Exchange exchange = holder.getExchange();
boolean timeout = holder.isTimeout();
if (timeout) {
// timeout occurred do a WARN log so its easier to spot in the logs
if (log.isWarnEnabled()) {
log.warn("Timeout occurred after {} millis waiting for reply message with correlationID [{}] on destination {}." + " Setting ExchangeTimedOutException on {} and continue routing.", new Object[] { holder.getRequestTimeout(), holder.getCorrelationId(), replyTo, ExchangeHelper.logIds(exchange) });
}
// no response, so lets set a timed out exception
String msg = "reply message with correlationID: " + holder.getCorrelationId() + " not received on destination: " + replyTo;
exchange.setException(new ExchangeTimedOutException(exchange, holder.getRequestTimeout(), msg));
} else {
Message message = holder.getMessage();
Session session = holder.getSession();
JmsMessage response = new JmsMessage(message, session, endpoint.getBinding());
// the JmsBinding is designed to be "pull-based": it will populate the Camel message on demand
// therefore, we link Exchange and OUT message before continuing, so that the JmsBinding has full access
// to everything it may need, and can populate headers, properties, etc. accordingly (solves CAMEL-6218).
exchange.setOut(response);
Object body = response.getBody();
if (endpoint.isTransferException() && body instanceof Exception) {
log.debug("Reply was an Exception. Setting the Exception on the Exchange: {}", body);
// we got an exception back and endpoint was configured to transfer exception
// therefore set response as exception
exchange.setException((Exception) body);
} else {
log.debug("Reply received. OUT message body set to reply payload: {}", body);
}
if (endpoint.isTransferFault()) {
// remove the header as we do not want to keep it on the Camel Message either
Object faultHeader = response.removeHeader(JmsConstants.JMS_TRANSFER_FAULT);
if (faultHeader != null) {
boolean isFault = exchange.getContext().getTypeConverter().tryConvertTo(boolean.class, faultHeader);
log.debug("Transfer fault on OUT message: {}", isFault);
if (isFault) {
exchange.getOut().setFault(true);
}
}
}
// restore correlation id in case the remote server messed with it
if (holder.getOriginalCorrelationId() != null) {
JmsMessageHelper.setCorrelationId(message, holder.getOriginalCorrelationId());
exchange.getOut().setHeader("JMSCorrelationID", holder.getOriginalCorrelationId());
}
}
} finally {
// notify callback
AsyncCallback callback = holder.getCallback();
callback.done(false);
}
}
}
use of org.apache.camel.AsyncCallback in project camel by apache.
the class EndpointMessageListener method onMessage.
@Override
public void onMessage(Message message, Session session) throws JMSException {
LOG.trace("onMessage START");
LOG.debug("{} consumer received JMS message: {}", endpoint, message);
boolean sendReply;
RuntimeCamelException rce;
try {
Object replyDestination = getReplyToDestination(message);
// we can only send back a reply if there was a reply destination configured
// and disableReplyTo hasn't been explicit enabled
sendReply = replyDestination != null && !disableReplyTo;
// we should also not send back reply to ourself if this destination and replyDestination is the same
Destination destination = JmsMessageHelper.getJMSDestination(message);
if (destination != null && sendReply && !endpoint.isReplyToSameDestinationAllowed() && destination.equals(replyDestination)) {
LOG.debug("JMSDestination and JMSReplyTo is the same, will skip sending a reply message to itself: {}", destination);
sendReply = false;
}
final Exchange exchange = createExchange(message, session, replyDestination);
if (eagerLoadingOfProperties) {
exchange.getIn().getHeaders();
}
String correlationId = message.getJMSCorrelationID();
if (correlationId != null) {
LOG.debug("Received Message has JMSCorrelationID [{}]", correlationId);
}
// process the exchange either asynchronously or synchronous
LOG.trace("onMessage.process START");
AsyncCallback callback = new EndpointMessageListenerAsyncCallback(message, exchange, endpoint, sendReply, replyDestination);
// async is by default false, which mean we by default will process the exchange synchronously
// to keep backwards compatible, as well ensure this consumer will pickup messages in order
// (eg to not consume the next message before the previous has been fully processed)
// but if end user explicit configure consumerAsync=true, then we can process the message
// asynchronously (unless endpoint has been configured synchronous, or we use transaction)
boolean forceSync = endpoint.isSynchronous() || endpoint.isTransacted();
if (forceSync || !isAsync()) {
// must process synchronous if transacted or configured to do so
if (LOG.isTraceEnabled()) {
LOG.trace("Processing exchange {} synchronously", exchange.getExchangeId());
}
try {
processor.process(exchange);
} catch (Exception e) {
exchange.setException(e);
} finally {
callback.done(true);
}
} else {
// process asynchronous using the async routing engine
if (LOG.isTraceEnabled()) {
LOG.trace("Processing exchange {} asynchronously", exchange.getExchangeId());
}
boolean sync = processor.process(exchange, callback);
if (!sync) {
// will be done async so return now
return;
}
}
// if we failed processed the exchange from the async callback task, then grab the exception
rce = exchange.getException(RuntimeCamelException.class);
} catch (Exception e) {
rce = wrapRuntimeCamelException(e);
}
// the JMS listener will use the error handler to handle the uncaught exception
if (rce != null) {
LOG.trace("onMessage END throwing exception: {}", rce.getMessage());
// on the JmsEndpoint to handle the exception
throw rce;
}
LOG.trace("onMessage END");
}
use of org.apache.camel.AsyncCallback in project camel by apache.
the class PahoConsumer method doStart.
@Override
protected void doStart() throws Exception {
super.doStart();
String topic = getEndpoint().getTopic();
getEndpoint().getClient().subscribe(topic);
getEndpoint().getClient().setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable cause) {
LOG.debug("MQTT broker connection lost due " + cause.getMessage(), cause);
}
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
LOG.debug("Message arrived on topic: {} -> {}", topic, message);
Exchange exchange = getEndpoint().createExchange(message, topic);
getAsyncProcessor().process(exchange, new AsyncCallback() {
@Override
public void done(boolean doneSync) {
// noop
}
});
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
LOG.debug("Delivery complete. Token: {}", token);
}
});
}
Aggregations