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
commit 30de879ed35c6349ca178d3c43fde4234091afbb Author: Claus Ibsen <[email protected]> AuthorDate: Fri Oct 30 13:40:58 2020 +0100 CAMEL-15763: camel-main - Add option to clear reifier after starting --- .../org/apache/camel/ExtendedCamelContext.java | 12 ++++++++++ .../camel/impl/engine/AbstractCamelContext.java | 18 +++++++++++++++ .../camel/impl/ExtendedCamelContextConfigurer.java | 5 +++++ .../camel/impl/lw/LightweightCamelContext.java | 10 +++++++++ .../impl/lw/LightweightRuntimeCamelContext.java | 10 +++++++++ .../MainConfigurationPropertiesConfigurer.java | 5 +++++ .../camel-main-configuration-metadata.json | 1 + core/camel-main/src/main/docs/main.adoc | 1 + .../camel/main/DefaultConfigurationConfigurer.java | 1 + .../camel/main/DefaultConfigurationProperties.java | 26 ++++++++++++++++++++++ 10 files changed, 89 insertions(+) diff --git a/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java b/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java index 25e4817..4adcce4 100644 --- a/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java +++ b/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java @@ -636,4 +636,16 @@ public interface ExtendedCamelContext extends CamelContext { */ Processor createErrorHandler(Route route, Processor processor) throws Exception; + /** + * Whether reifiers should be cleared. If enabled this will trigger some optimizations and memory reduction, however + * dynamic routes cannot be added after Camel has been started. + */ + void setClearReifiers(boolean clearReifiers); + + /** + * Whether reifiers should be cleared. If enabled this will trigger some optimizations and memory reduction, however + * dynamic routes cannot be added after Camel has been started. + */ + boolean isClearReifiers(); + } diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java index 876e411..ccf5071 100644 --- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java +++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java @@ -124,6 +124,7 @@ import org.apache.camel.spi.ProcessorFactory; import org.apache.camel.spi.PropertiesComponent; import org.apache.camel.spi.ReactiveExecutor; import org.apache.camel.spi.Registry; +import org.apache.camel.spi.ReifierStrategy; import org.apache.camel.spi.RestBindingJaxbDataFormatFactory; import org.apache.camel.spi.RestConfiguration; import org.apache.camel.spi.RestRegistry; @@ -241,6 +242,7 @@ public abstract class AbstractCamelContext extends BaseService private Boolean useBreadcrumb = Boolean.FALSE; private Boolean allowUseOriginalMessage = Boolean.FALSE; private Boolean caseInsensitiveHeaders = Boolean.TRUE; + private boolean clearReifiers; private Long delay; private ErrorHandlerFactory errorHandlerFactory; private Map<String, String> globalOptions = new HashMap<>(); @@ -2702,6 +2704,12 @@ public abstract class AbstractCamelContext extends BaseService getRouteController().getClass().getName()); } LOG.info("Apache Camel {} ({}) started in {}", getVersion(), getName(), TimeUtils.printDuration(stopWatch.taken())); + + if (isClearReifiers()) { + LOG.debug( + "Clearing reifiers to free memory from models and reifiers. Danger: Adding routes dynamically after this point is not possible."); + ReifierStrategy.clearReifiers(); + } } } @@ -3776,6 +3784,16 @@ public abstract class AbstractCamelContext extends BaseService } @Override + public boolean isClearReifiers() { + return clearReifiers; + } + + @Override + public void setClearReifiers(boolean clearReifiers) { + this.clearReifiers = clearReifiers; + } + + @Override public ExecutorServiceManager getExecutorServiceManager() { if (executorServiceManager == null) { synchronized (lock) { diff --git a/core/camel-core-engine/src/generated/java/org/apache/camel/impl/ExtendedCamelContextConfigurer.java b/core/camel-core-engine/src/generated/java/org/apache/camel/impl/ExtendedCamelContextConfigurer.java index e93005b..3dfcbd0 100644 --- a/core/camel-core-engine/src/generated/java/org/apache/camel/impl/ExtendedCamelContextConfigurer.java +++ b/core/camel-core-engine/src/generated/java/org/apache/camel/impl/ExtendedCamelContextConfigurer.java @@ -27,6 +27,7 @@ public class ExtendedCamelContextConfigurer extends org.apache.camel.support.com map.put("BeanIntrospection", org.apache.camel.spi.BeanIntrospection.class); map.put("CaseInsensitiveHeaders", java.lang.Boolean.class); map.put("ClassResolver", org.apache.camel.spi.ClassResolver.class); + map.put("ClearReifiers", boolean.class); map.put("ComponentNameResolver", org.apache.camel.spi.ComponentNameResolver.class); map.put("ComponentResolver", org.apache.camel.spi.ComponentResolver.class); map.put("ConfigurerResolver", org.apache.camel.spi.ConfigurerResolver.class); @@ -116,6 +117,8 @@ public class ExtendedCamelContextConfigurer extends org.apache.camel.support.com case "CaseInsensitiveHeaders": target.setCaseInsensitiveHeaders(property(camelContext, java.lang.Boolean.class, value)); return true; case "classresolver": case "ClassResolver": target.setClassResolver(property(camelContext, org.apache.camel.spi.ClassResolver.class, value)); return true; + case "clearreifiers": + case "ClearReifiers": target.setClearReifiers(property(camelContext, boolean.class, value)); return true; case "componentnameresolver": case "ComponentNameResolver": target.setComponentNameResolver(property(camelContext, org.apache.camel.spi.ComponentNameResolver.class, value)); return true; case "componentresolver": @@ -275,6 +278,8 @@ public class ExtendedCamelContextConfigurer extends org.apache.camel.support.com case "CaseInsensitiveHeaders": return target.isCaseInsensitiveHeaders(); case "classresolver": case "ClassResolver": return target.getClassResolver(); + case "clearreifiers": + case "ClearReifiers": return target.isClearReifiers(); case "componentnameresolver": case "ComponentNameResolver": return target.getComponentNameResolver(); case "componentresolver": diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java index e513636..7e1110d 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java @@ -1795,6 +1795,16 @@ public class LightweightCamelContext implements ExtendedCamelContext, CatalogCam getModelCamelContext().registerTransformer(transformer); } + @Override + public void setClearReifiers(boolean clearReifiers) { + getExtendedCamelContext().setClearReifiers(clearReifiers); + } + + @Override + public boolean isClearReifiers() { + return getExtendedCamelContext().isClearReifiers(); + } + // // Immutable // diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java index a61a186..c2b1427 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java @@ -345,6 +345,16 @@ public class LightweightRuntimeCamelContext implements ExtendedCamelContext, Cat } @Override + public void setClearReifiers(boolean clearReifiers) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isClearReifiers() { + return true; + } + + @Override public void setStreamCaching(Boolean cache) { throw new UnsupportedOperationException(); } diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java index d65b279..6d4cfe8 100644 --- a/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java +++ b/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java @@ -33,6 +33,7 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp map.put("BeanIntrospectionLoggingLevel", org.apache.camel.LoggingLevel.class); map.put("BeanPostProcessorEnabled", boolean.class); map.put("CaseInsensitiveHeaders", boolean.class); + map.put("ClearReifiers", boolean.class); map.put("ConfigurationClasses", java.lang.String.class); map.put("Configurations", java.util.List.class); map.put("ConsumerTemplateCacheSize", int.class); @@ -139,6 +140,8 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp case "BeanPostProcessorEnabled": target.setBeanPostProcessorEnabled(property(camelContext, boolean.class, value)); return true; case "caseinsensitiveheaders": case "CaseInsensitiveHeaders": target.setCaseInsensitiveHeaders(property(camelContext, boolean.class, value)); return true; + case "clearreifiers": + case "ClearReifiers": target.setClearReifiers(property(camelContext, boolean.class, value)); return true; case "configurationclasses": case "ConfigurationClasses": target.setConfigurationClasses(property(camelContext, java.lang.String.class, value)); return true; case "configurations": @@ -320,6 +323,8 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp case "BeanPostProcessorEnabled": return target.isBeanPostProcessorEnabled(); case "caseinsensitiveheaders": case "CaseInsensitiveHeaders": return target.isCaseInsensitiveHeaders(); + case "clearreifiers": + case "ClearReifiers": return target.isClearReifiers(); case "configurationclasses": case "ConfigurationClasses": return target.getConfigurationClasses(); case "configurations": diff --git a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json index b64d68b..c291594 100644 --- a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json +++ b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json @@ -25,6 +25,7 @@ { "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.beanPostProcessorEnabled", "description": "Can be used to turn off bean post processing. Be careful to turn this off, as this means that beans that use Camel annotations such as org.apache.camel.EndpointInject , org.apache.camel.ProducerTemplate , org.apache.camel.Produce , org.apache.camel.Consume etc will not be injected and in use. Turning this off should only be done if you are sure you do not use any of these Camel features. Not all runtimes allow turning t [...] { "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.clearReifiers", "description": "Whether reifiers should be cleared. If enabled this will trigger some optimizations and memory reduction, however dynamic routes cannot be added after Camel has been started.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean" }, { "name": "camel.main.configurationClasses", "description": "Sets classes names that will be used to configure the camel context as example by providing custom beans through org.apache.camel.BindToRegistry annotation.", "sourceType": "org.apache.camel.main.MainConfigurationProperties", "type": "string", "javaType": "java.lang.String" }, { "name": "camel.main.configurations", "description": "Sets the configuration objects used to configure the camel context.", "sourceType": "org.apache.camel.main.MainConfigurationProperties", "type": "object", "javaType": "java.util.List" }, { "name": "camel.main.consumerTemplateCacheSize", "description": "Consumer template endpoints cache size.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "integer", "javaType": "int", "defaultValue": 1000 }, diff --git a/core/camel-main/src/main/docs/main.adoc b/core/camel-main/src/main/docs/main.adoc index 832d6d9..2de4441 100644 --- a/core/camel-main/src/main/docs/main.adoc +++ b/core/camel-main/src/main/docs/main.adoc @@ -37,6 +37,7 @@ The following table lists all the options: | *camel.main.beanIntrospection{zwsp}LoggingLevel* | Sets the logging level used by bean introspection, logging activity of its usage. The default is TRACE. | | LoggingLevel | *camel.main.beanPostProcessor{zwsp}Enabled* | Can be used to turn off bean post processing. Be careful to turn this off, as this means that beans that use Camel annotations such as org.apache.camel.EndpointInject , org.apache.camel.ProducerTemplate , org.apache.camel.Produce , org.apache.camel.Consume etc will not be injected and in use. Turning this off should only be done if you are sure you do not use any of these Camel features. Not all runtimes allow turning this off (such as came [...] | *camel.main.caseInsensitive{zwsp}Headers* | 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 [...] +| *camel.main.clearReifiers* | Whether reifiers should be cleared. If enabled this will trigger some optimizations and memory reduction, however dynamic routes cannot be added after Camel has been started. | | boolean | *camel.main.configuration{zwsp}Classes* | Sets classes names that will be used to configure the camel context as example by providing custom beans through org.apache.camel.BindToRegistry annotation. | | String | *camel.main.configurations* | Sets the configuration objects used to configure the camel context. | | List | *camel.main.consumerTemplate{zwsp}CacheSize* | Consumer template endpoints cache size. | 1000 | int 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 3a1af5e..f8df0db 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 @@ -89,6 +89,7 @@ public final class DefaultConfigurationConfigurer { */ public static void configure(CamelContext camelContext, DefaultConfigurationProperties config) throws Exception { ExtendedCamelContext ecc = camelContext.adapt(ExtendedCamelContext.class); + ecc.setClearReifiers(config.isClearReifiers()); ecc.getBeanPostProcessor().setEnabled(config.isBeanPostProcessorEnabled()); ecc.getBeanIntrospection().setExtendedStatistics(config.isBeanIntrospectionExtendedStatistics()); if (config.getBeanIntrospectionLoggingLevel() != null) { 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 5939748..702b724 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 @@ -86,6 +86,7 @@ public abstract class DefaultConfigurationProperties<T> { private String xmlRouteTemplates = "classpath:camel-template/*.xml"; private String xmlRests = "classpath:camel-rest/*.xml"; private boolean lightweight; + private boolean clearReifiers; // route controller @Metadata(defaultValue = "INFO") private LoggingLevel routeControllerRouteStartupLoggingLevel = LoggingLevel.INFO; @@ -934,6 +935,20 @@ public abstract class DefaultConfigurationProperties<T> { this.lightweight = lightweight; } + @Experimental + public boolean isClearReifiers() { + return clearReifiers; + } + + /** + * Whether reifiers should be cleared. If enabled this will trigger some optimizations and memory reduction, however + * dynamic routes cannot be added after Camel has been started. + */ + @Experimental + public void setClearReifiers(boolean clearReifiers) { + this.clearReifiers = clearReifiers; + } + public LoggingLevel getRouteControllerRouteStartupLoggingLevel() { return routeControllerRouteStartupLoggingLevel; } @@ -1754,12 +1769,23 @@ public abstract class DefaultConfigurationProperties<T> { * a single Camel application (microservice like camel-main, camel-quarkus, camel-spring-boot). * As this affects the entire JVM where Camel JARs are on the classpath. */ + @Experimental public T withLightweight(boolean lightweight) { this.lightweight = lightweight; return (T) this; } /** + * Whether reifiers should be cleared. If enabled this will trigger some optimizations and memory reduction, however + * dynamic routes cannot be added after Camel has been started. + */ + @Experimental + public T withClearReifiers(boolean clearReifiers) { + this.clearReifiers = clearReifiers; + return (T) this; + } + + /** * Sets the logging level used for logging route startup activity. By default INFO level is used. You can use this * to change the level for example to OFF if this kind of logging is not wanted. */
