Return-Path: Delivered-To: apmail-camel-commits-archive@www.apache.org Received: (qmail 68317 invoked from network); 6 Dec 2010 15:29:28 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 6 Dec 2010 15:29:28 -0000 Received: (qmail 97598 invoked by uid 500); 6 Dec 2010 15:29:28 -0000 Delivered-To: apmail-camel-commits-archive@camel.apache.org Received: (qmail 97547 invoked by uid 500); 6 Dec 2010 15:29:28 -0000 Mailing-List: contact commits-help@camel.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@camel.apache.org Delivered-To: mailing list commits@camel.apache.org Received: (qmail 97536 invoked by uid 99); 6 Dec 2010 15:29:27 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 06 Dec 2010 15:29:27 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 06 Dec 2010 15:29:21 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id EB27A2388A33; Mon, 6 Dec 2010 15:28:58 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1042677 - in /camel/trunk: camel-core/src/main/java/org/apache/camel/ components/camel-cxf/src/main/java/org/apache/camel/component/cxf/ components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/ components/camel-cxf/src/main... Date: Mon, 06 Dec 2010 15:28:58 -0000 To: commits@camel.apache.org From: wtam@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20101206152858.EB27A2388A33@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: wtam Date: Mon Dec 6 15:28:58 2010 New Revision: 1042677 URL: http://svn.apache.org/viewvc?rev=1042677&view=rev Log: [CAMEL-3386] Support destination address override by CxfProvider and CxfrsProvider Added: camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfPayLoadMessageRouterAddressOverrideTest.java (with props) camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfRawMessageRouterAddressOverrideTest.java (with props) camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfSimpleRouterAddressOverrideTest.java (with props) camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducerAddressOverrideTest.java (with props) camel/trunk/components/camel-cxf/src/test/resources/org/apache/camel/component/cxf/jaxrs/CxfRsSpringProducerAddressOverride.xml (with props) Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/CxfEndpoint.java camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/CxfProducer.java camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/CxfSpringEndpoint.java camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsEndpoint.java camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsHeaderFilterStrategy.java camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducer.java camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsSpringEndpoint.java camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/util/CxfEndpointUtils.java Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java?rev=1042677&r1=1042676&r2=1042677&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java Mon Dec 6 15:28:58 2010 @@ -94,6 +94,7 @@ public interface Exchange { String DATASET_INDEX = "CamelDataSetIndex"; String DEFAULT_CHARSET_PROPERTY = "org.apache.camel.default.charset"; + String DESTINATION_OVERRIDE_URL = "CamelDestinationOverrideUrl"; String DISABLE_HTTP_STREAM_CACHE = "CamelDisableHttpStreamCache"; String ERRORHANDLER_HANDLED = "CamelErrorHandlerHandled"; Modified: camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/CxfEndpoint.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/CxfEndpoint.java?rev=1042677&r1=1042676&r2=1042677&view=diff ============================================================================== --- camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/CxfEndpoint.java (original) +++ camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/CxfEndpoint.java Mon Dec 6 15:28:58 2010 @@ -98,7 +98,8 @@ public class CxfEndpoint extends Default private boolean loggingFeatureEnabled; private String address; private boolean mtomEnabled; - + private int maxClientCacheSize = 10; + public CxfEndpoint(String remaining, CxfComponent cxfComponent) { super(remaining, cxfComponent); setAddress(remaining); @@ -246,12 +247,12 @@ public class CxfEndpoint extends Default /** * Populate a client factory bean */ - protected void setupClientFactoryBean(ClientProxyFactoryBean factoryBean, Class cls) { + protected void setupClientFactoryBean(ClientProxyFactoryBean factoryBean, Class cls, String serviceAddress) { // service class factoryBean.setServiceClass(cls); // address - factoryBean.setAddress(getAddress()); + factoryBean.setAddress(serviceAddress); // wsdl url if (getWsdlURL() != null) { @@ -289,9 +290,9 @@ public class CxfEndpoint extends Default } - protected void setupClientFactoryBean(ClientFactoryBean factoryBean) { + protected void setupClientFactoryBean(ClientFactoryBean factoryBean, String serviceAddress) { // address - factoryBean.setAddress(getAddress()); + factoryBean.setAddress(serviceAddress); // wsdl url if (getWsdlURL() != null) { @@ -335,6 +336,13 @@ public class CxfEndpoint extends Default * Create a CXF client object */ Client createClient() throws Exception { + return createClient(getAddress()); + } + + /** + * Create a CXF client object + */ + Client createClient(String serviceAddress) throws Exception { // get service class if (getDataFormat().equals(DataFormat.POJO)) { @@ -347,14 +355,14 @@ public class CxfEndpoint extends Default // create client factory bean ClientProxyFactoryBean factoryBean = createClientFactoryBean(cls); // setup client factory bean - setupClientFactoryBean(factoryBean, cls); + setupClientFactoryBean(factoryBean, cls, serviceAddress); return ((ClientProxy)Proxy.getInvocationHandler(factoryBean.create())).getClient(); } else { checkName(portName, "endpoint/port name"); checkName(serviceName, "service name"); ClientFactoryBean factoryBean = createClientFactoryBean(); // setup client factory bean - setupClientFactoryBean(factoryBean); + setupClientFactoryBean(factoryBean, serviceAddress); return factoryBean.create(); } @@ -583,6 +591,20 @@ public class CxfEndpoint extends Default } /** + * @param maxClientCacheSize the maxClientCacheSize to set + */ + public void setMaxClientCacheSize(int maxClientCacheSize) { + this.maxClientCacheSize = maxClientCacheSize; + } + + /** + * @return the maxClientCacheSize + */ + public int getMaxClientCacheSize() { + return maxClientCacheSize; + } + + /** * We need to override the {@link ClientImpl#setParameters} method * to insert parameters into CXF Message for {@link DataFormat#PAYLOAD} mode. */ Modified: camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/CxfProducer.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/CxfProducer.java?rev=1042677&r1=1042676&r2=1042677&view=diff ============================================================================== --- camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/CxfProducer.java (original) +++ camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/CxfProducer.java Mon Dec 6 15:28:58 2010 @@ -17,6 +17,7 @@ package org.apache.camel.component.cxf; import java.io.InputStream; +import java.lang.ref.SoftReference; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; @@ -32,7 +33,9 @@ import org.apache.camel.AsyncProcessor; import org.apache.camel.Exchange; import org.apache.camel.InvalidPayloadException; import org.apache.camel.RuntimeCamelException; +import org.apache.camel.component.cxf.util.CxfEndpointUtils; import org.apache.camel.impl.DefaultProducer; +import org.apache.camel.util.LRUCache; import org.apache.camel.util.ObjectHelper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -53,9 +56,9 @@ import org.apache.cxf.service.model.Bind */ public class CxfProducer extends DefaultProducer implements AsyncProcessor { private static final Log LOG = LogFactory.getLog(CxfProducer.class); - private Client client; private CxfEndpoint endpoint; - + private ClientCache clientCache; + /** * Constructor to create a CxfProducer. It will create a CXF client * object. @@ -67,7 +70,7 @@ public class CxfProducer extends Default public CxfProducer(CxfEndpoint endpoint) throws Exception { super(endpoint); this.endpoint = endpoint; - client = endpoint.createClient(); + clientCache = new ClientCache(endpoint.getMaxClientCacheSize()); } // As the cxf client async and sync api is implement different, @@ -81,8 +84,10 @@ public class CxfProducer extends Default // create CXF exchange ExchangeImpl cxfExchange = new ExchangeImpl(); + Client client = clientCache.get(CxfEndpointUtils.getEffectiveAddress(camelExchange, endpoint.getAddress())); + // prepare binding operation info - BindingOperationInfo boi = prepareBindingOperation(camelExchange, cxfExchange); + BindingOperationInfo boi = prepareBindingOperation(camelExchange, cxfExchange, client); Map invocationContext = new HashMap(); Map responseContext = new HashMap(); @@ -91,7 +96,7 @@ public class CxfProducer extends Default CxfClientCallback cxfClientCallback = new CxfClientCallback(callback, camelExchange, cxfExchange, boi, endpoint); // send the CXF async request - client.invoke(cxfClientCallback, boi, getParams(endpoint, camelExchange), + client.invoke(cxfClientCallback, boi, getParams(endpoint, camelExchange, client), invocationContext, cxfExchange); } catch (Throwable ex) { // error occurred before we had a chance to go async @@ -116,17 +121,20 @@ public class CxfProducer extends Default // create CXF exchange ExchangeImpl cxfExchange = new ExchangeImpl(); + Client client = clientCache.get(CxfEndpointUtils.getEffectiveAddress(camelExchange, endpoint.getAddress())); + // prepare binding operation info - BindingOperationInfo boi = prepareBindingOperation(camelExchange, cxfExchange); + BindingOperationInfo boi = prepareBindingOperation(camelExchange, cxfExchange, client); Map invocationContext = new HashMap(); Map responseContext = new HashMap(); invocationContext.put(Client.RESPONSE_CONTEXT, responseContext); invocationContext.put(Client.REQUEST_CONTEXT, prepareRequest(camelExchange, cxfExchange)); + try { // send the CXF request - client.invoke(boi, getParams(endpoint, camelExchange), + client.invoke(boi, getParams(endpoint, camelExchange, client), invocationContext, cxfExchange); } finally { // bind the CXF response to Camel exchange @@ -179,9 +187,9 @@ public class CxfProducer extends Default return requestContext.getWrappedMap(); } - private BindingOperationInfo prepareBindingOperation(Exchange camelExchange, org.apache.cxf.message.Exchange cxfExchange) { + private BindingOperationInfo prepareBindingOperation(Exchange camelExchange, org.apache.cxf.message.Exchange cxfExchange, Client client) { // get binding operation info - BindingOperationInfo boi = getBindingOperationInfo(camelExchange); + BindingOperationInfo boi = getBindingOperationInfo(camelExchange, client); ObjectHelper.notNull(boi, "BindingOperationInfo"); // keep the message wrapper in PAYLOAD mode @@ -209,8 +217,8 @@ public class CxfProducer extends Default return boi; } - private void checkParameterSize(CxfEndpoint endpoint, Exchange exchange, Object[] parameters) { - BindingOperationInfo boi = getBindingOperationInfo(exchange); + private void checkParameterSize(CxfEndpoint endpoint, Exchange exchange, Object[] parameters, Client client) { + BindingOperationInfo boi = getBindingOperationInfo(exchange, client); if (boi == null) { throw new RuntimeCamelException("Can't find the binding operation information from camel exchange"); } @@ -254,7 +262,7 @@ public class CxfProducer extends Default /** * Get the parameters for the web service operation */ - private Object[] getParams(CxfEndpoint endpoint, Exchange exchange) throws InvalidPayloadException { + private Object[] getParams(CxfEndpoint endpoint, Exchange exchange, Client client) throws InvalidPayloadException { Object[] params = null; if (endpoint.getDataFormat() == DataFormat.POJO) { @@ -278,7 +286,7 @@ public class CxfProducer extends Default } } // make sure we have the right number of parameters - checkParameterSize(endpoint, exchange, params); + checkParameterSize(endpoint, exchange, params, client); } else if (endpoint.getDataFormat() == DataFormat.PAYLOAD) { params = new Object[1]; @@ -303,7 +311,7 @@ public class CxfProducer extends Default * Get operation name from header and use it to lookup and return a * {@link BindingOperationInfo}. */ - private BindingOperationInfo getBindingOperationInfo(Exchange ex) { + private BindingOperationInfo getBindingOperationInfo(Exchange ex, Client client) { CxfEndpoint endpoint = (CxfEndpoint)this.getEndpoint(); BindingOperationInfo answer = null; String lp = ex.getIn().getHeader(CxfConstants.OPERATION_NAME, String.class); @@ -345,9 +353,46 @@ public class CxfProducer extends Default } return answer; } - - public Client getClient() { - return client; + + // only invoked by unit test + public Client getClient() throws Exception { + return clientCache.get(endpoint.getAddress()); } + /** + * Cache contains {@link org.apache.cxf.endpoint.Client} + */ + private class ClientCache { + private LRUCache> cache; + + public ClientCache(final int maxCacheSize) { + this.cache = new LRUCache>(maxCacheSize); + } + + public Client get(String address) throws Exception { + Client retval = null; + synchronized (cache) { + SoftReference ref = cache.get(address); + + if (ref != null) { + retval = ref.get(); + } + + if (retval == null) { + retval = ((CxfEndpoint)getEndpoint()).createClient(address); + cache.put(address, new SoftReference(retval)); + + if (LOG.isTraceEnabled()) { + LOG.trace("Created CXF client and add to cache for address '" + address + "'"); + } + + } else { + if (LOG.isTraceEnabled()) { + LOG.trace("Retrieved CXF client from cache for address '" + address + "'"); + } + } + } + return retval; + } + } } Modified: camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/CxfSpringEndpoint.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/CxfSpringEndpoint.java?rev=1042677&r1=1042676&r2=1042677&view=diff ============================================================================== --- camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/CxfSpringEndpoint.java (original) +++ camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/CxfSpringEndpoint.java Mon Dec 6 15:28:58 2010 @@ -103,7 +103,7 @@ public class CxfSpringEndpoint extends C * Create a CXF Client */ @Override - Client createClient() throws Exception { + Client createClient(String serviceAddress) throws Exception { // get service class Class cls = getSEIClass(); @@ -120,7 +120,7 @@ public class CxfSpringEndpoint extends C configure(factoryBean); // setup client factory bean - setupClientFactoryBean(factoryBean, cls); + setupClientFactoryBean(factoryBean, cls, serviceAddress); // fill in values that have not been filled. QName serviceQName = null; @@ -145,7 +145,7 @@ public class CxfSpringEndpoint extends C configure(factoryBean); // setup client factory bean - setupClientFactoryBean(factoryBean); + setupClientFactoryBean(factoryBean, serviceAddress); // fill in values that have not been filled. QName serviceQName = null; Modified: camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsEndpoint.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsEndpoint.java?rev=1042677&r1=1042676&r2=1042677&view=diff ============================================================================== --- camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsEndpoint.java (original) +++ camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsEndpoint.java Mon Dec 6 15:28:58 2010 @@ -47,7 +47,8 @@ public class CxfRsEndpoint extends Defau private boolean httpClientAPI = true; private String address; private boolean throwExceptionOnFailure = true; - + private int maxClientCacheSize = 10; + private AtomicBoolean bindingInitialized = new AtomicBoolean(false); public CxfRsEndpoint(String endpointUri, CamelContext camelContext) { @@ -142,9 +143,9 @@ public class CxfRsEndpoint extends Defau sfb.setStart(false); } - protected void setupJAXRSClientFactoryBean(JAXRSClientFactoryBean cfb) { + protected void setupJAXRSClientFactoryBean(JAXRSClientFactoryBean cfb, String address) { // address - cfb.setAddress(getAddress()); + cfb.setAddress(address); if (getResourceClasses() != null) { cfb.setResourceClass(getResourceClasses().get(0)); } @@ -157,8 +158,12 @@ public class CxfRsEndpoint extends Defau } public JAXRSClientFactoryBean createJAXRSClientFactoryBean() { + return createJAXRSClientFactoryBean(getAddress()); + } + + public JAXRSClientFactoryBean createJAXRSClientFactoryBean(String address) { JAXRSClientFactoryBean answer = new SpringJAXRSClientFactoryBean(); - setupJAXRSClientFactoryBean(answer); + setupJAXRSClientFactoryBean(answer, address); return answer; } @@ -189,4 +194,18 @@ public class CxfRsEndpoint extends Defau public void setThrowExceptionOnFailure(boolean throwExceptionOnFailure) { this.throwExceptionOnFailure = throwExceptionOnFailure; } + + /** + * @param maxClientCacheSize the maxClientCacheSize to set + */ + public void setMaxClientCacheSize(int maxClientCacheSize) { + this.maxClientCacheSize = maxClientCacheSize; + } + + /** + * @return the maxClientCacheSize + */ + public int getMaxClientCacheSize() { + return maxClientCacheSize; + } } Modified: camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsHeaderFilterStrategy.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsHeaderFilterStrategy.java?rev=1042677&r1=1042676&r2=1042677&view=diff ============================================================================== --- camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsHeaderFilterStrategy.java (original) +++ camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsHeaderFilterStrategy.java Mon Dec 6 15:28:58 2010 @@ -38,6 +38,8 @@ public class CxfRsHeaderFilterStrategy e getOutFilter().add(CxfConstants.OPERATION_NAME); getOutFilter().add(Exchange.HTTP_METHOD); getOutFilter().add(Exchange.HTTP_PATH); + getOutFilter().add(Exchange.DESTINATION_OVERRIDE_URL); + } } Modified: camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducer.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducer.java?rev=1042677&r1=1042676&r2=1042677&view=diff ============================================================================== --- camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducer.java (original) +++ camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducer.java Mon Dec 6 15:28:58 2010 @@ -16,6 +16,7 @@ */ package org.apache.camel.component.cxf.jaxrs; +import java.lang.ref.SoftReference; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; @@ -30,7 +31,9 @@ import org.apache.camel.Exchange; import org.apache.camel.Message; import org.apache.camel.component.cxf.CxfConstants; import org.apache.camel.component.cxf.CxfOperationException; +import org.apache.camel.component.cxf.util.CxfEndpointUtils; import org.apache.camel.impl.DefaultProducer; +import org.apache.camel.util.LRUCache; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.cxf.jaxrs.JAXRSServiceFactoryBean; @@ -47,13 +50,16 @@ public class CxfRsProducer extends Defau private static final Log LOG = LogFactory.getLog(CxfRsProducer.class); - JAXRSClientFactoryBean cfb; private boolean throwException; - + + // using a cache of factory beans instead of setting the address of a single cfb + // to avoid concurrent issues + private ClientFactoryBeanCache clientFactoryBeanCache; + public CxfRsProducer(CxfRsEndpoint endpoint) { super(endpoint); this.throwException = endpoint.isThrowExceptionOnFailure(); - cfb = endpoint.createJAXRSClientFactoryBean(); + clientFactoryBeanCache = new ClientFactoryBeanCache(endpoint.getMaxClientCacheSize()); } public void process(Exchange exchange) throws Exception { @@ -77,6 +83,9 @@ public class CxfRsProducer extends Defau @SuppressWarnings("unchecked") protected void invokeHttpClient(Exchange exchange) throws Exception { Message inMessage = exchange.getIn(); + JAXRSClientFactoryBean cfb = clientFactoryBeanCache.get(CxfEndpointUtils + .getEffectiveAddress(exchange, ((CxfRsEndpoint)getEndpoint()).getAddress())); + WebClient client = cfb.createWebClient(); String httpMethod = inMessage.getHeader(Exchange.HTTP_METHOD, String.class); Class responseClass = inMessage.getHeader(CxfConstants.CAMEL_CXF_RS_RESPONSE_CLASS, Class.class); @@ -163,6 +172,10 @@ public class CxfRsProducer extends Defau Object[] varValues = inMessage.getHeader(CxfConstants.CAMEL_CXF_RS_VAR_VALUES, Object[].class); String methodName = inMessage.getHeader(CxfConstants.OPERATION_NAME, String.class); Client target = null; + + JAXRSClientFactoryBean cfb = clientFactoryBeanCache.get(CxfEndpointUtils + .getEffectiveAddress(exchange, ((CxfRsEndpoint)getEndpoint()).getAddress())); + if (varValues == null) { target = cfb.create(); } else { @@ -270,4 +283,42 @@ public class CxfRsProducer extends Defau return answer; } + + /** + * Cache contains {@link org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean} + */ + private class ClientFactoryBeanCache { + private LRUCache> cache; + + public ClientFactoryBeanCache(final int maxCacheSize) { + this.cache = new LRUCache>(maxCacheSize); + } + + public JAXRSClientFactoryBean get(String address) throws Exception { + JAXRSClientFactoryBean retval = null; + synchronized (cache) { + SoftReference ref = cache.get(address); + + if (ref != null) { + retval = ref.get(); + } + + if (retval == null) { + retval = ((CxfRsEndpoint)getEndpoint()).createJAXRSClientFactoryBean(address); + + cache.put(address, new SoftReference(retval)); + + if (LOG.isTraceEnabled()) { + LOG.trace("Created client factory bean and add to cache for address '" + address + "'"); + } + + } else { + if (LOG.isTraceEnabled()) { + LOG.trace("Retrieved client factory bean from cache for address '" + address + "'"); + } + } + } + return retval; + } + } } Modified: camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsSpringEndpoint.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsSpringEndpoint.java?rev=1042677&r1=1042676&r2=1042677&view=diff ============================================================================== --- camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsSpringEndpoint.java (original) +++ camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsSpringEndpoint.java Mon Dec 6 15:28:58 2010 @@ -67,15 +67,18 @@ public class CxfRsSpringEndpoint extends } } + @Override protected void setupJAXRSServerFactoryBean(JAXRSServerFactoryBean sfb) { checkBeanType(JAXRSServerFactoryBean.class); configure(sfb); } - protected void setupJAXRSClientFactoryBean(JAXRSClientFactoryBean cfb) { + @Override + protected void setupJAXRSClientFactoryBean(JAXRSClientFactoryBean cfb, String address) { checkBeanType(JAXRSClientFactoryBean.class); - configure(cfb); + configure(cfb); + cfb.setAddress(address); } public String getBeanId() { Modified: camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/util/CxfEndpointUtils.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/util/CxfEndpointUtils.java?rev=1042677&r1=1042676&r2=1042677&view=diff ============================================================================== --- camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/util/CxfEndpointUtils.java (original) +++ camel/trunk/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/util/CxfEndpointUtils.java Mon Dec 6 15:28:58 2010 @@ -23,17 +23,21 @@ import javax.xml.namespace.QName; import javax.xml.ws.WebServiceProvider; import org.apache.camel.CamelException; +import org.apache.camel.Exchange; import org.apache.camel.component.cxf.CxfConstants; import org.apache.camel.component.cxf.CxfEndpoint; import org.apache.camel.component.cxf.CxfSpringEndpoint; import org.apache.camel.component.cxf.spring.CxfEndpointBean; import org.apache.camel.util.ObjectHelper; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.cxf.frontend.ClientProxyFactoryBean; import org.apache.cxf.frontend.ServerFactoryBean; import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; import org.apache.cxf.jaxws.JaxWsServerFactoryBean; public final class CxfEndpointUtils { + private static final Log LOG = LogFactory.getLog(CxfEndpointUtils.class); private CxfEndpointUtils() { // not constructed @@ -155,6 +159,26 @@ public final class CxfEndpointUtils { return result; } + /** + * Get effective address for a client to invoke a service. It first looks for the + * {@link org.apache.camel.Exchange#DESTINATION_OVERRIDE_URL} in the IN message header. + * If the header is not found, it will return the default address. + * + * @param exchange + * @param defaultAddress + */ + public static String getEffectiveAddress(Exchange exchange, String defaultAddress) { + String retval = exchange.getIn().getHeader(Exchange.DESTINATION_OVERRIDE_URL, String.class); + if (retval == null) { + retval = defaultAddress; + } else { + if (LOG.isTraceEnabled()) { + LOG.trace("Client address is overridden by header '" + Exchange.DESTINATION_OVERRIDE_URL + + "' to value '" + retval + "'"); + } + } + return retval; + } } Added: camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfPayLoadMessageRouterAddressOverrideTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfPayLoadMessageRouterAddressOverrideTest.java?rev=1042677&view=auto ============================================================================== --- camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfPayLoadMessageRouterAddressOverrideTest.java (added) +++ camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfPayLoadMessageRouterAddressOverrideTest.java Mon Dec 6 15:28:58 2010 @@ -0,0 +1,57 @@ +/** + * 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.util.List; + +import org.w3c.dom.Element; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; + +/** + * A unit test for testing reading SOAP body with address override in PAYLOAD mode. + * + * @version $Revision$ + */ +public class CxfPayLoadMessageRouterAddressOverrideTest extends CxfPayLoadMessageRouterTest { + private String routerEndpointURI = "cxf://" + ROUTER_ADDRESS + "?" + SERVICE_CLASS + "&dataFormat=PAYLOAD"; + private String serviceEndpointURI = "cxf://http://localhost:9002/badAddress" + "?" + SERVICE_CLASS + "&dataFormat=PAYLOAD"; + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + public void configure() { + from(routerEndpointURI).process(new Processor() { + public void process(Exchange exchange) throws Exception { + + exchange.getIn().setHeader(Exchange.DESTINATION_OVERRIDE_URL, SERVICE_ADDRESS); + + CxfPayload payload = exchange.getIn().getBody(CxfPayload.class); + List elements = payload.getBody(); + assertNotNull("We should get the elements here" , elements); + assertEquals("Get the wrong elements size" , elements.size(), 1); + assertEquals("Get the wrong namespace URI" , elements.get(0).getNamespaceURI(), "http://cxf.component.camel.apache.org/"); + } + + }) + .to(serviceEndpointURI); + } + }; + } + +} Propchange: camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfPayLoadMessageRouterAddressOverrideTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfPayLoadMessageRouterAddressOverrideTest.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Added: camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfRawMessageRouterAddressOverrideTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfRawMessageRouterAddressOverrideTest.java?rev=1042677&view=auto ============================================================================== --- camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfRawMessageRouterAddressOverrideTest.java (added) +++ camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfRawMessageRouterAddressOverrideTest.java Mon Dec 6 15:28:58 2010 @@ -0,0 +1,37 @@ +/** + * 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 org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; + +public class CxfRawMessageRouterAddressOverrideTest extends CxfRawMessageRouterTest { + private String routerEndpointURI = "cxf://" + ROUTER_ADDRESS + "?" + SERVICE_CLASS + "&dataFormat=MESSAGE"; + private String serviceEndpointURI = "cxf://http://localhost:9002/badAddress" + "?" + SERVICE_CLASS + "&dataFormat=MESSAGE"; + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + public void configure() { + from(routerEndpointURI).to("log:org.apache.camel?level=DEBUG") + .setHeader(Exchange.DESTINATION_OVERRIDE_URL, constant(SERVICE_ADDRESS)) + .to(serviceEndpointURI).to("mock:result"); + } + }; + } +} Propchange: camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfRawMessageRouterAddressOverrideTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfRawMessageRouterAddressOverrideTest.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Added: camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfSimpleRouterAddressOverrideTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfSimpleRouterAddressOverrideTest.java?rev=1042677&view=auto ============================================================================== --- camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfSimpleRouterAddressOverrideTest.java (added) +++ camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfSimpleRouterAddressOverrideTest.java Mon Dec 6 15:28:58 2010 @@ -0,0 +1,40 @@ +/** + * 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 org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; + +public class CxfSimpleRouterAddressOverrideTest extends CxfSimpleRouterTest { + + private String routerEndpointURI = "cxf://" + ROUTER_ADDRESS + "?" + SERVICE_CLASS + "&dataFormat=POJO"; + private String serviceEndpointURI = "cxf://http://localhost:9002/badAddress" + "?" + SERVICE_CLASS + "&dataFormat=POJO"; + + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + public void configure() { + errorHandler(noErrorHandler()); + from(routerEndpointURI).to("log:org.apache.camel?level=DEBUG") + .setHeader(Exchange.DESTINATION_OVERRIDE_URL, constant(SERVICE_ADDRESS)) + .to(serviceEndpointURI); + } + }; + } +} Propchange: camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfSimpleRouterAddressOverrideTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/CxfSimpleRouterAddressOverrideTest.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Added: camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducerAddressOverrideTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducerAddressOverrideTest.java?rev=1042677&view=auto ============================================================================== --- camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducerAddressOverrideTest.java (added) +++ camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducerAddressOverrideTest.java Mon Dec 6 15:28:58 2010 @@ -0,0 +1,101 @@ +/** + * 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.jaxrs; + +import org.apache.camel.Exchange; +import org.apache.camel.ExchangePattern; +import org.apache.camel.Message; +import org.apache.camel.Processor; +import org.apache.camel.component.cxf.CxfConstants; +import org.apache.camel.component.cxf.jaxrs.testbean.Customer; +import org.springframework.context.support.AbstractXmlApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class CxfRsProducerAddressOverrideTest extends CxfRsProducerTest { + @Override + protected AbstractXmlApplicationContext createApplicationContext() { + return new ClassPathXmlApplicationContext("org/apache/camel/component/cxf/jaxrs/CxfRsSpringProducerAddressOverride.xml"); + } + + @Override + public void testGetConstumerWithClientProxyAPI() { + // START SNIPPET: ProxyExample + Exchange exchange = template.send("direct://proxy", new Processor() { + + public void process(Exchange exchange) throws Exception { + exchange.setPattern(ExchangePattern.InOut); + Message inMessage = exchange.getIn(); + + inMessage.setHeader(Exchange.DESTINATION_OVERRIDE_URL, + "http://localhost:9002"); + + // set the operation name + inMessage.setHeader(CxfConstants.OPERATION_NAME, "getCustomer"); + // using the proxy client API + inMessage.setHeader(CxfConstants.CAMEL_CXF_RS_USING_HTTP_API, Boolean.FALSE); + // set the parameters , if you just have one parameter + // camel will put this object into an Object[] itself + inMessage.setBody("123"); + } + + }); + + // get the response message + Customer response = (Customer) exchange.getOut().getBody(); + + assertNotNull("The response should not be null ", response); + assertEquals("Get a wrong customer id ", String.valueOf(response.getId()), "123"); + assertEquals("Get a wrong customer name", response.getName(), "John"); + // END SNIPPET: ProxyExample + } + + @Override + public void testGetConstumerWithHttpCentralClientAPI() { + // START SNIPPET: HttpExample + Exchange exchange = template.send("direct://http", new Processor() { + + public void process(Exchange exchange) throws Exception { + exchange.setPattern(ExchangePattern.InOut); + Message inMessage = exchange.getIn(); + + inMessage.setHeader(Exchange.DESTINATION_OVERRIDE_URL, + "http://localhost:9002"); + + // using the http central client API + inMessage.setHeader(CxfConstants.CAMEL_CXF_RS_USING_HTTP_API, Boolean.TRUE); + // set the Http method + inMessage.setHeader(Exchange.HTTP_METHOD, "GET"); + // set the relative path + inMessage.setHeader(Exchange.HTTP_PATH, "/customerservice/customers/123"); + // Specify the response class , cxfrs will use InputStream as the response object type + inMessage.setHeader(CxfConstants.CAMEL_CXF_RS_RESPONSE_CLASS, Customer.class); + // since we use the Get method, so we don't need to set the message body + inMessage.setBody(null); + } + + }); + + // get the response message + Customer response = (Customer) exchange.getOut().getBody(); + + assertNotNull("The response should not be null ", response); + assertEquals("Get a wrong customer id ", String.valueOf(response.getId()), "123"); + assertEquals("Get a wrong customer name", response.getName(), "John"); + // END SNIPPET: HttpExample + } + +} Propchange: camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducerAddressOverrideTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducerAddressOverrideTest.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Added: camel/trunk/components/camel-cxf/src/test/resources/org/apache/camel/component/cxf/jaxrs/CxfRsSpringProducerAddressOverride.xml URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cxf/src/test/resources/org/apache/camel/component/cxf/jaxrs/CxfRsSpringProducerAddressOverride.xml?rev=1042677&view=auto ============================================================================== --- camel/trunk/components/camel-cxf/src/test/resources/org/apache/camel/component/cxf/jaxrs/CxfRsSpringProducerAddressOverride.xml (added) +++ camel/trunk/components/camel-cxf/src/test/resources/org/apache/camel/component/cxf/jaxrs/CxfRsSpringProducerAddressOverride.xml Mon Dec 6 15:28:58 2010 @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Propchange: camel/trunk/components/camel-cxf/src/test/resources/org/apache/camel/component/cxf/jaxrs/CxfRsSpringProducerAddressOverride.xml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/components/camel-cxf/src/test/resources/org/apache/camel/component/cxf/jaxrs/CxfRsSpringProducerAddressOverride.xml ------------------------------------------------------------------------------ svn:keywords = Rev Date Propchange: camel/trunk/components/camel-cxf/src/test/resources/org/apache/camel/component/cxf/jaxrs/CxfRsSpringProducerAddressOverride.xml ------------------------------------------------------------------------------ svn:mime-type = text/xml