You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ay...@apache.org on 2013/07/23 23:35:58 UTC

git commit: CAMEL-6393: Making header propagation from cxf to camel consistent

Updated Branches:
  refs/heads/master 7427a177f -> 1aba34725


CAMEL-6393: Making header propagation from cxf to camel consistent


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

Branch: refs/heads/master
Commit: 1aba34725f459f13d33ccba31aceca2dd170f085
Parents: 7427a17
Author: Akitoshi Yoshida <ay...@apache.org>
Authored: Tue Jul 23 23:32:49 2013 +0200
Committer: Akitoshi Yoshida <ay...@apache.org>
Committed: Tue Jul 23 23:35:34 2013 +0200

----------------------------------------------------------------------
 .../cxf/common/header/CxfHeaderHelper.java      |  34 +++++-
 .../cxf/common/message/CxfConstants.java        |   1 +
 .../cxf/common/header/CxfHeaderHelperTest.java  | 119 +++++++++++++++++++
 .../camel/component/cxf/DefaultCxfBinding.java  |  21 +++-
 .../component/cxf/DefaultCxfBindingTest.java    |  45 ++++++-
 5 files changed, 209 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/1aba3472/components/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/common/header/CxfHeaderHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/common/header/CxfHeaderHelper.java b/components/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/common/header/CxfHeaderHelper.java
index f6d301f..7e1672d 100644
--- a/components/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/common/header/CxfHeaderHelper.java
+++ b/components/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/common/header/CxfHeaderHelper.java
@@ -17,11 +17,13 @@
 package org.apache.camel.component.cxf.common.header;
 
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
 
 import org.apache.camel.Exchange;
+import org.apache.camel.component.cxf.common.message.CxfConstants;
 import org.apache.camel.spi.HeaderFilterStrategy;
 import org.apache.cxf.endpoint.Client;
 import org.apache.cxf.helpers.CastUtils;
@@ -71,9 +73,14 @@ public final class CxfHeaderHelper {
                             || Message.RESPONSE_CODE.equals(entry.getKey())) {
                     message.put(entry.getKey(), entry.getValue());
                 } else {
-                    List<String> listValue = new ArrayList<String>();
-                    listValue.add(entry.getValue().toString());
-                    cxfHeaders.put(entry.getKey(), listValue);
+                    Object values = entry.getValue();
+                    if (values instanceof List<?>) {
+                        cxfHeaders.put(entry.getKey(), CastUtils.cast((List<?>)values, String.class));
+                    } else {
+                        List<String> listValue = new ArrayList<String>();
+                        listValue.add(entry.getValue().toString());
+                        cxfHeaders.put(entry.getKey(), listValue);
+                    }
                 }
             }
         }
@@ -92,7 +99,26 @@ public final class CxfHeaderHelper {
         if (cxfHeaders != null) {
             for (Map.Entry<String, List<String>> entry : cxfHeaders.entrySet()) {
                 if (!strategy.applyFilterToExternalHeaders(entry.getKey(), entry.getValue(), exchange)) {
-                    headers.put(entry.getKey(), entry.getValue().get(0));
+                    List<String> values = entry.getValue();
+                    //headers.put(entry.getKey(), entry.getValue().get(0));
+                    Object evalue;
+                    if (values.size() > 1) {
+                        if (exchange.getProperty(CxfConstants.CAMEL_CXF_PROTOCOL_HEADERS_MERGED, Boolean.FALSE, Boolean.class)) {
+                            StringBuilder sb = new StringBuilder();
+                            for (Iterator<String> it = values.iterator(); it.hasNext();) {
+                                sb.append(it.next());
+                                if (it.hasNext()) {
+                                    sb.append(',').append(' ');
+                                }
+                            }
+                            evalue = sb.toString();
+                        } else {
+                            evalue = values;
+                        }
+                    } else {
+                        evalue = values.get(0);
+                    }
+                    headers.put(entry.getKey(), evalue);
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/camel/blob/1aba3472/components/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/common/message/CxfConstants.java
----------------------------------------------------------------------
diff --git a/components/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/common/message/CxfConstants.java b/components/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/common/message/CxfConstants.java
index 255cee0..5398da4 100644
--- a/components/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/common/message/CxfConstants.java
+++ b/components/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/common/message/CxfConstants.java
@@ -59,6 +59,7 @@ public final class CxfConstants {
 
     public static final String WSA_HEADERS_OUTBOUND = "javax.xml.ws.addressing.context.outbound";
 
+    public static final String CAMEL_CXF_PROTOCOL_HEADERS_MERGED = "CamelCxfProtocolHeadersMerged";
 
     private CxfConstants() {
         // Utility class

http://git-wip-us.apache.org/repos/asf/camel/blob/1aba3472/components/camel-cxf-transport/src/test/java/org/apache/camel/component/cxf/common/header/CxfHeaderHelperTest.java
----------------------------------------------------------------------
diff --git a/components/camel-cxf-transport/src/test/java/org/apache/camel/component/cxf/common/header/CxfHeaderHelperTest.java b/components/camel-cxf-transport/src/test/java/org/apache/camel/component/cxf/common/header/CxfHeaderHelperTest.java
new file mode 100755
index 0000000..25fd240
--- /dev/null
+++ b/components/camel-cxf-transport/src/test/java/org/apache/camel/component/cxf/common/header/CxfHeaderHelperTest.java
@@ -0,0 +1,119 @@
+/**
+ * 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.common.header;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.cxf.common.message.CxfConstants;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.impl.DefaultExchange;
+import org.apache.camel.impl.DefaultHeaderFilterStrategy;
+
+import org.apache.cxf.helpers.CastUtils;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * 
+ */
+public class CxfHeaderHelperTest extends Assert {
+    private DefaultCamelContext context = new DefaultCamelContext();
+    
+    @Test
+    public void testPropagateCamelToCxf() {
+        Exchange exchange = new DefaultExchange(context);
+        
+        exchange.getIn().setHeader("soapAction", "urn:hello:world");
+        exchange.getIn().setHeader("MyFruitHeader", "peach");
+        exchange.getIn().setHeader("MyBrewHeader", Arrays.asList("cappuccino", "espresso"));
+        org.apache.cxf.message.Message cxfMessage = new org.apache.cxf.message.MessageImpl();
+        
+        CxfHeaderHelper.propagateCamelToCxf(new DefaultHeaderFilterStrategy(), 
+                                            exchange.getIn().getHeaders(), cxfMessage, exchange);
+        
+        // check the protocol headers
+        Map<String, List<String>> cxfHeaders = 
+            CastUtils.cast((Map<?, ?>)cxfMessage.get(org.apache.cxf.message.Message.PROTOCOL_HEADERS));
+        assertNotNull(cxfHeaders);
+        assertTrue(cxfHeaders.size() == 3);
+        
+        verifyHeader(cxfHeaders, "soapaction", "urn:hello:world");
+        verifyHeader(cxfHeaders, "SoapAction", "urn:hello:world");
+        verifyHeader(cxfHeaders, "SOAPAction", "urn:hello:world");
+        verifyHeader(cxfHeaders, "myfruitheader", "peach");
+        verifyHeader(cxfHeaders, "myFruitHeader", "peach");
+        verifyHeader(cxfHeaders, "MYFRUITHEADER", "peach");
+        verifyHeader(cxfHeaders, "MyBrewHeader", Arrays.asList("cappuccino", "espresso"));
+    } 
+
+    @Test
+    public void testPropagateCxfToCamel() {
+        Exchange exchange = new DefaultExchange(context);
+        org.apache.cxf.message.Message cxfMessage = new org.apache.cxf.message.MessageImpl();
+        Map<String, List<String>> cxfHeaders = new TreeMap<String, List<String>>(String.CASE_INSENSITIVE_ORDER);
+        cxfHeaders.put("Content-Length", Arrays.asList("241"));
+        cxfHeaders.put("soapAction", Arrays.asList("urn:hello:world"));
+        cxfHeaders.put("myfruitheader", Arrays.asList("peach"));
+        cxfHeaders.put("mybrewheader", Arrays.asList("cappuccino", "espresso"));
+        cxfMessage.put(org.apache.cxf.message.Message.PROTOCOL_HEADERS, cxfHeaders);
+        
+        Map<String, Object> camelHeaders = exchange.getIn().getHeaders();
+        CxfHeaderHelper.propagateCxfToCamel(new DefaultHeaderFilterStrategy(), 
+                                            cxfMessage, camelHeaders, exchange);
+
+        assertEquals("urn:hello:world", camelHeaders.get("soapaction"));
+        assertEquals("urn:hello:world", camelHeaders.get("SoapAction"));
+        assertEquals("241", camelHeaders.get("content-length"));
+        assertEquals("peach", camelHeaders.get("MyFruitHeader"));
+        assertEquals(Arrays.asList("cappuccino", "espresso"), camelHeaders.get("MyBrewHeader"));
+    } 
+
+    @Test
+    public void testPropagateCxfToCamelWithMerged() {
+        Exchange exchange = new DefaultExchange(context);
+        exchange.setProperty(CxfConstants.CAMEL_CXF_PROTOCOL_HEADERS_MERGED, Boolean.TRUE);
+        
+        org.apache.cxf.message.Message cxfMessage = new org.apache.cxf.message.MessageImpl();
+        Map<String, List<String>> cxfHeaders = new TreeMap<String, List<String>>(String.CASE_INSENSITIVE_ORDER);
+        cxfHeaders.put("myfruitheader", Arrays.asList("peach"));
+        cxfHeaders.put("mybrewheader", Arrays.asList("cappuccino", "espresso"));
+        cxfMessage.put(org.apache.cxf.message.Message.PROTOCOL_HEADERS, cxfHeaders);
+
+        Map<String, Object> camelHeaders = exchange.getIn().getHeaders();
+        CxfHeaderHelper.propagateCxfToCamel(new DefaultHeaderFilterStrategy(), 
+                                            cxfMessage, camelHeaders, exchange);
+
+        assertEquals("peach", camelHeaders.get("MyFruitHeader"));
+        assertEquals("cappuccino, espresso", camelHeaders.get("MyBrewHeader"));
+    } 
+    
+    private void verifyHeader(Map<String, List<String>> headers, String name, List<String> value) {
+        List<String> values = headers.get(name);
+        assertTrue("The entry must be available", values != null && values.size() == ((List<?>)value).size());
+        assertEquals("The value must match", (List<?>)value, values);
+    }
+
+    private void verifyHeader(Map<String, List<String>> headers, String name, String value) {
+        List<String> values = headers.get(name);
+        assertTrue("The entry must be available", values != null && values.size() == 1);
+        assertEquals("The value must match", value, values.get(0));
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/1aba3472/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/DefaultCxfBinding.java
----------------------------------------------------------------------
diff --git a/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/DefaultCxfBinding.java b/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/DefaultCxfBinding.java
index 05129ec..1c65679 100644
--- a/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/DefaultCxfBinding.java
+++ b/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/DefaultCxfBinding.java
@@ -22,6 +22,7 @@ import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -509,7 +510,25 @@ public class DefaultCxfBinding implements CxfBinding, HeaderFilterStrategyAware
                     } else {
                         LOG.trace("Populate header from CXF header={} value={}",
                                 entry.getKey(), entry.getValue());
-                        camelHeaders.put(entry.getKey(), entry.getValue().get(0));
+                        List<String> values = entry.getValue();
+                        Object evalue;
+                        if (values.size() > 1) {
+                            if (exchange.getProperty(CxfConstants.CAMEL_CXF_PROTOCOL_HEADERS_MERGED, Boolean.FALSE, Boolean.class)) {
+                                StringBuilder sb = new StringBuilder();
+                                for (Iterator<String> it = values.iterator(); it.hasNext();) {
+                                    sb.append(it.next());
+                                    if (it.hasNext()) {
+                                        sb.append(',').append(' ');
+                                    }
+                                }
+                                evalue = sb.toString();
+                            } else {
+                                evalue = values;
+                            }
+                        } else {
+                            evalue = values.get(0);
+                        }
+                        camelHeaders.put(entry.getKey(), evalue);
                     }
                     
                 }

http://git-wip-us.apache.org/repos/asf/camel/blob/1aba3472/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/DefaultCxfBindingTest.java
----------------------------------------------------------------------
diff --git a/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/DefaultCxfBindingTest.java b/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/DefaultCxfBindingTest.java
index 5b7a038..a7e976d 100644
--- a/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/DefaultCxfBindingTest.java
+++ b/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/DefaultCxfBindingTest.java
@@ -91,6 +91,7 @@ public class DefaultCxfBindingTest extends Assert {
         
         exchange.getIn().setHeader("soapAction", "urn:hello:world");
         exchange.getIn().setHeader("MyFruitHeader", "peach");
+        exchange.getIn().setHeader("MyBrewHeader", Arrays.asList("cappuccino", "espresso"));
         exchange.getIn().addAttachment("att-1", new DataHandler(new FileDataSource("pom.xml")));
 
         cxfBinding.populateCxfRequestFromExchange(cxfExchange, exchange, requestContext);
@@ -98,7 +99,7 @@ public class DefaultCxfBindingTest extends Assert {
         // check the protocol headers
         Map<String, List<String>> headers = CastUtils.cast((Map<?, ?>)requestContext.get(Message.PROTOCOL_HEADERS));
         assertNotNull(headers);
-        assertTrue(headers.size() == 2);
+        assertEquals(3, headers.size());
         
         verifyHeader(headers, "soapaction", "urn:hello:world");
         verifyHeader(headers, "SoapAction", "urn:hello:world");
@@ -106,6 +107,7 @@ public class DefaultCxfBindingTest extends Assert {
         verifyHeader(headers, "myfruitheader", "peach");
         verifyHeader(headers, "myFruitHeader", "peach");
         verifyHeader(headers, "MYFRUITHEADER", "peach");
+        verifyHeader(headers, "MyBrewHeader", Arrays.asList("cappuccino", "espresso"));
         
         Set<Attachment> attachments 
             = CastUtils.cast((Set<?>)requestContext.get(CxfConstants.CAMEL_CXF_ATTACHMENTS));
@@ -204,6 +206,7 @@ public class DefaultCxfBindingTest extends Assert {
         headers.put("Content-Length", Arrays.asList("241"));
         headers.put("soapAction", Arrays.asList("urn:hello:world"));
         headers.put("myfruitheader", Arrays.asList("peach"));
+        headers.put("mybrewheader", Arrays.asList("cappuccino", "espresso"));
         cxfMessage.put(org.apache.cxf.message.Message.PROTOCOL_HEADERS, headers);
 
         Set<Attachment> attachments = new HashSet<Attachment>();
@@ -216,17 +219,47 @@ public class DefaultCxfBindingTest extends Assert {
         
         Map<String, Object> camelHeaders = exchange.getIn().getHeaders();
         assertNotNull(camelHeaders);
-        assertEquals(camelHeaders.get("soapaction"), "urn:hello:world");
-        assertEquals(camelHeaders.get("SoapAction"), "urn:hello:world");
-        assertEquals(camelHeaders.get("content-type"), "text/xml;charset=UTF-8");
-        assertEquals(camelHeaders.get("content-length"), "241");
-        assertEquals(camelHeaders.get("MyFruitHeader"), "peach");
+        assertEquals("urn:hello:world", camelHeaders.get("soapaction"));
+        assertEquals("urn:hello:world", camelHeaders.get("SoapAction"));
+        assertEquals("text/xml;charset=UTF-8", camelHeaders.get("content-type"));
+        assertEquals("241", camelHeaders.get("content-length"));
+        assertEquals("peach", camelHeaders.get("MyFruitHeader"));
+        assertEquals(Arrays.asList("cappuccino", "espresso"), camelHeaders.get("MyBrewHeader"));
         
         Map<String, DataHandler> camelAttachments = exchange.getIn().getAttachments();
         assertNotNull(camelAttachments);
         assertNotNull(camelAttachments.get("att-1"));
         
     }
+    @Test
+    public void testPopupalteExchangeFromCxfRequestWithHeaderMerged() {
+        DefaultCxfBinding cxfBinding = new DefaultCxfBinding();
+        cxfBinding.setHeaderFilterStrategy(new DefaultHeaderFilterStrategy());
+        Exchange exchange = new DefaultExchange(context);
+        exchange.setProperty(CxfConstants.CAMEL_CXF_PROTOCOL_HEADERS_MERGED, Boolean.TRUE);
+        org.apache.cxf.message.Exchange cxfExchange = new org.apache.cxf.message.ExchangeImpl();
+        exchange.setProperty(CxfConstants.DATA_FORMAT_PROPERTY, DataFormat.PAYLOAD);
+        org.apache.cxf.message.Message cxfMessage = new org.apache.cxf.message.MessageImpl();
+        Map<String, List<String>> headers = new TreeMap<String, List<String>>(String.CASE_INSENSITIVE_ORDER);
+        headers.put("myfruitheader", Arrays.asList("peach"));
+        headers.put("mybrewheader", Arrays.asList("cappuccino", "espresso"));
+        cxfMessage.put(org.apache.cxf.message.Message.PROTOCOL_HEADERS, headers);
+
+        cxfExchange.setInMessage(cxfMessage);
+
+        cxfBinding.populateExchangeFromCxfRequest(cxfExchange, exchange);
+        
+        Map<String, Object> camelHeaders = exchange.getIn().getHeaders();
+        assertNotNull(camelHeaders);
+        assertEquals("peach", camelHeaders.get("MyFruitHeader"));
+        assertEquals("cappuccino, espresso", camelHeaders.get("MyBrewHeader"));
+    }
+
+    private void verifyHeader(Map<String, List<String>> headers, String name, List<String> value) {
+        List<String> values = headers.get(name);
+        assertTrue("The entry must be available", values != null && values.size() == ((List<?>)value).size());
+        assertEquals("The value must match", (List<?>)value, values);
+    }
 
     private void verifyHeader(Map<String, List<String>> headers, String name, String value) {
         List<String> values = headers.get(name);