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)

Reply via email to