You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2020/01/31 06:13:03 UTC
[camel] branch master updated: CAMEL-14460: camel-core - Optimize
and allow to turn off case insensitive headers
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/master by this push:
new 0f02d00 CAMEL-14460: camel-core - Optimize and allow to turn off case insensitive headers
0f02d00 is described below
commit 0f02d00a5c69eba2ae78beebee2f5f6266a8b698
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Fri Jan 31 07:12:30 2020 +0100
CAMEL-14460: camel-core - Optimize and allow to turn off case insensitive headers
---
.../camel/blueprint/CamelContextFactoryBean.java | 11 +++++
.../camel/cdi/xml/CamelContextFactoryBean.java | 12 +++++
.../camel/spring/CamelContextFactoryBean.java | 21 ++++++++
.../org/apache/camel/RuntimeConfiguration.java | 20 ++++++++
.../camel/impl/engine/AbstractCamelContext.java | 17 ++++++-
.../camel/impl/engine/DefaultRouteContext.java | 12 +++++
.../core/xml/AbstractCamelContextFactoryBean.java | 5 ++
.../CamelCaseInsentiveHeadersFalseTest.java | 56 +++++++++++++++++++++
.../CamelCaseInsentiveHeadersTrueTest.java | 57 ++++++++++++++++++++++
.../camel/main/DefaultConfigurationConfigurer.java | 1 +
.../camel/main/DefaultConfigurationProperties.java | 34 +++++++++++++
.../camel-main-configuration-metadata.json | 1 +
12 files changed, 246 insertions(+), 1 deletion(-)
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java
index 02f3989..cb55279 100644
--- a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java
@@ -125,6 +125,8 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Blu
@XmlAttribute
private String allowUseOriginalMessage;
@XmlAttribute
+ private String caseInsensitiveHeaders;
+ @XmlAttribute
private String runtimeEndpointRegistryEnabled;
@XmlAttribute
private String managementNamePattern;
@@ -454,6 +456,15 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Blu
}
@Override
+ public String getCaseInsensitiveHeaders() {
+ return caseInsensitiveHeaders;
+ }
+
+ public void setCaseInsensitiveHeaders(String caseInsensitiveHeaders) {
+ this.caseInsensitiveHeaders = caseInsensitiveHeaders;
+ }
+
+ @Override
public String getRuntimeEndpointRegistryEnabled() {
return runtimeEndpointRegistryEnabled;
}
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java
index 812a0c1..a945b37 100644
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java
@@ -126,6 +126,9 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Def
private String allowUseOriginalMessage;
@XmlAttribute
+ private String caseInsensitiveHeaders;
+
+ @XmlAttribute
private String runtimeEndpointRegistryEnabled;
@XmlAttribute
@@ -715,6 +718,15 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Def
}
@Override
+ public String getCaseInsensitiveHeaders() {
+ return caseInsensitiveHeaders;
+ }
+
+ public void setCaseInsensitiveHeaders(String caseInsensitiveHeaders) {
+ this.caseInsensitiveHeaders = caseInsensitiveHeaders;
+ }
+
+ @Override
public String getRuntimeEndpointRegistryEnabled() {
return runtimeEndpointRegistryEnabled;
}
diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java b/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java
index e9195b5..3429e9d 100644
--- a/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java
+++ b/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java
@@ -137,6 +137,8 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Spr
@XmlAttribute
private String allowUseOriginalMessage;
@XmlAttribute
+ private String caseInsensitiveHeaders;
+ @XmlAttribute
private String runtimeEndpointRegistryEnabled;
@XmlAttribute @Metadata(defaultValue = "#name#")
private String managementNamePattern;
@@ -910,6 +912,25 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Spr
}
@Override
+ public String getCaseInsensitiveHeaders() {
+ return caseInsensitiveHeaders;
+ }
+
+ /**
+ * Whether to use case sensitive or insensitive headers.
+ *
+ * Important: When using case sensitive (this is set to false).
+ * Then the map is case sensitive which means headers such as content-type and Content-Type are
+ * two different keys which can be a problem for some protocols such as HTTP based, which rely on case insensitive headers.
+ * However case sensitive implementations can yield faster performance. Therefore use case sensitive implementation with care.
+ *
+ * Default is true.
+ */
+ public void setCaseInsensitiveHeaders(String caseInsensitiveHeaders) {
+ this.caseInsensitiveHeaders = caseInsensitiveHeaders;
+ }
+
+ @Override
public String getRuntimeEndpointRegistryEnabled() {
return runtimeEndpointRegistryEnabled;
}
diff --git a/core/camel-api/src/main/java/org/apache/camel/RuntimeConfiguration.java b/core/camel-api/src/main/java/org/apache/camel/RuntimeConfiguration.java
index e060773..4edbd32 100644
--- a/core/camel-api/src/main/java/org/apache/camel/RuntimeConfiguration.java
+++ b/core/camel-api/src/main/java/org/apache/camel/RuntimeConfiguration.java
@@ -234,4 +234,24 @@ public interface RuntimeConfiguration {
*/
Boolean isAllowUseOriginalMessage();
+ /**
+ * Whether to use case sensitive or insensitive headers.
+ *
+ * Important: When using case sensitive (this is set to false).
+ * Then 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, which rely on case insensitive headers.
+ * However case sensitive implementations can yield faster performance. Therefore use case sensitive implementation with care.
+ */
+ Boolean isCaseInsensitiveHeaders();
+
+ /**
+ * Whether to use case sensitive or insensitive headers.
+ *
+ * Important: When using case sensitive (this is set to false).
+ * Then 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, which rely on case insensitive headers.
+ * However case sensitive implementations can yield faster performance. Therefore use case sensitive implementation with care.
+ */
+ void setCaseInsensitiveHeaders(Boolean caseInsensitiveHeaders);
+
}
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index b4853da..31b7768 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -214,6 +214,7 @@ public abstract class AbstractCamelContext extends ServiceSupport implements Ext
private Boolean useDataType = Boolean.FALSE;
private Boolean useBreadcrumb = Boolean.FALSE;
private Boolean allowUseOriginalMessage = Boolean.FALSE;
+ private Boolean caseInsensitiveHeaders = Boolean.TRUE;
private Long delay;
private ErrorHandlerFactory errorHandlerFactory;
private Map<String, String> globalOptions = new HashMap<>();
@@ -3317,7 +3318,13 @@ public abstract class AbstractCamelContext extends ServiceSupport implements Ext
// we want headers map to be created as then JVM can optimize using it as we use it per exchange/message
synchronized (lock) {
if (headersMapFactory == null) {
- setHeadersMapFactory(createHeadersMapFactory());
+ if (isCaseInsensitiveHeaders()) {
+ // use factory to find the map factory to use
+ setHeadersMapFactory(createHeadersMapFactory());
+ } else {
+ // case sensitive so we can use hash map
+ setHeadersMapFactory(new HashMapHeadersMapFactory());
+ }
}
}
}
@@ -3864,6 +3871,14 @@ public abstract class AbstractCamelContext extends ServiceSupport implements Ext
return allowUseOriginalMessage != null && allowUseOriginalMessage;
}
+ public Boolean isCaseInsensitiveHeaders() {
+ return caseInsensitiveHeaders != null && caseInsensitiveHeaders;
+ }
+
+ public void setCaseInsensitiveHeaders(Boolean caseInsensitiveHeaders) {
+ this.caseInsensitiveHeaders = caseInsensitiveHeaders;
+ }
+
@Override
public ExecutorServiceManager getExecutorServiceManager() {
if (executorServiceManager == null) {
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRouteContext.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRouteContext.java
index 5397988..9cf4ad0 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRouteContext.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRouteContext.java
@@ -461,6 +461,18 @@ public class DefaultRouteContext implements RouteContext {
}
@Override
+ public Boolean isCaseInsensitiveHeaders() {
+ // can only be configured on CamelContext
+ return getCamelContext().isCaseInsensitiveHeaders();
+ }
+
+ @Override
+ public void setCaseInsensitiveHeaders(Boolean caseInsensitiveHeaders) {
+ // can only be configured on CamelContext
+ getCamelContext().setCaseInsensitiveHeaders(caseInsensitiveHeaders);
+ }
+
+ @Override
public ShutdownRoute getShutdownRoute() {
if (shutdownRoute != null) {
return shutdownRoute;
diff --git a/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
index e529703..8594aee 100644
--- a/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
+++ b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
@@ -816,6 +816,8 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex
public abstract String getAllowUseOriginalMessage();
+ public abstract String getCaseInsensitiveHeaders();
+
public abstract String getRuntimeEndpointRegistryEnabled();
public abstract String getManagementNamePattern();
@@ -936,6 +938,9 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex
if (getAllowUseOriginalMessage() != null) {
context.setAllowUseOriginalMessage(CamelContextHelper.parseBoolean(context, getAllowUseOriginalMessage()));
}
+ if (getCaseInsensitiveHeaders() != null) {
+ context.setCaseInsensitiveHeaders(CamelContextHelper.parseBoolean(context, getCaseInsensitiveHeaders()));
+ }
if (getRuntimeEndpointRegistryEnabled() != null) {
context.getRuntimeEndpointRegistry().setEnabled(CamelContextHelper.parseBoolean(context, getRuntimeEndpointRegistryEnabled()));
}
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/CamelCaseInsentiveHeadersFalseTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/CamelCaseInsentiveHeadersFalseTest.java
new file mode 100644
index 0000000..46c58c4
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/CamelCaseInsentiveHeadersFalseTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.processor;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.Test;
+
+public class CamelCaseInsentiveHeadersFalseTest extends ContextTestSupport {
+
+ @Override
+ protected CamelContext createCamelContext() throws Exception {
+ CamelContext context = super.createCamelContext();
+ context.setCaseInsensitiveHeaders(false);
+ return context;
+ }
+
+ @Test
+ public void testCasesensitive() throws Exception {
+ getMockEndpoint("mock:foo").expectedBodiesReceived("Hello foo");
+ getMockEndpoint("mock:bar").expectedBodiesReceived("Hello bar");
+
+ template.sendBodyAndHeader("direct:start", "Hello foo", "foo", "123");
+ template.sendBodyAndHeader("direct:start", "Hello bar", "FOO", "456");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:start")
+ .choice()
+ .when(header("foo")).to("mock:foo")
+ .otherwise().to("mock:bar");
+ }
+ };
+ }
+}
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/CamelCaseInsentiveHeadersTrueTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/CamelCaseInsentiveHeadersTrueTest.java
new file mode 100644
index 0000000..cdb4c87
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/CamelCaseInsentiveHeadersTrueTest.java
@@ -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.processor;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.Test;
+
+public class CamelCaseInsentiveHeadersTrueTest extends ContextTestSupport {
+
+ @Override
+ protected CamelContext createCamelContext() throws Exception {
+ CamelContext context = super.createCamelContext();
+ context.setCaseInsensitiveHeaders(true);
+ return context;
+ }
+
+ @Test
+ public void testCasesensitive() throws Exception {
+ getMockEndpoint("mock:foo").expectedBodiesReceived("Hello foo", "Hello bar");
+ getMockEndpoint("mock:bar").expectedMessageCount(0);
+
+ template.sendBodyAndHeader("direct:start", "Hello foo", "foo", "123");
+ template.sendBodyAndHeader("direct:start", "Hello bar", "FOO", "456");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:start")
+ .choice()
+ .when(header("foo")).to("mock:foo")
+ .otherwise().to("mock:bar");
+ }
+ };
+ }
+}
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
index 95ad66b..69cc2d0 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
@@ -145,6 +145,7 @@ public final class DefaultConfigurationConfigurer {
camelContext.setLogExhaustedMessageBody(config.isLogExhaustedMessageBody());
camelContext.setAutoStartup(config.isAutoStartup());
camelContext.setAllowUseOriginalMessage(config.isAllowUseOriginalMessage());
+ camelContext.setCaseInsensitiveHeaders(config.isCaseInsensitiveHeaders());
camelContext.setUseBreadcrumb(config.isUseBreadcrumb());
camelContext.setUseDataType(config.isUseDataType());
camelContext.setUseMDCLogging(config.isUseMdcLogging());
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
index ecd7754..1a26864 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
@@ -59,6 +59,7 @@ public abstract class DefaultConfigurationProperties<T> {
private boolean logExhaustedMessageBody;
private boolean autoStartup = true;
private boolean allowUseOriginalMessage;
+ private boolean caseInsensitiveHeaders = true;
private boolean endpointRuntimeStatisticsEnabled;
private boolean endpointLazyStartProducer;
private boolean endpointBridgeErrorHandler;
@@ -527,6 +528,24 @@ public abstract class DefaultConfigurationProperties<T> {
this.allowUseOriginalMessage = allowUseOriginalMessage;
}
+ public boolean isCaseInsensitiveHeaders() {
+ return caseInsensitiveHeaders;
+ }
+
+ /**
+ * Whether to use case sensitive or insensitive headers.
+ *
+ * Important: When using case sensitive (this is set to false).
+ * Then the map is case sensitive which means headers such as content-type and Content-Type are
+ * two different keys which can be a problem for some protocols such as HTTP based, which rely on case insensitive headers.
+ * However case sensitive implementations can yield faster performance. Therefore use case sensitive implementation with care.
+ *
+ * Default is true.
+ */
+ public void setCaseInsensitiveHeaders(boolean caseInsensitiveHeaders) {
+ this.caseInsensitiveHeaders = caseInsensitiveHeaders;
+ }
+
public boolean isEndpointRuntimeStatisticsEnabled() {
return endpointRuntimeStatisticsEnabled;
}
@@ -1205,6 +1224,21 @@ public abstract class DefaultConfigurationProperties<T> {
}
/**
+ * Whether to use case sensitive or insensitive headers.
+ *
+ * Important: When using case sensitive (this is set to false).
+ * Then the map is case sensitive which means headers such as content-type and Content-Type are
+ * two different keys which can be a problem for some protocols such as HTTP based, which rely on case insensitive headers.
+ * However case sensitive implementations can yield faster performance. Therefore use case sensitive implementation with care.
+ *
+ * Default is true.
+ */
+ public T withCaseInsensitiveHeaders(boolean caseInsensitiveHeaders) {
+ this.caseInsensitiveHeaders = caseInsensitiveHeaders;
+ return (T) this;
+ }
+
+ /**
* Sets whether endpoint runtime statistics is enabled (gathers runtime usage of each incoming and outgoing endpoints).
*
* The default value is false.
diff --git a/core/camel-main/src/main/resources/META-INF/camel-main-configuration-metadata.json b/core/camel-main/src/main/resources/META-INF/camel-main-configuration-metadata.json
index 2d72e68..65b7e3c 100644
--- a/core/camel-main/src/main/resources/META-INF/camel-main-configuration-metadata.json
+++ b/core/camel-main/src/main/resources/META-INF/camel-main-configuration-metadata.json
@@ -19,6 +19,7 @@
{ "name": "camel.main.backlogTracing", "description": "Sets whether backlog tracing is enabled or not. Default is false.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean" },
{ "name": "camel.main.beanIntrospectionExtendedStatistics", "description": "Sets whether bean introspection uses extended statistics. The default is false.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean" },
{ "name": "camel.main.beanIntrospectionLoggingLevel", "description": "Sets the logging level used by bean introspection, logging activity of its usage. The default is TRACE.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "object", "javaType": "org.apache.camel.LoggingLevel", "enum": [ "ERROR", "WARN", "INFO", "DEBUG", "TRACE", "OFF" ] },
+ { "name": "camel.main.caseInsensitiveHeaders", "description": "Whether to use case sensitive or insensitive headers. Important: When using case sensitive (this is set to false). Then the map is case sensitive which means headers such as content-type and Content-Type are two different keys which can be a problem for some protocols such as HTTP based, which rely on case insensitive headers. However case sensitive implementations can yield faster performance. Therefore use case sensitiv [...]
{ "name": "camel.main.consumerTemplateCacheSize", "description": "Consumer template endpoints cache size.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "integer", "javaType": "int", "defaultValue": 1000 },
{ "name": "camel.main.durationHitExitCode", "description": "Sets the exit code for the application if duration was hit", "sourceType": "org.apache.camel.main.MainConfigurationProperties", "type": "integer", "javaType": "int" },
{ "name": "camel.main.durationMaxIdleSeconds", "description": "To specify for how long time in seconds Camel can be idle before automatic terminating the JVM. You can use this to run Camel for a short while.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "integer", "javaType": "int" },