Return-Path: X-Original-To: apmail-camel-commits-archive@www.apache.org Delivered-To: apmail-camel-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id BB7001070E for ; Tue, 23 Jul 2013 21:55:05 +0000 (UTC) Received: (qmail 84901 invoked by uid 500); 23 Jul 2013 21:55:05 -0000 Delivered-To: apmail-camel-commits-archive@camel.apache.org Received: (qmail 84873 invoked by uid 500); 23 Jul 2013 21:55:05 -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 84866 invoked by uid 99); 23 Jul 2013 21:55:05 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 23 Jul 2013 21:55:05 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 5F7B48B2A7F; Tue, 23 Jul 2013 21:55:05 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: ay@apache.org To: commits@camel.apache.org Message-Id: <341a34dcd7aa431daad843a02dc04dc4@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: git commit: CAMEL-6393: Making header propagation from cxf to camel consistent Date: Tue, 23 Jul 2013 21:55:05 +0000 (UTC) Updated Branches: refs/heads/camel-2.11.x 1953eff4d -> 53696fcc8 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/53696fcc Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/53696fcc Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/53696fcc Branch: refs/heads/camel-2.11.x Commit: 53696fcc8ba44196808dd778c3d6723292ff915c Parents: 1953eff Author: Akitoshi Yoshida Authored: Tue Jul 23 23:32:49 2013 +0200 Committer: Akitoshi Yoshida Committed: Tue Jul 23 23:54:45 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/53696fcc/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 listValue = new ArrayList(); - 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 listValue = new ArrayList(); + listValue.add(entry.getValue().toString()); + cxfHeaders.put(entry.getKey(), listValue); + } } } } @@ -92,7 +99,26 @@ public final class CxfHeaderHelper { if (cxfHeaders != null) { for (Map.Entry> entry : cxfHeaders.entrySet()) { if (!strategy.applyFilterToExternalHeaders(entry.getKey(), entry.getValue(), exchange)) { - headers.put(entry.getKey(), entry.getValue().get(0)); + List 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 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/53696fcc/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/53696fcc/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> 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> cxfHeaders = new TreeMap>(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 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> cxfHeaders = new TreeMap>(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 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> headers, String name, List value) { + List 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> headers, String name, String value) { + List 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/53696fcc/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 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 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/53696fcc/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 92729bf..5c5e941 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 @@ -92,6 +92,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); @@ -99,7 +100,7 @@ public class DefaultCxfBindingTest extends Assert { // check the protocol headers Map> 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"); @@ -107,6 +108,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 attachments = CastUtils.cast((Set)requestContext.get(CxfConstants.CAMEL_CXF_ATTACHMENTS)); @@ -205,6 +207,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 attachments = new HashSet(); @@ -217,17 +220,47 @@ public class DefaultCxfBindingTest extends Assert { Map 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 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> headers = new TreeMap>(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 camelHeaders = exchange.getIn().getHeaders(); + assertNotNull(camelHeaders); + assertEquals("peach", camelHeaders.get("MyFruitHeader")); + assertEquals("cappuccino, espresso", camelHeaders.get("MyBrewHeader")); + } + + private void verifyHeader(Map> headers, String name, List value) { + List 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> headers, String name, String value) { List values = headers.get(name);