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