Search in sources :

Example 16 with SynchronizationAdapter

use of org.apache.camel.support.SynchronizationAdapter in project camel by apache.

the class DefaultProducerTemplateAsyncTest method testAsyncCallbackInOutProcessor.

public void testAsyncCallbackInOutProcessor() throws Exception {
    ORDER.set(0);
    final CountDownLatch latch = new CountDownLatch(1);
    template.asyncCallback("direct:echo", new Processor() {

        public void process(Exchange exchange) throws Exception {
            exchange.getIn().setBody("Hello");
            exchange.setPattern(ExchangePattern.InOut);
        }
    }, new SynchronizationAdapter() {

        @Override
        public void onDone(Exchange exchange) {
            assertEquals("HelloHello", exchange.getOut().getBody());
            ORDER.addAndGet(2);
            latch.countDown();
        }
    });
    ORDER.addAndGet(1);
    assertTrue(latch.await(10, TimeUnit.SECONDS));
    ORDER.addAndGet(4);
    assertEquals(7, ORDER.get());
}
Also used : Exchange(org.apache.camel.Exchange) Processor(org.apache.camel.Processor) CountDownLatch(java.util.concurrent.CountDownLatch) RuntimeCamelException(org.apache.camel.RuntimeCamelException) SynchronizationAdapter(org.apache.camel.support.SynchronizationAdapter)

Example 17 with SynchronizationAdapter

use of org.apache.camel.support.SynchronizationAdapter in project vertx-camel-bridge by vert-x3.

the class InboundEndpointTest method testWithDirectEndpointWithPublishAndCustomTypeNoCodec.

@Test
public void testWithDirectEndpointWithPublishAndCustomTypeNoCodec(TestContext context) throws Exception {
    Async async = context.async();
    Endpoint endpoint = camel.getEndpoint("direct:foo");
    bridge = CamelBridge.create(vertx, new CamelBridgeOptions(camel).addInboundMapping(fromCamel(endpoint).toVertx("test").usePublish()));
    camel.start();
    BridgeHelper.startBlocking(bridge);
    ProducerTemplate producer = camel.createProducerTemplate();
    producer.asyncSend(endpoint, exchange -> {
        Message message = exchange.getIn();
        message.setBody(new Person().setName("bob"));
        exchange.addOnCompletion(new SynchronizationAdapter() {

            @Override
            public void onFailure(Exchange exchange) {
                context.assertTrue(exchange.getException().getMessage().contains("No message codec"));
                async.complete();
            }
        });
    });
}
Also used : Exchange(org.apache.camel.Exchange) ProducerTemplate(org.apache.camel.ProducerTemplate) Endpoint(org.apache.camel.Endpoint) Message(org.apache.camel.Message) Async(io.vertx.ext.unit.Async) SynchronizationAdapter(org.apache.camel.support.SynchronizationAdapter) Test(org.junit.Test)

Example 18 with SynchronizationAdapter

use of org.apache.camel.support.SynchronizationAdapter in project camel by apache.

the class DisruptorProducer method process.

@Override
public boolean process(final Exchange exchange, final AsyncCallback callback) {
    WaitForTaskToComplete wait = waitForTaskToComplete;
    if (exchange.getProperty(Exchange.ASYNC_WAIT) != null) {
        wait = exchange.getProperty(Exchange.ASYNC_WAIT, WaitForTaskToComplete.class);
    }
    if (wait == WaitForTaskToComplete.Always || (wait == WaitForTaskToComplete.IfReplyExpected && ExchangeHelper.isOutCapable(exchange))) {
        // do not handover the completion as we wait for the copy to complete, and copy its result back when it done
        final Exchange copy = prepareCopy(exchange, false);
        // latch that waits until we are complete
        final CountDownLatch latch = new CountDownLatch(1);
        // we should wait for the reply so install a on completion so we know when its complete
        copy.addOnCompletion(new SynchronizationAdapter() {

            @Override
            public void onDone(final Exchange response) {
                // check for timeout, which then already would have invoked the latch
                if (latch.getCount() == 0) {
                    if (log.isTraceEnabled()) {
                        log.trace("{}. Timeout occurred so response will be ignored: {}", this, response.hasOut() ? response.getOut() : response.getIn());
                    }
                } else {
                    if (log.isTraceEnabled()) {
                        log.trace("{} with response: {}", this, response.hasOut() ? response.getOut() : response.getIn());
                    }
                    try {
                        ExchangeHelper.copyResults(exchange, response);
                    } finally {
                        // always ensure latch is triggered
                        latch.countDown();
                    }
                }
            }

            @Override
            public boolean allowHandover() {
                // at this point in the routing (at this leg), instead of at the very last (this ensure timeout is honored)
                return false;
            }

            @Override
            public String toString() {
                return "onDone at endpoint: " + endpoint;
            }
        });
        doPublish(copy);
        if (timeout > 0) {
            if (log.isTraceEnabled()) {
                log.trace("Waiting for task to complete using timeout (ms): {} at [{}]", timeout, endpoint.getEndpointUri());
            }
            // lets see if we can get the task done before the timeout
            boolean done = false;
            try {
                done = latch.await(timeout, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
            // ignore
            }
            if (!done) {
                // Remove timed out Exchange from disruptor endpoint.
                // We can't actually remove a published exchange from an active Disruptor.
                // Instead we prevent processing of the exchange by setting a Property on the exchange and the value
                // would be an AtomicBoolean. This is set by the Producer and the Consumer would look up that Property and
                // check the AtomicBoolean. If the AtomicBoolean says that we are good to proceed, it will process the
                // exchange. If false, it will simply disregard the exchange.
                // But since the Property map is a Concurrent one, maybe we don't need the AtomicBoolean. Check with Simon.
                // Also check the TimeoutHandler of the new Disruptor 3.0.0, consider making the switch to the latest version.
                exchange.setProperty(DisruptorEndpoint.DISRUPTOR_IGNORE_EXCHANGE, true);
                exchange.setException(new ExchangeTimedOutException(exchange, timeout));
                // count down to indicate timeout
                latch.countDown();
            }
        } else {
            if (log.isTraceEnabled()) {
                log.trace("Waiting for task to complete (blocking) at [{}]", endpoint.getEndpointUri());
            }
            // no timeout then wait until its done
            try {
                latch.await();
            } catch (InterruptedException e) {
            // ignore
            }
        }
    } else {
        // no wait, eg its a InOnly then just publish to the ringbuffer and return
        // handover the completion so its the copy which performs that, as we do not wait
        final Exchange copy = prepareCopy(exchange, true);
        doPublish(copy);
    }
    // we use OnCompletion on the Exchange to callback and wait for the Exchange to be done
    // so we should just signal the callback we are done synchronously
    callback.done(true);
    return true;
}
Also used : Exchange(org.apache.camel.Exchange) WaitForTaskToComplete(org.apache.camel.WaitForTaskToComplete) CountDownLatch(java.util.concurrent.CountDownLatch) ExchangeTimedOutException(org.apache.camel.ExchangeTimedOutException) SynchronizationAdapter(org.apache.camel.support.SynchronizationAdapter)

Example 19 with SynchronizationAdapter

use of org.apache.camel.support.SynchronizationAdapter in project camel by apache.

the class HttpProducer method process.

public void process(Exchange exchange) throws Exception {
    if (getEndpoint().isClearExpiredCookies() && !getEndpoint().isBridgeEndpoint()) {
        // create the cookies before the invocation
        getEndpoint().getCookieStore().clearExpired(new Date());
    }
    // if we bridge endpoint then we need to skip matching headers with the HTTP_QUERY to avoid sending
    // duplicated headers to the receiver, so use this skipRequestHeaders as the list of headers to skip
    Map<String, Object> skipRequestHeaders = null;
    if (getEndpoint().isBridgeEndpoint()) {
        exchange.setProperty(Exchange.SKIP_GZIP_ENCODING, Boolean.TRUE);
        String queryString = exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class);
        if (queryString != null) {
            skipRequestHeaders = URISupport.parseQuery(queryString, false, true);
        }
    }
    HttpRequestBase httpRequest = createMethod(exchange);
    Message in = exchange.getIn();
    String httpProtocolVersion = in.getHeader(Exchange.HTTP_PROTOCOL_VERSION, String.class);
    if (httpProtocolVersion != null) {
        // set the HTTP protocol version
        int[] version = HttpHelper.parserHttpVersion(httpProtocolVersion);
        httpRequest.setProtocolVersion(new HttpVersion(version[0], version[1]));
    }
    HeaderFilterStrategy strategy = getEndpoint().getHeaderFilterStrategy();
    // propagate headers as HTTP headers
    for (Map.Entry<String, Object> entry : in.getHeaders().entrySet()) {
        String key = entry.getKey();
        Object headerValue = in.getHeader(key);
        if (headerValue != null) {
            // use an iterator as there can be multiple values. (must not use a delimiter, and allow empty values)
            final Iterator<?> it = ObjectHelper.createIterator(headerValue, null, true);
            // the value to add as request header
            final List<String> values = new ArrayList<String>();
            // should be combined into a single value
            while (it.hasNext()) {
                String value = exchange.getContext().getTypeConverter().convertTo(String.class, it.next());
                // as then we would duplicate headers on both the endpoint uri, and in HTTP headers as well
                if (skipRequestHeaders != null && skipRequestHeaders.containsKey(key)) {
                    continue;
                }
                if (value != null && strategy != null && !strategy.applyFilterToCamelHeaders(key, value, exchange)) {
                    values.add(value);
                }
            }
            // add the value(s) as a http request header
            if (values.size() > 0) {
                // use the default toString of a ArrayList to create in the form [xxx, yyy]
                // if multi valued, for a single value, then just output the value as is
                String s = values.size() > 1 ? values.toString() : values.get(0);
                httpRequest.addHeader(key, s);
            }
        }
    }
    if (getEndpoint().getCookieHandler() != null) {
        Map<String, List<String>> cookieHeaders = getEndpoint().getCookieHandler().loadCookies(exchange, httpRequest.getURI());
        for (Map.Entry<String, List<String>> entry : cookieHeaders.entrySet()) {
            String key = entry.getKey();
            if (entry.getValue().size() > 0) {
                // use the default toString of a ArrayList to create in the form [xxx, yyy]
                // if multi valued, for a single value, then just output the value as is
                String s = entry.getValue().size() > 1 ? entry.getValue().toString() : entry.getValue().get(0);
                httpRequest.addHeader(key, s);
            }
        }
    }
    //if this option is set, and the exchange Host header is not null, we will set it's current value on the httpRequest
    if (getEndpoint().isPreserveHostHeader()) {
        String hostHeader = exchange.getIn().getHeader("Host", String.class);
        if (hostHeader != null) {
            //HttpClient 4 will check to see if the Host header is present, and use it if it is, see org.apache.http.protocol.RequestTargetHost in httpcore
            httpRequest.setHeader("Host", hostHeader);
        }
    }
    if (getEndpoint().isConnectionClose()) {
        httpRequest.addHeader("Connection", HTTP.CONN_CLOSE);
    }
    // lets store the result in the output message.
    HttpResponse httpResponse = null;
    try {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Executing http {} method: {}", httpRequest.getMethod(), httpRequest.getURI().toString());
        }
        httpResponse = executeMethod(httpRequest);
        int responseCode = httpResponse.getStatusLine().getStatusCode();
        LOG.debug("Http responseCode: {}", responseCode);
        if (!throwException) {
            // if we do not use failed exception then populate response for all response codes
            populateResponse(exchange, httpRequest, httpResponse, in, strategy, responseCode);
        } else {
            boolean ok = HttpHelper.isStatusCodeOk(responseCode, getEndpoint().getOkStatusCodeRange());
            if (ok) {
                // only populate response for OK response
                populateResponse(exchange, httpRequest, httpResponse, in, strategy, responseCode);
            } else {
                // operation failed so populate exception to throw
                throw populateHttpOperationFailedException(exchange, httpRequest, httpResponse, responseCode);
            }
        }
    } finally {
        final HttpResponse response = httpResponse;
        if (httpResponse != null && getEndpoint().isDisableStreamCache()) {
            // close the stream at the end of the exchange to ensure it gets eventually closed later
            exchange.addOnCompletion(new SynchronizationAdapter() {

                @Override
                public void onDone(Exchange exchange) {
                    try {
                        EntityUtils.consume(response.getEntity());
                    } catch (Throwable e) {
                    // ignore
                    }
                }
            });
        } else if (httpResponse != null) {
            // close the stream now
            try {
                EntityUtils.consume(response.getEntity());
            } catch (Throwable e) {
            // ignore
            }
        }
    }
}
Also used : HttpRequestBase(org.apache.http.client.methods.HttpRequestBase) Message(org.apache.camel.Message) ArrayList(java.util.ArrayList) HttpResponse(org.apache.http.HttpResponse) HeaderFilterStrategy(org.apache.camel.spi.HeaderFilterStrategy) HttpProtocolHeaderFilterStrategy(org.apache.camel.http.common.HttpProtocolHeaderFilterStrategy) Date(java.util.Date) Exchange(org.apache.camel.Exchange) List(java.util.List) ArrayList(java.util.ArrayList) HttpVersion(org.apache.http.HttpVersion) Map(java.util.Map) HashMap(java.util.HashMap) SynchronizationAdapter(org.apache.camel.support.SynchronizationAdapter)

Example 20 with SynchronizationAdapter

use of org.apache.camel.support.SynchronizationAdapter in project camel by apache.

the class MailConsumer method processBatch.

public int processBatch(Queue<Object> exchanges) throws Exception {
    int total = exchanges.size();
    // limit if needed
    if (maxMessagesPerPoll > 0 && total > maxMessagesPerPoll) {
        LOG.debug("Limiting to maximum messages to poll {} as there were {} messages in this poll.", maxMessagesPerPoll, total);
        total = maxMessagesPerPoll;
    }
    for (int index = 0; index < total && isBatchAllowed(); index++) {
        // only loop if we are started (allowed to run)
        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;
        // must use the original message in case we need to workaround a charset issue when extracting mail content
        final Message mail = exchange.getIn(MailMessage.class).getOriginalMessage();
        // add on completion to handle after work when the exchange is done
        exchange.addOnCompletion(new SynchronizationAdapter() {

            public void onComplete(Exchange exchange) {
                processCommit(mail, exchange);
            }

            public void onFailure(Exchange exchange) {
                processRollback(mail, exchange);
            }

            @Override
            public boolean allowHandover() {
                // on the same session that polled the messages
                return false;
            }

            @Override
            public String toString() {
                return "MailConsumerOnCompletion";
            }
        });
        // process the exchange
        processExchange(exchange);
    }
    return total;
}
Also used : Exchange(org.apache.camel.Exchange) Message(javax.mail.Message) SynchronizationAdapter(org.apache.camel.support.SynchronizationAdapter)

Aggregations

Exchange (org.apache.camel.Exchange)34 SynchronizationAdapter (org.apache.camel.support.SynchronizationAdapter)34 CountDownLatch (java.util.concurrent.CountDownLatch)13 Processor (org.apache.camel.Processor)13 RouteBuilder (org.apache.camel.builder.RouteBuilder)10 Message (org.apache.camel.Message)4 ExchangeTimedOutException (org.apache.camel.ExchangeTimedOutException)3 RuntimeCamelException (org.apache.camel.RuntimeCamelException)3 WaitForTaskToComplete (org.apache.camel.WaitForTaskToComplete)3 Async (io.vertx.ext.unit.Async)2 Endpoint (org.apache.camel.Endpoint)2 ProducerTemplate (org.apache.camel.ProducerTemplate)2 Test (org.junit.Test)2 ObjectMetadata (com.amazonaws.services.s3.model.ObjectMetadata)1 Channel (io.netty.channel.Channel)1 ChannelFuture (io.netty.channel.ChannelFuture)1 ChannelFutureListener (io.netty.channel.ChannelFutureListener)1 ChannelHandler (io.netty.channel.ChannelHandler)1 EpollDatagramChannel (io.netty.channel.epoll.EpollDatagramChannel)1 EpollSocketChannel (io.netty.channel.epoll.EpollSocketChannel)1