Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.cxf;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.nio.charset.Charset;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import javax.activation.DataHandler;
import javax.security.auth.Subject;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.ws.Holder;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.apache.camel.Exchange;
import org.apache.camel.ExchangePattern;
import org.apache.camel.ExchangePropertyKey;
import org.apache.camel.ExtendedExchange;
import org.apache.camel.attachment.AttachmentMessage;
import org.apache.camel.attachment.DefaultAttachment;
import org.apache.camel.component.cxf.common.header.CxfHeaderHelper;
import org.apache.camel.component.cxf.common.message.CxfConstants;
import org.apache.camel.component.cxf.util.ReaderInputStream;
import org.apache.camel.spi.HeaderFilterStrategy;
import org.apache.camel.spi.HeaderFilterStrategyAware;
import org.apache.camel.support.ExchangeHelper;
import org.apache.camel.support.SynchronizationAdapter;
import org.apache.camel.util.IOHelper;
import org.apache.camel.util.ObjectHelper;
import org.apache.cxf.attachment.AttachmentImpl;
import org.apache.cxf.binding.soap.Soap11;
import org.apache.cxf.binding.soap.Soap12;
import org.apache.cxf.binding.soap.SoapBindingConstants;
import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.SoapVersion;
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.helpers.HttpHeaderHelper;
import org.apache.cxf.jaxws.context.WrappedMessageContext;
import org.apache.cxf.message.Attachment;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageContentsList;
import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.security.LoginSecurityContext;
import org.apache.cxf.security.SecurityContext;
import org.apache.cxf.service.Service;
import org.apache.cxf.service.invoker.MethodDispatcher;
import org.apache.cxf.service.model.BindingMessageInfo;
import org.apache.cxf.service.model.BindingOperationInfo;
import org.apache.cxf.service.model.MessagePartInfo;
import org.apache.cxf.service.model.OperationInfo;
import org.apache.cxf.staxutils.StaxUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Default CXF binding implementation.
*/
public class DefaultCxfBinding implements CxfBinding, HeaderFilterStrategyAware {
private static final Logger LOG = LoggerFactory.getLogger(DefaultCxfBinding.class);
private HeaderFilterStrategy headerFilterStrategy;
// CxfBinding Methods
// -------------------------------------------------------------------------
/**
* This method is called by {@link CxfProducer#process(Exchange)}. It populates the CXF exchange and invocation
* context (i.e. request/response) contexts, it but does not create and populate a CXF message as a ClientImpl's
* invoke method will create a new CXF Message. That method will put all properties from the CXF exchange and
* request context to the CXF message.
*/
@Override
public void populateCxfRequestFromExchange(
org.apache.cxf.message.Exchange cxfExchange, Exchange camelExchange,
Map requestContext) {
// propagate request context
Map camelHeaders = camelExchange.getIn().getHeaders();
extractInvocationContextFromCamel(camelExchange, camelHeaders,
requestContext, Client.REQUEST_CONTEXT);
// propagate headers
propagateHeadersFromCamelToCxf(camelExchange, camelHeaders, cxfExchange,
requestContext);
String overrideAddress = camelExchange.getIn().getHeader(Exchange.DESTINATION_OVERRIDE_URL, String.class);
if (overrideAddress != null) {
LOG.trace("Client address is overridden by header '{}' to value '{}'",
Exchange.DESTINATION_OVERRIDE_URL, overrideAddress);
requestContext.put(Message.ENDPOINT_ADDRESS, overrideAddress);
}
// propagate attachments
Set attachments = null;
boolean isXop = Boolean.valueOf(camelExchange.getProperty(Message.MTOM_ENABLED, String.class));
DataFormat dataFormat = camelExchange.getProperty(CxfConstants.DATA_FORMAT_PROPERTY,
DataFormat.class);
// we should avoid adding the attachments if the data format is CXFMESSAGE, as the message stream
// already has the attachment information
if (!DataFormat.CXF_MESSAGE.equals(dataFormat)) {
if (camelExchange.getIn(AttachmentMessage.class).hasAttachments()) {
for (Map.Entry entry : camelExchange
.getIn(AttachmentMessage.class).getAttachmentObjects().entrySet()) {
if (attachments == null) {
attachments = new HashSet<>();
}
AttachmentImpl attachment = new AttachmentImpl(entry.getKey());
org.apache.camel.attachment.Attachment camelAttachment = entry.getValue();
attachment.setDataHandler(camelAttachment.getDataHandler());
for (String name : camelAttachment.getHeaderNames()) {
attachment.setHeader(name, camelAttachment.getHeader(name));
}
attachment.setXOP(isXop);
attachments.add(attachment);
}
}
}
if (attachments != null) {
requestContext.put(CxfConstants.CAMEL_CXF_ATTACHMENTS, attachments);
}
}
/**
* 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.
*/
@Override
public void populateExchangeFromCxfResponse(
Exchange camelExchange,
org.apache.cxf.message.Exchange cxfExchange,
Map 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
String encoding = (String) camelExchange.getProperty(ExchangePropertyKey.CHARSET_NAME);
camelExchange.getOut().setBody(DefaultCxfBinding.getContentFromCxf(cxfMessage,
camelExchange.getProperty(CxfConstants.DATA_FORMAT_PROPERTY, DataFormat.class), encoding));
// 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);
// propagate attachments
if (cxfMessage.getAttachments() != null) {
// propagate attachments
for (Attachment attachment : cxfMessage.getAttachments()) {
camelExchange.getOut(AttachmentMessage.class).addAttachmentObject(attachment.getId(),
createCamelAttachment(attachment));
}
}
addAttachmentFileCloseUoW(camelExchange, cxfExchange);
}
/**
* CXF may cache attachments in the filesystem temp folder. The files may leak if they were not used. Add a cleanup
* handler to remove the attachments after message processing.
*
* @param camelExchange
* @param cxfExchange
*/
private void addAttachmentFileCloseUoW(Exchange camelExchange, org.apache.cxf.message.Exchange cxfExchange) {
camelExchange.adapt(ExtendedExchange.class).addOnCompletion(new SynchronizationAdapter() {
@Override
public void onDone(org.apache.camel.Exchange exchange) {
Collection atts = cxfExchange.getInMessage().getAttachments();
if (atts != null) {
for (Attachment att : atts) {
DataHandler dh = att.getDataHandler();
if (dh != null) {
try {
InputStream is = dh.getInputStream();
IOHelper.close(is);
} catch (Exception e) {
// ignore
}
}
}
}
}
});
}
private DefaultAttachment createCamelAttachment(Attachment attachment) {
DefaultAttachment camelAttachment = new DefaultAttachment(attachment.getDataHandler());
Iterator headers = attachment.getHeaderNames();
while (headers.hasNext()) {
String name = headers.next();
camelAttachment.addHeader(name, attachment.getHeader(name));
}
return camelAttachment;
}
/**
* This method is called by {@link CxfConsumer}.
*/
@Override
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) {
Principal user = securityContext.getUserPrincipal();
if (user != null) {
Subject subject = new Subject();
subject.getPrincipals().add(user);
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
String encoding = (String) camelExchange.getProperty(ExchangePropertyKey.CHARSET_NAME);
Object body = DefaultCxfBinding.getContentFromCxf(cxfMessage,
camelExchange.getProperty(CxfConstants.DATA_FORMAT_PROPERTY, DataFormat.class), encoding);
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(AttachmentMessage.class).addAttachmentObject(attachment.getId(),
createCamelAttachment(attachment));
}
}
addAttachmentFileCloseUoW(camelExchange, cxfExchange);
}
/**
* This method is called by {@link CxfConsumer} to populate a CXF response protocol headers from a Camel exchange
* headers before CheckError. Ensure can send protocol headers back even error/exception thrown
*/
public void populateCxfHeaderFromCamelExchangeBeforeCheckError(
Exchange camelExchange,
org.apache.cxf.message.Exchange cxfExchange) {
if (cxfExchange.isOneWay()) {
return;
}
// create response context
Map responseContext = new HashMap<>();
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 camelHeaders = response.getHeaders();
extractInvocationContextFromCamel(camelExchange, camelHeaders,
responseContext, Client.RESPONSE_CONTEXT);
propagateHeadersFromCamelToCxf(camelExchange, camelHeaders, cxfExchange,
responseContext);
if (cxfExchange.getOutMessage() != null) {
cxfExchange.getOutMessage().put(Message.PROTOCOL_HEADERS, responseContext.get(Message.PROTOCOL_HEADERS));
}
}
/**
* This method is called by {@link CxfConsumer} to populate a CXF response exchange from a Camel exchange.
*/
@Override
public void populateCxfResponseFromExchange(
Exchange camelExchange,
org.apache.cxf.message.Exchange cxfExchange) {
if (cxfExchange.isOneWay()) {
return;
}
// create response context
Map responseContext = new HashMap<>();
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 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();
if (cxfExchange.getInMessage() instanceof SoapMessage) {
SoapVersion soapVersion = ((SoapMessage) cxfExchange.getInMessage()).getVersion();
((SoapMessage) outMessage).setVersion(soapVersion);
}
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 attachments = null;
boolean isXop = Boolean.valueOf(camelExchange.getProperty(Message.MTOM_ENABLED, String.class));
if (camelExchange.hasOut() && camelExchange.getOut(AttachmentMessage.class).hasAttachments()) {
for (Map.Entry entry : camelExchange.getOut(AttachmentMessage.class)
.getAttachmentObjects().entrySet()) {
if (attachments == null) {
attachments = new HashSet<>();
}
AttachmentImpl attachment = new AttachmentImpl(entry.getKey());
org.apache.camel.attachment.Attachment camelAttachment = entry.getValue();
attachment.setDataHandler(camelAttachment.getDataHandler());
for (String name : camelAttachment.getHeaderNames()) {
attachment.setHeader(name, camelAttachment.getHeader(name));
}
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());
}
}
// HeaderFilterStrategyAware Methods
// -------------------------------------------------------------------------
protected void setCharsetWithContentType(Exchange camelExchange) {
// setup the charset from content-type header
String contentTypeHeader = ExchangeHelper.getContentType(camelExchange);
if (contentTypeHeader != null) {
String charset = HttpHeaderHelper.findCharset(contentTypeHeader);
String normalizedEncoding = HttpHeaderHelper.mapCharset(charset, Charset.forName("UTF-8").name());
if (normalizedEncoding != null) {
camelExchange.setProperty(ExchangePropertyKey.CHARSET_NAME, normalizedEncoding);
}
}
}
@Override
public HeaderFilterStrategy getHeaderFilterStrategy() {
return headerFilterStrategy;
}
@Override
public void setHeaderFilterStrategy(HeaderFilterStrategy strategy) {
this.headerFilterStrategy = strategy;
}
// Non public methods
// -------------------------------------------------------------------------
protected MessageContentsList getResponsePayloadList(
org.apache.cxf.message.Exchange exchange,
List