You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ni...@apache.org on 2014/12/03 15:10:19 UTC

[1/4] camel git commit: CAMEL-8076 Fixed the issue that CamelJob cannot find right QuartzEndpoint when recoverying the job

Repository: camel
Updated Branches:
  refs/heads/camel-2.13.x 2883bbfef -> 1e064a358
  refs/heads/camel-2.14.x 751856a13 -> ef142f9e9


CAMEL-8076 Fixed the issue that CamelJob cannot find right QuartzEndpoint when recoverying the job


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/01e7af34
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/01e7af34
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/01e7af34

Branch: refs/heads/camel-2.14.x
Commit: 01e7af3466baeb4813e3e20e244fc7dac8c044fc
Parents: 751856a
Author: Willem Jiang <wi...@gmail.com>
Authored: Wed Dec 3 21:43:21 2014 +0800
Committer: Willem Jiang <wi...@gmail.com>
Committed: Wed Dec 3 22:09:13 2014 +0800

----------------------------------------------------------------------
 .../camel/component/quartz2/CamelJob.java       |  9 +++--
 ...rtzConsumerTwoAppsClusteredRecoveryTest.java | 35 ++++++++++++++++----
 ...ingQuartzConsumerRecoveryClusteredAppOne.xml |  6 ++--
 3 files changed, 38 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/01e7af34/components/camel-quartz2/src/main/java/org/apache/camel/component/quartz2/CamelJob.java
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/main/java/org/apache/camel/component/quartz2/CamelJob.java b/components/camel-quartz2/src/main/java/org/apache/camel/component/quartz2/CamelJob.java
index 1d5d88d..a4b7836 100644
--- a/components/camel-quartz2/src/main/java/org/apache/camel/component/quartz2/CamelJob.java
+++ b/components/camel-quartz2/src/main/java/org/apache/camel/component/quartz2/CamelJob.java
@@ -21,8 +21,10 @@ import org.apache.camel.CamelExchangeException;
 import org.apache.camel.Exchange;
 import org.apache.camel.Route;
 import org.quartz.Job;
+import org.quartz.JobDetail;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobExecutionException;
+import org.quartz.JobKey;
 import org.quartz.SchedulerContext;
 import org.quartz.SchedulerException;
 import org.quartz.TriggerKey;
@@ -89,10 +91,12 @@ public class CamelJob implements Job {
 
     protected QuartzEndpoint lookupQuartzEndpoint(CamelContext camelContext, JobExecutionContext quartzContext) throws JobExecutionException {
         TriggerKey triggerKey = quartzContext.getTrigger().getKey();
+        JobDetail jobDetail = quartzContext.getJobDetail(); 
+        JobKey jobKey =  jobDetail.getKey();
         if (LOG.isDebugEnabled()) {
             LOG.debug("Looking up existing QuartzEndpoint with triggerKey={}", triggerKey);
         }
-
+        
         // check all active routes for the quartz endpoint this task matches
         // as we prefer to use the existing endpoint from the routes
         for (Route route : camelContext.getRoutes()) {
@@ -102,7 +106,8 @@ public class CamelJob implements Job {
                 if (LOG.isTraceEnabled()) {
                     LOG.trace("Checking route endpoint={} with checkTriggerKey={}", quartzEndpoint, checkTriggerKey);
                 }
-                if (triggerKey.equals(checkTriggerKey)) {
+                if (triggerKey.equals(checkTriggerKey)
+                    || (jobDetail.requestsRecovery() && jobKey.getGroup().equals(checkTriggerKey.getGroup()) && jobKey.getName().equals(checkTriggerKey.getName()))) {
                     return quartzEndpoint;
                 }
             }

http://git-wip-us.apache.org/repos/asf/camel/blob/01e7af34/components/camel-quartz2/src/test/java/org/apache/camel/component/quartz2/SpringQuartzConsumerTwoAppsClusteredRecoveryTest.java
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/test/java/org/apache/camel/component/quartz2/SpringQuartzConsumerTwoAppsClusteredRecoveryTest.java b/components/camel-quartz2/src/test/java/org/apache/camel/component/quartz2/SpringQuartzConsumerTwoAppsClusteredRecoveryTest.java
index 4fe1ab9..9758097 100644
--- a/components/camel-quartz2/src/test/java/org/apache/camel/component/quartz2/SpringQuartzConsumerTwoAppsClusteredRecoveryTest.java
+++ b/components/camel-quartz2/src/test/java/org/apache/camel/component/quartz2/SpringQuartzConsumerTwoAppsClusteredRecoveryTest.java
@@ -19,10 +19,14 @@ package org.apache.camel.component.quartz2;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.Predicate;
+import org.apache.camel.Processor;
 import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.test.junit4.TestSupport;
 import org.apache.camel.util.IOHelper;
 import org.junit.Test;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
 import org.springframework.context.support.AbstractXmlApplicationContext;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 
@@ -42,19 +46,20 @@ public class SpringQuartzConsumerTwoAppsClusteredRecoveryTest extends TestSuppor
         // now launch the first clustered app which will acquire the quartz database lock and become the master
         AbstractXmlApplicationContext app = new ClassPathXmlApplicationContext("org/apache/camel/component/quartz2/SpringQuartzConsumerRecoveryClusteredAppOne.xml");
         app.start();
-
-        // as well as the second one which will run in slave mode as it will not be able to acquire the same lock
-        AbstractXmlApplicationContext app2 = new ClassPathXmlApplicationContext("org/apache/camel/component/quartz2/SpringQuartzConsumerRecoveryClusteredAppTwo.xml");
-        app2.start();
-
+        
         // now let's simulate a crash of the first app (the quartz instance 'app-one')
         log.warn("The first app is going to crash NOW!");
-        IOHelper.close(app);
 
         log.warn("Crashed...");
         log.warn("Crashed...");
         log.warn("Crashed...");
-
+        
+        Thread.sleep(2000);
+        
+        // as well as the second one which will run in slave mode as it will not be able to acquire the same lock
+        AbstractXmlApplicationContext app2 = new ClassPathXmlApplicationContext("org/apache/camel/component/quartz2/SpringQuartzConsumerRecoveryClusteredAppTwo.xml");
+        app2.start();
+        
         // wait long enough until the second app takes it over...
         Thread.sleep(20000);
         // inside the logs one can then clearly see how the route of the second app ('app-two') starts consuming:
@@ -91,5 +96,21 @@ public class SpringQuartzConsumerTwoAppsClusteredRecoveryTest extends TestSuppor
         }
 
     }
+    
+    public static class MyProcessor implements Processor, ApplicationContextAware {
+        ApplicationContext applicationContext;
+
+        @Override
+        public void process(Exchange exchange) throws Exception {
+            // shutdown the application context;
+            ((AbstractXmlApplicationContext)applicationContext).close();
+        }
+
+        @Override
+        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+            this.applicationContext = applicationContext;
+        }
+        
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/01e7af34/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzConsumerRecoveryClusteredAppOne.xml
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzConsumerRecoveryClusteredAppOne.xml b/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzConsumerRecoveryClusteredAppOne.xml
index a01b1c0..91c07b1 100644
--- a/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzConsumerRecoveryClusteredAppOne.xml
+++ b/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzConsumerRecoveryClusteredAppOne.xml
@@ -58,6 +58,8 @@
       </props>
     </property>
   </bean>
+  
+  <bean id="myProcessor" class="org.apache.camel.component.quartz2.SpringQuartzConsumerTwoAppsClusteredRecoveryTest$MyProcessor" />
 
   <camelContext id="camelContext" shutdownEager="false" xmlns="http://camel.apache.org/schema/spring">
     <template id="template" />
@@ -67,9 +69,7 @@
         <simple>clustering PINGS!</simple>
       </transform>
       <to uri="log:triggered" />
-      <!--delay>
-         <constant>10000</constant>
-       </delay-->
+      <process ref="myProcessor"/>
       <to uri="mock:result" />
     </route>
   </camelContext>


[3/4] camel git commit: CAMEL-8076 Fixed the issue that CamelJob cannot find right QuartzEndpoint when recoverying the job

Posted by ni...@apache.org.
CAMEL-8076 Fixed the issue that CamelJob cannot find right QuartzEndpoint when recoverying the job


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/9b84cf42
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/9b84cf42
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/9b84cf42

Branch: refs/heads/camel-2.13.x
Commit: 9b84cf423712d0e595ffb57eea996eda1f6b564c
Parents: 2883bbf
Author: Willem Jiang <wi...@gmail.com>
Authored: Wed Dec 3 21:43:21 2014 +0800
Committer: Willem Jiang <wi...@gmail.com>
Committed: Wed Dec 3 22:09:47 2014 +0800

----------------------------------------------------------------------
 .../camel/component/quartz2/CamelJob.java       |  9 +++--
 ...rtzConsumerTwoAppsClusteredRecoveryTest.java | 35 ++++++++++++++++----
 ...ingQuartzConsumerRecoveryClusteredAppOne.xml |  6 ++--
 3 files changed, 38 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/9b84cf42/components/camel-quartz2/src/main/java/org/apache/camel/component/quartz2/CamelJob.java
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/main/java/org/apache/camel/component/quartz2/CamelJob.java b/components/camel-quartz2/src/main/java/org/apache/camel/component/quartz2/CamelJob.java
index df580a0..1a70a34 100644
--- a/components/camel-quartz2/src/main/java/org/apache/camel/component/quartz2/CamelJob.java
+++ b/components/camel-quartz2/src/main/java/org/apache/camel/component/quartz2/CamelJob.java
@@ -21,8 +21,10 @@ import org.apache.camel.CamelExchangeException;
 import org.apache.camel.Exchange;
 import org.apache.camel.Route;
 import org.quartz.Job;
+import org.quartz.JobDetail;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobExecutionException;
+import org.quartz.JobKey;
 import org.quartz.SchedulerContext;
 import org.quartz.SchedulerException;
 import org.quartz.TriggerKey;
@@ -89,10 +91,12 @@ public class CamelJob implements Job {
 
     private QuartzEndpoint lookupQuartzEndpoint(CamelContext camelContext, JobExecutionContext quartzContext) throws JobExecutionException {
         TriggerKey triggerKey = quartzContext.getTrigger().getKey();
+        JobDetail jobDetail = quartzContext.getJobDetail(); 
+        JobKey jobKey =  jobDetail.getKey();
         if (LOG.isDebugEnabled()) {
             LOG.debug("Looking up existing QuartzEndpoint with triggerKey={}", triggerKey);
         }
-
+        
         // check all active routes for the quartz endpoint this task matches
         // as we prefer to use the existing endpoint from the routes
         for (Route route : camelContext.getRoutes()) {
@@ -102,7 +106,8 @@ public class CamelJob implements Job {
                 if (LOG.isTraceEnabled()) {
                     LOG.trace("Checking route endpoint={} with checkTriggerKey={}", quartzEndpoint, checkTriggerKey);
                 }
-                if (triggerKey.equals(checkTriggerKey)) {
+                if (triggerKey.equals(checkTriggerKey)
+                    || (jobDetail.requestsRecovery() && jobKey.getGroup().equals(checkTriggerKey.getGroup()) && jobKey.getName().equals(checkTriggerKey.getName()))) {
                     return quartzEndpoint;
                 }
             }

http://git-wip-us.apache.org/repos/asf/camel/blob/9b84cf42/components/camel-quartz2/src/test/java/org/apache/camel/component/quartz2/SpringQuartzConsumerTwoAppsClusteredRecoveryTest.java
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/test/java/org/apache/camel/component/quartz2/SpringQuartzConsumerTwoAppsClusteredRecoveryTest.java b/components/camel-quartz2/src/test/java/org/apache/camel/component/quartz2/SpringQuartzConsumerTwoAppsClusteredRecoveryTest.java
index 4fe1ab9..9758097 100644
--- a/components/camel-quartz2/src/test/java/org/apache/camel/component/quartz2/SpringQuartzConsumerTwoAppsClusteredRecoveryTest.java
+++ b/components/camel-quartz2/src/test/java/org/apache/camel/component/quartz2/SpringQuartzConsumerTwoAppsClusteredRecoveryTest.java
@@ -19,10 +19,14 @@ package org.apache.camel.component.quartz2;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.Predicate;
+import org.apache.camel.Processor;
 import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.test.junit4.TestSupport;
 import org.apache.camel.util.IOHelper;
 import org.junit.Test;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
 import org.springframework.context.support.AbstractXmlApplicationContext;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 
@@ -42,19 +46,20 @@ public class SpringQuartzConsumerTwoAppsClusteredRecoveryTest extends TestSuppor
         // now launch the first clustered app which will acquire the quartz database lock and become the master
         AbstractXmlApplicationContext app = new ClassPathXmlApplicationContext("org/apache/camel/component/quartz2/SpringQuartzConsumerRecoveryClusteredAppOne.xml");
         app.start();
-
-        // as well as the second one which will run in slave mode as it will not be able to acquire the same lock
-        AbstractXmlApplicationContext app2 = new ClassPathXmlApplicationContext("org/apache/camel/component/quartz2/SpringQuartzConsumerRecoveryClusteredAppTwo.xml");
-        app2.start();
-
+        
         // now let's simulate a crash of the first app (the quartz instance 'app-one')
         log.warn("The first app is going to crash NOW!");
-        IOHelper.close(app);
 
         log.warn("Crashed...");
         log.warn("Crashed...");
         log.warn("Crashed...");
-
+        
+        Thread.sleep(2000);
+        
+        // as well as the second one which will run in slave mode as it will not be able to acquire the same lock
+        AbstractXmlApplicationContext app2 = new ClassPathXmlApplicationContext("org/apache/camel/component/quartz2/SpringQuartzConsumerRecoveryClusteredAppTwo.xml");
+        app2.start();
+        
         // wait long enough until the second app takes it over...
         Thread.sleep(20000);
         // inside the logs one can then clearly see how the route of the second app ('app-two') starts consuming:
@@ -91,5 +96,21 @@ public class SpringQuartzConsumerTwoAppsClusteredRecoveryTest extends TestSuppor
         }
 
     }
+    
+    public static class MyProcessor implements Processor, ApplicationContextAware {
+        ApplicationContext applicationContext;
+
+        @Override
+        public void process(Exchange exchange) throws Exception {
+            // shutdown the application context;
+            ((AbstractXmlApplicationContext)applicationContext).close();
+        }
+
+        @Override
+        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+            this.applicationContext = applicationContext;
+        }
+        
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/9b84cf42/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzConsumerRecoveryClusteredAppOne.xml
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzConsumerRecoveryClusteredAppOne.xml b/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzConsumerRecoveryClusteredAppOne.xml
index a01b1c0..91c07b1 100644
--- a/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzConsumerRecoveryClusteredAppOne.xml
+++ b/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzConsumerRecoveryClusteredAppOne.xml
@@ -58,6 +58,8 @@
       </props>
     </property>
   </bean>
+  
+  <bean id="myProcessor" class="org.apache.camel.component.quartz2.SpringQuartzConsumerTwoAppsClusteredRecoveryTest$MyProcessor" />
 
   <camelContext id="camelContext" shutdownEager="false" xmlns="http://camel.apache.org/schema/spring">
     <template id="template" />
@@ -67,9 +69,7 @@
         <simple>clustering PINGS!</simple>
       </transform>
       <to uri="log:triggered" />
-      <!--delay>
-         <constant>10000</constant>
-       </delay-->
+      <process ref="myProcessor"/>
       <to uri="mock:result" />
     </route>
   </camelContext>


[2/4] camel git commit: CAMEL-8092 Fixed the cxf:producer Matrix Params missing issue with thanks to kumarann

Posted by ni...@apache.org.
CAMEL-8092 Fixed the cxf:producer Matrix Params missing issue with thanks to kumarann


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/ef142f9e
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/ef142f9e
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/ef142f9e

Branch: refs/heads/camel-2.14.x
Commit: ef142f9e9cb2d96800c1950731661dbe9a90f9ce
Parents: 01e7af3
Author: Willem Jiang <wi...@gmail.com>
Authored: Wed Dec 3 21:45:15 2014 +0800
Committer: Willem Jiang <wi...@gmail.com>
Committed: Wed Dec 3 22:09:30 2014 +0800

----------------------------------------------------------------------
 .../component/cxf/jaxrs/CxfRsProducer.java      | 42 ++++++++++++++++++++
 1 file changed, 42 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/ef142f9e/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducer.java b/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducer.java
index c220487..7b6e6ea 100644
--- a/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducer.java
+++ b/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducer.java
@@ -43,6 +43,7 @@ import org.apache.cxf.jaxrs.JAXRSServiceFactoryBean;
 import org.apache.cxf.jaxrs.client.Client;
 import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
 import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.message.MessageImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -121,6 +122,30 @@ public class CxfRsProducer extends DefaultProducer {
         
     }
     
+    protected void setupClientMatrix(WebClient client, Exchange exchange) throws Exception {
+        
+        org.apache.cxf.message.Message cxfMessage = (org.apache.cxf.message.Message) exchange.getIn().getHeader("CamelCxfMessage");
+        if (cxfMessage != null) {
+            String requestURL = (String)cxfMessage.get("org.apache.cxf.request.uri"); 
+            String matrixParam = null;
+            int matrixStart = requestURL.indexOf(";");
+            int matrixEnd = requestURL.indexOf("?") > -1 ? requestURL.indexOf("?") : requestURL.length();
+            Map<String, String> maps = null;
+            if (requestURL != null && matrixStart > 0) {
+                matrixParam = requestURL.substring(matrixStart + 1, matrixEnd);
+                if (matrixParam != null) {
+                    maps = getMatrixParametersFromMatrixString(matrixParam, IOHelper.getCharsetName(exchange));
+                }
+            }
+            if (maps != null) {
+                for (Map.Entry<String, String> entry : maps.entrySet()) {
+                    client.matrix(entry.getKey(), entry.getValue());
+                    LOG.debug("Matrix param " + entry.getKey() + " :: " + entry.getValue());
+                }
+            }
+        }
+    }
+    
     protected void setupClientHeaders(Client client, Exchange exchange) throws Exception {
         Message inMessage = exchange.getIn();
         CxfRsEndpoint cxfRsEndpoint = (CxfRsEndpoint) getEndpoint();
@@ -172,6 +197,8 @@ public class CxfRsProducer extends DefaultProducer {
                 }
             }
         }
+        
+        setupClientMatrix(client, exchange); 
 
         setupClientQueryAndHeaders(client, exchange);
         
@@ -342,6 +369,21 @@ public class CxfRsProducer extends DefaultProducer {
         return answer;
     }
 
+    private Map<String, String> getMatrixParametersFromMatrixString(String matrixString, String charset) throws UnsupportedEncodingException {
+        Map<String, String> answer  = new LinkedHashMap<String, String>();
+        for (String param : matrixString.split(";")) {
+            String[] pair = param.split("=", 2);
+            if (pair.length == 2) {
+                String name = URLDecoder.decode(pair[0], charset);
+                String value = URLDecoder.decode(pair[1], charset);
+                answer.put(name, value);
+            } else {
+                throw new IllegalArgumentException("Invalid parameter, expected to be a pair but was " + param);
+            }
+        }
+        return answer;
+    }
+    
     private String arrayToString(Object[] array) {
         StringBuilder buffer = new StringBuilder("[");
         for (Object obj : array) {


[4/4] camel git commit: CAMEL-8092 Fixed the cxf:producer Matrix Params missing issue with thanks to kumarann

Posted by ni...@apache.org.
CAMEL-8092 Fixed the cxf:producer Matrix Params missing issue with thanks to kumarann


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/1e064a35
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/1e064a35
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/1e064a35

Branch: refs/heads/camel-2.13.x
Commit: 1e064a358b4ff147c9932f9cecd47562aa235701
Parents: 9b84cf4
Author: Willem Jiang <wi...@gmail.com>
Authored: Wed Dec 3 21:45:15 2014 +0800
Committer: Willem Jiang <wi...@gmail.com>
Committed: Wed Dec 3 22:09:51 2014 +0800

----------------------------------------------------------------------
 .../component/cxf/jaxrs/CxfRsProducer.java      | 42 ++++++++++++++++++++
 1 file changed, 42 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/1e064a35/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducer.java b/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducer.java
index 32ed918..91381e9 100644
--- a/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducer.java
+++ b/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsProducer.java
@@ -43,6 +43,7 @@ import org.apache.cxf.jaxrs.JAXRSServiceFactoryBean;
 import org.apache.cxf.jaxrs.client.Client;
 import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
 import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.message.MessageImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -121,6 +122,30 @@ public class CxfRsProducer extends DefaultProducer {
         
     }
     
+    protected void setupClientMatrix(WebClient client, Exchange exchange) throws Exception {
+        
+        org.apache.cxf.message.Message cxfMessage = (org.apache.cxf.message.Message) exchange.getIn().getHeader("CamelCxfMessage");
+        if (cxfMessage != null) {
+            String requestURL = (String)cxfMessage.get("org.apache.cxf.request.uri"); 
+            String matrixParam = null;
+            int matrixStart = requestURL.indexOf(";");
+            int matrixEnd = requestURL.indexOf("?") > -1 ? requestURL.indexOf("?") : requestURL.length();
+            Map<String, String> maps = null;
+            if (requestURL != null && matrixStart > 0) {
+                matrixParam = requestURL.substring(matrixStart + 1, matrixEnd);
+                if (matrixParam != null) {
+                    maps = getMatrixParametersFromMatrixString(matrixParam, IOHelper.getCharsetName(exchange));
+                }
+            }
+            if (maps != null) {
+                for (Map.Entry<String, String> entry : maps.entrySet()) {
+                    client.matrix(entry.getKey(), entry.getValue());
+                    LOG.debug("Matrix param " + entry.getKey() + " :: " + entry.getValue());
+                }
+            }
+        }
+    }
+    
     protected void setupClientHeaders(Client client, Exchange exchange) throws Exception {
         Message inMessage = exchange.getIn();
         CxfRsEndpoint cxfRsEndpoint = (CxfRsEndpoint) getEndpoint();
@@ -172,6 +197,8 @@ public class CxfRsProducer extends DefaultProducer {
                 }
             }
         }
+        
+        setupClientMatrix(client, exchange); 
 
         setupClientQueryAndHeaders(client, exchange);
         
@@ -338,6 +365,21 @@ public class CxfRsProducer extends DefaultProducer {
         return answer;
     }
 
+    private Map<String, String> getMatrixParametersFromMatrixString(String matrixString, String charset) throws UnsupportedEncodingException {
+        Map<String, String> answer  = new LinkedHashMap<String, String>();
+        for (String param : matrixString.split(";")) {
+            String[] pair = param.split("=", 2);
+            if (pair.length == 2) {
+                String name = URLDecoder.decode(pair[0], charset);
+                String value = URLDecoder.decode(pair[1], charset);
+                answer.put(name, value);
+            } else {
+                throw new IllegalArgumentException("Invalid parameter, expected to be a pair but was " + param);
+            }
+        }
+        return answer;
+    }
+    
     private String arrayToString(Object[] array) {
         StringBuilder buffer = new StringBuilder("[");
         for (Object obj : array) {