[
https://issues.apache.org/jira/browse/CAMEL-24637?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18117893#comment-18117893
]
Karol Krawczyk commented on CAMEL-24637:
----------------------------------------
I would like to take this, but the shape of the fix needs your call first,
because what camel-jms can honestly do differs from what the SPI javadoc
promises. Findings from main.
h3. The username and password path already heals itself
{{JmsComponent#createEndpoint}} reads {{username}} and {{password}} (lines
1245-1246) on a {{copy()}} of the configuration and wraps the connection
factory in a fresh {{UserCredentialsConnectionFactoryAdapter}} per endpoint
(1248-1256). The component-level configuration never gets the adapter. So when
the routes are rebuilt, the new endpoints carry the newly resolved credentials.
On top of that, {{BaseMainSupport#doAutoConfigurationFromProperties}} removes
and re-creates the component when a {{camel.component.jms.*}} option whose
value is a placeholder is re-applied, so there is not even a stale component
left to fix.
That is the same reasoning CAMEL-24639 used to close camel-http with a
documentation note (commit 471ad9363a38).
h3. What does not heal itself
The {{ConnectionFactory}} bean. camel-jms never creates one -
{{JmsConfiguration#createConnectionFactory}} only null-checks and returns null
- so the factory is a registry bean, and registry beans are not rebuilt by the
reload. A caching or pooling factory therefore keeps physical connections
authenticated with the revoked secret, and a vendor factory keeps its own
{{user}}/{{password}} resolved at bean creation time.
h3. Three obstacles to doing something about it
# *Reach.* From the camel-jms compile classpath the only thing that can be
reset is Spring's {{SingleConnectionFactory#resetConnection()}}, which
{{CachingConnectionFactory}} inherits. {{pooled-jms}} is test scope in the
module (pom.xml lines 136-140), so {{JmsPoolConnectionFactory}} is not
reachable from main code without a new dependency or reflection - and that is
the common Spring Boot and Quarkus topology.
# *No way to tell whether anything changed.* The SPI asks implementations to
refresh "if the credentials it holds are no longer the configured ones".
camel-jms cannot determine that: {{UserCredentialsConnectionFactoryAdapter}}
exposes setters but no getters and no {{getTargetConnectionFactory()}}, and a
vendor factory exposes nothing at all. So the implementation would be
unconditional - a reset on every reload, whatever secret rotated.
# *It is somebody else's bean.* Resetting a shared factory before the routes
restart also drops the connections of whatever else in the application uses it.
And since {{DefaultContextReloadStrategy#notifySecretRotation}} swallows
listener exceptions (lines 160-163), a reset that half fails leaves one WARN
line and a route set coming back up against a broken factory.
h3. Two ways to close this
# Document it, as camel-http did: state that the credentials configured on the
component or the endpoint are picked up on reload, and that refreshing a pooled
or caching {{ConnectionFactory}} bean is the responsibility of whoever created
it.
# Implement it narrowly: {{JmsComponent implements SecretRotationAware}},
resetting only a factory camel-jms itself wrapped or one that arrived through
{{camel.component.jms.connectionFactory}}, leaving a foreign bean alone, plus
the documentation from option 1 for the rest.
I lean towards the second, because it delivers something real without tearing
down every JMS connection in the application on an unrelated rotation - but
option 1 is defensible too, and you wrote the SPI, whose javadoc names "a
pooled JMS connection factory" as the motivating example. Which one do you
want? I will take the ticket either way, and CAMEL-24638 looks like the same
question for a {{DataSource}}.
_Reported by Claude Code on behalf of Karol Krawczyk_
> camel-jms: implement SecretRotationAware to re-authenticate on secret rotation
> ------------------------------------------------------------------------------
>
> Key: CAMEL-24637
> URL: https://issues.apache.org/jira/browse/CAMEL-24637
> Project: Camel
> Issue Type: Sub-task
> Components: camel-jms
> Reporter: Andrea Cosentino
> Priority: Major
>
> Sub-task of CAMEL-24636.
> Adopt the {{SecretRotationAware}} SPI in camel-jms.
> {{JmsComponent#setUsername}} and {{setPassword}} delegate to a shared
> {{JmsConfiguration}}, whose values are resolved from property placeholders
> once at configure time. The {{ConnectionFactory}} itself is normally a
> registry bean (often a pooled one) created at bootstrap with the credentials
> valid at that moment.
> Neither is refreshed by {{RouteController.reloadAllRoutes()}}, so after a
> secret rotation the component keeps presenting the old credentials.
> On {{onSecretRotation}} the component should re-resolve its configured
> username and password and re-authenticate the connection factory in place,
> closing and re-establishing pooled connections as needed.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)