Search in sources :

Example 16 with AsyncCallback

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;
}
Also used : Exchange(org.apache.camel.Exchange) AsyncCallback(org.apache.camel.AsyncCallback) Synchronization(org.apache.camel.spi.Synchronization)

Example 17 with AsyncCallback

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);
    }
}
Also used : DefaultExchange(org.apache.camel.impl.DefaultExchange) Continuation(org.eclipse.jetty.continuation.Continuation) AsyncCallback(org.apache.camel.AsyncCallback) IOException(java.io.IOException) HttpConsumer(org.apache.camel.http.common.HttpConsumer) ServletException(javax.servlet.ServletException) TimeoutException(java.util.concurrent.TimeoutException) IOException(java.io.IOException) DefaultExchange(org.apache.camel.impl.DefaultExchange) Exchange(org.apache.camel.Exchange) ServletException(javax.servlet.ServletException) HttpMessage(org.apache.camel.http.common.HttpMessage) HttpCommonEndpoint(org.apache.camel.http.common.HttpCommonEndpoint) TimeoutException(java.util.concurrent.TimeoutException)

Example 18 with AsyncCallback

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);
        }
    }
}
Also used : Exchange(org.apache.camel.Exchange) Message(javax.jms.Message) JmsMessage(org.apache.camel.component.jms.JmsMessage) AsyncCallback(org.apache.camel.AsyncCallback) ExchangeTimedOutException(org.apache.camel.ExchangeTimedOutException) JMSException(javax.jms.JMSException) ExchangeTimedOutException(org.apache.camel.ExchangeTimedOutException) Session(javax.jms.Session) JmsMessage(org.apache.camel.component.jms.JmsMessage)

Example 19 with AsyncCallback

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");
}
Also used : Exchange(org.apache.camel.Exchange) Destination(javax.jms.Destination) AsyncCallback(org.apache.camel.AsyncCallback) RuntimeCamelException(org.apache.camel.RuntimeCamelException) ObjectHelper.wrapRuntimeCamelException(org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException) RuntimeCamelException(org.apache.camel.RuntimeCamelException) RollbackExchangeException(org.apache.camel.RollbackExchangeException) JMSException(javax.jms.JMSException) ObjectHelper.wrapRuntimeCamelException(org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException)

Example 20 with AsyncCallback

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);
        }
    });
}
Also used : Exchange(org.apache.camel.Exchange) MqttMessage(org.eclipse.paho.client.mqttv3.MqttMessage) AsyncCallback(org.apache.camel.AsyncCallback) MqttCallback(org.eclipse.paho.client.mqttv3.MqttCallback) IMqttDeliveryToken(org.eclipse.paho.client.mqttv3.IMqttDeliveryToken)

Aggregations

AsyncCallback (org.apache.camel.AsyncCallback)67 Exchange (org.apache.camel.Exchange)47 AsyncProcessor (org.apache.camel.AsyncProcessor)12 CamelExchangeException (org.apache.camel.CamelExchangeException)8 Message (org.apache.camel.Message)5 Processor (org.apache.camel.Processor)5 CountDownLatch (java.util.concurrent.CountDownLatch)4 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)4 Endpoint (org.apache.camel.Endpoint)4 Producer (org.apache.camel.Producer)4 Synchronization (org.apache.camel.spi.Synchronization)4 StopWatch (org.apache.camel.util.StopWatch)4 InetSocketAddress (java.net.InetSocketAddress)3 HashMap (java.util.HashMap)3 Map (java.util.Map)3 ExchangePattern (org.apache.camel.ExchangePattern)3 ChannelHandler (io.netty.channel.ChannelHandler)2 IOException (java.io.IOException)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 ConnectException (java.net.ConnectException)2