ServerFactoryBean svrBean = endpoint.createServerFactoryBean();
svrBean.setInvoker(new Invoker() {
// we receive a CXF request when this method is called
public Object invoke(Exchange cxfExchange, Object o) {
LOG.trace("Received CXF Request: {}", cxfExchange);
Continuation continuation;
if (!endpoint.isSynchronous() && isAsyncInvocationSupported(cxfExchange)
&& (continuation = getContinuation(cxfExchange)) != null) {
LOG.trace("Calling the Camel async processors.");
return asyncInvoke(cxfExchange, continuation);
} else {
LOG.trace("Calling the Camel sync processors.");
return syncInvoke(cxfExchange);
}
}
// NOTE this code cannot work with CXF 2.2.x and JMSContinuation
// as it doesn't break out the interceptor chain when we call it
private Object asyncInvoke(Exchange cxfExchange, final Continuation continuation) {
synchronized (continuation) {
if (continuation.isNew()) {
final org.apache.camel.Exchange camelExchange = prepareCamelExchange(cxfExchange);
// Now we don't set up the timeout value
LOG.trace("Suspending continuation of exchangeId: {}", camelExchange.getExchangeId());
// TODO Support to set the timeout in case the Camel can't send the response back on time.
// The continuation could be called before the suspend is called
continuation.suspend(0);
// use the asynchronous API to process the exchange
getAsyncProcessor().process(camelExchange, new AsyncCallback() {
public void done(boolean doneSync) {
// make sure the continuation resume will not be called before the suspend method in other thread
synchronized (continuation) {
LOG.trace("Resuming continuation of exchangeId: {}", camelExchange.getExchangeId());
// resume processing after both, sync and async callbacks
continuation.setObject(camelExchange);
continuation.resume();
}
}
});
} else if (continuation.isResumed()) {
org.apache.camel.Exchange camelExchange = (org.apache.camel.Exchange)continuation.getObject();
try {
setResponseBack(cxfExchange, camelExchange);
} finally {
CxfConsumer.this.doneUoW(camelExchange);
}
}
}
return null;
}
private Continuation getContinuation(Exchange cxfExchange) {
ContinuationProvider provider =
(ContinuationProvider)cxfExchange.getInMessage().get(ContinuationProvider.class.getName());
Continuation continuation = provider == null ? null : provider.getContinuation();
// Make sure we don't return the JMSContinuation, as it doesn't support the Continuation we wants
// Don't want to introduce the dependency of cxf-rt-transprot-jms here
if (continuation != null && continuation.getClass().getName().equals("org.apache.cxf.transport.jms.continuations.JMSContinuation")) {
return null;
} else {
return continuation;
}
}