try {
LOG.trace("Processing +++ START +++");
// send Camel exchange to the target processor
getProcessor().process(camelExchange);
} catch (Exception e) {
throw new Fault(e);
}
LOG.trace("Processing +++ END +++");
setResponseBack(cxfExchange, camelExchange);
} finally {
doneUoW(camelExchange);
}
// response should have been set in outMessage's content
return null;
}
private org.apache.camel.Exchange prepareCamelExchange(Exchange cxfExchange) {
// get CXF binding
CxfEndpoint endpoint = (CxfEndpoint)getEndpoint();
CxfBinding binding = endpoint.getCxfBinding();
// create a Camel exchange, the default MEP is InOut
org.apache.camel.Exchange camelExchange = endpoint.createExchange();
DataFormat dataFormat = endpoint.getDataFormat();
BindingOperationInfo boi = cxfExchange.getBindingOperationInfo();
// make sure the "boi" is remained as wrapped in PAYLOAD mode
if (boi != null && dataFormat == DataFormat.PAYLOAD && boi.isUnwrapped()) {
boi = boi.getWrappedOperation();
cxfExchange.put(BindingOperationInfo.class, boi);
}
if (boi != null) {
camelExchange.setProperty(BindingOperationInfo.class.getName(), boi);
LOG.trace("Set exchange property: BindingOperationInfo: {}", boi);
// set the message exchange patter with the boi
if (boi.getOperationInfo().isOneWay()) {
camelExchange.setPattern(ExchangePattern.InOnly);
}
}
// set data format mode in Camel exchange
camelExchange.setProperty(CxfConstants.DATA_FORMAT_PROPERTY, dataFormat);
LOG.trace("Set Exchange property: {}={}", DataFormat.class.getName(), dataFormat);
camelExchange.setProperty(Message.MTOM_ENABLED, String.valueOf(endpoint.isMtomEnabled()));
if (endpoint.getMergeProtocolHeaders()) {
camelExchange.setProperty(CxfConstants.CAMEL_CXF_PROTOCOL_HEADERS_MERGED, Boolean.TRUE);
}
// bind the CXF request into a Camel exchange
binding.populateExchangeFromCxfRequest(cxfExchange, camelExchange);
// extract the javax.xml.ws header
Map<String, Object> context = new HashMap<String, Object>();
binding.extractJaxWsContext(cxfExchange, context);
// put the context into camelExchange
camelExchange.setProperty(CxfConstants.JAXWS_CONTEXT, context);
// we want to handle the UoW
try {
CxfConsumer.this.createUoW(camelExchange);
} catch (Exception e) {
log.error("Error processing request", e);
throw new Fault(e);
}
return camelExchange;
}
@SuppressWarnings("unchecked")
private void setResponseBack(Exchange cxfExchange, org.apache.camel.Exchange camelExchange) {
CxfEndpoint endpoint = (CxfEndpoint)getEndpoint();
CxfBinding binding = endpoint.getCxfBinding();
checkFailure(camelExchange, cxfExchange);
binding.populateCxfResponseFromExchange(camelExchange, cxfExchange);
// check failure again as fault could be discovered by converter
checkFailure(camelExchange, cxfExchange);
// copy the headers javax.xml.ws header back
binding.copyJaxWsContext(cxfExchange, (Map<String, Object>)camelExchange.getProperty(CxfConstants.JAXWS_CONTEXT));
}
private void checkFailure(org.apache.camel.Exchange camelExchange, Exchange cxfExchange) throws Fault {
final Throwable t;
if (camelExchange.isFailed()) {
t = (camelExchange.hasOut() && camelExchange.getOut().isFault()) ? camelExchange.getOut()
.getBody(Throwable.class) : camelExchange.getException();
cxfExchange.getInMessage().put(FaultMode.class, FaultMode.UNCHECKED_APPLICATION_FAULT);
if (t instanceof Fault) {
cxfExchange.getInMessage().put(FaultMode.class, FaultMode.CHECKED_APPLICATION_FAULT);
throw (Fault)t;
} else if (t != null) {
// This is not a CXF Fault. Build the CXF Fault manually.
Fault fault = new Fault(t);
if (fault.getMessage() == null) {
// The Fault has no Message. This is the case if it has
// no message, for example was a NullPointerException.
fault.setMessage(t.getClass().getSimpleName());
}
WebFault faultAnnotation = t.getClass().getAnnotation(WebFault.class);
Object faultInfo = null;
try {
Method method = t.getClass().getMethod("getFaultInfo");
faultInfo = method.invoke(t, new Object[0]);
} catch (Exception e) {
// do nothing here
}
if (faultAnnotation != null && faultInfo == null) {
// t has a JAX-WS WebFault annotation, which describes
// in detail the Web Service Fault that should be thrown. Add the
// detail.
Element detail = fault.getOrCreateDetail();
Element faultDetails = detail.getOwnerDocument()
.createElementNS(faultAnnotation.targetNamespace(), faultAnnotation.name());
detail.appendChild(faultDetails);
}