This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
commit 25036ff2bd3441118f1f377531a00163f1b6b5b1 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Sat Feb 18 11:48:57 2023 +0100 CAMEL-19073: camel-main / camel-jbang - Reload properties should only reload changed properties. --- .../org/apache/camel/spi/PropertiesComponent.java | 9 ++++ .../component/properties/PropertiesComponent.java | 13 +++++ .../PropertiesComponentKeepOnlyChangedTest.java | 62 ++++++++++++++++++++++ .../camel/support/RouteWatcherReloadStrategy.java | 38 ++++++++----- 4 files changed, 108 insertions(+), 14 deletions(-) diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/PropertiesComponent.java b/core/camel-api/src/main/java/org/apache/camel/spi/PropertiesComponent.java index a49fbc81bd6..2f3d3030400 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/PropertiesComponent.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/PropertiesComponent.java @@ -277,6 +277,15 @@ public interface PropertiesComponent extends StaticService { */ boolean reloadProperties(String pattern); + /** + * Filters the given list of properties, by removing properties that are already loaded and have same key and value. + * + * If all properties are not changed then the properties will become empty. + * + * @param properties the given properties to filter. + */ + void keepOnlyChangeProperties(Properties properties); + /** * Adds the {@link PropertiesLookupListener}. */ diff --git a/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java b/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java index ecbe3f1269f..dee58f6cccf 100644 --- a/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java +++ b/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Properties; import java.util.function.Function; @@ -704,6 +705,18 @@ public class PropertiesComponent extends ServiceSupport return answer; } + @Override + public void keepOnlyChangeProperties(Properties properties) { + Properties loaded = loadProperties(); + for (String key : loaded.stringPropertyNames()) { + Object v1 = loaded.getProperty(key); + Object v2 = properties.getProperty(key); + if (Objects.equals(v1, v2)) { + properties.remove(key); + } + } + } + @Override protected void doInit() throws Exception { super.doInit(); diff --git a/core/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentKeepOnlyChangedTest.java b/core/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentKeepOnlyChangedTest.java new file mode 100644 index 00000000000..90275371232 --- /dev/null +++ b/core/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentKeepOnlyChangedTest.java @@ -0,0 +1,62 @@ +/* + * 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.properties; + +import java.util.Properties; + +import org.apache.camel.ContextTestSupport; +import org.apache.camel.spi.PropertiesComponent; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class PropertiesComponentKeepOnlyChangedTest extends ContextTestSupport { + + @Override + public boolean isUseRouteBuilder() { + return false; + } + + @Test + public void testChanged() throws Exception { + PropertiesComponent pc = context.getPropertiesComponent(); + pc.addInitialProperty("foo", "123"); + pc.addInitialProperty("bar", "true"); + + Properties p = new Properties(); + p.setProperty("foo", "123"); + p.setProperty("bar", "false"); + pc.keepOnlyChangeProperties(p); + Assertions.assertEquals(1, p.size()); + Assertions.assertEquals("false", p.getProperty("bar")); + + p = new Properties(); + p.setProperty("foo", "123"); + p.setProperty("bar", "true"); + pc.keepOnlyChangeProperties(p); + Assertions.assertEquals(0, p.size()); + + p = new Properties(); + p.setProperty("foo", "123"); + p.setProperty("bar", "false"); + p.setProperty("cheese", "gauda"); + pc.keepOnlyChangeProperties(p); + Assertions.assertEquals(2, p.size()); + Assertions.assertEquals("false", p.getProperty("bar")); + Assertions.assertEquals("gauda", p.getProperty("cheese")); + } + +} diff --git a/core/camel-support/src/main/java/org/apache/camel/support/RouteWatcherReloadStrategy.java b/core/camel-support/src/main/java/org/apache/camel/support/RouteWatcherReloadStrategy.java index caef6d0e41d..a3ac3215fae 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/RouteWatcherReloadStrategy.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/RouteWatcherReloadStrategy.java @@ -166,22 +166,32 @@ public class RouteWatcherReloadStrategy extends FileWatcherResourceReloadStrateg LOG.info("Reloading properties: {}. (Only Camel routes and components can be updated with changes)", resource.getLocation()); + // optimize to only update if something changed + OrderedLocationProperties changed = null; + PropertiesComponent pc = getCamelContext().getPropertiesComponent(); - boolean reloaded = pc.reloadProperties(resource.getLocation()); - if (reloaded) { - PropertiesReload pr = getCamelContext().hasService(PropertiesReload.class); - if (pr != null) { - // load the properties, so we can update (remember location) - InputStream is = resource.getInputStream(); - OrderedProperties tmp = new OrderedProperties(); - tmp.load(is); - IOHelper.close(is); - OrderedLocationProperties properties = new OrderedLocationProperties(); - properties.putAll(resource.getLocation(), tmp); - pr.onReload(resource.getLocation(), properties); + PropertiesReload pr = getCamelContext().hasService(PropertiesReload.class); + if (pr != null) { + // load the properties, so we can update (remember location) + InputStream is = resource.getInputStream(); + OrderedProperties tmp = new OrderedProperties(); + tmp.load(is); + IOHelper.close(is); + changed = new OrderedLocationProperties(); + changed.putAll(resource.getLocation(), tmp); + // filter to only keep changed properties + pc.keepOnlyChangeProperties(changed); + } + + if (changed == null || !changed.isEmpty()) { + boolean reloaded = pc.reloadProperties(resource.getLocation()); + if (reloaded) { + if (pr != null) { + pr.onReload(resource.getLocation(), changed); + } + // trigger all routes to be reloaded + onRouteReload(null); } - // trigger all routes to be reloaded - onRouteReload(null); } }