/** * This method is called by {@link CxfProducer#process(Exchange)}. It propagates information from * CXF Exchange to Camel Exchange. The CXF Exchange contains a request from a CXF server. */ public void populateExchangeFromCxfResponse( Exchange camelExchange, org.apache.cxf.message.Exchange cxfExchange, Map<String, Object> responseContext) { Message cxfMessage = cxfExchange.getInMessage(); // Need to check if the inMessage is set if (cxfMessage == null) { return; } LOG.trace("Populate exchange from CXF response message: {}", cxfMessage); // copy the InMessage header to OutMessage header camelExchange.getOut().getHeaders().putAll(camelExchange.getIn().getHeaders()); // propagate body camelExchange .getOut() .setBody( DefaultCxfBinding.getContentFromCxf( cxfMessage, camelExchange.getProperty(CxfConstants.DATA_FORMAT_PROPERTY, DataFormat.class))); // propagate response context if (responseContext != null && responseContext.size() > 0) { if (!headerFilterStrategy.applyFilterToExternalHeaders( Client.RESPONSE_CONTEXT, responseContext, camelExchange)) { camelExchange.getOut().setHeader(Client.RESPONSE_CONTEXT, responseContext); LOG.trace("Set header = {} value = {}", Client.RESPONSE_CONTEXT, responseContext); } } // propagate protocol headers propagateHeadersFromCxfToCamel(cxfMessage, camelExchange.getOut(), camelExchange); DataFormat dataFormat = camelExchange.getProperty(CxfConstants.DATA_FORMAT_PROPERTY, DataFormat.class); boolean isXop = Boolean.valueOf(camelExchange.getProperty(Message.MTOM_ENABLED, String.class)); // propagate attachments if (cxfMessage.getAttachments() != null) { // propagate attachments for (Attachment attachment : cxfMessage.getAttachments()) { camelExchange.getOut().addAttachment(attachment.getId(), attachment.getDataHandler()); } } }
/** * This method is called by {@link CxfConsumer} to populate a CXF response exchange from a Camel * exchange. */ public void populateCxfResponseFromExchange( Exchange camelExchange, org.apache.cxf.message.Exchange cxfExchange) { if (cxfExchange.isOneWay()) { return; } // create response context Map<String, Object> responseContext = new HashMap<String, Object>(); org.apache.camel.Message response; if (camelExchange.getPattern().isOutCapable()) { if (camelExchange.hasOut()) { response = camelExchange.getOut(); LOG.trace("Get the response from the out message"); } else { // Take the in message as a fall back response = camelExchange.getIn(); LOG.trace("Get the response from the in message as a fallback"); } } else { response = camelExchange.getIn(); LOG.trace("Get the response from the in message"); } // propagate response context Map<String, Object> camelHeaders = response.getHeaders(); extractInvocationContextFromCamel( camelExchange, camelHeaders, responseContext, Client.RESPONSE_CONTEXT); propagateHeadersFromCamelToCxf(camelExchange, camelHeaders, cxfExchange, responseContext); // create out message Endpoint ep = cxfExchange.get(Endpoint.class); Message outMessage = ep.getBinding().createMessage(); cxfExchange.setOutMessage(outMessage); DataFormat dataFormat = camelExchange.getProperty(CxfConstants.DATA_FORMAT_PROPERTY, DataFormat.class); // make sure the "requestor role" property does not get propagated as we do switch role responseContext.remove(Message.REQUESTOR_ROLE); outMessage.putAll(responseContext); // Do we still need to put the response context back like this outMessage.put(Client.RESPONSE_CONTEXT, responseContext); LOG.trace("Set out response context = {}", responseContext); // set body Object outBody = DefaultCxfBinding.getBodyFromCamel(response, dataFormat); if (outBody != null) { if (dataFormat == DataFormat.PAYLOAD) { CxfPayload<?> payload = (CxfPayload<?>) outBody; outMessage.setContent( List.class, getResponsePayloadList(cxfExchange, payload.getBodySources())); outMessage.put(Header.HEADER_LIST, payload.getHeaders()); } else { if (responseContext.get(Header.HEADER_LIST) != null) { outMessage.put(Header.HEADER_LIST, responseContext.get(Header.HEADER_LIST)); } MessageContentsList resList = null; // Create a new MessageContentsList to avoid OOM from the HolderOutInterceptor if (outBody instanceof List) { resList = new MessageContentsList((List<?>) outBody); } else if (outBody.getClass().isArray()) { resList = new MessageContentsList((Object[]) outBody); } else { resList = new MessageContentsList(outBody); } if (resList != null) { outMessage.setContent(List.class, resList); LOG.trace("Set Out CXF message content = {}", resList); } } } else if (!cxfExchange.isOneWay() && cxfExchange.getInMessage() != null && MessageUtils.isTrue( cxfExchange .getInMessage() .getContextualProperty("jaxws.provider.interpretNullAsOneway"))) { // treat this non-oneway call as oneway when the provider returns a null changeToOneway(cxfExchange); return; } // propagate attachments Set<Attachment> attachments = null; boolean isXop = Boolean.valueOf(camelExchange.getProperty(Message.MTOM_ENABLED, String.class)); for (Map.Entry<String, DataHandler> entry : camelExchange.getOut().getAttachments().entrySet()) { if (attachments == null) { attachments = new HashSet<Attachment>(); } AttachmentImpl attachment = new AttachmentImpl(entry.getKey(), entry.getValue()); attachment.setXOP(isXop); attachments.add(attachment); } if (attachments != null) { outMessage.setAttachments(attachments); } BindingOperationInfo boi = cxfExchange.get(BindingOperationInfo.class); if (boi != null) { cxfExchange.put(BindingMessageInfo.class, boi.getOutput()); } }
/** This method is called by {@link CxfConsumer}. */ public void populateExchangeFromCxfRequest( org.apache.cxf.message.Exchange cxfExchange, Exchange camelExchange) { Method method = null; QName operationName = null; ExchangePattern mep = ExchangePattern.InOut; // extract binding operation information BindingOperationInfo boi = camelExchange.getProperty(BindingOperationInfo.class.getName(), BindingOperationInfo.class); if (boi != null) { Service service = cxfExchange.get(Service.class); if (service != null) { MethodDispatcher md = (MethodDispatcher) service.get(MethodDispatcher.class.getName()); if (md != null) { method = md.getMethod(boi); } } if (boi.getOperationInfo().isOneWay()) { mep = ExchangePattern.InOnly; } operationName = boi.getName(); } // set operation name in header if (operationName != null) { camelExchange .getIn() .setHeader(CxfConstants.OPERATION_NAMESPACE, boi.getName().getNamespaceURI()); camelExchange.getIn().setHeader(CxfConstants.OPERATION_NAME, boi.getName().getLocalPart()); if (LOG.isTraceEnabled()) { LOG.trace( "Set IN header: {}={}", CxfConstants.OPERATION_NAMESPACE, boi.getName().getNamespaceURI()); LOG.trace( "Set IN header: {}={}", CxfConstants.OPERATION_NAME, boi.getName().getLocalPart()); } } else if (method != null) { camelExchange.getIn().setHeader(CxfConstants.OPERATION_NAME, method.getName()); if (LOG.isTraceEnabled()) { LOG.trace("Set IN header: {}={}", CxfConstants.OPERATION_NAME, method.getName()); } } // set message exchange pattern camelExchange.setPattern(mep); LOG.trace("Set exchange MEP: {}", mep); // propagate headers Message cxfMessage = cxfExchange.getInMessage(); propagateHeadersFromCxfToCamel(cxfMessage, camelExchange.getIn(), camelExchange); // propagate the security subject from CXF security context SecurityContext securityContext = cxfMessage.get(SecurityContext.class); if (securityContext instanceof LoginSecurityContext && ((LoginSecurityContext) securityContext).getSubject() != null) { camelExchange .getIn() .getHeaders() .put(Exchange.AUTHENTICATION, ((LoginSecurityContext) securityContext).getSubject()); } else if (securityContext != null && securityContext.getUserPrincipal() != null) { Subject subject = new Subject(); subject.getPrincipals().add(securityContext.getUserPrincipal()); camelExchange.getIn().getHeaders().put(Exchange.AUTHENTICATION, subject); } // Propagating properties from CXF Exchange to Camel Exchange has an // side effect of copying reply side stuff when the producer is retried. // So, we do not want to do this. // camelExchange.getProperties().putAll(cxfExchange); // propagate request context Object value = cxfMessage.get(Client.REQUEST_CONTEXT); if (value != null && !headerFilterStrategy.applyFilterToExternalHeaders( Client.REQUEST_CONTEXT, value, camelExchange)) { camelExchange.getIn().setHeader(Client.REQUEST_CONTEXT, value); LOG.trace("Populate context from CXF message {} value={}", Client.REQUEST_CONTEXT, value); } // setup the charset from content-type header setCharsetWithContentType(camelExchange); // set body Object body = DefaultCxfBinding.getContentFromCxf( cxfMessage, camelExchange.getProperty(CxfConstants.DATA_FORMAT_PROPERTY, DataFormat.class)); if (body != null) { camelExchange.getIn().setBody(body); } // propagate attachments if the data format is not POJO if (cxfMessage.getAttachments() != null && !camelExchange .getProperty(CxfConstants.DATA_FORMAT_PROPERTY, DataFormat.class) .equals(DataFormat.POJO)) { for (Attachment attachment : cxfMessage.getAttachments()) { camelExchange.getIn().addAttachment(attachment.getId(), attachment.getDataHandler()); } } }