oscerd commented on code in PR #26166:
URL: https://github.com/apache/camel/pull/26166#discussion_r3955545680


##########
core/camel-support/src/main/java/org/apache/camel/support/DefaultContextReloadStrategy.java:
##########
@@ -87,6 +99,68 @@ protected void reloadProperties(Object source) throws 
Exception {
         }
     }
 
+    /**
+     * Re-applies the configuration properties whose value is a property 
placeholder, so that components are
+     * re-configured with what those placeholders resolve to now.
+     * <p/>
+     * A component option such as 
<tt>camel.component.kafka.saslJaasConfig</tt> has its placeholder resolved 
once, when
+     * the component is configured, and the resolved value is what is stored 
on the component. Reloading the routes
+     * rebuilds the endpoints from that same already-resolved value, so 
without this step a rotated secret would never
+     * reach the component. Only <tt>camel.</tt> options whose value is a 
placeholder are re-applied, as they are the
+     * only ones whose resolved value can change while the raw configuration 
stays the same.
+     */
+    protected void reloadComponentProperties(Object source) throws Exception {
+        PropertiesReload pr = 
getCamelContext().hasService(PropertiesReload.class);
+        if (pr == null) {
+            // component re-configuration is only supported when running with 
Camel Main
+            return;
+        }
+
+        PropertiesComponent pc = getCamelContext().getPropertiesComponent();
+        Properties prop = pc.loadProperties();
+        // stringPropertyNames is a live view of the keys, so snapshot before 
removing
+        Set<String> keys = new LinkedHashSet<>(prop.stringPropertyNames());
+        for (String key : keys) {
+            Object value = prop.get(key);
+            boolean placeholder = key.startsWith("camel.")
+                    && value instanceof String str && 
str.contains(PropertiesComponent.PREFIX_TOKEN);
+            if (!placeholder) {
+                prop.remove(key);
+            }
+        }
+        if (!prop.isEmpty()) {
+            LOG.debug("Re-applying {} property placeholder based options to 
components", prop.size());
+            pr.onReload(source != null ? source.toString() : "ContextReload", 
prop);
+        }
+    }
+
+    /**
+     * Notifies every {@link SecretRotationAware} component and registry bean 
that the secrets they captured may have
+     * been rotated, so they can re-authenticate before the routes are 
restarted.
+     * <p/>
+     * A listener that throws is logged and skipped, so that one component 
cannot prevent the others from being
+     * refreshed, nor fail the reload as a whole.
+     */
+    protected void notifySecretRotation(Object source) {
+        Set<SecretRotationAware> targets = new LinkedHashSet<>();

Review Comment:
   Thanks — the observation is accurate. I confirmed 
`doAutoConfigurationFromProperties` calls `computeProperties` for exactly 
`camel.component.`, `camel.dataformat.` and `camel.language.` and nothing else, 
so anything else matching the `camel.` prefilter is forwarded and silently 
dropped.
   
   I went with the comment rather than tightening the `startsWith` check, for a 
layering reason: `PropertiesReload` is a generic SPI and `MainPropertiesReload` 
is only one implementation of it. Hardcoding those three prefixes into 
`DefaultContextReloadStrategy` would make camel-support depend on a detail of 
camel-main, and would silently starve any other `PropertiesReload` 
implementation that legitimately cares about different keys. Keeping the 
strategy's filter at "camel options whose value can change" and letting the 
listener decide what it acts on keeps that boundary intact.
   
   Pushed in 2da4c1e45290:
   
   ```java
   // filter on camel. rather than on the individual option prefixes: 
PropertiesReload is a generic SPI and
   // each implementation decides which options it acts on. 
MainPropertiesReload, for example, re-applies only
   // camel.component., camel.dataformat. and camel.language., and silently 
ignores everything else
   ```
   
   I also reworded the javadoc from "are re-applied" to "are handed to the 
listener", since that is what this method actually guarantees — the re-applying 
is the listener's decision.
   
   _Claude Code on behalf of oscerd_



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to