This is an automated email from the ASF dual-hosted git repository.
jamesnetherton pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
The following commit(s) were added to refs/heads/main by this push:
new 3690f97408 Add TLS Registry extension
3690f97408 is described below
commit 3690f97408e8596cdd82bd4eabb7b652b1a4fc0f
Author: James Netherton <[email protected]>
AuthorDate: Wed May 6 15:01:24 2026 +0100
Add TLS Registry extension
Fixes #6393
This extension provides a bridge for integration between the Quarkus TLS
Registry
and Camel SSLContextParameters. TLS configurations defined via quarkus.tls.*
properties are automatically converted and registered as
SSLContextParameters
beans in the Camel registry.
Key features:
- Auto-discovery of default and named TLS configurations
- Optional global SSL context configuration
- Automatic certificate reload
- Support for both PKCS12 and PEM formats
- Bean name conflict detection with helpful error messages
Co-authored-by: Claude Sonnet 4.5 <[email protected]>
---
catalog/pom.xml | 13 ++
docs/modules/ROOT/nav.adoc | 1 +
.../pages/reference/extensions/tls-registry.adoc | 252 +++++++++++++++++++++
extensions/pom.xml | 1 +
extensions/tls-registry/deployment/pom.xml | 65 ++++++
.../core/tls/deployment/TlsRegistryProcessor.java | 55 +++++
extensions/tls-registry/pom.xml | 40 ++++
extensions/tls-registry/runtime/pom.xml | 71 ++++++
.../tls-registry/runtime/src/main/doc/usage.adoc | 135 +++++++++++
.../core/tls/TlsCertificateReloadObserver.java | 173 ++++++++++++++
.../core/tls/TlsConfigurationConverter.java | 126 +++++++++++
.../camel/quarkus/core/tls/TlsRegistryConfig.java | 88 +++++++
.../camel/quarkus/core/tls/TlsRegistryHelper.java | 172 ++++++++++++++
.../quarkus/core/tls/TlsRegistryRecorder.java | 97 ++++++++
.../main/resources/META-INF/quarkus-extension.yaml | 34 +++
integration-tests/pom.xml | 1 +
integration-tests/tls-registry/pom.xml | 156 +++++++++++++
.../core/tls/it/TlsRegistryReloadResource.java | 111 +++++++++
.../quarkus/core/tls/it/TlsRegistryResource.java | 99 ++++++++
.../quarkus/core/tls/it/TlsRegistryRoutes.java | 34 +++
.../src/main/resources/application.properties | 21 ++
.../tls/it/TlsRegistryCertificateReloadIT.java | 23 ++
.../tls/it/TlsRegistryCertificateReloadTest.java | 115 ++++++++++
.../quarkus/core/tls/it/TlsRegistryDisabledIT.java | 23 ++
.../core/tls/it/TlsRegistryDisabledTest.java | 61 +++++
.../TlsRegistryFilesystemCertificateReloadIT.java | 23 ++
...TlsRegistryFilesystemCertificateReloadTest.java | 127 +++++++++++
.../quarkus/core/tls/it/TlsRegistryGlobalIT.java | 23 ++
.../quarkus/core/tls/it/TlsRegistryGlobalTest.java | 78 +++++++
.../core/tls/it/TlsRegistryHttpsGlobalIT.java | 23 ++
.../core/tls/it/TlsRegistryHttpsGlobalTest.java | 60 +++++
.../quarkus/core/tls/it/TlsRegistryHttpsIT.java | 23 ++
.../quarkus/core/tls/it/TlsRegistryHttpsTest.java | 60 +++++
.../camel/quarkus/core/tls/it/TlsRegistryIT.java | 24 ++
.../core/tls/it/TlsRegistryMultipleConfigsIT.java | 23 ++
.../tls/it/TlsRegistryMultipleConfigsTest.java | 100 ++++++++
.../camel/quarkus/core/tls/it/TlsRegistryTest.java | 81 +++++++
io/quarkus/tls/TlsConfigurationRegistry.class | Bin 0 -> 557 bytes
poms/bom/pom.xml | 10 +
poms/bom/src/main/generated/flattened-full-pom.xml | 10 +
.../src/main/generated/flattened-reduced-pom.xml | 10 +
.../generated/flattened-reduced-verbose-pom.xml | 10 +
tooling/scripts/test-categories.yaml | 1 +
43 files changed, 2653 insertions(+)
diff --git a/catalog/pom.xml b/catalog/pom.xml
index 4cf8b26ccd..76a60b5275 100644
--- a/catalog/pom.xml
+++ b/catalog/pom.xml
@@ -4439,6 +4439,19 @@
</exclusion>
</exclusions>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-tls-registry</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-twilio</artifactId>
diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc
index b86caa5b1e..36093cb510 100644
--- a/docs/modules/ROOT/nav.adoc
+++ b/docs/modules/ROOT/nav.adoc
@@ -320,6 +320,7 @@
*** xref:reference/extensions/stringtemplate.adoc[String Template]
*** xref:reference/extensions/stub.adoc[Stub]
*** xref:reference/extensions/syslog.adoc[Syslog]
+*** xref:reference/extensions/tls-registry.adoc[TLS Registry]
*** xref:reference/extensions/tarfile.adoc[Tar File]
*** xref:reference/extensions/telegram.adoc[Telegram]
*** xref:reference/extensions/telemetry-dev.adoc[Telemetry Dev]
diff --git a/docs/modules/ROOT/pages/reference/extensions/tls-registry.adoc
b/docs/modules/ROOT/pages/reference/extensions/tls-registry.adoc
new file mode 100644
index 0000000000..185e79ef3e
--- /dev/null
+++ b/docs/modules/ROOT/pages/reference/extensions/tls-registry.adoc
@@ -0,0 +1,252 @@
+// Do not edit directly!
+// This file was generated by
camel-quarkus-maven-plugin:update-extension-doc-page
+[id="extensions-tls-registry"]
+= TLS Registry
+:linkattrs:
+:cq-artifact-id: camel-quarkus-tls-registry
+:cq-native-supported: true
+:cq-status: Experimental
+:cq-status-deprecation: Experimental
+:cq-description: Configuration bridge for the Quarkus TLS registry and Camel
SSLContextParameters
+:cq-deprecated: false
+:cq-jvm-since: 3.36.0
+:cq-native-since: 3.36.0
+
+ifeval::[{doc-show-badges} == true]
+[.badges]
+[.badge-key]##JVM since##[.badge-supported]##3.36.0## [.badge-key]##Native
since##[.badge-supported]##3.36.0##
[.badge-key]##🧪##[.badge-unsupported]##Experimental##
+endif::[]
+
+Configuration bridge for the Quarkus TLS registry and Camel
SSLContextParameters
+
+[id="extensions-tls-registry-maven-coordinates"]
+== Maven coordinates
+
+https://{link-quarkus-code-generator}/?extension-search=camel-quarkus-tls-registry[Create
a new project with this extension on {link-quarkus-code-generator},
window="_blank"]
+
+Or add the coordinates to your existing project:
+
+[source,xml]
+----
+<dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-tls-registry</artifactId>
+</dependency>
+----
+ifeval::[{doc-show-user-guide-link} == true]
+Check the xref:user-guide/index.adoc[User guide] for more information about
writing Camel Quarkus applications.
+endif::[]
+
+[id="extensions-tls-registry-usage"]
+== Usage
+This extension provides integration between
https://quarkus.io/guides/tls-registry-reference[Quarkus TLS Registry] and
xref:manual::camel-configuration-utilities.adoc[Camel SSLContextParameters].
+When enabled, TLS configurations defined via `quarkus.tls.*` properties are
automatically converted and registered as `SSLContextParameters` beans in the
Camel registry.
+
+This eliminates the need to configure TLS separately for Quarkus and Camel
components - configure it once in Quarkus, and use it everywhere in your Camel
routes.
+
+[id="extensions-tls-registry-usage-basic-configuration"]
+=== Basic Configuration
+
+[id="extensions-tls-registry-usage-default-tls-configuration"]
+==== Default TLS Configuration
+
+Configure a default TLS configuration using `quarkus.tls.*` properties:
+
+[source,properties]
+----
+# Default TLS configuration
+quarkus.tls.key-store.p12.path=/etc/ssl/keystore.p12
+quarkus.tls.key-store.p12.password=changeit
+quarkus.tls.trust-store.p12.path=/etc/ssl/truststore.p12
+quarkus.tls.trust-store.p12.password=changeit
+----
+
+This creates an `SSLContextParameters` bean named
`defaultSslContextParameters` that can be referenced in your routes:
+
+[source,java]
+----
+from("timer:tick")
+
.to("https://api.example.com?sslContextParameters=#defaultSslContextParameters");
+----
+
+NOTE: The bean name for the default TLS configuration can be customized using
`quarkus.camel.tls-registry.default-bean-name`.
+
+[id="extensions-tls-registry-usage-named-tls-configurations"]
+==== Named TLS Configurations
+
+Define multiple named TLS configurations for different purposes (e.g.,
separate client and server certificates):
+
+[source,properties]
+----
+# Client TLS configuration
+quarkus.tls.client.key-store.p12.path=/etc/ssl/client-keystore.p12
+quarkus.tls.client.key-store.p12.password=changeit
+quarkus.tls.client.trust-all=true
+
+# Server TLS configuration
+quarkus.tls.server.key-store.p12.path=/etc/ssl/server-keystore.p12
+quarkus.tls.server.key-store.p12.password=changeit
+quarkus.tls.server.trust-store.p12.path=/etc/ssl/server-truststore.p12
+----
+
+Named configurations are automatically discovered and registered as beans with
their configuration name:
+
+[source,java]
+----
+// Use the client certificate
+from("timer:tick")
+ .to("https://api.example.com?sslContextParameters=#client");
+
+// Use the server certificate
+from("netty-http:https://0.0.0.0:8443/secure?sslContextParameters=#server")
+ .to("log:requests");
+----
+
+[id="extensions-tls-registry-usage-global-ssl-context"]
+=== Global SSL Context
+
+You can set the Quarkus default TLS configuration as Camel's global
`SSLContextParameters`:
+
+[source,properties]
+----
+quarkus.camel.tls-registry.quarkus-default-as-global=true
+
+# Default TLS configuration becomes global
+quarkus.tls.key-store.p12.path=/etc/ssl/keystore.p12
+quarkus.tls.key-store.p12.password=changeit
+----
+
+When configured as global, Camel components can opt in to using it
automatically:
+
+[source,java]
+----
+from("timer:tick")
+ // No need to specify sslContextParameters, uses global SSL context
+ .to("https://api.example.com?useGlobalSslContextParameters=true");
+----
+
+[id="extensions-tls-registry-usage-certificate-reload"]
+=== Certificate Reload
+
+The extension automatically observes certificate reload events from Quarkus
TLS registry.
+When certificates are reloaded (e.g., due to file system changes), the
corresponding `SSLContextParameters` beans are updated and Camel routes are
restarted to pick up the new certificates.
+
+This feature is enabled by default but can be controlled via configuration:
+
+[source,properties]
+----
+# Enable certificate reloading
+quarkus.tls.reload-period=1h
+
+# Enable/disable certificate reload (default: true)
+quarkus.camel.tls-registry.reload-on-certificate-update=true
+
+# Debounce delay in milliseconds to avoid multiple reloads (default: 2000)
+quarkus.camel.tls-registry.reload-certificate-delay=2000
+----
+
+The debounce delay ensures that when multiple certificates are updated in
quick succession, only a single Camel context reload occurs after all updates
have stabilized.
+
+For more information see the
https://quarkus.io/guides/tls-registry-reference#reloading-certificates[Quarkus
TLS Registry Reference Guide].
+
+[id="extensions-tls-registry-usage-bean-name-conflicts"]
+=== Bean Name Conflicts
+
+If you have an existing `SSLContextParameters` bean with the same name as a
Quarkus TLS configuration, the extension will throw an `IllegalStateException`
at startup with a helpful message.
+
+To resolve this, you can either:
+
+1. Remove or rename the existing `SSLContextParameters` bean, or
+2. Rename the Quarkus TLS configuration (e.g., `quarkus.tls.my-config.*`
instead of the conflicting name)
+
+[id="extensions-tls-registry-usage-pem-format-support"]
+=== PEM Format Support
+
+Quarkus TLS registry supports both PKCS12 and PEM formats.
+The extension automatically works with both:
+
+[source,properties]
+----
+# PEM format
+quarkus.tls.key-store.pem.cert=/etc/ssl/cert.pem
+quarkus.tls.key-store.pem.key=/etc/ssl/key.pem
+quarkus.tls.trust-store.pem.certs=/etc/ssl/ca-bundle.pem
+
+# Or PKCS12 format
+quarkus.tls.key-store.p12.path=/etc/ssl/keystore.p12
+quarkus.tls.key-store.p12.password=changeit
+----
+
+[id="extensions-tls-registry-usage-additional-resources"]
+=== Additional Resources
+
+* https://quarkus.io/guides/tls-registry-reference[Quarkus TLS Registry
Reference Guide]
+* xref:manual::camel-configuration-utilities.adoc[Camel SSLContextParameters
Documentation]
+
+
+[id="extensions-tls-registry-additional-camel-quarkus-configuration"]
+== Additional Camel Quarkus configuration
+
+[width="100%",cols="80,5,15",options="header"]
+|===
+| Configuration property | Type | Default
+
+
+a|
[[quarkus-camel-tls-registry-enabled]]`link:#quarkus-camel-tls-registry-enabled[quarkus.camel.tls-registry.enabled]`
+
+Enable automatic conversion and registration of Quarkus TLS configurations
+as Camel SSLContextParameters beans.
+
+When enabled, the default TLS configuration and any named configurations will
+be automatically discovered and registered as beans in the Camel registry.
+| `boolean`
+| `true`
+
+a|
[[quarkus-camel-tls-registry-quarkus-default-as-global]]`link:#quarkus-camel-tls-registry-quarkus-default-as-global[quarkus.camel.tls-registry.quarkus-default-as-global]`
+
+Whether to set the Quarkus default TLS configuration as Camel's global
+SSLContextParameters.
+
+When true, if a default TLS configuration exists (`quarkus.tls.*`), it will
+be converted and set as the global SSL context via
`CamelContext.setSSLContextParameters()`.
+Components can opt in to this global context using
`useGlobalSslContextParameters=true`.
+| `boolean`
+| `false`
+
+a|
[[quarkus-camel-tls-registry-default-bean-name]]`link:#quarkus-camel-tls-registry-default-bean-name[quarkus.camel.tls-registry.default-bean-name]`
+
+The name to use when registering the default TLS configuration as a bean.
+
+Only applicable if the default configuration is not set as global
+(i.e., `quarkus-default-as-global=false`).
+| `string`
+| `defaultSslContextParameters`
+
+a|
[[quarkus-camel-tls-registry-reload-on-certificate-update]]`link:#quarkus-camel-tls-registry-reload-on-certificate-update[quarkus.camel.tls-registry.reload-on-certificate-update]`
+
+Enable automatic Camel Context reload when certificates are updated.
+
+When enabled, if Quarkus reloads a certificate (e.g., file watch detects
changes),
+the corresponding SSLContextParameters bean will be updated in the Camel
registry
+and a context reload will be triggered to restart routes with the new
certificates.
+
+This uses Camel's `ContextReloadStrategy` to gracefully restart routes without
+stopping the entire application.
+
+To avoid excessive reloads when multiple certificates are updated in quick
succession,
+the reload is debounced with a configurable delay. If additional certificate
updates occur
+during this delay, the timer is reset, ensuring only one reload happens after
all
+updates have stabilized.
+| `boolean`
+| `true`
+
+a|
[[quarkus-camel-tls-registry-reload-certificate-delay]]`link:#quarkus-camel-tls-registry-reload-certificate-delay[quarkus.camel.tls-registry.reload-certificate-delay]`
+
+Delay period to avoid excessive Camel Context reloads when multiple
certificates are updated in quick succession.
+| `long`
+| `2000`
+|===
+
+[.configuration-legend]
+{doc-link-icon-lock}[title=Fixed at build time] Configuration property fixed
at build time. All other configuration properties are overridable at runtime.
+
diff --git a/extensions/pom.xml b/extensions/pom.xml
index 323b72ff18..d4a7258b29 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -279,6 +279,7 @@
<module>telemetry-dev</module>
<module>tika</module>
<module>timer</module>
+ <module>tls-registry</module>
<module>twilio</module>
<module>twitter</module>
<module>univocity-parsers</module>
diff --git a/extensions/tls-registry/deployment/pom.xml
b/extensions/tls-registry/deployment/pom.xml
new file mode 100644
index 0000000000..9ac7075a79
--- /dev/null
+++ b/extensions/tls-registry/deployment/pom.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-tls-registry-parent</artifactId>
+ <version>3.36.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>camel-quarkus-tls-registry-deployment</artifactId>
+ <name>Camel Quarkus :: TLS Registry :: Deployment</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-core-deployment</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-tls-registry</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-tls-registry-deployment</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <annotationProcessorPaths>
+ <path>
+ <groupId>io.quarkus</groupId>
+
<artifactId>quarkus-extension-processor</artifactId>
+ <version>${quarkus.version}</version>
+ </path>
+ </annotationProcessorPaths>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git
a/extensions/tls-registry/deployment/src/main/java/org/apache/camel/quarkus/core/tls/deployment/TlsRegistryProcessor.java
b/extensions/tls-registry/deployment/src/main/java/org/apache/camel/quarkus/core/tls/deployment/TlsRegistryProcessor.java
new file mode 100644
index 0000000000..8e8510646f
--- /dev/null
+++
b/extensions/tls-registry/deployment/src/main/java/org/apache/camel/quarkus/core/tls/deployment/TlsRegistryProcessor.java
@@ -0,0 +1,55 @@
+/*
+ * 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.quarkus.core.tls.deployment;
+
+import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
+import io.quarkus.arc.deployment.SyntheticBeansRuntimeInitBuildItem;
+import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.annotations.Consume;
+import io.quarkus.deployment.annotations.ExecutionTime;
+import io.quarkus.deployment.annotations.Record;
+import io.quarkus.deployment.builditem.FeatureBuildItem;
+import org.apache.camel.quarkus.core.deployment.spi.CamelContextBuildItem;
+import org.apache.camel.quarkus.core.deployment.spi.CamelRuntimeTaskBuildItem;
+import org.apache.camel.quarkus.core.tls.TlsCertificateReloadObserver;
+import org.apache.camel.quarkus.core.tls.TlsRegistryRecorder;
+
+public class TlsRegistryProcessor {
+ private static final String FEATURE = "camel-tls-registry";
+
+ @BuildStep
+ FeatureBuildItem feature() {
+ return new FeatureBuildItem(FEATURE);
+ }
+
+ @BuildStep
+ AdditionalBeanBuildItem registerReloadObserver() {
+ return
AdditionalBeanBuildItem.unremovableOf(TlsCertificateReloadObserver.class);
+ }
+
+ @BuildStep
+ @Record(ExecutionTime.RUNTIME_INIT)
+ @Consume(SyntheticBeansRuntimeInitBuildItem.class)
+ CamelRuntimeTaskBuildItem registerTlsConfigurations(
+ TlsRegistryRecorder recorder,
+ CamelContextBuildItem camelContext) {
+
+ recorder.registerTlsConfigurations(camelContext.getCamelContext());
+
+ return new CamelRuntimeTaskBuildItem("tls-registry");
+ }
+}
diff --git a/extensions/tls-registry/pom.xml b/extensions/tls-registry/pom.xml
new file mode 100644
index 0000000000..36d779ae43
--- /dev/null
+++ b/extensions/tls-registry/pom.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-extensions</artifactId>
+ <version>3.36.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>camel-quarkus-tls-registry-parent</artifactId>
+ <name>Camel Quarkus :: TLS Registry</name>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>deployment</module>
+ <module>runtime</module>
+ </modules>
+
+</project>
diff --git a/extensions/tls-registry/runtime/pom.xml
b/extensions/tls-registry/runtime/pom.xml
new file mode 100644
index 0000000000..fd2d7beb8f
--- /dev/null
+++ b/extensions/tls-registry/runtime/pom.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-tls-registry-parent</artifactId>
+ <version>3.36.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>camel-quarkus-tls-registry</artifactId>
+ <name>Camel Quarkus :: TLS Registry :: Runtime</name>
+ <description>Configuration bridge for the Quarkus TLS registry and Camel
SSLContextParameters</description>
+
+ <properties>
+ <camel.quarkus.jvmSince>3.36.0</camel.quarkus.jvmSince>
+ <camel.quarkus.nativeSince>3.36.0</camel.quarkus.nativeSince>
+ <quarkus.metadata.status>experimental</quarkus.metadata.status>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-tls-registry</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-extension-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <annotationProcessorPaths>
+ <path>
+ <groupId>io.quarkus</groupId>
+
<artifactId>quarkus-extension-processor</artifactId>
+ <version>${quarkus.version}</version>
+ </path>
+ </annotationProcessorPaths>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/extensions/tls-registry/runtime/src/main/doc/usage.adoc
b/extensions/tls-registry/runtime/src/main/doc/usage.adoc
new file mode 100644
index 0000000000..9cf61d22c1
--- /dev/null
+++ b/extensions/tls-registry/runtime/src/main/doc/usage.adoc
@@ -0,0 +1,135 @@
+This extension provides integration between
https://quarkus.io/guides/tls-registry-reference[Quarkus TLS Registry] and
xref:manual::camel-configuration-utilities.adoc[Camel SSLContextParameters].
+When enabled, TLS configurations defined via `quarkus.tls.*` properties are
automatically converted and registered as `SSLContextParameters` beans in the
Camel registry.
+
+This eliminates the need to configure TLS separately for Quarkus and Camel
components - configure it once in Quarkus, and use it everywhere in your Camel
routes.
+
+=== Basic Configuration
+
+==== Default TLS Configuration
+
+Configure a default TLS configuration using `quarkus.tls.*` properties:
+
+[source,properties]
+----
+# Default TLS configuration
+quarkus.tls.key-store.p12.path=/etc/ssl/keystore.p12
+quarkus.tls.key-store.p12.password=changeit
+quarkus.tls.trust-store.p12.path=/etc/ssl/truststore.p12
+quarkus.tls.trust-store.p12.password=changeit
+----
+
+This creates an `SSLContextParameters` bean named
`defaultSslContextParameters` that can be referenced in your routes:
+
+[source,java]
+----
+from("timer:tick")
+
.to("https://api.example.com?sslContextParameters=#defaultSslContextParameters");
+----
+
+NOTE: The bean name for the default TLS configuration can be customized using
`quarkus.camel.tls-registry.default-bean-name`.
+
+==== Named TLS Configurations
+
+Define multiple named TLS configurations for different purposes (e.g.,
separate client and server certificates):
+
+[source,properties]
+----
+# Client TLS configuration
+quarkus.tls.client.key-store.p12.path=/etc/ssl/client-keystore.p12
+quarkus.tls.client.key-store.p12.password=changeit
+quarkus.tls.client.trust-all=true
+
+# Server TLS configuration
+quarkus.tls.server.key-store.p12.path=/etc/ssl/server-keystore.p12
+quarkus.tls.server.key-store.p12.password=changeit
+quarkus.tls.server.trust-store.p12.path=/etc/ssl/server-truststore.p12
+----
+
+Named configurations are automatically discovered and registered as beans with
their configuration name:
+
+[source,java]
+----
+// Use the client certificate
+from("timer:tick")
+ .to("https://api.example.com?sslContextParameters=#client");
+
+// Use the server certificate
+from("netty-http:https://0.0.0.0:8443/secure?sslContextParameters=#server")
+ .to("log:requests");
+----
+
+=== Global SSL Context
+
+You can set the Quarkus default TLS configuration as Camel's global
`SSLContextParameters`:
+
+[source,properties]
+----
+quarkus.camel.tls-registry.quarkus-default-as-global=true
+
+# Default TLS configuration becomes global
+quarkus.tls.key-store.p12.path=/etc/ssl/keystore.p12
+quarkus.tls.key-store.p12.password=changeit
+----
+
+When configured as global, Camel components can opt in to using it
automatically:
+
+[source,java]
+----
+from("timer:tick")
+ // No need to specify sslContextParameters, uses global SSL context
+ .to("https://api.example.com?useGlobalSslContextParameters=true");
+----
+
+=== Certificate Reload
+
+The extension automatically observes certificate reload events from Quarkus
TLS registry.
+When certificates are reloaded (e.g., due to file system changes), the
corresponding `SSLContextParameters` beans are updated and Camel routes are
restarted to pick up the new certificates.
+
+This feature is enabled by default but can be controlled via configuration:
+
+[source,properties]
+----
+# Enable certificate reloading
+quarkus.tls.reload-period=1h
+
+# Enable/disable certificate reload (default: true)
+quarkus.camel.tls-registry.reload-on-certificate-update=true
+
+# Debounce delay in milliseconds to avoid multiple reloads (default: 2000)
+quarkus.camel.tls-registry.reload-certificate-delay=2000
+----
+
+The debounce delay ensures that when multiple certificates are updated in
quick succession, only a single Camel context reload occurs after all updates
have stabilized.
+
+For more information see the
https://quarkus.io/guides/tls-registry-reference#reloading-certificates[Quarkus
TLS Registry Reference Guide].
+
+=== Bean Name Conflicts
+
+If you have an existing `SSLContextParameters` bean with the same name as a
Quarkus TLS configuration, the extension will throw an `IllegalStateException`
at startup with a helpful message.
+
+To resolve this, you can either:
+
+1. Remove or rename the existing `SSLContextParameters` bean, or
+2. Rename the Quarkus TLS configuration (e.g., `quarkus.tls.my-config.*`
instead of the conflicting name)
+
+=== PEM Format Support
+
+Quarkus TLS registry supports both PKCS12 and PEM formats.
+The extension automatically works with both:
+
+[source,properties]
+----
+# PEM format
+quarkus.tls.key-store.pem.cert=/etc/ssl/cert.pem
+quarkus.tls.key-store.pem.key=/etc/ssl/key.pem
+quarkus.tls.trust-store.pem.certs=/etc/ssl/ca-bundle.pem
+
+# Or PKCS12 format
+quarkus.tls.key-store.p12.path=/etc/ssl/keystore.p12
+quarkus.tls.key-store.p12.password=changeit
+----
+
+=== Additional Resources
+
+* https://quarkus.io/guides/tls-registry-reference[Quarkus TLS Registry
Reference Guide]
+* xref:manual::camel-configuration-utilities.adoc[Camel SSLContextParameters
Documentation]
diff --git
a/extensions/tls-registry/runtime/src/main/java/org/apache/camel/quarkus/core/tls/TlsCertificateReloadObserver.java
b/extensions/tls-registry/runtime/src/main/java/org/apache/camel/quarkus/core/tls/TlsCertificateReloadObserver.java
new file mode 100644
index 0000000000..a6e9d4897e
--- /dev/null
+++
b/extensions/tls-registry/runtime/src/main/java/org/apache/camel/quarkus/core/tls/TlsCertificateReloadObserver.java
@@ -0,0 +1,173 @@
+/*
+ * 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.quarkus.core.tls;
+
+import java.util.Optional;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import io.quarkus.tls.CertificateUpdatedEvent;
+import io.quarkus.tls.TlsConfiguration;
+import io.quarkus.tls.TlsConfigurationRegistry;
+import jakarta.annotation.PreDestroy;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.event.Observes;
+import jakarta.inject.Inject;
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ContextReloadStrategy;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Observes certificate update events from Quarkus TLS registry and triggers
+ * Camel context reload to pick up new certificates.
+ *
+ * When a certificate is reloaded by Quarkus (e.g., file watch detects
changes),
+ * this observer:
+ *
+ * 1. Updates the corresponding SSLContextParameters bean in Camel registry
+ * 2. Triggers a Camel context reload to restart routes with new certificates
+ */
+@ApplicationScoped
+public class TlsCertificateReloadObserver {
+ private static final Logger LOG =
LoggerFactory.getLogger(TlsCertificateReloadObserver.class);
+
+ @Inject
+ CamelContext camelContext;
+
+ @Inject
+ TlsRegistryConfig config;
+
+ private final AtomicReference<ScheduledFuture<?>> pendingReload = new
AtomicReference<>();
+ private ScheduledExecutorService scheduler;
+
+ /**
+ * Observes certificate updated events from Quarkus TLS registry.
+ *
+ * When a certificate is reloaded, this method:
+ *
+ * 1. Converts the updated TLS configuration to SSLContextParameters
+ * 2. Updates the bean in Camel registry (or global SSL context)
+ * 3. Triggers Camel context reload to restart routes
+ *
+ * @param event the certificate updated event
+ */
+ void onCertificateUpdated(@Observes CertificateUpdatedEvent event) {
+ if (!config.enabled() || !config.reloadOnCertificateUpdate()) {
+ LOG.debug("TLS registry integration is disabled, ignoring
certificate update for '{}'", event.name());
+ return;
+ }
+
+ LOG.info("Certificate '{}' has been updated, reloading Camel SSL
configuration", event.name());
+
+ try {
+ // Access TLS registry to get the updated configuration
+ TlsConfigurationRegistry tlsRegistry =
TlsRegistryHelper.getTlsRegistry();
+ if (tlsRegistry == null) {
+ LOG.warn("TLS configuration registry not available, cannot
reload certificate '{}'", event.name());
+ return;
+ }
+
+ // Get the updated TLS configuration
+ Optional<TlsConfiguration> tlsConfig =
TlsRegistryHelper.getTlsConfiguration(tlsRegistry, event.name());
+ if (tlsConfig.isEmpty()) {
+ LOG.warn("TLS configuration '{}' not found in registry after
update event", event.name());
+ return;
+ }
+
+ // Update the bean in the Camel registry
+ TlsRegistryHelper.registerOrUpdateBean(camelContext, config,
event.name(), tlsConfig.get());
+
+ // Schedule a debounced context reload to restart routes with new
certificates
+ scheduleCamelContextReload();
+ } catch (Exception e) {
+ LOG.error("Failed to update Camel SSL configuration for
certificate '{}'", event.name(), e);
+ }
+ }
+
+ /**
+ * Schedules a debounced context reload.
+ *
+ * If multiple certificate updates occur in quick succession, this ensures
only one
+ * reload happens after the updates have stabilized.
+ */
+ private void scheduleCamelContextReload() {
+ // Cancel any pending reload
+ ScheduledFuture<?> existing = pendingReload.get();
+ if (existing != null) {
+ existing.cancel(false);
+ LOG.debug("Canceled pending reload due to new certificate update");
+ }
+
+ // Schedule a new reload
+ ScheduledFuture<?> newReload = getScheduler().schedule(
+ this::triggerContextReload,
+ config.reloadCertificateDelay(),
+ TimeUnit.MILLISECONDS);
+
+ pendingReload.set(newReload);
+ LOG.debug("Scheduled context reload in {}ms",
config.reloadCertificateDelay());
+ }
+
+ /**
+ * Gets or creates the scheduler for debounced reloads.
+ */
+ private ScheduledExecutorService getScheduler() {
+ if (scheduler == null) {
+ scheduler = camelContext.getExecutorServiceManager()
+ .newScheduledThreadPool(this, "CamelQuarkusTlsReload", 1);
+ }
+ return scheduler;
+ }
+
+ /**
+ * Cleanup scheduler on bean destruction.
+ */
+ @PreDestroy
+ void cleanup() {
+ ScheduledFuture<?> pending = pendingReload.get();
+ if (pending != null) {
+ pending.cancel(false);
+ }
+ if (scheduler != null) {
+ camelContext.getExecutorServiceManager().shutdown(scheduler);
+ }
+ }
+
+ /**
+ * Triggers a Camel context reload to restart routes with updated
certificates.
+ *
+ * This uses Camel's context reload strategy to gracefully restart routes
without
+ * stopping the entire application.
+ */
+ private void triggerContextReload() {
+ try {
+ ContextReloadStrategy reloadStrategy =
camelContext.hasService(ContextReloadStrategy.class);
+ if (reloadStrategy != null) {
+ LOG.info("Triggering Camel context reload to apply updated
certificates");
+ reloadStrategy.onReload(this);
+ } else {
+ LOG.warn("ContextReloadStrategy not available, routes will not
be restarted. "
+ + "New certificates will be used on next route
start.");
+ }
+ } catch (Exception e) {
+ LOG.error("Failed to trigger Camel context reload", e);
+ }
+ }
+}
diff --git
a/extensions/tls-registry/runtime/src/main/java/org/apache/camel/quarkus/core/tls/TlsConfigurationConverter.java
b/extensions/tls-registry/runtime/src/main/java/org/apache/camel/quarkus/core/tls/TlsConfigurationConverter.java
new file mode 100644
index 0000000000..83fa202fb1
--- /dev/null
+++
b/extensions/tls-registry/runtime/src/main/java/org/apache/camel/quarkus/core/tls/TlsConfigurationConverter.java
@@ -0,0 +1,126 @@
+/*
+ * 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.quarkus.core.tls;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+
+import javax.net.ssl.SSLContext;
+
+import io.quarkus.tls.TlsConfiguration;
+import org.apache.camel.CamelContext;
+import org.apache.camel.support.jsse.KeyManagersParameters;
+import org.apache.camel.support.jsse.KeyStoreParameters;
+import org.apache.camel.support.jsse.SSLContextParameters;
+import org.apache.camel.support.jsse.TrustManagersParameters;
+
+/**
+ * Converts Quarkus TlsConfiguration to Camel SSLContextParameters.
+ */
+final class TlsConfigurationConverter {
+ private TlsConfigurationConverter() {
+ // Utility class
+ }
+
+ /**
+ * Convert a Quarkus TlsConfiguration to Camel SSLContextParameters.
+ *
+ * This implementation delegates to Quarkus's pre-configured SSLContext
and also
+ * provides access to the underlying keystores for components that need
them
+ * (e.g., camel-vertx-http).
+ *
+ * The Quarkus TLS registry handles all the complexity of:
+ *
+ * - Loading keystores and truststores (JKS, PKCS12, PEM)
+ * - Configuring key and trust managers
+ * - Setting cipher suites and protocols
+ * - Handling certificate reloading
+ *
+ * @param tlsConfig the Quarkus TLS configuration
+ * @param name the configuration name (for logging)
+ * @return SSLContextParameters that delegates to Quarkus's TLS
configuration
+ */
+ static SSLContextParameters convert(TlsConfiguration tlsConfig, String
name) {
+ return new SSLContextParameters() {
+ @Override
+ public SSLContext createSSLContext(CamelContext camelContext)
throws GeneralSecurityException, IOException {
+ try {
+ return tlsConfig.createSSLContext();
+ } catch (Exception e) {
+ throw new GeneralSecurityException(
+ "Failed to create SSLContext from Quarkus TLS
configuration '" + name + "'", e);
+ }
+ }
+
+ @Override
+ public KeyManagersParameters getKeyManagers() {
+ KeyStore keyStore = tlsConfig.getKeyStore();
+ if (keyStore == null) {
+ return null;
+ }
+
+ // Create a KeyManagersParameters that wraps the Quarkus
keystore
+ KeyManagersParameters kmp = new KeyManagersParameters();
+
+ // Create KeyStoreParameters wrapping the pre-loaded Quarkus
keystore
+ KeyStoreParameters ksp = new KeyStoreParameters() {
+ @Override
+ public KeyStore createKeyStore() {
+ // Return the already-loaded Quarkus keystore
+ return keyStore;
+ }
+ };
+ kmp.setKeyStore(ksp);
+
+ return kmp;
+ }
+
+ @Override
+ public TrustManagersParameters getTrustManagers() {
+ KeyStore trustStore = tlsConfig.getTrustStore();
+
+ // If no truststore and not trust-all mode, return null
+ // This is valid for scenarios where no server verification is
needed
+ if (trustStore == null && !tlsConfig.isTrustAll()) {
+ return null;
+ }
+
+ // If trust-all is enabled, return null and let the SSLContext
handle it
+ // The SSLContext from Quarkus is already configured for
trust-all
+ if (tlsConfig.isTrustAll()) {
+ return null;
+ }
+
+ // Create a TrustManagersParameters that wraps the Quarkus
truststore
+ TrustManagersParameters tmp = new TrustManagersParameters();
+
+ // Create KeyStoreParameters wrapping the pre-loaded Quarkus
truststore
+ KeyStoreParameters ksp = new KeyStoreParameters() {
+ @Override
+ public KeyStore createKeyStore() {
+ // Return the already-loaded Quarkus truststore
+ return trustStore;
+ }
+ };
+ tmp.setKeyStore(ksp);
+
+ return tmp;
+ }
+ };
+ }
+}
diff --git
a/extensions/tls-registry/runtime/src/main/java/org/apache/camel/quarkus/core/tls/TlsRegistryConfig.java
b/extensions/tls-registry/runtime/src/main/java/org/apache/camel/quarkus/core/tls/TlsRegistryConfig.java
new file mode 100644
index 0000000000..7b9ce50fb2
--- /dev/null
+++
b/extensions/tls-registry/runtime/src/main/java/org/apache/camel/quarkus/core/tls/TlsRegistryConfig.java
@@ -0,0 +1,88 @@
+/*
+ * 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.quarkus.core.tls;
+
+import io.quarkus.runtime.annotations.ConfigPhase;
+import io.quarkus.runtime.annotations.ConfigRoot;
+import io.smallrye.config.ConfigMapping;
+import io.smallrye.config.WithDefault;
+import io.smallrye.config.WithName;
+
+/**
+ * Runtime configuration for the Camel Quarkus TLS Registry integration.
+ */
+@ConfigRoot(phase = ConfigPhase.RUN_TIME)
+@ConfigMapping(prefix = "quarkus.camel.tls-registry")
+public interface TlsRegistryConfig {
+
+ String DEFAULT_BEAN_NAME = "defaultSslContextParameters";
+
+ /**
+ * Enable automatic conversion and registration of Quarkus TLS
configurations
+ * as Camel SSLContextParameters beans.
+ *
+ * When enabled, the default TLS configuration and any named
configurations will
+ * be automatically discovered and registered as beans in the Camel
registry.
+ */
+ @WithDefault("true")
+ boolean enabled();
+
+ /**
+ * Whether to set the Quarkus default TLS configuration as Camel's global
+ * SSLContextParameters.
+ *
+ * When true, if a default TLS configuration exists (`quarkus.tls.*`), it
will
+ * be converted and set as the global SSL context via
`CamelContext.setSSLContextParameters()`.
+ * Components can opt in to this global context using
`useGlobalSslContextParameters=true`.
+ */
+ @WithName("quarkus-default-as-global")
+ @WithDefault("false")
+ boolean quarkusDefaultAsGlobal();
+
+ /**
+ * The name to use when registering the default TLS configuration as a
bean.
+ *
+ * Only applicable if the default configuration is not set as global
+ * (i.e., `quarkus-default-as-global=false`).
+ */
+ @WithDefault(DEFAULT_BEAN_NAME)
+ String defaultBeanName();
+
+ /**
+ * Enable automatic Camel Context reload when certificates are updated.
+ *
+ * When enabled, if Quarkus reloads a certificate (e.g., file watch
detects changes),
+ * the corresponding SSLContextParameters bean will be updated in the
Camel registry
+ * and a context reload will be triggered to restart routes with the new
certificates.
+ *
+ * This uses Camel's `ContextReloadStrategy` to gracefully restart routes
without
+ * stopping the entire application.
+ *
+ * To avoid excessive reloads when multiple certificates are updated in
quick succession,
+ * the reload is debounced with a configurable delay. If additional
certificate updates occur
+ * during this delay, the timer is reset, ensuring only one reload happens
after all
+ * updates have stabilized.
+ */
+ @WithDefault("true")
+ boolean reloadOnCertificateUpdate();
+
+ /**
+ * Delay period to avoid excessive Camel Context reloads when multiple
certificates are updated in quick succession.
+ */
+ @WithDefault("2000")
+ long reloadCertificateDelay();
+}
diff --git
a/extensions/tls-registry/runtime/src/main/java/org/apache/camel/quarkus/core/tls/TlsRegistryHelper.java
b/extensions/tls-registry/runtime/src/main/java/org/apache/camel/quarkus/core/tls/TlsRegistryHelper.java
new file mode 100644
index 0000000000..fe51db2d86
--- /dev/null
+++
b/extensions/tls-registry/runtime/src/main/java/org/apache/camel/quarkus/core/tls/TlsRegistryHelper.java
@@ -0,0 +1,172 @@
+/*
+ * 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.quarkus.core.tls;
+
+import java.util.Optional;
+
+import io.quarkus.arc.Arc;
+import io.quarkus.tls.TlsConfiguration;
+import io.quarkus.tls.TlsConfigurationRegistry;
+import io.quarkus.tls.runtime.config.TlsConfig;
+import org.apache.camel.CamelContext;
+import org.apache.camel.support.jsse.SSLContextParameters;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Helper class for managing Quarkus TLS configurations as Camel
SSLContextParameters beans.
+ */
+final class TlsRegistryHelper {
+ private static final Logger LOG =
LoggerFactory.getLogger(TlsRegistryHelper.class);
+
+ private TlsRegistryHelper() {
+ // Utility class
+ }
+
+ /**
+ * Get the Quarkus TLS configuration registry.
+ *
+ * @return the TLS registry, or null if not available
+ */
+ static TlsConfigurationRegistry getTlsRegistry() {
+ return Arc.container()
+ .select(TlsConfigurationRegistry.class)
+ .orNull();
+ }
+
+ /**
+ * Check if a TLS configuration name represents the default configuration.
+ *
+ * @param name the configuration name
+ * @return true if this is the default config
+ */
+ static boolean isDefaultConfig(String name) {
+ return "default".equals(name) || TlsConfig.DEFAULT_NAME.equals(name);
+ }
+
+ /**
+ * Get a TLS configuration by name.
+ *
+ * @param registry the TLS registry
+ * @param name the configuration name
+ * @return the TLS configuration if found
+ */
+ static Optional<TlsConfiguration>
getTlsConfiguration(TlsConfigurationRegistry registry, String name) {
+ if (isDefaultConfig(name)) {
+ return registry.getDefault();
+ } else {
+ return registry.get(name);
+ }
+ }
+
+ /**
+ * Register or update a TLS configuration as a Camel SSLContextParameters
bean.
+ *
+ * @param camelContext the Camel context
+ * @param config the TLS registry configuration
+ * @param name the TLS configuration name
+ * @param tlsConfig the TLS configuration
+ */
+ static void registerOrUpdateBean(
+ CamelContext camelContext,
+ TlsRegistryConfig config,
+ String name,
+ TlsConfiguration tlsConfig) {
+
+ SSLContextParameters sslParams =
TlsConfigurationConverter.convert(tlsConfig, name);
+ boolean isDefault = isDefaultConfig(name);
+
+ if (isDefault && config.quarkusDefaultAsGlobal()) {
+ LOG.info("Updating Camel global SSLContextParameters with reloaded
certificate");
+ camelContext.setSSLContextParameters(sslParams);
+ } else {
+ String beanName = isDefault ? config.defaultBeanName() : name;
+ updateBean(camelContext, beanName, sslParams);
+ }
+ }
+
+ /**
+ * Register a new TLS configuration as a Camel SSLContextParameters bean.
+ * Throws an exception if a bean with the same name already exists.
+ *
+ * @param camelContext the Camel context
+ * @param config the TLS registry configuration
+ * @param name the TLS configuration name
+ * @param tlsConfig the TLS configuration
+ * @throws IllegalStateException if a bean with the same name already
exists
+ */
+ static void registerBean(
+ CamelContext camelContext,
+ TlsRegistryConfig config,
+ String name,
+ TlsConfiguration tlsConfig) {
+
+ SSLContextParameters sslParams =
TlsConfigurationConverter.convert(tlsConfig, name);
+ boolean isDefault = isDefaultConfig(name);
+
+ if (isDefault && config.quarkusDefaultAsGlobal()) {
+ LOG.info("Setting Quarkus default TLS as Camel global
SSLContextParameters");
+ camelContext.setSSLContextParameters(sslParams);
+ } else {
+ String beanName = isDefault ? config.defaultBeanName() : name;
+ registerBeanWithConflictCheck(camelContext, beanName, sslParams,
name);
+ }
+ }
+
+ /**
+ * Update an existing bean in the Camel registry.
+ *
+ * @param context the Camel context
+ * @param name the bean name
+ * @param sslParams the SSL context parameters
+ */
+ static void updateBean(CamelContext context, String name,
SSLContextParameters sslParams) {
+ LOG.info("Updating Camel SSLContextParameters bean '{}' with reloaded
certificate", name);
+ context.getRegistry().bind(name, SSLContextParameters.class,
sslParams);
+ }
+
+ /**
+ * Register a bean in the Camel registry, checking for conflicts.
+ *
+ * @param context the Camel context
+ * @param beanName the bean name to register
+ * @param sslParams the SSL context parameters
+ * @param tlsConfigName the original TLS config name (for error
messages)
+ * @throws IllegalStateException if a bean with the same name already
exists
+ */
+ static void registerBeanWithConflictCheck(
+ CamelContext context,
+ String beanName,
+ SSLContextParameters sslParams,
+ String tlsConfigName) {
+
+ SSLContextParameters existing = context.getRegistry()
+ .lookupByNameAndType(beanName, SSLContextParameters.class);
+
+ if (existing != null) {
+ throw new IllegalStateException(String.format(
+ "SSLContextParameters bean with name '%s' already exists
in the Camel registry. "
+ + "To use the Quarkus TLS registry configuration
instead, either:%n"
+ + " 1. Remove or rename the existing
SSLContextParameters bean, OR%n"
+ + " 2. Rename the Quarkus TLS configuration
(quarkus.tls.%s.* → quarkus.tls.<new-name>.*)",
+ beanName, tlsConfigName));
+ }
+
+ LOG.info("Registering Quarkus TLS configuration '{}' as Camel
SSLContextParameters bean", tlsConfigName);
+ context.getRegistry().bind(beanName, SSLContextParameters.class,
sslParams);
+ }
+}
diff --git
a/extensions/tls-registry/runtime/src/main/java/org/apache/camel/quarkus/core/tls/TlsRegistryRecorder.java
b/extensions/tls-registry/runtime/src/main/java/org/apache/camel/quarkus/core/tls/TlsRegistryRecorder.java
new file mode 100644
index 0000000000..8c30cffd74
--- /dev/null
+++
b/extensions/tls-registry/runtime/src/main/java/org/apache/camel/quarkus/core/tls/TlsRegistryRecorder.java
@@ -0,0 +1,97 @@
+/*
+ * 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.quarkus.core.tls;
+
+import java.util.Optional;
+
+import io.quarkus.runtime.RuntimeValue;
+import io.quarkus.runtime.annotations.Recorder;
+import io.quarkus.tls.TlsConfiguration;
+import io.quarkus.tls.TlsConfigurationRegistry;
+import io.quarkus.tls.runtime.config.TlsConfig;
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ContextReloadStrategy;
+import org.apache.camel.support.DefaultContextReloadStrategy;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Runtime recorder for registering Quarkus TLS configurations as Camel
SSLContextParameters beans.
+ */
+@Recorder
+public class TlsRegistryRecorder {
+ private static final Logger LOG =
LoggerFactory.getLogger(TlsRegistryRecorder.class);
+
+ private final RuntimeValue<TlsRegistryConfig>
tlsRegistryConfigRuntimeValue;
+ private final RuntimeValue<TlsConfig> tlsConfigRuntimeValue;
+
+ public TlsRegistryRecorder(RuntimeValue<TlsRegistryConfig>
tlsRegistryConfigRuntimeValue,
+ RuntimeValue<TlsConfig> tlsConfigRuntimeValue) {
+ this.tlsRegistryConfigRuntimeValue = tlsRegistryConfigRuntimeValue;
+ this.tlsConfigRuntimeValue = tlsConfigRuntimeValue;
+ }
+
+ /**
+ * Register Quarkus TLS configurations as Camel SSLContextParameters beans.
+ * Called at RUNTIME_INIT after the Camel context is created.
+ *
+ * @param camelContextRuntimeValue the Camel context
+ */
+ public void registerTlsConfigurations(RuntimeValue<CamelContext>
camelContextRuntimeValue) {
+ TlsRegistryConfig config = tlsRegistryConfigRuntimeValue.getValue();
+
+ if (!config.enabled()) {
+ LOG.debug("TLS registry integration is disabled");
+ return;
+ }
+
+ // Access TLS registry at runtime
+ TlsConfigurationRegistry tlsRegistry =
TlsRegistryHelper.getTlsRegistry();
+ if (tlsRegistry == null) {
+ LOG.debug("TLS configuration registry not available (no TLS
configured)");
+ return;
+ }
+
+ CamelContext camelContext = camelContextRuntimeValue.getValue();
+
+ // Configure context reloading for cert updates if required
+ if (config.reloadOnCertificateUpdate() &&
camelContext.hasService(ContextReloadStrategy.class) == null) {
+ ContextReloadStrategy reloader = new
DefaultContextReloadStrategy();
+ try {
+ camelContext.addService(reloader);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ // Process default TLS configuration
+ Optional<TlsConfiguration> defaultTls = tlsRegistry.getDefault();
+ if (defaultTls.isPresent()) {
+ TlsRegistryHelper.registerBean(camelContext, config, "default",
defaultTls.get());
+ }
+
+ // Process all named TLS configurations
+ TlsConfig tlsConfig = tlsConfigRuntimeValue.getValue();
+ for (String name : tlsConfig.namedCertificateConfig().keySet()) {
+ Optional<TlsConfiguration> namedTls = tlsRegistry.get(name);
+ if (namedTls.isPresent()) {
+ LOG.debug("Processing named TLS configuration '{}'", name);
+ TlsRegistryHelper.registerBean(camelContext, config, name,
namedTls.get());
+ }
+ }
+ }
+}
diff --git
a/extensions/tls-registry/runtime/src/main/resources/META-INF/quarkus-extension.yaml
b/extensions/tls-registry/runtime/src/main/resources/META-INF/quarkus-extension.yaml
new file mode 100644
index 0000000000..a6470b72ee
--- /dev/null
+++
b/extensions/tls-registry/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -0,0 +1,34 @@
+#
+# 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.
+#
+
+# This is a generated file. Do not edit directly!
+# To re-generate, run the following command from the top level directory:
+#
+# mvn -N cq:update-quarkus-metadata
+#
+---
+name: "Camel TLS Registry"
+description: "Configuration bridge for the Quarkus TLS registry and Camel
SSLContextParameters"
+metadata:
+ icon-url:
"https://raw.githubusercontent.com/apache/camel-website/main/antora-ui-camel/src/img/logo-d.svg"
+ sponsor: "Apache Software Foundation"
+ guide:
"https://camel.apache.org/camel-quarkus/latest/reference/extensions/tls-registry.html"
+ categories:
+ - "integration"
+ config:
+ - "quarkus.camel.tls-registry"
+ status: "experimental"
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index d5d4ec459c..10fa5dc7f8 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -249,6 +249,7 @@
<module>telegram</module>
<module>telemetry-dev</module>
<module>tika</module>
+ <module>tls-registry</module>
<module>twilio</module>
<module>twitter</module>
<module>univocity-parsers</module>
diff --git a/integration-tests/tls-registry/pom.xml
b/integration-tests/tls-registry/pom.xml
new file mode 100644
index 0000000000..84579d5a2c
--- /dev/null
+++ b/integration-tests/tls-registry/pom.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-build-parent-it</artifactId>
+ <version>3.36.0-SNAPSHOT</version>
+ <relativePath>../../poms/build-parent-it/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>camel-quarkus-integration-test-tls-registry</artifactId>
+ <name>Camel Quarkus :: Integration Tests :: TLS Registry</name>
+ <description>Integration tests for Camel Quarkus TLS Registry
extension</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-tls-registry</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-http</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-direct</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-rest</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-rest-jackson</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.rest-assured</groupId>
+ <artifactId>rest-assured</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+
<artifactId>camel-quarkus-integration-tests-support-certificate-generator</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.awaitility</groupId>
+ <artifactId>awaitility</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <profiles>
+ <profile>
+ <id>native</id>
+ <activation>
+ <property>
+ <name>native</name>
+ </property>
+ </activation>
+ <properties>
+ <quarkus.native.enabled>true</quarkus.native.enabled>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>integration-test</goal>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>virtualDependencies</id>
+ <activation>
+ <property>
+ <name>!noVirtualDependencies</name>
+ </property>
+ </activation>
+ <dependencies>
+ <!-- The following dependencies guarantee that this module is
built after them. You can update them by running `mvn process-resources
-Pformat -N` from the source tree root directory -->
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-direct-deployment</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-http-deployment</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+
<artifactId>camel-quarkus-tls-registry-deployment</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+ </profile>
+ </profiles>
+</project>
diff --git
a/integration-tests/tls-registry/src/main/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryReloadResource.java
b/integration-tests/tls-registry/src/main/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryReloadResource.java
new file mode 100644
index 0000000000..8440396406
--- /dev/null
+++
b/integration-tests/tls-registry/src/main/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryReloadResource.java
@@ -0,0 +1,111 @@
+/*
+ * 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.quarkus.core.tls.it;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import io.quarkus.tls.CertificateUpdatedEvent;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.event.Event;
+import jakarta.enterprise.event.Observes;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.MediaType;
+import org.apache.camel.CamelContext;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.impl.event.CamelContextReloadedEvent;
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+
+@Path("/tls-registry/reload")
+@ApplicationScoped
+public class TlsRegistryReloadResource {
+
+ @Inject
+ Event<CertificateUpdatedEvent> certificateEventProducer;
+
+ @Inject
+ ProducerTemplate producerTemplate;
+
+ @Inject
+ CamelContext camelContext;
+
+ @ConfigProperty(name = "quarkus.http.ssl-port", defaultValue = "8444")
+ int httpsPort;
+
+ private final AtomicInteger reloadCount = new AtomicInteger(0);
+
+ /**
+ * Observes CamelContextReloadedEvent and counts reloads.
+ */
+ void onContextReloaded(@Observes CamelContextReloadedEvent event) {
+ reloadCount.incrementAndGet();
+ }
+
+ /**
+ * Fires a certificate updated event.
+ */
+ @POST
+ @Path("/fire-event/{certName}")
+ @Produces(MediaType.TEXT_PLAIN)
+ public String fireCertificateEvent(@PathParam("certName") String certName)
{
+ certificateEventProducer.fire(new CertificateUpdatedEvent(certName,
null));
+ return "Event fired for: " + certName;
+ }
+
+ /**
+ * Returns the number of context reloads that have occurred.
+ */
+ @GET
+ @Path("/count")
+ @Produces(MediaType.TEXT_PLAIN)
+ public String getReloadCount() {
+ return String.valueOf(reloadCount.get());
+ }
+
+ /**
+ * Resets the reload counter.
+ */
+ @POST
+ @Path("/reset")
+ @Produces(MediaType.TEXT_PLAIN)
+ public String resetCounter() {
+ reloadCount.set(0);
+ return "Counter reset";
+ }
+
+ /**
+ * Makes an HTTPS call using the default TLS configuration.
+ * This verifies that SSL/TLS is working correctly by calling back to the
Quarkus HTTPS server.
+ */
+ @GET
+ @Path("/test-https")
+ @Produces(MediaType.TEXT_PLAIN)
+ public String testHttpsConnection() {
+ try {
+ String url = "https://localhost:" + httpsPort
+ +
"/tls-registry/ping?sslContextParameters=#defaultSslContextParameters";
+ String result = producerTemplate.requestBody(url, null,
String.class);
+ return result != null ? result : "No response";
+ } catch (Exception e) {
+ return "ERROR: " + e.getMessage();
+ }
+ }
+}
diff --git
a/integration-tests/tls-registry/src/main/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryResource.java
b/integration-tests/tls-registry/src/main/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryResource.java
new file mode 100644
index 0000000000..3fb04018ec
--- /dev/null
+++
b/integration-tests/tls-registry/src/main/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryResource.java
@@ -0,0 +1,99 @@
+/*
+ * 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.quarkus.core.tls.it;
+
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.MediaType;
+import org.apache.camel.CamelContext;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.support.jsse.SSLContextParameters;
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+
+@Path("/tls-registry")
+@ApplicationScoped
+public class TlsRegistryResource {
+
+ @Inject
+ CamelContext context;
+
+ @Inject
+ ProducerTemplate producerTemplate;
+
+ @ConfigProperty(name = "quarkus.http.ssl-port", defaultValue = "8443")
+ int httpsPort;
+
+ @Path("/beans")
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ public Map<String, String> getSSLBeans() {
+ return
context.getRegistry().findByTypeWithName(SSLContextParameters.class).entrySet().stream()
+ .collect(Collectors.toMap(
+ Map.Entry::getKey,
+ e -> "SSLContextParameters"));
+ }
+
+ @Path("/bean/exists/{name}")
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ public boolean beanExists(@PathParam("name") String name) {
+ return context.getRegistry().lookupByNameAndType(name,
SSLContextParameters.class) != null;
+ }
+
+ @Path("/global-ssl")
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ public boolean hasGlobalSSL() {
+ return context.getSSLContextParameters() != null;
+ }
+
+ @Path("/ping")
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ public String ping() {
+ return "pong";
+ }
+
+ @Path("/http/call-with-named-ssl/{sslBeanName}")
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ public String callWithNamedSsl(@PathParam("sslBeanName") String
sslBeanName) {
+ String host = "localhost:" + httpsPort + "/tls-registry/ping";
+ return
producerTemplate.requestBodyAndHeaders("direct:https-with-named-ssl",
+ null,
+ Map.of("host", host, "sslBeanName", sslBeanName),
+ String.class);
+ }
+
+ @Path("/http/call-with-global-ssl")
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ public String callWithGlobalSsl() {
+ String host = "localhost:" + httpsPort + "/tls-registry/ping";
+ return
producerTemplate.requestBodyAndHeader("direct:https-with-global-ssl",
+ null,
+ "host", host,
+ String.class);
+ }
+}
diff --git
a/integration-tests/tls-registry/src/main/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryRoutes.java
b/integration-tests/tls-registry/src/main/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryRoutes.java
new file mode 100644
index 0000000000..cc68c94bff
--- /dev/null
+++
b/integration-tests/tls-registry/src/main/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryRoutes.java
@@ -0,0 +1,34 @@
+/*
+ * 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.quarkus.core.tls.it;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import org.apache.camel.builder.RouteBuilder;
+
+@ApplicationScoped
+public class TlsRegistryRoutes extends RouteBuilder {
+ @Override
+ public void configure() throws Exception {
+ // Route using named SSL configuration from TLS registry
+ from("direct:https-with-named-ssl")
+
.toD("https://${header.host}?sslContextParameters=#${header.sslBeanName}");
+
+ // Route using global SSL configuration (enabled by default in
application.properties)
+ from("direct:https-with-global-ssl")
+ .toD("https://${header.host}");
+ }
+}
diff --git
a/integration-tests/tls-registry/src/main/resources/application.properties
b/integration-tests/tls-registry/src/main/resources/application.properties
new file mode 100644
index 0000000000..2fec12f25f
--- /dev/null
+++ b/integration-tests/tls-registry/src/main/resources/application.properties
@@ -0,0 +1,21 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+# Reduce log verbosity due to Awaitility polling
+quarkus.test.rest-assured.enable-logging-on-failure=false
+
+camel.component.https.use-global-ssl-context-parameters=true
diff --git
a/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryCertificateReloadIT.java
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryCertificateReloadIT.java
new file mode 100644
index 0000000000..1d788e6964
--- /dev/null
+++
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryCertificateReloadIT.java
@@ -0,0 +1,23 @@
+/*
+ * 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.quarkus.core.tls.it;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+class TlsRegistryCertificateReloadIT extends TlsRegistryCertificateReloadTest {
+}
diff --git
a/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryCertificateReloadTest.java
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryCertificateReloadTest.java
new file mode 100644
index 0000000000..038089b3b3
--- /dev/null
+++
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryCertificateReloadTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.quarkus.core.tls.it;
+
+import java.util.Map;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.junit.QuarkusTestProfile;
+import io.quarkus.test.junit.TestProfile;
+import io.restassured.RestAssured;
+import io.smallrye.certs.Format;
+import io.smallrye.certs.junit5.Certificate;
+import org.apache.camel.quarkus.test.support.certificate.TestCertificates;
+import org.awaitility.Awaitility;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import static org.hamcrest.Matchers.equalTo;
+
+@TestCertificates(certificates = {
+ @Certificate(name = "tls-reload", formats = { Format.PKCS12,
Format.PEM }, password = "changeit")
+})
+@QuarkusTest
+@TestProfile(TlsRegistryCertificateReloadTest.CertReloadTestProfile.class)
+class TlsRegistryCertificateReloadTest {
+
+ @BeforeEach
+ void resetCounter() {
+ RestAssured.given()
+ .post("/tls-registry/reload/reset")
+ .then()
+ .statusCode(200);
+ }
+
+ @Test
+ void testSingleCertificateUpdateTriggersReload() {
+ // Fire a certificate updated event for the default cert (which exists
in TLS registry)
+ RestAssured.given()
+ .post("/tls-registry/reload/fire-event/default")
+ .then()
+ .statusCode(200);
+
+ // Wait for debounced reload (2 seconds + buffer) and verify exactly
one reload occurred
+ Awaitility.await()
+ .atMost(4, SECONDS)
+ .pollInterval(100, java.util.concurrent.TimeUnit.MILLISECONDS)
+ .untilAsserted(() -> RestAssured.given()
+ .get("/tls-registry/reload/count")
+ .then()
+ .statusCode(200)
+ .body(equalTo("1")));
+ }
+
+ @Test
+ void testMultipleCertificateUpdatesDebouncedToSingleReload() {
+ // Fire multiple certificate updated events in quick succession for
the default cert
+ for (int i = 1; i <= 5; i++) {
+ RestAssured.given()
+ .post("/tls-registry/reload/fire-event/default")
+ .then()
+ .statusCode(200);
+
+ // Space out events by 100ms
+ if (i < 5) {
+ Awaitility.await().pollDelay(100,
java.util.concurrent.TimeUnit.MILLISECONDS).until(() -> true);
+ }
+ }
+
+ // Wait for debounced reload (2 seconds + buffer from last event)
+ // Should have exactly one reload despite 5 certificate updates
+ Awaitility.await()
+ .atMost(4, SECONDS)
+ .pollInterval(100, java.util.concurrent.TimeUnit.MILLISECONDS)
+ .untilAsserted(() -> RestAssured.given()
+ .get("/tls-registry/reload/count")
+ .then()
+ .statusCode(200)
+ .body(equalTo("1")));
+
+ // Verify it's still 1 after a bit more time (no additional reloads)
+ Awaitility.await().pollDelay(500,
java.util.concurrent.TimeUnit.MILLISECONDS).until(() -> true);
+ RestAssured.given()
+ .get("/tls-registry/reload/count")
+ .then()
+ .statusCode(200)
+ .body(equalTo("1"));
+ }
+
+ public static class CertReloadTestProfile implements QuarkusTestProfile {
+ @Override
+ public Map<String, String> getConfigOverrides() {
+ return Map.ofEntries(
+ Map.entry("quarkus.camel.tls-registry.enabled", "true"),
+
Map.entry("quarkus.camel.tls-registry.reload-on-certificate-update", "true"),
+ Map.entry("quarkus.tls.key-store.p12.path",
"target/certs/tls-reload-keystore.p12"),
+ Map.entry("quarkus.tls.key-store.p12.password",
"changeit"));
+ }
+ }
+}
diff --git
a/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryDisabledIT.java
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryDisabledIT.java
new file mode 100644
index 0000000000..a33ef3cab3
--- /dev/null
+++
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryDisabledIT.java
@@ -0,0 +1,23 @@
+/*
+ * 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.quarkus.core.tls.it;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+class TlsRegistryDisabledIT extends TlsRegistryDisabledTest {
+}
diff --git
a/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryDisabledTest.java
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryDisabledTest.java
new file mode 100644
index 0000000000..2517bf76b4
--- /dev/null
+++
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryDisabledTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.quarkus.core.tls.it;
+
+import java.util.Map;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.junit.QuarkusTestProfile;
+import io.quarkus.test.junit.TestProfile;
+import io.restassured.RestAssured;
+import io.restassured.common.mapper.TypeRef;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@QuarkusTest
+@TestProfile(TlsRegistryDisabledTest.DisabledProfile.class)
+class TlsRegistryDisabledTest {
+
+ @Test
+ void testRegistryDisabled() {
+ // Verify no global SSL context
+ RestAssured.given()
+ .get("/tls-registry/global-ssl")
+ .then()
+ .statusCode(200)
+ .body(is("false"));
+
+ // Verify no beans are registered
+ Map<String, String> beans = RestAssured.given()
+ .get("/tls-registry/beans")
+ .then()
+ .statusCode(200)
+ .extract().as(new TypeRef<Map<String, String>>() {
+ });
+
+ assertEquals(0, beans.size(), "Should have no SSL beans when
disabled");
+ }
+
+ public static class DisabledProfile implements QuarkusTestProfile {
+ @Override
+ public Map<String, String> getConfigOverrides() {
+ return Map.of("quarkus.camel.tls-registry.enabled", "false");
+ }
+ }
+}
diff --git
a/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryFilesystemCertificateReloadIT.java
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryFilesystemCertificateReloadIT.java
new file mode 100644
index 0000000000..e81411bd12
--- /dev/null
+++
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryFilesystemCertificateReloadIT.java
@@ -0,0 +1,23 @@
+/*
+ * 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.quarkus.core.tls.it;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+class TlsRegistryFilesystemCertificateReloadIT extends
TlsRegistryFilesystemCertificateReloadTest {
+}
diff --git
a/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryFilesystemCertificateReloadTest.java
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryFilesystemCertificateReloadTest.java
new file mode 100644
index 0000000000..55b110645d
--- /dev/null
+++
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryFilesystemCertificateReloadTest.java
@@ -0,0 +1,127 @@
+/*
+ * 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.quarkus.core.tls.it;
+
+import java.io.File;
+import java.time.Duration;
+import java.util.List;
+import java.util.Map;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.junit.QuarkusTestProfile;
+import io.quarkus.test.junit.TestProfile;
+import io.restassured.RestAssured;
+import io.smallrye.certs.CertificateGenerator;
+import io.smallrye.certs.CertificateRequest;
+import io.smallrye.certs.Format;
+import io.smallrye.certs.junit5.Certificate;
+import org.apache.camel.quarkus.test.support.certificate.TestCertificates;
+import org.awaitility.Awaitility;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import static org.hamcrest.Matchers.equalTo;
+
+/**
+ * Tests that certificate reload works when certificates are actually
regenerated on the filesystem.
+ * This test simulates real-world certificate rotation by regenerating certs
and letting Quarkus
+ * TLS reload mechanism detect the changes.
+ */
+@TestCertificates(certificates = {
+ @Certificate(name = "tls-fs-reload", formats = { Format.PKCS12 },
password = "changeit")
+})
+@QuarkusTest
+@TestProfile(TlsRegistryFilesystemCertificateReloadTest.FilesystemReloadTestProfile.class)
+class TlsRegistryFilesystemCertificateReloadTest {
+
+ private static final String CERT_BASE_DIR = "target/certs";
+ private static final String CERT_NAME = "tls-fs-reload";
+
+ @BeforeEach
+ void resetCounter() {
+ RestAssured.given()
+ .post("/tls-registry/reload/reset")
+ .then()
+ .statusCode(200);
+ }
+
+ @Test
+ void testHttpsConnectionWorksAfterFilesystemCertificateReload() throws
Exception {
+ // 1. Verify initial HTTPS connectivity works
+ RestAssured.given()
+ .get("/tls-registry/reload/test-https")
+ .then()
+ .statusCode(200)
+ .body(equalTo("pong"));
+
+ // 2. Regenerate certificates on filesystem (simulating cert rotation)
+ // Add small delay to ensure file timestamp will be detectably
different
+ Thread.sleep(100);
+
+ File baseDir = new File(CERT_BASE_DIR);
+ CertificateGenerator generator = new
CertificateGenerator(baseDir.toPath(), true);
+ CertificateRequest request = new CertificateRequest()
+ .withName(CERT_NAME)
+ .withFormats(List.of(Format.PKCS12))
+ .withPassword("changeit")
+ .withDuration(Duration.ofDays(1));
+
+ // Force regeneration by specifying replaceIfExists=true
+ generator.generate(request);
+
+ // Touch the keystore file to force a modification time update that
Quarkus will detect
+ File keystoreFile = new File(CERT_BASE_DIR, CERT_NAME +
"-keystore.p12");
+ keystoreFile.setLastModified(System.currentTimeMillis());
+
+ // 3. Wait for Quarkus TLS to detect the change and trigger Camel
context reload
+ // Quarkus reload-period is 1s, plus debounce delay of 2s
+ // Allow extra time for filesystem polling and debouncing - wait up to
15s
+ Awaitility.await()
+ .atMost(15, SECONDS)
+ .pollInterval(200, java.util.concurrent.TimeUnit.MILLISECONDS)
+ .untilAsserted(() -> RestAssured.given()
+ .get("/tls-registry/reload/count")
+ .then()
+ .statusCode(200)
+ .body(equalTo("1")));
+
+ // 4. Verify HTTPS still works after real certificate reload
+ RestAssured.given()
+ .get("/tls-registry/reload/test-https")
+ .then()
+ .statusCode(200)
+ .body(equalTo("pong"));
+ }
+
+ public static class FilesystemReloadTestProfile implements
QuarkusTestProfile {
+ @Override
+ public Map<String, String> getConfigOverrides() {
+ String keystorePath = CERT_BASE_DIR + "/" + CERT_NAME +
"-keystore.p12";
+
+ return Map.ofEntries(
+ Map.entry("quarkus.camel.tls-registry.enabled", "true"),
+
Map.entry("quarkus.camel.tls-registry.reload-on-certificate-update", "true"),
+ Map.entry("quarkus.tls.reload-period", "5s"),
+ Map.entry("quarkus.tls.key-store.p12.path", keystorePath),
+ Map.entry("quarkus.tls.key-store.p12.password",
"changeit"),
+ Map.entry("quarkus.tls.trust-store.p12.path",
keystorePath),
+ Map.entry("quarkus.tls.trust-store.p12.password",
"changeit"));
+ }
+ }
+}
diff --git
a/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryGlobalIT.java
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryGlobalIT.java
new file mode 100644
index 0000000000..9b41f75780
--- /dev/null
+++
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryGlobalIT.java
@@ -0,0 +1,23 @@
+/*
+ * 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.quarkus.core.tls.it;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+class TlsRegistryGlobalIT extends TlsRegistryGlobalTest {
+}
diff --git
a/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryGlobalTest.java
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryGlobalTest.java
new file mode 100644
index 0000000000..13a265c0e4
--- /dev/null
+++
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryGlobalTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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.quarkus.core.tls.it;
+
+import java.util.Map;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.junit.QuarkusTestProfile;
+import io.quarkus.test.junit.TestProfile;
+import io.restassured.RestAssured;
+import io.restassured.common.mapper.TypeRef;
+import io.smallrye.certs.Format;
+import io.smallrye.certs.junit5.Certificate;
+import org.apache.camel.quarkus.test.support.certificate.TestCertificates;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@TestCertificates(certificates = {
+ @Certificate(name = "tls-test", formats = { Format.PKCS12, Format.PEM
}, password = "changeit")
+})
+@QuarkusTest
+@TestProfile(TlsRegistryGlobalTest.GlobalConfigProfile.class)
+class TlsRegistryGlobalTest {
+
+ @Test
+ void testGlobalSslContext() {
+ // Verify global SSL context is set
+ RestAssured.given()
+ .get("/tls-registry/global-ssl")
+ .then()
+ .statusCode(200)
+ .body(is("true"));
+
+ // Verify no named beans (global doesn't create a named bean)
+ Map<String, String> beans = RestAssured.given()
+ .get("/tls-registry/beans")
+ .then()
+ .statusCode(200)
+ .extract().as(new TypeRef<Map<String, String>>() {
+ });
+
+ assertEquals(0, beans.size(), "Should have no named SSL beans when
using global");
+
+ // Verify "defaultSslContextParameters" bean does not exist (using
global instead)
+ RestAssured.given()
+ .get("/tls-registry/bean/exists/defaultSslContextParameters")
+ .then()
+ .statusCode(200)
+ .body(is("false"));
+ }
+
+ public static class GlobalConfigProfile implements QuarkusTestProfile {
+ @Override
+ public Map<String, String> getConfigOverrides() {
+ return Map.of(
+ "quarkus.camel.tls-registry.enabled", "true",
+ "quarkus.camel.tls-registry.quarkus-default-as-global",
"true",
+ "quarkus.tls.key-store.p12.path",
"target/certs/tls-test-keystore.p12",
+ "quarkus.tls.key-store.p12.password", "changeit");
+ }
+ }
+}
diff --git
a/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryHttpsGlobalIT.java
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryHttpsGlobalIT.java
new file mode 100644
index 0000000000..1d809d8baa
--- /dev/null
+++
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryHttpsGlobalIT.java
@@ -0,0 +1,23 @@
+/*
+ * 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.quarkus.core.tls.it;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+class TlsRegistryHttpsGlobalIT extends TlsRegistryHttpsGlobalTest {
+}
diff --git
a/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryHttpsGlobalTest.java
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryHttpsGlobalTest.java
new file mode 100644
index 0000000000..0f990d5ed1
--- /dev/null
+++
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryHttpsGlobalTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.quarkus.core.tls.it;
+
+import java.util.Map;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.junit.QuarkusTestProfile;
+import io.quarkus.test.junit.TestProfile;
+import io.restassured.RestAssured;
+import io.smallrye.certs.Format;
+import io.smallrye.certs.junit5.Certificate;
+import org.apache.camel.quarkus.test.support.certificate.TestCertificates;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.Matchers.equalTo;
+
+@TestCertificates(certificates = {
+ @Certificate(name = "tls-global", formats = { Format.PKCS12,
Format.PEM }, password = "changeit")
+})
+@QuarkusTest
+@TestProfile(TlsRegistryHttpsGlobalTest.HttpsGlobalTestProfile.class)
+class TlsRegistryHttpsGlobalTest {
+
+ @Test
+ void testHttpsCallWithGlobalSsl() {
+ RestAssured.given()
+ .get("/tls-registry/http/call-with-global-ssl")
+ .then()
+ .statusCode(200)
+ .body(equalTo("pong"));
+ }
+
+ public static class HttpsGlobalTestProfile implements QuarkusTestProfile {
+ @Override
+ public Map<String, String> getConfigOverrides() {
+ return Map.of(
+ "quarkus.camel.tls-registry.enabled", "true",
+ "quarkus.camel.tls-registry.quarkus-default-as-global",
"true",
+ "quarkus.tls.key-store.p12.path",
"target/certs/tls-global-keystore.p12",
+ "quarkus.tls.key-store.p12.password", "changeit",
+ "quarkus.tls.trust-store.p12.path",
"target/certs/tls-global-keystore.p12",
+ "quarkus.tls.trust-store.p12.password", "changeit");
+ }
+ }
+}
diff --git
a/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryHttpsIT.java
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryHttpsIT.java
new file mode 100644
index 0000000000..7322df3826
--- /dev/null
+++
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryHttpsIT.java
@@ -0,0 +1,23 @@
+/*
+ * 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.quarkus.core.tls.it;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+class TlsRegistryHttpsIT extends TlsRegistryHttpsTest {
+}
diff --git
a/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryHttpsTest.java
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryHttpsTest.java
new file mode 100644
index 0000000000..c7822d1cad
--- /dev/null
+++
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryHttpsTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.quarkus.core.tls.it;
+
+import java.util.Map;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.junit.QuarkusTestProfile;
+import io.quarkus.test.junit.TestProfile;
+import io.restassured.RestAssured;
+import io.smallrye.certs.Format;
+import io.smallrye.certs.junit5.Certificate;
+import org.apache.camel.quarkus.test.support.certificate.TestCertificates;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.Matchers.equalTo;
+
+@TestCertificates(certificates = {
+ @Certificate(name = "tls-test", formats = { Format.PKCS12, Format.PEM
}, password = "changeit")
+})
+@QuarkusTest
+@TestProfile(TlsRegistryHttpsTest.HttpsTestProfile.class)
+class TlsRegistryHttpsTest {
+
+ @Test
+ void testHttpsCallWithNamedSsl() {
+ RestAssured.given()
+
.get("/tls-registry/http/call-with-named-ssl/defaultSslContextParameters")
+ .then()
+ .statusCode(200)
+ .body(equalTo("pong"));
+ }
+
+ public static class HttpsTestProfile implements QuarkusTestProfile {
+ @Override
+ public Map<String, String> getConfigOverrides() {
+ return Map.of(
+ "quarkus.camel.tls-registry.enabled", "true",
+ "quarkus.camel.tls-registry.quarkus-default-as-global",
"false",
+ "quarkus.tls.key-store.p12.path",
"target/certs/tls-test-keystore.p12",
+ "quarkus.tls.key-store.p12.password", "changeit",
+ "quarkus.tls.trust-store.p12.path",
"target/certs/tls-test-truststore.p12",
+ "quarkus.tls.trust-store.p12.password", "changeit");
+ }
+ }
+}
diff --git
a/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryIT.java
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryIT.java
new file mode 100644
index 0000000000..80f5558886
--- /dev/null
+++
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryIT.java
@@ -0,0 +1,24 @@
+/*
+ * 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.quarkus.core.tls.it;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+class TlsRegistryIT extends TlsRegistryTest {
+ // Runs the same tests in native mode
+}
diff --git
a/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryMultipleConfigsIT.java
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryMultipleConfigsIT.java
new file mode 100644
index 0000000000..8a24594a9f
--- /dev/null
+++
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryMultipleConfigsIT.java
@@ -0,0 +1,23 @@
+/*
+ * 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.quarkus.core.tls.it;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+class TlsRegistryMultipleConfigsIT extends TlsRegistryMultipleConfigsTest {
+}
diff --git
a/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryMultipleConfigsTest.java
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryMultipleConfigsTest.java
new file mode 100644
index 0000000000..78d84039b1
--- /dev/null
+++
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryMultipleConfigsTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.quarkus.core.tls.it;
+
+import java.util.Map;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.junit.QuarkusTestProfile;
+import io.quarkus.test.junit.TestProfile;
+import io.restassured.RestAssured;
+import io.restassured.common.mapper.TypeRef;
+import io.smallrye.certs.Format;
+import io.smallrye.certs.junit5.Certificate;
+import org.apache.camel.quarkus.test.support.certificate.TestCertificates;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@TestCertificates(certificates = {
+ @Certificate(name = "tls-test", formats = { Format.PKCS12, Format.PEM
}, password = "changeit")
+})
+@QuarkusTest
+@TestProfile(TlsRegistryMultipleConfigsTest.MultipleConfigsProfile.class)
+class TlsRegistryMultipleConfigsTest {
+
+ @Test
+ void testMultipleNamedConfigs() {
+ // Verify default bean exists
+ RestAssured.given()
+ .get("/tls-registry/bean/exists/defaultSslContextParameters")
+ .then()
+ .statusCode(200)
+ .body(is("true"));
+
+ // Verify client bean exists
+ RestAssured.given()
+ .get("/tls-registry/bean/exists/client")
+ .then()
+ .statusCode(200)
+ .body(is("true"));
+
+ // Verify server bean exists
+ RestAssured.given()
+ .get("/tls-registry/bean/exists/server")
+ .then()
+ .statusCode(200)
+ .body(is("true"));
+
+ // Verify no global SSL context
+ RestAssured.given()
+ .get("/tls-registry/global-ssl")
+ .then()
+ .statusCode(200)
+ .body(is("false"));
+
+ // Verify all beans are registered
+ Map<String, String> beans = RestAssured.given()
+ .get("/tls-registry/beans")
+ .then()
+ .statusCode(200)
+ .extract().as(new TypeRef<Map<String, String>>() {
+ });
+
+ assertTrue(beans.containsKey("defaultSslContextParameters"), "Should
contain 'defaultSslContextParameters' bean");
+ assertTrue(beans.containsKey("client"), "Should contain 'client'
bean");
+ assertTrue(beans.containsKey("server"), "Should contain 'server'
bean");
+ }
+
+ public static class MultipleConfigsProfile implements QuarkusTestProfile {
+ @Override
+ public Map<String, String> getConfigOverrides() {
+ return Map.ofEntries(
+ Map.entry("quarkus.camel.tls-registry.enabled", "true"),
+
Map.entry("quarkus.camel.tls-registry.quarkus-default-as-global", "false"),
+ Map.entry("quarkus.tls.key-store.p12.path",
"target/certs/tls-test-keystore.p12"),
+ Map.entry("quarkus.tls.key-store.p12.password",
"changeit"),
+ Map.entry("quarkus.tls.client.key-store.p12.path",
"target/certs/tls-test-keystore.p12"),
+ Map.entry("quarkus.tls.client.key-store.p12.password",
"changeit"),
+ Map.entry("quarkus.tls.client.trust-all", "true"),
+ Map.entry("quarkus.tls.server.key-store.p12.path",
"target/certs/tls-test-keystore.p12"),
+ Map.entry("quarkus.tls.server.key-store.p12.password",
"changeit"),
+ Map.entry("quarkus.tls.server.trust-all", "true"));
+ }
+ }
+}
diff --git
a/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryTest.java
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryTest.java
new file mode 100644
index 0000000000..b0ad325456
--- /dev/null
+++
b/integration-tests/tls-registry/src/test/java/org/apache/camel/quarkus/core/tls/it/TlsRegistryTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.quarkus.core.tls.it;
+
+import java.util.Map;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.junit.QuarkusTestProfile;
+import io.quarkus.test.junit.TestProfile;
+import io.restassured.RestAssured;
+import io.restassured.common.mapper.TypeRef;
+import io.smallrye.certs.Format;
+import io.smallrye.certs.junit5.Certificate;
+import org.apache.camel.quarkus.test.support.certificate.TestCertificates;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@TestCertificates(certificates = {
+ @Certificate(name = "tls-test", formats = { Format.PKCS12, Format.PEM
}, password = "changeit")
+})
+@QuarkusTest
+@TestProfile(TlsRegistryTest.DefaultNamedConfigProfile.class)
+class TlsRegistryTest {
+
+ @Test
+ void testDefaultNamedBean() {
+ // Verify default TLS config is registered as named bean "default"
+ RestAssured.given()
+ .get("/tls-registry/bean/exists/default")
+ .then()
+ .statusCode(200)
+ .body(is("true"));
+
+ // Verify no global SSL context
+ RestAssured.given()
+ .get("/tls-registry/global-ssl")
+ .then()
+ .statusCode(200)
+ .body(is("false"));
+
+ // Verify beans are registered
+ Map<String, String> beans = RestAssured.given()
+ .get("/tls-registry/beans")
+ .then()
+ .statusCode(200)
+ .extract().as(new TypeRef<Map<String, String>>() {
+ });
+
+ assertTrue(beans.containsKey("default"), "Should contain 'default'
bean");
+ assertEquals(1, beans.size(), "Should have exactly 1 SSL bean");
+ }
+
+ public static class DefaultNamedConfigProfile implements
QuarkusTestProfile {
+ @Override
+ public Map<String, String> getConfigOverrides() {
+ return Map.of(
+ "quarkus.camel.tls-registry.enabled", "true",
+ "quarkus.camel.tls-registry.quarkus-default-as-global",
"false",
+ "quarkus.camel.tls-registry.default-bean-name", "default",
+ "quarkus.tls.key-store.p12.path",
"target/certs/tls-test-keystore.p12",
+ "quarkus.tls.key-store.p12.password", "changeit");
+ }
+ }
+}
diff --git a/io/quarkus/tls/TlsConfigurationRegistry.class
b/io/quarkus/tls/TlsConfigurationRegistry.class
new file mode 100644
index 0000000000..43301c4d07
Binary files /dev/null and b/io/quarkus/tls/TlsConfigurationRegistry.class
differ
diff --git a/poms/bom/pom.xml b/poms/bom/pom.xml
index b16e87dd10..c34f011909 100644
--- a/poms/bom/pom.xml
+++ b/poms/bom/pom.xml
@@ -6800,6 +6800,16 @@
<artifactId>camel-quarkus-timer-deployment</artifactId>
<version>${camel-quarkus.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-tls-registry</artifactId>
+ <version>${camel-quarkus.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-tls-registry-deployment</artifactId>
+ <version>${camel-quarkus.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-twilio</artifactId>
diff --git a/poms/bom/src/main/generated/flattened-full-pom.xml
b/poms/bom/src/main/generated/flattened-full-pom.xml
index 6a2b61bda0..e1488ea697 100644
--- a/poms/bom/src/main/generated/flattened-full-pom.xml
+++ b/poms/bom/src/main/generated/flattened-full-pom.xml
@@ -6685,6 +6685,16 @@
<artifactId>camel-quarkus-timer-deployment</artifactId><!--
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
<version>3.36.0-SNAPSHOT</version><!--
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
</dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId><!--
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <artifactId>camel-quarkus-tls-registry</artifactId><!--
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <version>3.36.0-SNAPSHOT</version><!--
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId><!--
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <artifactId>camel-quarkus-tls-registry-deployment</artifactId><!--
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <version>3.36.0-SNAPSHOT</version><!--
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId><!--
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
<artifactId>camel-quarkus-twilio</artifactId><!--
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
diff --git a/poms/bom/src/main/generated/flattened-reduced-pom.xml
b/poms/bom/src/main/generated/flattened-reduced-pom.xml
index 6279b8e5e4..f3961f27ce 100644
--- a/poms/bom/src/main/generated/flattened-reduced-pom.xml
+++ b/poms/bom/src/main/generated/flattened-reduced-pom.xml
@@ -6664,6 +6664,16 @@
<artifactId>camel-quarkus-timer-deployment</artifactId>
<version>3.36.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-tls-registry</artifactId>
+ <version>3.36.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-tls-registry-deployment</artifactId>
+ <version>3.36.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-twilio</artifactId>
diff --git a/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml
b/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml
index 338262a6a3..36535c5ab8 100644
--- a/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml
+++ b/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml
@@ -6664,6 +6664,16 @@
<artifactId>camel-quarkus-timer-deployment</artifactId><!--
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
<version>3.36.0-SNAPSHOT</version><!--
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
</dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId><!--
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <artifactId>camel-quarkus-tls-registry</artifactId><!--
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <version>3.36.0-SNAPSHOT</version><!--
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId><!--
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <artifactId>camel-quarkus-tls-registry-deployment</artifactId><!--
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <version>3.36.0-SNAPSHOT</version><!--
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId><!--
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
<artifactId>camel-quarkus-twilio</artifactId><!--
org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
diff --git a/tooling/scripts/test-categories.yaml
b/tooling/scripts/test-categories.yaml
index c228da4da2..b8d45da965 100644
--- a/tooling/scripts/test-categories.yaml
+++ b/tooling/scripts/test-categories.yaml
@@ -201,6 +201,7 @@ group-10:
- platform-http-proxy-ssl
- solr
- swift
+ - tls-registry
- weaviate
group-11:
- compression-grouped