use of org.apache.camel.support.SynchronizationAdapter in project camel by apache.
the class NettyProducer method processWithConnectedChannel.
public void processWithConnectedChannel(final Exchange exchange, final BodyReleaseCallback callback, final ChannelFuture channelFuture, final Object body) {
// remember channel so we can reuse it
final Channel channel = channelFuture.channel();
if (getConfiguration().isReuseChannel() && exchange.getProperty(NettyConstants.NETTY_CHANNEL) == null) {
exchange.setProperty(NettyConstants.NETTY_CHANNEL, channel);
// and defer closing the channel until we are done routing the exchange
exchange.addOnCompletion(new SynchronizationAdapter() {
@Override
public void onComplete(Exchange exchange) {
// should channel be closed after complete?
Boolean close;
if (ExchangeHelper.isOutCapable(exchange)) {
close = exchange.getOut().getHeader(NettyConstants.NETTY_CLOSE_CHANNEL_WHEN_COMPLETE, Boolean.class);
} else {
close = exchange.getIn().getHeader(NettyConstants.NETTY_CLOSE_CHANNEL_WHEN_COMPLETE, Boolean.class);
}
// should we disconnect, the header can override the configuration
boolean disconnect = getConfiguration().isDisconnect();
if (close != null) {
disconnect = close;
}
if (disconnect) {
LOG.trace("Closing channel {} as routing the Exchange is done", channel);
NettyHelper.close(channel);
}
releaseChannel(channelFuture);
}
});
}
if (exchange.getIn().getHeader(NettyConstants.NETTY_REQUEST_TIMEOUT) != null) {
long timeoutInMs = exchange.getIn().getHeader(NettyConstants.NETTY_REQUEST_TIMEOUT, Long.class);
ChannelHandler oldHandler = channel.pipeline().get("timeout");
ReadTimeoutHandler newHandler = new ReadTimeoutHandler(timeoutInMs, TimeUnit.MILLISECONDS);
if (oldHandler == null) {
channel.pipeline().addBefore("handler", "timeout", newHandler);
} else {
channel.pipeline().replace(oldHandler, "timeout", newHandler);
}
}
//This will refer to original callback since netty will release body by itself
final AsyncCallback producerCallback;
if (configuration.isReuseChannel()) {
// use callback as-is because we should not put it back in the pool as NettyProducerCallback would do
// as when reuse channel is enabled it will put the channel back in the pool when exchange is done using on completion
producerCallback = callback.getOriginalCallback();
} else {
producerCallback = new NettyProducerCallback(channelFuture, callback.getOriginalCallback());
}
// setup state as attachment on the channel, so we can access the state later when needed
putState(channel, new NettyCamelState(producerCallback, exchange));
// here we need to setup the remote address information here
InetSocketAddress remoteAddress = null;
if (!isTcp()) {
remoteAddress = new InetSocketAddress(configuration.getHost(), configuration.getPort());
}
// write body
NettyHelper.writeBodyAsync(LOG, channel, remoteAddress, body, exchange, new ChannelFutureListener() {
public void operationComplete(ChannelFuture channelFuture) throws Exception {
LOG.trace("Operation complete {}", channelFuture);
if (!channelFuture.isSuccess()) {
// no success then exit, (any exception has been handled by ClientChannelHandler#exceptionCaught)
return;
}
// if we do not expect any reply then signal callback to continue routing
if (!configuration.isSync()) {
try {
// should channel be closed after complete?
Boolean close;
if (ExchangeHelper.isOutCapable(exchange)) {
close = exchange.getOut().getHeader(NettyConstants.NETTY_CLOSE_CHANNEL_WHEN_COMPLETE, Boolean.class);
} else {
close = exchange.getIn().getHeader(NettyConstants.NETTY_CLOSE_CHANNEL_WHEN_COMPLETE, Boolean.class);
}
// should we disconnect, the header can override the configuration
boolean disconnect = getConfiguration().isDisconnect();
if (close != null) {
disconnect = close;
}
// we should not close if we are reusing the channel
if (!configuration.isReuseChannel() && disconnect) {
if (LOG.isTraceEnabled()) {
LOG.trace("Closing channel when complete at address: {}", getEndpoint().getConfiguration().getAddress());
}
NettyHelper.close(channel);
}
} finally {
// signal callback to continue routing
producerCallback.done(false);
}
}
}
});
}
use of org.apache.camel.support.SynchronizationAdapter in project camel by apache.
the class DisruptorWaitForTaskCompleteOnCompletionTest method createRouteBuilder.
@Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
errorHandler(defaultErrorHandler().maximumRedeliveries(3).redeliveryDelay(0));
from("direct:start").process(new Processor() {
@Override
public void process(final Exchange exchange) throws Exception {
exchange.addOnCompletion(new SynchronizationAdapter() {
@Override
public void onDone(final Exchange exchange) {
done += "A";
}
});
}
}).to("disruptor:foo?waitForTaskToComplete=Always").process(new Processor() {
@Override
public void process(final Exchange exchange) throws Exception {
done += "B";
}
}).to("mock:result");
from("disruptor:foo").errorHandler(noErrorHandler()).process(new Processor() {
@Override
public void process(final Exchange exchange) throws Exception {
done = done + "C";
}
}).throwException(new IllegalArgumentException("Forced"));
}
};
}
use of org.apache.camel.support.SynchronizationAdapter in project camel by apache.
the class DisruptorWaitForTaskNeverOnCompletionTest method createRouteBuilder.
@Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
errorHandler(deadLetterChannel("mock:dead").maximumRedeliveries(3).redeliveryDelay(0));
from("direct:start").process(new Processor() {
@Override
public void process(final Exchange exchange) throws Exception {
exchange.addOnCompletion(new SynchronizationAdapter() {
@Override
public void onDone(final Exchange exchange) {
done = done + "A";
latch.countDown();
}
});
}
}).to("disruptor:foo?waitForTaskToComplete=Never").process(new Processor() {
@Override
public void process(final Exchange exchange) throws Exception {
done = done + "B";
}
}).to("mock:result");
from("disruptor:foo").errorHandler(noErrorHandler()).delay(1000).process(new Processor() {
@Override
public void process(final Exchange exchange) throws Exception {
done = done + "C";
}
}).throwException(new IllegalArgumentException("Forced"));
}
};
}
use of org.apache.camel.support.SynchronizationAdapter in project camel by apache.
the class DisruptorInOutChainedWithOnCompletionTest method createRouteBuilder.
@Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
from("disruptor:a").process(new Processor() {
@Override
public void process(final Exchange exchange) throws Exception {
// should come in last
exchange.addOnCompletion(new SynchronizationAdapter() {
@Override
public void onDone(final Exchange exchange) {
template.sendBody("mock:c", "onCustomCompletion");
}
});
}
}).to("mock:a").transform(simple("${body}-a")).to("disruptor:b");
from("disruptor:b").to("mock:b").transform(simple("${body}-b")).to("disruptor:c");
from("disruptor:c").to("mock:c").transform(simple("${body}-c"));
}
};
}
use of org.apache.camel.support.SynchronizationAdapter in project camel by apache.
the class RemoteFileConsumer method processExchange.
@Override
protected boolean processExchange(Exchange exchange) {
// mark the exchange to be processed synchronously as the ftp client is not thread safe
// and we must execute the callbacks in the same thread as this consumer
exchange.setProperty(Exchange.UNIT_OF_WORK_PROCESS_SYNC, Boolean.TRUE);
// defer disconnect til the UoW is complete - but only the last exchange from the batch should do that
boolean isLast = exchange.getProperty(Exchange.BATCH_COMPLETE, true, Boolean.class);
if (isLast && getEndpoint().isDisconnect()) {
exchange.addOnCompletion(new SynchronizationAdapter() {
@Override
public void onDone(Exchange exchange) {
log.trace("postPollCheck disconnect from: {}", getEndpoint());
disconnect();
}
@Override
public boolean allowHandover() {
// do not allow handover as we must execute the callbacks in the same thread as this consumer
return false;
}
@Override
public int getOrder() {
// we want to disconnect last
return Ordered.LOWEST;
}
public String toString() {
return "Disconnect";
}
});
}
return super.processExchange(exchange);
}
Aggregations