Valeriy Ak created CAMEL-25415:
----------------------------------
Summary: Graceful SSL Bundle Hot Reload for Camel HTTP Component
Key: CAMEL-25415
URL: https://issues.apache.org/jira/browse/CAMEL-25415
Project: Camel
Issue Type: Improvement
Components: camel-http
Affects Versions: 4.22.0
Reporter: Valeriy Ak
With the current {{ssl-bundle-hot-reload}} configuration in the Camel HTTP
component, {{HttpComponentSslBundleAutoConfiguration#onBundleUpdate()}}
performs the following operations:
{code:java}
HttpClientConnectionManager manager = component.getClientConnectionManager();
if (manager != null) {
manager.close();
}
component.setClientConnectionManager(null);
applySslBundle(component, updatedBundle);
private void applySslBundle(HttpComponent component, SslBundle bundle) {
component.setSslContextParameters(new SSLContextParameters(bundle));
}
{code}
h3. Problems with the Current Implementation
# *No explicitly configured* {{*clientConnectionManager*}}
If no {{clientConnectionManager}} is configured in {{{}HttpComponent{}}}, each
{{HttpEndpoint}} creates its own {{{}PoolingHttpClientConnectionManager{}}}.
{{onBundleUpdate()}} only updates the {{SSLContextParameters}} of the
{{{}HttpComponent{}}}. As a result, this change has no effect on already
created {{HttpEndpoint}} instances and their connection managers.
# *Explicitly configured* {{*clientConnectionManager*}}
If a {{clientConnectionManager}} is configured in {{{}HttpComponent{}}},
{{HttpEndpoint}} keeps a reference to it.
However, after {{manager.close()}} is called, existing {{HttpEndpoint}}
instances do not obtain a new connection manager from the
{{{}HttpComponent{}}}. They continue using the already closed connection pool.
# {{*HttpProducer*}} *caches the HTTP client*
{{HttpProducer}} caches the HTTP client obtained from the {{HttpEndpoint}}
during initialization.
Therefore, simply replacing the connection manager in the {{HttpComponent}} or
{{HttpEndpoint}} is not sufficient. The existing {{HttpProducer}} will continue
using the previously created {{{}HttpClient{}}}.
h3. Expected Behavior
When the Spring Boot {{SslBundle}} is updated, the Camel HTTP component should
perform a *graceful takeover* of the existing connections:
# Requests that are already in progress at the time of the update must {*}not
be interrupted{*}.
# Idle connections using the old SSL bundle must be {*}immediately removed
from the connection pool{*}.
# New requests must {*}not reuse connections associated with the old SSL
bundle{*}.
# Any new TLS handshake must use the {*}updated SSL bundle{*}.
# Connections that were in use at the time of the update must be {*}closed
after the current request completes{*}, instead of being returned to the
keep-alive pool.
h3. Possible Implementation
One possible approach is to introduce a decorator around
{{PoolingHttpClientConnectionManager}} with an {{onBundleUpdate()}} method.
When the SSL bundle is updated, the decorator should:
# *Atomically replace the active* {{*TlsSocketStrategy*}} with the one created
from the updated SSL bundle.
# *Close all idle connections* associated with the old SSL bundle immediately.
# Ensure that connections which were *in use at the time of the update* are
not returned to the keep-alive pool after the current request completes, but
are closed instead.
This approach would allow the existing {{HttpClient}} and {{HttpProducer}}
instances to remain valid while transparently switching the underlying TLS
configuration and gracefully draining connections created with the previous SSL
bundle.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)