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 2023/02/18 10:57:40 UTC
[camel] 01/02: CAMEL-19071: camel-main / camel-jbang - Reload properties should reload components in dev mode.
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 bf94c4494b44a9498bd380878473587f95315bfe
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sat Feb 18 11:08:41 2023 +0100
CAMEL-19071: camel-main / camel-jbang - Reload properties should reload components in dev mode.
---
.../{ResourceReload.java => PropertiesReload.java} | 15 +++--
.../java/org/apache/camel/spi/ResourceReload.java | 7 +-
.../org/apache/camel/main/BaseMainSupport.java | 75 ++++++++++++++++++++++
.../apache/camel/main/MainPropertiesReload.java | 57 ++++++++++++++++
.../camel/support/RouteWatcherReloadStrategy.java | 20 +++++-
5 files changed, 163 insertions(+), 11 deletions(-)
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/ResourceReload.java b/core/camel-api/src/main/java/org/apache/camel/spi/PropertiesReload.java
similarity index 65%
copy from core/camel-api/src/main/java/org/apache/camel/spi/ResourceReload.java
copy to core/camel-api/src/main/java/org/apache/camel/spi/PropertiesReload.java
index cdbb63255e1..2c795a6cbb0 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/ResourceReload.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/PropertiesReload.java
@@ -16,18 +16,21 @@
*/
package org.apache.camel.spi;
+import java.util.Properties;
+
/**
- * Listener for re-loading a {@link Resource} such as a Camel route.
+ * Listener for re-loading a {@link java.util.Properties} such as a Camel route.
*/
@FunctionalInterface
-public interface ResourceReload {
+public interface PropertiesReload {
/**
- * Callback when the resource is re-loaded.
+ * Callback when the properties is re-loaded.
*
- * @param name name of the resource such as the file name (absolute)
- * @param resource the resource
+ * @param name name of the resource such as the file name (absolute)
+ * @param properties the properties that was re-loaded
+ * @throws Exception error reloading properties
*/
- void onReload(String name, Resource resource);
+ void onReload(String name, Properties properties) throws Exception;
}
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/ResourceReload.java b/core/camel-api/src/main/java/org/apache/camel/spi/ResourceReload.java
index cdbb63255e1..5176ef8cbcd 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/ResourceReload.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/ResourceReload.java
@@ -25,9 +25,10 @@ public interface ResourceReload {
/**
* Callback when the resource is re-loaded.
*
- * @param name name of the resource such as the file name (absolute)
- * @param resource the resource
+ * @param name name of the resource such as the file name (absolute)
+ * @param resource the resource
+ * @throws Exception error reloading the resources
*/
- void onReload(String name, Resource resource);
+ void onReload(String name, Resource resource) throws Exception;
}
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
index eb4b3f90bbf..ce1b2aaa190 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
@@ -488,6 +488,8 @@ public abstract class BaseMainSupport extends BaseService {
if (mainConfigurationProperties.isAutoConfigurationEnabled()) {
autoConfigurationFromProperties(camelContext, autoConfiguredProperties);
autowireWildcardProperties(camelContext);
+ // register properties reloader so we can auto-update if updated
+ camelContext.addService(new MainPropertiesReload(this));
}
// log summary of configurations
@@ -1622,8 +1624,78 @@ public abstract class BaseMainSupport extends BaseService {
prop.remove(key);
}
+ doAutoConfigurationFromProperties(camelContext, prop, properties, false, autoConfiguredProperties);
+ }
+
+ protected void autoConfigurationFromReloadedProperties(
+ CamelContext camelContext, OrderedLocationProperties reloadedProperties)
+ throws Exception {
+
+ Map<PropertyOptionKey, OrderedLocationProperties> properties = new LinkedHashMap<>();
+
+ // filter out wildcard properties
+ for (String key : reloadedProperties.stringPropertyNames()) {
+ if (key.contains("*")) {
+ String loc = reloadedProperties.getLocation(key);
+ wildcardProperties.put(loc, key, reloadedProperties.getProperty(key));
+ }
+ }
+ // and remove wildcards
+ for (String key : wildcardProperties.stringPropertyNames()) {
+ reloadedProperties.remove(key);
+ }
+
+ OrderedLocationProperties autoConfiguredProperties = new OrderedLocationProperties();
+ doAutoConfigurationFromProperties(camelContext, reloadedProperties, properties, true, autoConfiguredProperties);
+
+ // log summary of configurations
+ if (mainConfigurationProperties.isAutoConfigurationLogSummary() && !autoConfiguredProperties.isEmpty()) {
+ boolean header = false;
+ for (var entry : autoConfiguredProperties.entrySet()) {
+ String k = entry.getKey().toString();
+ Object v = entry.getValue();
+ String loc = locationSummary(autoConfiguredProperties, k);
+
+ // tone down logging noise for our own internal configurations
+ boolean debug = loc.contains("[camel-main]");
+ if (debug && !LOG.isDebugEnabled()) {
+ continue;
+ }
+
+ if (!header) {
+ LOG.info("Auto-configuration summary");
+ header = true;
+ }
+
+ if (SensitiveUtils.containsSensitive(k)) {
+ if (debug) {
+ LOG.debug(" {} {}=xxxxxx", loc, k);
+ } else {
+ LOG.info(" {} {}=xxxxxx", loc, k);
+ }
+ } else {
+ if (debug) {
+ LOG.debug(" {} {}={}", loc, k, v);
+ } else {
+ LOG.info(" {} {}={}", loc, k, v);
+ }
+ }
+ }
+ }
+ }
+
+ protected void doAutoConfigurationFromProperties(
+ CamelContext camelContext, OrderedLocationProperties prop,
+ Map<PropertyOptionKey, OrderedLocationProperties> properties, boolean reload,
+ OrderedLocationProperties autoConfiguredProperties)
+ throws Exception {
+
for (String key : prop.stringPropertyNames()) {
computeProperties("camel.component.", key, prop, properties, name -> {
+ if (reload) {
+ // force re-creating component on reload
+ camelContext.removeComponent(name);
+ }
// its an existing component name
Component target = camelContext.getComponent(name);
if (target == null) {
@@ -1706,6 +1778,9 @@ public abstract class BaseMainSupport extends BaseService {
doAutowireWildcardProperties(name, component);
}
});
+
+ // clear in case we reload later
+ wildcardProperties.clear();
}
protected void doAutowireWildcardProperties(String name, Component component) {
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/MainPropertiesReload.java b/core/camel-main/src/main/java/org/apache/camel/main/MainPropertiesReload.java
new file mode 100644
index 00000000000..34ddef39139
--- /dev/null
+++ b/core/camel-main/src/main/java/org/apache/camel/main/MainPropertiesReload.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.main;
+
+import java.util.Properties;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.spi.PropertiesReload;
+import org.apache.camel.support.service.ServiceSupport;
+import org.apache.camel.util.OrderedLocationProperties;
+
+/**
+ * Reloading of application.properties when using Camel Main in reload mode, such as when using camel-jbang.
+ */
+public class MainPropertiesReload extends ServiceSupport implements PropertiesReload, CamelContextAware {
+
+ private final BaseMainSupport main;
+ private CamelContext camelContext;
+
+ public MainPropertiesReload(BaseMainSupport main) {
+ this.main = main;
+ }
+
+ @Override
+ public CamelContext getCamelContext() {
+ return camelContext;
+ }
+
+ @Override
+ public void setCamelContext(CamelContext camelContext) {
+ this.camelContext = camelContext;
+ }
+
+ @Override
+ public void onReload(String name, Properties properties) throws Exception {
+ if (properties instanceof OrderedLocationProperties) {
+ OrderedLocationProperties prop = (OrderedLocationProperties) properties;
+ main.autoConfigurationFromReloadedProperties(camelContext, prop);
+ main.autowireWildcardProperties(camelContext);
+ }
+ }
+}
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 faa64ed8997..caef6d0e41d 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
@@ -17,6 +17,7 @@
package org.apache.camel.support;
import java.io.File;
+import java.io.InputStream;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Paths;
@@ -32,10 +33,14 @@ import org.apache.camel.RuntimeCamelException;
import org.apache.camel.ServiceStatus;
import org.apache.camel.StartupSummaryLevel;
import org.apache.camel.spi.PropertiesComponent;
+import org.apache.camel.spi.PropertiesReload;
import org.apache.camel.spi.Resource;
import org.apache.camel.util.AntPathMatcher;
import org.apache.camel.util.FileUtil;
+import org.apache.camel.util.IOHelper;
import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.OrderedLocationProperties;
+import org.apache.camel.util.OrderedProperties;
import org.apache.camel.util.URISupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -157,13 +162,24 @@ public class RouteWatcherReloadStrategy extends FileWatcherResourceReloadStrateg
return "Live route reloading enabled (directory: " + dir + ")";
}
- protected void onPropertiesReload(Resource resource) {
- LOG.info("Reloading properties: {}. (Only Camel routes can be updated with changes)",
+ protected void onPropertiesReload(Resource resource) throws Exception {
+ LOG.info("Reloading properties: {}. (Only Camel routes and components can be updated with changes)",
resource.getLocation());
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);
+ }
// trigger all routes to be reloaded
onRouteReload(null);
}