CAMEL-11149: SPI - Allow to plugin different headers map implementation
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/04088ff9 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/04088ff9 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/04088ff9 Branch: refs/heads/master Commit: 04088ff94945617f4a52d200bd5a3c0b44bb82e6 Parents: d50e480 Author: Claus Ibsen <davscl...@apache.org> Authored: Thu May 25 11:16:21 2017 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Thu May 25 11:16:21 2017 +0200 ---------------------------------------------------------------------- .../org/apache/camel/impl/DefaultExchange.java | 5 +- .../camel/impl/DefaultHeadersMapFactory.java | 2 +- .../org/apache/camel/impl/DefaultMessage.java | 2 +- .../camel/impl/HashMapHeadersMapFactory.java | 46 +++++++++++++++ .../org/apache/camel/spi/HeadersMapFactory.java | 2 +- .../impl/CustomHeadersMapFactoryRouteTest.java | 2 +- .../impl/DefaultHeadersMapFactoryTest.java | 4 +- .../impl/HashMapHeadersMapFactoryRouteTest.java | 61 ++++++++++++++++++++ 8 files changed, 115 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/04088ff9/camel-core/src/main/java/org/apache/camel/impl/DefaultExchange.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultExchange.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultExchange.java index 3534296..520dcad 100644 --- a/camel-core/src/main/java/org/apache/camel/impl/DefaultExchange.java +++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultExchange.java @@ -30,7 +30,6 @@ import org.apache.camel.Message; import org.apache.camel.MessageHistory; import org.apache.camel.spi.Synchronization; import org.apache.camel.spi.UnitOfWork; -import org.apache.camel.util.CaseInsensitiveMap; import org.apache.camel.util.EndpointHelper; import org.apache.camel.util.ExchangeHelper; import org.apache.camel.util.ObjectHelper; @@ -133,7 +132,7 @@ public final class DefaultExchange implements Exchange { return null; } - return context.getHeadersMapFactory().fromMap(headers); + return context.getHeadersMapFactory().newMap(headers); } @SuppressWarnings("unchecked") @@ -142,7 +141,7 @@ public final class DefaultExchange implements Exchange { return null; } - Map<String, Object> answer = context.getHeadersMapFactory().fromMap(properties); + Map<String, Object> answer = context.getHeadersMapFactory().newMap(properties); // safe copy message history using a defensive copy List<MessageHistory> history = (List<MessageHistory>) answer.remove(Exchange.MESSAGE_HISTORY); http://git-wip-us.apache.org/repos/asf/camel/blob/04088ff9/camel-core/src/main/java/org/apache/camel/impl/DefaultHeadersMapFactory.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultHeadersMapFactory.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultHeadersMapFactory.java index efc7e5e..77d38cb 100644 --- a/camel-core/src/main/java/org/apache/camel/impl/DefaultHeadersMapFactory.java +++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultHeadersMapFactory.java @@ -36,7 +36,7 @@ public class DefaultHeadersMapFactory implements HeadersMapFactory { } @Override - public Map<String, Object> fromMap(Map<String, Object> map) { + public Map<String, Object> newMap(Map<String, Object> map) { return new CaseInsensitiveMap(map); } http://git-wip-us.apache.org/repos/asf/camel/blob/04088ff9/camel-core/src/main/java/org/apache/camel/impl/DefaultMessage.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultMessage.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultMessage.java index 397298d..06040ba 100644 --- a/camel-core/src/main/java/org/apache/camel/impl/DefaultMessage.java +++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultMessage.java @@ -224,7 +224,7 @@ public class DefaultMessage extends MessageSupport { this.headers = headers; } else { // create a new map - this.headers = getCamelContext().getHeadersMapFactory().fromMap(headers); + this.headers = getCamelContext().getHeadersMapFactory().newMap(headers); } } http://git-wip-us.apache.org/repos/asf/camel/blob/04088ff9/camel-core/src/main/java/org/apache/camel/impl/HashMapHeadersMapFactory.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/impl/HashMapHeadersMapFactory.java b/camel-core/src/main/java/org/apache/camel/impl/HashMapHeadersMapFactory.java new file mode 100644 index 0000000..c6f7b75 --- /dev/null +++ b/camel-core/src/main/java/org/apache/camel/impl/HashMapHeadersMapFactory.java @@ -0,0 +1,46 @@ +/** + * 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.impl; + +import java.util.Map; + +import org.apache.camel.spi.HeadersMapFactory; +import org.apache.camel.util.CaseInsensitiveMap; + +/** + * HashMap {@link HeadersMapFactory} which uses a plain {@link java.util.HashMap}. + * Important: The map is case sensitive which means headers such as <tt>content-type</tt> and <tt>Content-Type</tt> are + * two different keys which can be a problem for some protocols such as HTTP based. + * Therefore use this implementation with care. + */ +public class HashMapHeadersMapFactory implements HeadersMapFactory { + + @Override + public Map<String, Object> newMap() { + return new CaseInsensitiveMap(); + } + + @Override + public Map<String, Object> newMap(Map<String, Object> map) { + return new CaseInsensitiveMap(map); + } + + @Override + public boolean isInstanceOf(Map<String, Object> map) { + return map instanceof CaseInsensitiveMap; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/04088ff9/camel-core/src/main/java/org/apache/camel/spi/HeadersMapFactory.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/spi/HeadersMapFactory.java b/camel-core/src/main/java/org/apache/camel/spi/HeadersMapFactory.java index bb4556d..c789763 100644 --- a/camel-core/src/main/java/org/apache/camel/spi/HeadersMapFactory.java +++ b/camel-core/src/main/java/org/apache/camel/spi/HeadersMapFactory.java @@ -44,7 +44,7 @@ public interface HeadersMapFactory { * @param map existing map to copy over (must use defensive copy) * @return new map with the content from the existing map */ - Map<String, Object> fromMap(Map<String, Object> map); + Map<String, Object> newMap(Map<String, Object> map); /** * Whether the given {@link Map} implementation is created by this factory? http://git-wip-us.apache.org/repos/asf/camel/blob/04088ff9/camel-core/src/test/java/org/apache/camel/impl/CustomHeadersMapFactoryRouteTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/impl/CustomHeadersMapFactoryRouteTest.java b/camel-core/src/test/java/org/apache/camel/impl/CustomHeadersMapFactoryRouteTest.java index 9c2faec..734fb7a 100644 --- a/camel-core/src/test/java/org/apache/camel/impl/CustomHeadersMapFactoryRouteTest.java +++ b/camel-core/src/test/java/org/apache/camel/impl/CustomHeadersMapFactoryRouteTest.java @@ -71,7 +71,7 @@ public class CustomHeadersMapFactoryRouteTest extends ContextTestSupport { } @Override - public Map<String, Object> fromMap(Map<String, Object> map) { + public Map<String, Object> newMap(Map<String, Object> map) { return new HashMap<>(map); } http://git-wip-us.apache.org/repos/asf/camel/blob/04088ff9/camel-core/src/test/java/org/apache/camel/impl/DefaultHeadersMapFactoryTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/impl/DefaultHeadersMapFactoryTest.java b/camel-core/src/test/java/org/apache/camel/impl/DefaultHeadersMapFactoryTest.java index c23d3e6..cf5f67f 100644 --- a/camel-core/src/test/java/org/apache/camel/impl/DefaultHeadersMapFactoryTest.java +++ b/camel-core/src/test/java/org/apache/camel/impl/DefaultHeadersMapFactoryTest.java @@ -42,7 +42,7 @@ public class DefaultHeadersMapFactoryTest extends TestCase { other.put("Foo", "cheese"); other.put("bar", 123); - Map<String, Object> map = new DefaultHeadersMapFactory().fromMap(other); + Map<String, Object> map = new DefaultHeadersMapFactory().newMap(other); assertEquals("cheese", map.get("FOO")); assertEquals("cheese", map.get("foo")); @@ -56,7 +56,7 @@ public class DefaultHeadersMapFactoryTest extends TestCase { public void testIsInstance() { Map<String, Object> map = new DefaultHeadersMapFactory().newMap(); - Map<String, Object> other = new DefaultHeadersMapFactory().fromMap(map); + Map<String, Object> other = new DefaultHeadersMapFactory().newMap(map); other.put("Foo", "cheese"); other.put("bar", 123); http://git-wip-us.apache.org/repos/asf/camel/blob/04088ff9/camel-core/src/test/java/org/apache/camel/impl/HashMapHeadersMapFactoryRouteTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/impl/HashMapHeadersMapFactoryRouteTest.java b/camel-core/src/test/java/org/apache/camel/impl/HashMapHeadersMapFactoryRouteTest.java new file mode 100644 index 0000000..fd91ff0 --- /dev/null +++ b/camel-core/src/test/java/org/apache/camel/impl/HashMapHeadersMapFactoryRouteTest.java @@ -0,0 +1,61 @@ +/** + * 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.impl; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.camel.CamelContext; +import org.apache.camel.ContextTestSupport; +import org.apache.camel.builder.RouteBuilder; + +public class HashMapHeadersMapFactoryRouteTest extends ContextTestSupport { + + @Override + protected CamelContext createCamelContext() throws Exception { + CamelContext context = super.createCamelContext(); + context.setHeadersMapFactory(new HashMapHeadersMapFactory()); + return context; + } + + public void testHashMapHeaders() throws Exception { + getMockEndpoint("mock:result").expectedHeaderReceived("foo", 123); + getMockEndpoint("mock:result").expectedHeaderReceived("FOO", 456); + getMockEndpoint("mock:result").expectedHeaderReceived("Bar", "yes"); + + Map<String, Object> headers = new HashMap<>(); + headers.put("foo", 123); + headers.put("FOO", 456); + headers.put("Bar", "yes"); + + template.sendBodyAndHeaders("direct:start", "Hello World", headers); + + assertMockEndpointsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from("direct:start") + .to("mock:result"); + } + }; + } + +}