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);
         }
     }
 

Reply via email to