This is an automated email from the ASF dual-hosted git repository. oscerd pushed a commit to branch fix/CAMEL-23444 in repository https://gitbox.apache.org/repos/asf/camel.git
commit 4dd7652e38985129073450cf7748273736f7e33b Author: Andrea Cosentino <[email protected]> AuthorDate: Thu Jun 11 13:00:17 2026 +0200 CAMEL-23444: camel-elasticsearch - Add SSLContextParameters support for TLS configuration Add SSLContextParameters support to camel-elasticsearch so TLS can be configured with fine-grained control (named groups, signature schemes, cipher suites and protocols), e.g. post-quantum named groups such as X25519MLKEM768 on JDK 25+. ElasticsearchComponent now implements SSLContextParametersAware with a global SSLContextParameters fallback, and ElasticsearchProducer builds the SSLContext from SSLContextParameters when configured, keeping the existing certificatePath (CA-only) path as a fallback. Mirrors CAMEL-23314 (camel-opensearch). The HTTP client configuration callback is now always applied (previously it was only set when basic-auth credentials were present), so the TLS configuration is honored regardless of whether credentials are set. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Signed-off-by: Andrea Cosentino <[email protected]> --- .../camel/catalog/components/elasticsearch.json | 7 +- .../es/ElasticsearchComponentConfigurer.java | 12 +++ .../es/ElasticsearchEndpointConfigurer.java | 6 ++ .../es/ElasticsearchEndpointUriFactory.java | 3 +- .../apache/camel/component/es/elasticsearch.json | 7 +- .../camel/component/es/ElasticsearchComponent.java | 37 +++++++- .../component/es/ElasticsearchConfiguration.java | 16 ++++ .../camel/component/es/ElasticsearchProducer.java | 29 ++++-- .../es/ElasticsearchSslContextParametersTest.java | 104 +++++++++++++++++++++ .../dsl/ElasticsearchComponentBuilderFactory.java | 36 +++++++ .../dsl/ElasticsearchEndpointBuilderFactory.java | 36 +++++++ 11 files changed, 277 insertions(+), 16 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/elasticsearch.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/elasticsearch.json index 1d6b698ce6b2..0477c8b7ca2e 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/elasticsearch.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/elasticsearch.json @@ -38,7 +38,9 @@ "certificatePath": { "index": 11, "kind": "property", "displayName": "Certificate Path", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The path of the self-signed certificate to use to access to Elasticsearch." }, "enableSSL": { "index": 12, "kind": "property", "displayName": "Enable SSL", "group": "security", "label": "security", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Enable SSL" }, "password": { "index": 13, "kind": "property", "displayName": "Password", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "security": "secret", "description": "Password for authenticating" }, - "user": { "index": 14, "kind": "property", "displayName": "User", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "security": "secret", "description": "Basic authenticate user" } + "sslContextParameters": { "index": 14, "kind": "property", "displayName": "Ssl Context Parameters", "group": "security", "label": "security", "required": false, "type": "object", "javaType": "org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, "autowired": false, "secret": false, "description": "To configure security using SSLContextParameters. When configured, this takes precedence over the certificatePath option." }, + "useGlobalSslContextParameters": { "index": 15, "kind": "property", "displayName": "Use Global Ssl Context Parameters", "group": "security", "label": "security", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Enable usage of global SSL context parameters." }, + "user": { "index": 16, "kind": "property", "displayName": "User", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "security": "secret", "description": "Basic authenticate user" } }, "headers": { "CamelElasticsearchOperation": { "index": 0, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "org.apache.camel.component.es.ElasticsearchOperation", "enum": [ "Index", "Update", "Bulk", "GetById", "MultiGet", "MultiSearch", "Delete", "DeleteIndex", "Search", "Exists", "Ping" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The operation to perform", "constantName": "org.apache.cam [...] @@ -73,6 +75,7 @@ "sniffAfterFailureDelay": { "index": 17, "kind": "parameter", "displayName": "Sniff After Failure Delay", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 60000, "configurationClass": "org.apache.camel.component.es.ElasticsearchConfiguration", "configurationField": "configuration", "description": "The delay of a sniff execution scheduled after a failure (in mill [...] "snifferInterval": { "index": 18, "kind": "parameter", "displayName": "Sniffer Interval", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 300000, "configurationClass": "org.apache.camel.component.es.ElasticsearchConfiguration", "configurationField": "configuration", "description": "The interval between consecutive ordinary sniff executions in milliseconds. Will [...] "certificatePath": { "index": 19, "kind": "parameter", "displayName": "Certificate Path", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "supportFileReference": true, "configurationClass": "org.apache.camel.component.es.ElasticsearchConfiguration", "configurationField": "configuration", "description": "The certificate that can be used to acc [...] - "enableSSL": { "index": 20, "kind": "parameter", "displayName": "Enable SSL", "group": "security", "label": "security", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.es.ElasticsearchConfiguration", "configurationField": "configuration", "description": "Enable SSL" } + "enableSSL": { "index": 20, "kind": "parameter", "displayName": "Enable SSL", "group": "security", "label": "security", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.es.ElasticsearchConfiguration", "configurationField": "configuration", "description": "Enable SSL" }, + "sslContextParameters": { "index": 21, "kind": "parameter", "displayName": "Ssl Context Parameters", "group": "security", "label": "security", "required": false, "type": "object", "javaType": "org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.es.ElasticsearchConfiguration", "configurationField": "configuration", "description": "To configure security using SSLContextParameter [...] } } diff --git a/components/camel-elasticsearch/src/generated/java/org/apache/camel/component/es/ElasticsearchComponentConfigurer.java b/components/camel-elasticsearch/src/generated/java/org/apache/camel/component/es/ElasticsearchComponentConfigurer.java index 2a6d4fce7b34..49bcfbc94bf7 100644 --- a/components/camel-elasticsearch/src/generated/java/org/apache/camel/component/es/ElasticsearchComponentConfigurer.java +++ b/components/camel-elasticsearch/src/generated/java/org/apache/camel/component/es/ElasticsearchComponentConfigurer.java @@ -49,6 +49,10 @@ public class ElasticsearchComponentConfigurer extends PropertyConfigurerSupport case "snifferInterval": target.setSnifferInterval(property(camelContext, int.class, value)); return true; case "sockettimeout": case "socketTimeout": target.setSocketTimeout(property(camelContext, int.class, value)); return true; + case "sslcontextparameters": + case "sslContextParameters": target.setSslContextParameters(property(camelContext, org.apache.camel.support.jsse.SSLContextParameters.class, value)); return true; + case "useglobalsslcontextparameters": + case "useGlobalSslContextParameters": target.setUseGlobalSslContextParameters(property(camelContext, boolean.class, value)); return true; case "user": target.setUser(property(camelContext, java.lang.String.class, value)); return true; default: return false; } @@ -88,6 +92,10 @@ public class ElasticsearchComponentConfigurer extends PropertyConfigurerSupport case "snifferInterval": return int.class; case "sockettimeout": case "socketTimeout": return int.class; + case "sslcontextparameters": + case "sslContextParameters": return org.apache.camel.support.jsse.SSLContextParameters.class; + case "useglobalsslcontextparameters": + case "useGlobalSslContextParameters": return boolean.class; case "user": return java.lang.String.class; default: return null; } @@ -123,6 +131,10 @@ public class ElasticsearchComponentConfigurer extends PropertyConfigurerSupport case "snifferInterval": return target.getSnifferInterval(); case "sockettimeout": case "socketTimeout": return target.getSocketTimeout(); + case "sslcontextparameters": + case "sslContextParameters": return target.getSslContextParameters(); + case "useglobalsslcontextparameters": + case "useGlobalSslContextParameters": return target.isUseGlobalSslContextParameters(); case "user": return target.getUser(); default: return null; } diff --git a/components/camel-elasticsearch/src/generated/java/org/apache/camel/component/es/ElasticsearchEndpointConfigurer.java b/components/camel-elasticsearch/src/generated/java/org/apache/camel/component/es/ElasticsearchEndpointConfigurer.java index 9d97d6641d68..653af95fe896 100644 --- a/components/camel-elasticsearch/src/generated/java/org/apache/camel/component/es/ElasticsearchEndpointConfigurer.java +++ b/components/camel-elasticsearch/src/generated/java/org/apache/camel/component/es/ElasticsearchEndpointConfigurer.java @@ -55,6 +55,8 @@ public class ElasticsearchEndpointConfigurer extends PropertyConfigurerSupport i case "snifferInterval": target.getConfiguration().setSnifferInterval(property(camelContext, int.class, value)); return true; case "sockettimeout": case "socketTimeout": target.getConfiguration().setSocketTimeout(property(camelContext, int.class, value)); return true; + case "sslcontextparameters": + case "sslContextParameters": target.getConfiguration().setSslContextParameters(property(camelContext, org.apache.camel.support.jsse.SSLContextParameters.class, value)); return true; case "usescroll": case "useScroll": target.getConfiguration().setUseScroll(property(camelContext, boolean.class, value)); return true; case "waitforactiveshards": @@ -98,6 +100,8 @@ public class ElasticsearchEndpointConfigurer extends PropertyConfigurerSupport i case "snifferInterval": return int.class; case "sockettimeout": case "socketTimeout": return int.class; + case "sslcontextparameters": + case "sslContextParameters": return org.apache.camel.support.jsse.SSLContextParameters.class; case "usescroll": case "useScroll": return boolean.class; case "waitforactiveshards": @@ -142,6 +146,8 @@ public class ElasticsearchEndpointConfigurer extends PropertyConfigurerSupport i case "snifferInterval": return target.getConfiguration().getSnifferInterval(); case "sockettimeout": case "socketTimeout": return target.getConfiguration().getSocketTimeout(); + case "sslcontextparameters": + case "sslContextParameters": return target.getConfiguration().getSslContextParameters(); case "usescroll": case "useScroll": return target.getConfiguration().isUseScroll(); case "waitforactiveshards": diff --git a/components/camel-elasticsearch/src/generated/java/org/apache/camel/component/es/ElasticsearchEndpointUriFactory.java b/components/camel-elasticsearch/src/generated/java/org/apache/camel/component/es/ElasticsearchEndpointUriFactory.java index e19c1c94d73f..3af6a0919595 100644 --- a/components/camel-elasticsearch/src/generated/java/org/apache/camel/component/es/ElasticsearchEndpointUriFactory.java +++ b/components/camel-elasticsearch/src/generated/java/org/apache/camel/component/es/ElasticsearchEndpointUriFactory.java @@ -24,7 +24,7 @@ public class ElasticsearchEndpointUriFactory extends org.apache.camel.support.co private static final Set<String> ENDPOINT_IDENTITY_PROPERTY_NAMES; private static final Map<String, String> MULTI_VALUE_PREFIXES; static { - Set<String> props = new HashSet<>(21); + Set<String> props = new HashSet<>(22); props.add("certificatePath"); props.add("clusterName"); props.add("connectionTimeout"); @@ -44,6 +44,7 @@ public class ElasticsearchEndpointUriFactory extends org.apache.camel.support.co props.add("sniffAfterFailureDelay"); props.add("snifferInterval"); props.add("socketTimeout"); + props.add("sslContextParameters"); props.add("useScroll"); props.add("waitForActiveShards"); PROPERTY_NAMES = Collections.unmodifiableSet(props); diff --git a/components/camel-elasticsearch/src/generated/resources/META-INF/org/apache/camel/component/es/elasticsearch.json b/components/camel-elasticsearch/src/generated/resources/META-INF/org/apache/camel/component/es/elasticsearch.json index 1d6b698ce6b2..0477c8b7ca2e 100644 --- a/components/camel-elasticsearch/src/generated/resources/META-INF/org/apache/camel/component/es/elasticsearch.json +++ b/components/camel-elasticsearch/src/generated/resources/META-INF/org/apache/camel/component/es/elasticsearch.json @@ -38,7 +38,9 @@ "certificatePath": { "index": 11, "kind": "property", "displayName": "Certificate Path", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The path of the self-signed certificate to use to access to Elasticsearch." }, "enableSSL": { "index": 12, "kind": "property", "displayName": "Enable SSL", "group": "security", "label": "security", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Enable SSL" }, "password": { "index": 13, "kind": "property", "displayName": "Password", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "security": "secret", "description": "Password for authenticating" }, - "user": { "index": 14, "kind": "property", "displayName": "User", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "security": "secret", "description": "Basic authenticate user" } + "sslContextParameters": { "index": 14, "kind": "property", "displayName": "Ssl Context Parameters", "group": "security", "label": "security", "required": false, "type": "object", "javaType": "org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, "autowired": false, "secret": false, "description": "To configure security using SSLContextParameters. When configured, this takes precedence over the certificatePath option." }, + "useGlobalSslContextParameters": { "index": 15, "kind": "property", "displayName": "Use Global Ssl Context Parameters", "group": "security", "label": "security", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Enable usage of global SSL context parameters." }, + "user": { "index": 16, "kind": "property", "displayName": "User", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "security": "secret", "description": "Basic authenticate user" } }, "headers": { "CamelElasticsearchOperation": { "index": 0, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "org.apache.camel.component.es.ElasticsearchOperation", "enum": [ "Index", "Update", "Bulk", "GetById", "MultiGet", "MultiSearch", "Delete", "DeleteIndex", "Search", "Exists", "Ping" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The operation to perform", "constantName": "org.apache.cam [...] @@ -73,6 +75,7 @@ "sniffAfterFailureDelay": { "index": 17, "kind": "parameter", "displayName": "Sniff After Failure Delay", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 60000, "configurationClass": "org.apache.camel.component.es.ElasticsearchConfiguration", "configurationField": "configuration", "description": "The delay of a sniff execution scheduled after a failure (in mill [...] "snifferInterval": { "index": 18, "kind": "parameter", "displayName": "Sniffer Interval", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 300000, "configurationClass": "org.apache.camel.component.es.ElasticsearchConfiguration", "configurationField": "configuration", "description": "The interval between consecutive ordinary sniff executions in milliseconds. Will [...] "certificatePath": { "index": 19, "kind": "parameter", "displayName": "Certificate Path", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "supportFileReference": true, "configurationClass": "org.apache.camel.component.es.ElasticsearchConfiguration", "configurationField": "configuration", "description": "The certificate that can be used to acc [...] - "enableSSL": { "index": 20, "kind": "parameter", "displayName": "Enable SSL", "group": "security", "label": "security", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.es.ElasticsearchConfiguration", "configurationField": "configuration", "description": "Enable SSL" } + "enableSSL": { "index": 20, "kind": "parameter", "displayName": "Enable SSL", "group": "security", "label": "security", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.es.ElasticsearchConfiguration", "configurationField": "configuration", "description": "Enable SSL" }, + "sslContextParameters": { "index": 21, "kind": "parameter", "displayName": "Ssl Context Parameters", "group": "security", "label": "security", "required": false, "type": "object", "javaType": "org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.es.ElasticsearchConfiguration", "configurationField": "configuration", "description": "To configure security using SSLContextParameter [...] } } diff --git a/components/camel-elasticsearch/src/main/java/org/apache/camel/component/es/ElasticsearchComponent.java b/components/camel-elasticsearch/src/main/java/org/apache/camel/component/es/ElasticsearchComponent.java index 1e2d7cf922d7..d117eba6e9d6 100644 --- a/components/camel-elasticsearch/src/main/java/org/apache/camel/component/es/ElasticsearchComponent.java +++ b/components/camel-elasticsearch/src/main/java/org/apache/camel/component/es/ElasticsearchComponent.java @@ -23,9 +23,11 @@ import java.util.Map; import org.apache.camel.CamelContext; import org.apache.camel.Endpoint; +import org.apache.camel.SSLContextParametersAware; import org.apache.camel.spi.Metadata; import org.apache.camel.spi.annotations.Component; import org.apache.camel.support.DefaultComponent; +import org.apache.camel.support.jsse.SSLContextParameters; import org.apache.http.HttpHost; import org.elasticsearch.client.RestClient; @@ -33,7 +35,7 @@ import org.elasticsearch.client.RestClient; * Represents the component that manages {@link ElasticsearchEndpoint}. */ @Component("elasticsearch") -public class ElasticsearchComponent extends DefaultComponent { +public class ElasticsearchComponent extends DefaultComponent implements SSLContextParametersAware { @Metadata(label = "advanced", autowired = true) private RestClient client; @@ -55,6 +57,10 @@ public class ElasticsearchComponent extends DefaultComponent { private boolean enableSSL; @Metadata(label = "security") private String certificatePath; + @Metadata(label = "security") + private SSLContextParameters sslContextParameters; + @Metadata(label = "security", defaultValue = "false") + private boolean useGlobalSslContextParameters; @Metadata(label = "advanced") private boolean enableSniffer; @Metadata(label = "advanced", defaultValue = "" + ElasticsearchConstants.DEFAULT_SNIFFER_INTERVAL) @@ -81,6 +87,7 @@ public class ElasticsearchComponent extends DefaultComponent { config.setEnableSSL(this.isEnableSSL()); config.setPassword(this.getPassword()); config.setCertificatePath(this.getCertificatePath()); + config.setSslContextParameters(this.getSslContextParameters()); config.setEnableSniffer(this.isEnableSniffer()); config.setSnifferInterval(this.getSnifferInterval()); config.setSniffAfterFailureDelay(this.getSniffAfterFailureDelay()); @@ -89,6 +96,9 @@ public class ElasticsearchComponent extends DefaultComponent { Endpoint endpoint = new ElasticsearchEndpoint(uri, this, config, client); setProperties(endpoint, parameters); + if (config.getSslContextParameters() == null) { + config.setSslContextParameters(retrieveGlobalSslContextParameters()); + } config.setHostAddressesList(parseHostAddresses(config.getHostAddresses(), config)); return endpoint; @@ -265,4 +275,29 @@ public class ElasticsearchComponent extends DefaultComponent { this.sniffAfterFailureDelay = sniffAfterFailureDelay; } + public SSLContextParameters getSslContextParameters() { + return sslContextParameters; + } + + /** + * To configure security using SSLContextParameters. When configured, this takes precedence over the + * {@code certificatePath} option. + */ + public void setSslContextParameters(SSLContextParameters sslContextParameters) { + this.sslContextParameters = sslContextParameters; + } + + @Override + public boolean isUseGlobalSslContextParameters() { + return useGlobalSslContextParameters; + } + + /** + * Enable usage of global SSL context parameters. + */ + @Override + public void setUseGlobalSslContextParameters(boolean useGlobalSslContextParameters) { + this.useGlobalSslContextParameters = useGlobalSslContextParameters; + } + } diff --git a/components/camel-elasticsearch/src/main/java/org/apache/camel/component/es/ElasticsearchConfiguration.java b/components/camel-elasticsearch/src/main/java/org/apache/camel/component/es/ElasticsearchConfiguration.java index d08309282cdf..f2849896ca4e 100644 --- a/components/camel-elasticsearch/src/main/java/org/apache/camel/component/es/ElasticsearchConfiguration.java +++ b/components/camel-elasticsearch/src/main/java/org/apache/camel/component/es/ElasticsearchConfiguration.java @@ -23,6 +23,7 @@ import org.apache.camel.spi.Metadata; import org.apache.camel.spi.UriParam; import org.apache.camel.spi.UriParams; import org.apache.camel.spi.UriPath; +import org.apache.camel.support.jsse.SSLContextParameters; import org.apache.http.HttpHost; @UriParams @@ -62,6 +63,8 @@ public class ElasticsearchConfiguration { @UriParam(label = "security") @Metadata(supportFileReference = true) private String certificatePath; + @UriParam(label = "security") + private SSLContextParameters sslContextParameters; @UriParam private boolean useScroll; @UriParam(defaultValue = "" + ElasticsearchConstants.DEFAULT_SCROLL_KEEP_ALIVE_MS) @@ -227,6 +230,19 @@ public class ElasticsearchConfiguration { this.certificatePath = certificatePath; } + public SSLContextParameters getSslContextParameters() { + return sslContextParameters; + } + + /** + * To configure security using SSLContextParameters. When configured, this takes precedence over the + * {@code certificatePath} option. This allows configuring named groups, signature schemes, cipher suites, and + * protocols for the TLS connection. + */ + public void setSslContextParameters(SSLContextParameters sslContextParameters) { + this.sslContextParameters = sslContextParameters; + } + /** * The time in ms before retry */ diff --git a/components/camel-elasticsearch/src/main/java/org/apache/camel/component/es/ElasticsearchProducer.java b/components/camel-elasticsearch/src/main/java/org/apache/camel/component/es/ElasticsearchProducer.java index 0e57044b94f5..ed43d1a8da1c 100644 --- a/components/camel-elasticsearch/src/main/java/org/apache/camel/component/es/ElasticsearchProducer.java +++ b/components/camel-elasticsearch/src/main/java/org/apache/camel/component/es/ElasticsearchProducer.java @@ -501,18 +501,27 @@ class ElasticsearchProducer extends DefaultAsyncProducer { builder.setRequestConfigCallback(requestConfigBuilder -> requestConfigBuilder .setConnectTimeout(configuration.getConnectionTimeout()).setSocketTimeout(configuration.getSocketTimeout())); - if (configuration.getUser() != null && configuration.getPassword() != null) { - final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); - credentialsProvider.setCredentials(AuthScope.ANY, - new UsernamePasswordCredentials(configuration.getUser(), configuration.getPassword())); - builder.setHttpClientConfigCallback(httpClientBuilder -> { + builder.setHttpClientConfigCallback(httpClientBuilder -> { + if (configuration.getUser() != null && configuration.getPassword() != null) { + final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); + credentialsProvider.setCredentials(AuthScope.ANY, + new UsernamePasswordCredentials(configuration.getUser(), configuration.getPassword())); httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider); - if (configuration.getCertificatePath() != null) { - httpClientBuilder.setSSLContext(createSslContextFromCa()); + } + if (configuration.getSslContextParameters() != null) { + // Use SSLContextParameters (allows configuring named groups, signature schemes, cipher suites and + // protocols), e.g. for post-quantum readiness on JDK 25+ + try { + httpClientBuilder.setSSLContext( + configuration.getSslContextParameters().createSSLContext(getEndpoint().getCamelContext())); + } catch (Exception e) { + throw new RuntimeException("Failed to create SSLContext from SSLContextParameters", e); } - return httpClientBuilder; - }); - } + } else if (configuration.getCertificatePath() != null) { + httpClientBuilder.setSSLContext(createSslContextFromCa()); + } + return httpClientBuilder; + }); final RestClient restClient = builder.build(); if (configuration.isEnableSniffer()) { SnifferBuilder snifferBuilder = Sniffer.builder(restClient); diff --git a/components/camel-elasticsearch/src/test/java/org/apache/camel/component/es/ElasticsearchSslContextParametersTest.java b/components/camel-elasticsearch/src/test/java/org/apache/camel/component/es/ElasticsearchSslContextParametersTest.java new file mode 100644 index 000000000000..268d4c466b9e --- /dev/null +++ b/components/camel-elasticsearch/src/test/java/org/apache/camel/component/es/ElasticsearchSslContextParametersTest.java @@ -0,0 +1,104 @@ +/* + * 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.component.es; + +import org.apache.camel.CamelContext; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.support.jsse.SSLContextParameters; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class ElasticsearchSslContextParametersTest { + + @Test + public void configurationPropertyRoundTrip() { + ElasticsearchConfiguration configuration = new ElasticsearchConfiguration(); + assertNull(configuration.getSslContextParameters(), + "SSLContextParameters should be null by default"); + + SSLContextParameters sslContextParameters = new SSLContextParameters(); + configuration.setSslContextParameters(sslContextParameters); + assertSame(sslContextParameters, configuration.getSslContextParameters(), + "Getter should return the value set via setter"); + } + + @Test + public void componentPropagatesSslContextParametersToEndpoint() throws Exception { + try (CamelContext context = new DefaultCamelContext()) { + context.start(); + + SSLContextParameters sslContextParameters = new SSLContextParameters(); + ElasticsearchComponent component = new ElasticsearchComponent(context); + component.setHostAddresses("localhost:9200"); + component.setSslContextParameters(sslContextParameters); + context.addComponent("elasticsearch", component); + + ElasticsearchEndpoint endpoint + = context.getEndpoint("elasticsearch:test-cluster?enableSSL=true", ElasticsearchEndpoint.class); + assertNotNull(endpoint); + assertSame(sslContextParameters, endpoint.getConfiguration().getSslContextParameters(), + "Component-level SSLContextParameters must propagate to the endpoint configuration"); + } + } + + @Test + public void endpointUsesGlobalSslContextParametersWhenEnabled() throws Exception { + try (CamelContext context = new DefaultCamelContext()) { + SSLContextParameters globalParameters = new SSLContextParameters(); + context.setSSLContextParameters(globalParameters); + context.start(); + + ElasticsearchComponent component = new ElasticsearchComponent(context); + component.setHostAddresses("localhost:9200"); + component.setUseGlobalSslContextParameters(true); + context.addComponent("elasticsearch", component); + + ElasticsearchEndpoint endpoint + = context.getEndpoint("elasticsearch:test-cluster?enableSSL=true", ElasticsearchEndpoint.class); + assertNotNull(endpoint); + assertTrue(component.isUseGlobalSslContextParameters()); + assertSame(globalParameters, endpoint.getConfiguration().getSslContextParameters(), + "Global SSLContextParameters must be used when useGlobalSslContextParameters is true"); + } + } + + @Test + public void explicitSslContextParametersWinOverGlobal() throws Exception { + try (CamelContext context = new DefaultCamelContext()) { + SSLContextParameters globalParameters = new SSLContextParameters(); + context.setSSLContextParameters(globalParameters); + context.start(); + + SSLContextParameters explicitParameters = new SSLContextParameters(); + ElasticsearchComponent component = new ElasticsearchComponent(context); + component.setHostAddresses("localhost:9200"); + component.setUseGlobalSslContextParameters(true); + component.setSslContextParameters(explicitParameters); + context.addComponent("elasticsearch", component); + + ElasticsearchEndpoint endpoint + = context.getEndpoint("elasticsearch:test-cluster?enableSSL=true", ElasticsearchEndpoint.class); + assertNotNull(endpoint); + assertSame(explicitParameters, endpoint.getConfiguration().getSslContextParameters(), + "Component-level SSLContextParameters must win over the global one"); + } + } +} diff --git a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/ElasticsearchComponentBuilderFactory.java b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/ElasticsearchComponentBuilderFactory.java index eb4255b95652..591068cf1d4d 100644 --- a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/ElasticsearchComponentBuilderFactory.java +++ b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/ElasticsearchComponentBuilderFactory.java @@ -308,6 +308,40 @@ public interface ElasticsearchComponentBuilderFactory { return this; } + /** + * To configure security using SSLContextParameters. When configured, + * this takes precedence over the certificatePath option. + * + * The option is a: + * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type. + * + * Group: security + * + * @param sslContextParameters the value to set + * @return the dsl builder + */ + default ElasticsearchComponentBuilder sslContextParameters(org.apache.camel.support.jsse.SSLContextParameters sslContextParameters) { + doSetProperty("sslContextParameters", sslContextParameters); + return this; + } + + + /** + * Enable usage of global SSL context parameters. + * + * The option is a: <code>boolean</code> type. + * + * Default: false + * Group: security + * + * @param useGlobalSslContextParameters the value to set + * @return the dsl builder + */ + default ElasticsearchComponentBuilder useGlobalSslContextParameters(boolean useGlobalSslContextParameters) { + doSetProperty("useGlobalSslContextParameters", useGlobalSslContextParameters); + return this; + } + /** * Basic authenticate user. * @@ -351,6 +385,8 @@ public interface ElasticsearchComponentBuilderFactory { case "certificatePath": ((ElasticsearchComponent) component).setCertificatePath((java.lang.String) value); return true; case "enableSSL": ((ElasticsearchComponent) component).setEnableSSL((boolean) value); return true; case "password": ((ElasticsearchComponent) component).setPassword((java.lang.String) value); return true; + case "sslContextParameters": ((ElasticsearchComponent) component).setSslContextParameters((org.apache.camel.support.jsse.SSLContextParameters) value); return true; + case "useGlobalSslContextParameters": ((ElasticsearchComponent) component).setUseGlobalSslContextParameters((boolean) value); return true; case "user": ((ElasticsearchComponent) component).setUser((java.lang.String) value); return true; default: return false; } diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/ElasticsearchEndpointBuilderFactory.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/ElasticsearchEndpointBuilderFactory.java index a4fc5ae1f108..e9d56c38d199 100644 --- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/ElasticsearchEndpointBuilderFactory.java +++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/ElasticsearchEndpointBuilderFactory.java @@ -460,6 +460,42 @@ public interface ElasticsearchEndpointBuilderFactory { doSetProperty("enableSSL", enableSSL); return this; } + /** + * To configure security using SSLContextParameters. When configured, + * this takes precedence over the certificatePath option. This allows + * configuring named groups, signature schemes, cipher suites, and + * protocols for the TLS connection. + * + * The option is a: + * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type. + * + * Group: security + * + * @param sslContextParameters the value to set + * @return the dsl builder + */ + default ElasticsearchEndpointBuilder sslContextParameters(org.apache.camel.support.jsse.SSLContextParameters sslContextParameters) { + doSetProperty("sslContextParameters", sslContextParameters); + return this; + } + /** + * To configure security using SSLContextParameters. When configured, + * this takes precedence over the certificatePath option. This allows + * configuring named groups, signature schemes, cipher suites, and + * protocols for the TLS connection. + * + * The option will be converted to a + * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type. + * + * Group: security + * + * @param sslContextParameters the value to set + * @return the dsl builder + */ + default ElasticsearchEndpointBuilder sslContextParameters(String sslContextParameters) { + doSetProperty("sslContextParameters", sslContextParameters); + return this; + } } /**
