This is an automated email from the ASF dual-hosted git repository. gnodet pushed a commit to branch shadowed-house in repository https://gitbox.apache.org/repos/asf/camel.git
commit 18206b543a2d6d04b2e4e4755d26e55bc585c107 Author: Guillaume Nodet <[email protected]> AuthorDate: Mon Mar 23 21:49:11 2026 +0100 CAMEL-21095: Make it easier to configure SSL using XML and YAML DSL Co-Authored-By: Claude Opus 4.6 <[email protected]> --- .../META-INF/org/apache/camel/model/app/beans.json | 15 +- .../META-INF/org/apache/camel/model/app/camel.json | 15 +- .../camel/model/app/sslContextParameters.json | 42 ++ .../org/apache/camel/model/app/jaxb.index | 1 + .../apache/camel/model/app/BeansDefinition.java | 15 + .../model/app/SSLContextParametersDefinition.java | 578 +++++++++++++++++++++ .../java/org/apache/camel/xml/in/ModelParser.java | 32 ++ .../java/org/apache/camel/xml/out/ModelWriter.java | 34 ++ .../camel/dsl/xml/io/XmlRoutesBuilderLoader.java | 15 + .../apache/camel/dsl/xml/io/XmlLoadAppTest.java | 37 ++ .../org/apache/camel/dsl/xml/io/camel-app-ssl.xml | 28 + .../dsl/yaml/deserializers/ModelDeserializers.java | 187 +++++++ .../deserializers/ModelDeserializersResolver.java | 2 + .../generated/resources/schema/camelYamlDsl.json | 85 +++ .../camel/dsl/yaml/YamlRoutesBuilderLoader.java | 12 + .../camel/dsl/yaml/SSLContextParametersTest.groovy | 82 +++ 16 files changed, 1166 insertions(+), 14 deletions(-) diff --git a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/app/beans.json b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/app/beans.json index 142431336a46..1d4dc96e4082 100644 --- a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/app/beans.json +++ b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/app/beans.json @@ -14,12 +14,13 @@ "properties": { "component-scan": { "index": 0, "kind": "element", "displayName": "Component-scan", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.app.ComponentScanDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Component scanning that can auto-discover Camel route builders from the classpath." }, "bean": { "index": 1, "kind": "element", "displayName": "Bean", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.BeanFactoryDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "List of bean" }, - "dataFormat": { "index": 2, "kind": "element", "displayName": "Data Format", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.DataFormatDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel data formats" }, - "restConfiguration": { "index": 3, "kind": "element", "displayName": "Rest Configuration", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestConfigurationDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel Rest DSL Configuration" }, - "rest": { "index": 4, "kind": "element", "displayName": "Rest", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel Rest DSL" }, - "routeConfiguration": { "index": 5, "kind": "element", "displayName": "Route Configuration", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.RouteConfigurationDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel route configurations" }, - "routeTemplate": { "index": 6, "kind": "element", "displayName": "Route Template", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.RouteTemplateDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel route templates" }, - "templatedRoute": { "index": 7, "kind": "element", "displayName": "Templated Route", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.TemplatedRouteDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel routes to be created from template" }, - "route": { "index": 8, "kind": "element", "displayName": "Route", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.RouteDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel routes" } + "sslContextParameters": { "index": 2, "kind": "element", "displayName": "Ssl Context Parameters", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.app.SSLContextParametersDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "SSL\/TLS context parameters configuration" }, + "dataFormat": { "index": 3, "kind": "element", "displayName": "Data Format", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.DataFormatDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel data formats" }, + "restConfiguration": { "index": 4, "kind": "element", "displayName": "Rest Configuration", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestConfigurationDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel Rest DSL Configuration" }, + "rest": { "index": 5, "kind": "element", "displayName": "Rest", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel Rest DSL" }, + "routeConfiguration": { "index": 6, "kind": "element", "displayName": "Route Configuration", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.RouteConfigurationDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel route configurations" }, + "routeTemplate": { "index": 7, "kind": "element", "displayName": "Route Template", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.RouteTemplateDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel route templates" }, + "templatedRoute": { "index": 8, "kind": "element", "displayName": "Templated Route", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.TemplatedRouteDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel routes to be created from template" }, + "route": { "index": 9, "kind": "element", "displayName": "Route", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.RouteDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel routes" } } } diff --git a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/app/camel.json b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/app/camel.json index 6d14ff17da6c..6beef4da1fb7 100644 --- a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/app/camel.json +++ b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/app/camel.json @@ -14,12 +14,13 @@ "properties": { "component-scan": { "index": 0, "kind": "element", "displayName": "Component-scan", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.app.ComponentScanDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Component scanning that can auto-discover Camel route builders from the classpath." }, "bean": { "index": 1, "kind": "element", "displayName": "Bean", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.BeanFactoryDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "List of bean" }, - "dataFormat": { "index": 2, "kind": "element", "displayName": "Data Format", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.DataFormatDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel data formats" }, - "restConfiguration": { "index": 3, "kind": "element", "displayName": "Rest Configuration", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestConfigurationDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel Rest DSL Configuration" }, - "rest": { "index": 4, "kind": "element", "displayName": "Rest", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel Rest DSL" }, - "routeConfiguration": { "index": 5, "kind": "element", "displayName": "Route Configuration", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.RouteConfigurationDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel route configurations" }, - "routeTemplate": { "index": 6, "kind": "element", "displayName": "Route Template", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.RouteTemplateDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel route templates" }, - "templatedRoute": { "index": 7, "kind": "element", "displayName": "Templated Route", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.TemplatedRouteDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel routes to be created from template" }, - "route": { "index": 8, "kind": "element", "displayName": "Route", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.RouteDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel routes" } + "sslContextParameters": { "index": 2, "kind": "element", "displayName": "Ssl Context Parameters", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.app.SSLContextParametersDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "SSL\/TLS context parameters configuration" }, + "dataFormat": { "index": 3, "kind": "element", "displayName": "Data Format", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.DataFormatDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel data formats" }, + "restConfiguration": { "index": 4, "kind": "element", "displayName": "Rest Configuration", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestConfigurationDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel Rest DSL Configuration" }, + "rest": { "index": 5, "kind": "element", "displayName": "Rest", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel Rest DSL" }, + "routeConfiguration": { "index": 6, "kind": "element", "displayName": "Route Configuration", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.RouteConfigurationDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel route configurations" }, + "routeTemplate": { "index": 7, "kind": "element", "displayName": "Route Template", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.RouteTemplateDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel route templates" }, + "templatedRoute": { "index": 8, "kind": "element", "displayName": "Templated Route", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.TemplatedRouteDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel routes to be created from template" }, + "route": { "index": 9, "kind": "element", "displayName": "Route", "group": "common", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.RouteDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Camel routes" } } } diff --git a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/app/sslContextParameters.json b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/app/sslContextParameters.json new file mode 100644 index 000000000000..c47cc7ab1758 --- /dev/null +++ b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/app/sslContextParameters.json @@ -0,0 +1,42 @@ +{ + "model": { + "kind": "model", + "name": "sslContextParameters", + "title": "Ssl Context Parameters", + "description": "SSL\/TLS context parameters configuration. This provides a simplified way to configure SSL\/TLS in XML and YAML DSL, with flat attributes instead of the complex nested structure used in Spring XML DSL. Example usage in XML DSL: <sslContextParameters id=mySSL keyStore=server.p12 keystorePassword=changeit trustStore=truststore.p12 trustStorePassword=changeit\/> Example usage in YAML DSL: - sslContextParameters: id: mySSL keyStore: server.p12 keystorePassword: chan [...] + "deprecated": false, + "label": "configuration,security", + "javaType": "org.apache.camel.model.app.SSLContextParametersDefinition", + "abstract": false, + "input": false, + "output": false + }, + "properties": { + "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The id of this SSL configuration." }, + "provider": { "index": 1, "kind": "attribute", "displayName": "Provider", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a specific provider for creating SSLContext. The list of available providers returned by java.security.Security.getProviders() or null to use the highest priority provider implementing the secure socket protocol." }, + "secureSocketProtocol": { "index": 2, "kind": "attribute", "displayName": "Secure Socket Protocol", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "TLSv1.3", "description": "The protocol for the secure sockets created by the SSLContext. See https:\/\/docs.oracle.com\/en\/java\/javase\/17\/docs\/specs\/security\/standard-names.html" }, + "certAlias": { "index": 3, "kind": "attribute", "displayName": "Cert Alias", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "An optional certificate alias to use. This is useful when the keystore has multiple certificates." }, + "sessionTimeout": { "index": 4, "kind": "attribute", "displayName": "Session Timeout", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "86400", "description": "Timeout in seconds to use for SSLContext. The default is 24 hours." }, + "cipherSuites": { "index": 5, "kind": "attribute", "displayName": "Cipher Suites", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "List of TLS\/SSL cipher suite algorithm names. Multiple names can be separated by comma." }, + "cipherSuitesInclude": { "index": 6, "kind": "attribute", "displayName": "Cipher Suites Include", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Filters TLS\/SSL cipher suites algorithms names. This filter is used for including algorithms that matches the naming pattern. Multiple names can be separated by comma. Notice that if the cipherSuites opti [...] + "cipherSuitesExclude": { "index": 7, "kind": "attribute", "displayName": "Cipher Suites Exclude", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Filters TLS\/SSL cipher suites algorithms names. This filter is used for excluding algorithms that matches the naming pattern. Multiple names can be separated by comma. Notice that if the cipherSuites opti [...] + "namedGroups": { "index": 8, "kind": "attribute", "displayName": "Named Groups", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "List of TLS\/SSL named groups (key exchange groups). Multiple names can be separated by comma. Named groups control which key exchange algorithms are available during the TLS handshake, including post-quantum hybrid groups [...] + "namedGroupsInclude": { "index": 9, "kind": "attribute", "displayName": "Named Groups Include", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Filters TLS\/SSL named groups. This filter is used for including named groups that match the naming pattern. Multiple names can be separated by comma. Notice that if the namedGroups option has been configure [...] + "namedGroupsExclude": { "index": 10, "kind": "attribute", "displayName": "Named Groups Exclude", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Filters TLS\/SSL named groups. This filter is used for excluding named groups that match the naming pattern. Multiple names can be separated by comma. Notice that if the namedGroups option has been configur [...] + "signatureSchemes": { "index": 11, "kind": "attribute", "displayName": "Signature Schemes", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "List of TLS\/SSL signature schemes. Multiple names can be separated by comma. Signature schemes control which signature algorithms are available during the TLS handshake, including post-quantum signature algorit [...] + "signatureSchemesInclude": { "index": 12, "kind": "attribute", "displayName": "Signature Schemes Include", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Filters TLS\/SSL signature schemes. This filter is used for including signature schemes that match the naming pattern. Multiple names can be separated by comma. Notice that if the signatureSchemes [...] + "signatureSchemesExclude": { "index": 13, "kind": "attribute", "displayName": "Signature Schemes Exclude", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Filters TLS\/SSL signature schemes. This filter is used for excluding signature schemes that match the naming pattern. Multiple names can be separated by comma. Notice that if the signatureSchemes [...] + "keyStore": { "index": 14, "kind": "attribute", "displayName": "Key Store", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The key store to load. The key store is by default loaded from classpath. If you must load from file system, then use file: as prefix. file:nameOfFile (to refer to the file system) classpath:nameOfFile (to refer to the classpath; default) http:uri (t [...] + "keyStoreType": { "index": 15, "kind": "attribute", "displayName": "Key Store Type", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The type of the key store to load. See https:\/\/docs.oracle.com\/en\/java\/javase\/17\/docs\/specs\/security\/standard-names.html" }, + "keyStoreProvider": { "index": 16, "kind": "attribute", "displayName": "Key Store Provider", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a specific provider for creating KeyStore. The list of available providers returned by java.security.Security.getProviders() or null to use the highest priority provider implementing the secure socket pr [...] + "keystorePassword": { "index": 17, "kind": "attribute", "displayName": "Keystore Password", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the SSL Keystore password." }, + "trustStore": { "index": 18, "kind": "attribute", "displayName": "Trust Store", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The trust store to load. The trust store is by default loaded from classpath. If you must load from file system, then use file: as prefix. file:nameOfFile (to refer to the file system) classpath:nameOfFile (to refer to the classpath; default) htt [...] + "trustStorePassword": { "index": 19, "kind": "attribute", "displayName": "Trust Store Password", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the SSL Truststore password." }, + "trustAllCertificates": { "index": 20, "kind": "attribute", "displayName": "Trust All Certificates", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Allows to trust all SSL certificates without performing certificate validation. This can be used in development environment but may expose the system to security risks. Notice that if the trustAllCertificates option is set to [...] + "keyManagerAlgorithm": { "index": 21, "kind": "attribute", "displayName": "Key Manager Algorithm", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Algorithm name used for creating the KeyManagerFactory. See https:\/\/docs.oracle.com\/en\/java\/javase\/17\/docs\/specs\/security\/standard-names.html" }, + "keyManagerProvider": { "index": 22, "kind": "attribute", "displayName": "Key Manager Provider", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a specific provider for creating KeyManagerFactory. The list of available providers returned by java.security.Security.getProviders() or null to use the highest priority provider implementing the sec [...] + "secureRandomAlgorithm": { "index": 23, "kind": "attribute", "displayName": "Secure Random Algorithm", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Algorithm name used for creating the SecureRandom. See https:\/\/docs.oracle.com\/en\/java\/javase\/17\/docs\/specs\/security\/standard-names.html" }, + "secureRandomProvider": { "index": 24, "kind": "attribute", "displayName": "Secure Random Provider", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a specific provider for creating SecureRandom. The list of available providers returned by java.security.Security.getProviders() or null to use the highest priority provider implementing the secu [...] + "clientAuthentication": { "index": 25, "kind": "attribute", "displayName": "Client Authentication", "group": "common", "required": false, "type": "enum", "javaType": "java.lang.String", "enum": [ "NONE", "WANT", "REQUIRE" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "NONE", "description": "Sets the configuration for server-side client-authentication requirements." } + } +} diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/app/jaxb.index b/core/camel-core-model/src/generated/resources/org/apache/camel/model/app/jaxb.index index 4a07d359a8c5..0c1c62edebf9 100644 --- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/app/jaxb.index +++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/app/jaxb.index @@ -6,3 +6,4 @@ BeanPropertiesDefinition BeanPropertyDefinition BeansDefinition ComponentScanDefinition +SSLContextParametersDefinition diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/app/BeansDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/app/BeansDefinition.java index bcc2c6731977..6b9761f07ea8 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/app/BeansDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/app/BeansDefinition.java @@ -54,6 +54,7 @@ import org.apache.camel.spi.annotations.ExternalSchemaElement; "componentScanning", "beans", "springOrBlueprintBeans", + "sslContextParameters", "dataFormats", "restConfigurations", "rests", @@ -93,6 +94,9 @@ public class BeansDefinition { // initially we'll be supporting only these elements which are parsed by // org.apache.camel.dsl.xml.io.XmlRoutesBuilderLoader in camel-xml-io-dsl + @XmlElement(name = "sslContextParameters") + private List<SSLContextParametersDefinition> sslContextParameters = new ArrayList<>(); + @XmlElementWrapper(name = "dataFormats") @XmlElement(name = "dataFormat") @DslProperty(name = "dataFormats") // yaml-dsl @@ -145,6 +149,17 @@ public class BeansDefinition { this.springOrBlueprintBeans = springOrBlueprintBeans; } + public List<SSLContextParametersDefinition> getSslContextParameters() { + return sslContextParameters; + } + + /** + * SSL/TLS context parameters configuration + */ + public void setSslContextParameters(List<SSLContextParametersDefinition> sslContextParameters) { + this.sslContextParameters = sslContextParameters; + } + public List<RestConfigurationDefinition> getRestConfigurations() { return restConfigurations; } diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/app/SSLContextParametersDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/app/SSLContextParametersDefinition.java new file mode 100644 index 000000000000..e315ef0c2321 --- /dev/null +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/app/SSLContextParametersDefinition.java @@ -0,0 +1,578 @@ +/* + * 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.model.app; + +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlRootElement; + +import org.apache.camel.CamelContext; +import org.apache.camel.spi.Metadata; +import org.apache.camel.support.jsse.CipherSuitesParameters; +import org.apache.camel.support.jsse.FilterParameters; +import org.apache.camel.support.jsse.KeyManagersParameters; +import org.apache.camel.support.jsse.KeyStoreParameters; +import org.apache.camel.support.jsse.NamedGroupsParameters; +import org.apache.camel.support.jsse.SSLContextParameters; +import org.apache.camel.support.jsse.SSLContextServerParameters; +import org.apache.camel.support.jsse.SecureRandomParameters; +import org.apache.camel.support.jsse.SignatureSchemesParameters; +import org.apache.camel.support.jsse.TrustAllTrustManager; +import org.apache.camel.support.jsse.TrustManagersParameters; + +/** + * SSL/TLS context parameters configuration. + * + * <p> + * This provides a simplified way to configure SSL/TLS in XML and YAML DSL, with flat attributes instead of the complex + * nested structure used in Spring XML DSL. + * </p> + * + * <p> + * Example usage in XML DSL: + * + * <pre> + * <sslContextParameters id="mySSL" keyStore="server.p12" keystorePassword="changeit" + * trustStore="truststore.p12" trustStorePassword="changeit"/> + * </pre> + * + * Example usage in YAML DSL: + * + * <pre> + * - sslContextParameters: + * id: mySSL + * keyStore: server.p12 + * keystorePassword: changeit + * trustStore: truststore.p12 + * trustStorePassword: changeit + * </pre> + */ +@Metadata(label = "configuration,security") +@XmlRootElement(name = "sslContextParameters") +@XmlAccessorType(XmlAccessType.FIELD) +public class SSLContextParametersDefinition { + + @XmlAttribute + @Metadata(description = "The id of this SSL configuration.") + private String id; + + @XmlAttribute + @Metadata(label = "advanced", + description = "To use a specific provider for creating SSLContext." + + " The list of available providers returned by java.security.Security.getProviders()" + + " or null to use the highest priority provider implementing the secure socket protocol.") + private String provider; + + @XmlAttribute + @Metadata(label = "advanced", defaultValue = "TLSv1.3", + description = "The protocol for the secure sockets created by the SSLContext." + + " See https://docs.oracle.com/en/java/javase/17/docs/specs/security/standard-names.html") + private String secureSocketProtocol; + + @XmlAttribute + @Metadata(label = "advanced", + description = "An optional certificate alias to use. This is useful when the keystore has multiple certificates.") + private String certAlias; + + @XmlAttribute + @Metadata(label = "advanced", defaultValue = "86400", + description = "Timeout in seconds to use for SSLContext. The default is 24 hours.") + private String sessionTimeout; + + @XmlAttribute + @Metadata(label = "advanced", + description = "List of TLS/SSL cipher suite algorithm names. Multiple names can be separated by comma.") + private String cipherSuites; + + @XmlAttribute + @Metadata(label = "advanced", + description = "Filters TLS/SSL cipher suites algorithms names." + + " This filter is used for including algorithms that matches the naming pattern." + + " Multiple names can be separated by comma." + + " Notice that if the cipherSuites option has been configured then the include/exclude filters are not in use.") + private String cipherSuitesInclude; + + @XmlAttribute + @Metadata(label = "advanced", + description = "Filters TLS/SSL cipher suites algorithms names." + + " This filter is used for excluding algorithms that matches the naming pattern." + + " Multiple names can be separated by comma." + + " Notice that if the cipherSuites option has been configured then the include/exclude filters are not in use.") + private String cipherSuitesExclude; + + @XmlAttribute + @Metadata(label = "advanced", + description = "List of TLS/SSL named groups (key exchange groups). Multiple names can be separated by comma." + + " Named groups control which key exchange algorithms are available during the TLS handshake," + + " including post-quantum hybrid groups such as X25519MLKEM768.") + private String namedGroups; + + @XmlAttribute + @Metadata(label = "advanced", + description = "Filters TLS/SSL named groups." + + " This filter is used for including named groups that match the naming pattern." + + " Multiple names can be separated by comma." + + " Notice that if the namedGroups option has been configured then the include/exclude filters are not in use.") + private String namedGroupsInclude; + + @XmlAttribute + @Metadata(label = "advanced", + description = "Filters TLS/SSL named groups." + + " This filter is used for excluding named groups that match the naming pattern." + + " Multiple names can be separated by comma." + + " Notice that if the namedGroups option has been configured then the include/exclude filters are not in use.") + private String namedGroupsExclude; + + @XmlAttribute + @Metadata(label = "advanced", + description = "List of TLS/SSL signature schemes. Multiple names can be separated by comma." + + " Signature schemes control which signature algorithms are available during the TLS handshake," + + " including post-quantum signature algorithms such as ML-DSA.") + private String signatureSchemes; + + @XmlAttribute + @Metadata(label = "advanced", + description = "Filters TLS/SSL signature schemes." + + " This filter is used for including signature schemes that match the naming pattern." + + " Multiple names can be separated by comma." + + " Notice that if the signatureSchemes option has been configured then the include/exclude filters are not in use.") + private String signatureSchemesInclude; + + @XmlAttribute + @Metadata(label = "advanced", + description = "Filters TLS/SSL signature schemes." + + " This filter is used for excluding signature schemes that match the naming pattern." + + " Multiple names can be separated by comma." + + " Notice that if the signatureSchemes option has been configured then the include/exclude filters are not in use.") + private String signatureSchemesExclude; + + @XmlAttribute + @Metadata(description = "The key store to load." + + " The key store is by default loaded from classpath. If you must load from file system, then use file: as prefix." + + " file:nameOfFile (to refer to the file system)" + + " classpath:nameOfFile (to refer to the classpath; default)" + + " http:uri (to load the resource using HTTP)" + + " ref:nameOfBean (to lookup an existing KeyStore instance from the registry, for example for testing and development).") + private String keyStore; + + @XmlAttribute + @Metadata(label = "advanced", + description = "The type of the key store to load." + + " See https://docs.oracle.com/en/java/javase/17/docs/specs/security/standard-names.html") + private String keyStoreType; + + @XmlAttribute + @Metadata(label = "advanced", + description = "To use a specific provider for creating KeyStore." + + " The list of available providers returned by java.security.Security.getProviders()" + + " or null to use the highest priority provider implementing the secure socket protocol.") + private String keyStoreProvider; + + @XmlAttribute + @Metadata(description = "Sets the SSL Keystore password.") + private String keystorePassword; + + @XmlAttribute + @Metadata(description = "The trust store to load." + + " The trust store is by default loaded from classpath. If you must load from file system, then use file: as prefix." + + " file:nameOfFile (to refer to the file system)" + + " classpath:nameOfFile (to refer to the classpath; default)" + + " http:uri (to load the resource using HTTP)" + + " ref:nameOfBean (to lookup an existing KeyStore instance from the registry, for example for testing and development).") + private String trustStore; + + @XmlAttribute + @Metadata(description = "Sets the SSL Truststore password.") + private String trustStorePassword; + + @XmlAttribute + @Metadata(description = "Allows to trust all SSL certificates without performing certificate validation." + + " This can be used in development environment but may expose the system to security risks." + + " Notice that if the trustAllCertificates option is set to true" + + " then the trustStore/trustStorePassword options are not in use.") + private String trustAllCertificates; + + @XmlAttribute + @Metadata(label = "advanced", + description = "Algorithm name used for creating the KeyManagerFactory." + + " See https://docs.oracle.com/en/java/javase/17/docs/specs/security/standard-names.html") + private String keyManagerAlgorithm; + + @XmlAttribute + @Metadata(label = "advanced", + description = "To use a specific provider for creating KeyManagerFactory." + + " The list of available providers returned by java.security.Security.getProviders()" + + " or null to use the highest priority provider implementing the secure socket protocol.") + private String keyManagerProvider; + + @XmlAttribute + @Metadata(label = "advanced", + description = "Algorithm name used for creating the SecureRandom." + + " See https://docs.oracle.com/en/java/javase/17/docs/specs/security/standard-names.html") + private String secureRandomAlgorithm; + + @XmlAttribute + @Metadata(label = "advanced", + description = "To use a specific provider for creating SecureRandom." + + " The list of available providers returned by java.security.Security.getProviders()" + + " or null to use the highest priority provider implementing the secure socket protocol.") + private String secureRandomProvider; + + @XmlAttribute + @Metadata(defaultValue = "NONE", enums = "NONE,WANT,REQUIRE", + description = "Sets the configuration for server-side client-authentication requirements.") + private String clientAuthentication; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getProvider() { + return provider; + } + + public void setProvider(String provider) { + this.provider = provider; + } + + public String getSecureSocketProtocol() { + return secureSocketProtocol; + } + + public void setSecureSocketProtocol(String secureSocketProtocol) { + this.secureSocketProtocol = secureSocketProtocol; + } + + public String getCertAlias() { + return certAlias; + } + + public void setCertAlias(String certAlias) { + this.certAlias = certAlias; + } + + public String getSessionTimeout() { + return sessionTimeout; + } + + public void setSessionTimeout(String sessionTimeout) { + this.sessionTimeout = sessionTimeout; + } + + public String getCipherSuites() { + return cipherSuites; + } + + public void setCipherSuites(String cipherSuites) { + this.cipherSuites = cipherSuites; + } + + public String getCipherSuitesInclude() { + return cipherSuitesInclude; + } + + public void setCipherSuitesInclude(String cipherSuitesInclude) { + this.cipherSuitesInclude = cipherSuitesInclude; + } + + public String getCipherSuitesExclude() { + return cipherSuitesExclude; + } + + public void setCipherSuitesExclude(String cipherSuitesExclude) { + this.cipherSuitesExclude = cipherSuitesExclude; + } + + public String getNamedGroups() { + return namedGroups; + } + + public void setNamedGroups(String namedGroups) { + this.namedGroups = namedGroups; + } + + public String getNamedGroupsInclude() { + return namedGroupsInclude; + } + + public void setNamedGroupsInclude(String namedGroupsInclude) { + this.namedGroupsInclude = namedGroupsInclude; + } + + public String getNamedGroupsExclude() { + return namedGroupsExclude; + } + + public void setNamedGroupsExclude(String namedGroupsExclude) { + this.namedGroupsExclude = namedGroupsExclude; + } + + public String getSignatureSchemes() { + return signatureSchemes; + } + + public void setSignatureSchemes(String signatureSchemes) { + this.signatureSchemes = signatureSchemes; + } + + public String getSignatureSchemesInclude() { + return signatureSchemesInclude; + } + + public void setSignatureSchemesInclude(String signatureSchemesInclude) { + this.signatureSchemesInclude = signatureSchemesInclude; + } + + public String getSignatureSchemesExclude() { + return signatureSchemesExclude; + } + + public void setSignatureSchemesExclude(String signatureSchemesExclude) { + this.signatureSchemesExclude = signatureSchemesExclude; + } + + public String getKeyStore() { + return keyStore; + } + + public void setKeyStore(String keyStore) { + this.keyStore = keyStore; + } + + public String getKeyStoreType() { + return keyStoreType; + } + + public void setKeyStoreType(String keyStoreType) { + this.keyStoreType = keyStoreType; + } + + public String getKeyStoreProvider() { + return keyStoreProvider; + } + + public void setKeyStoreProvider(String keyStoreProvider) { + this.keyStoreProvider = keyStoreProvider; + } + + public String getKeystorePassword() { + return keystorePassword; + } + + public void setKeystorePassword(String keystorePassword) { + this.keystorePassword = keystorePassword; + } + + public String getTrustStore() { + return trustStore; + } + + public void setTrustStore(String trustStore) { + this.trustStore = trustStore; + } + + public String getTrustStorePassword() { + return trustStorePassword; + } + + public void setTrustStorePassword(String trustStorePassword) { + this.trustStorePassword = trustStorePassword; + } + + public String getTrustAllCertificates() { + return trustAllCertificates; + } + + public void setTrustAllCertificates(String trustAllCertificates) { + this.trustAllCertificates = trustAllCertificates; + } + + public String getKeyManagerAlgorithm() { + return keyManagerAlgorithm; + } + + public void setKeyManagerAlgorithm(String keyManagerAlgorithm) { + this.keyManagerAlgorithm = keyManagerAlgorithm; + } + + public String getKeyManagerProvider() { + return keyManagerProvider; + } + + public void setKeyManagerProvider(String keyManagerProvider) { + this.keyManagerProvider = keyManagerProvider; + } + + public String getSecureRandomAlgorithm() { + return secureRandomAlgorithm; + } + + public void setSecureRandomAlgorithm(String secureRandomAlgorithm) { + this.secureRandomAlgorithm = secureRandomAlgorithm; + } + + public String getSecureRandomProvider() { + return secureRandomProvider; + } + + public void setSecureRandomProvider(String secureRandomProvider) { + this.secureRandomProvider = secureRandomProvider; + } + + public String getClientAuthentication() { + return clientAuthentication; + } + + public void setClientAuthentication(String clientAuthentication) { + this.clientAuthentication = clientAuthentication; + } + + /** + * Creates a runtime {@link SSLContextParameters} object from this definition. + * + * @param camelContext the CamelContext + * @return the SSL context parameters + */ + public SSLContextParameters createSSLContextParameters(CamelContext camelContext) { + KeyStoreParameters ksp = new KeyStoreParameters(); + ksp.setCamelContext(camelContext); + ksp.setResource(keyStore); + ksp.setType(keyStoreType); + ksp.setPassword(keystorePassword); + ksp.setProvider(keyStoreProvider); + + KeyManagersParameters kmp = new KeyManagersParameters(); + kmp.setCamelContext(camelContext); + kmp.setKeyPassword(keystorePassword); + kmp.setKeyStore(ksp); + kmp.setAlgorithm(keyManagerAlgorithm); + kmp.setProvider(keyManagerProvider); + + TrustManagersParameters tmp = null; + if ("true".equalsIgnoreCase(trustAllCertificates)) { + tmp = new TrustManagersParameters(); + tmp.setCamelContext(camelContext); + tmp.setTrustManager(TrustAllTrustManager.INSTANCE); + } else if (trustStore != null) { + KeyStoreParameters tsp = new KeyStoreParameters(); + tsp.setCamelContext(camelContext); + tsp.setResource(trustStore); + tsp.setPassword(trustStorePassword); + tmp = new TrustManagersParameters(); + tmp.setCamelContext(camelContext); + tmp.setKeyStore(tsp); + } + + SSLContextServerParameters scsp = null; + if (clientAuthentication != null) { + scsp = new SSLContextServerParameters(); + scsp.setCamelContext(camelContext); + scsp.setClientAuthentication(clientAuthentication); + } + + SecureRandomParameters srp = null; + if (secureRandomAlgorithm != null || secureRandomProvider != null) { + srp = new SecureRandomParameters(); + srp.setCamelContext(camelContext); + srp.setAlgorithm(secureRandomAlgorithm); + srp.setProvider(secureRandomProvider); + } + + SSLContextParameters scp = new SSLContextParameters(); + scp.setCamelContext(camelContext); + scp.setProvider(provider); + scp.setSecureSocketProtocol(secureSocketProtocol); + scp.setCertAlias(certAlias); + if (sessionTimeout != null) { + scp.setSessionTimeout(sessionTimeout); + } + if (cipherSuites != null) { + CipherSuitesParameters csp = new CipherSuitesParameters(); + for (String c : cipherSuites.split(",")) { + csp.addCipherSuite(c.trim()); + } + scp.setCipherSuites(csp); + } + if (cipherSuitesInclude != null || cipherSuitesExclude != null) { + FilterParameters fp = new FilterParameters(); + if (cipherSuitesInclude != null) { + for (String c : cipherSuitesInclude.split(",")) { + fp.addInclude(c.trim()); + } + } + if (cipherSuitesExclude != null) { + for (String c : cipherSuitesExclude.split(",")) { + fp.addExclude(c.trim()); + } + } + scp.setCipherSuitesFilter(fp); + } + if (namedGroups != null) { + NamedGroupsParameters ngp = new NamedGroupsParameters(); + for (String g : namedGroups.split(",")) { + ngp.addNamedGroup(g.trim()); + } + scp.setNamedGroups(ngp); + } + if (namedGroupsInclude != null || namedGroupsExclude != null) { + FilterParameters fp = new FilterParameters(); + if (namedGroupsInclude != null) { + for (String g : namedGroupsInclude.split(",")) { + fp.addInclude(g.trim()); + } + } + if (namedGroupsExclude != null) { + for (String g : namedGroupsExclude.split(",")) { + fp.addExclude(g.trim()); + } + } + scp.setNamedGroupsFilter(fp); + } + if (signatureSchemes != null) { + SignatureSchemesParameters ssp = new SignatureSchemesParameters(); + for (String s : signatureSchemes.split(",")) { + ssp.addSignatureScheme(s.trim()); + } + scp.setSignatureSchemes(ssp); + } + if (signatureSchemesInclude != null || signatureSchemesExclude != null) { + FilterParameters fp = new FilterParameters(); + if (signatureSchemesInclude != null) { + for (String s : signatureSchemesInclude.split(",")) { + fp.addInclude(s.trim()); + } + } + if (signatureSchemesExclude != null) { + for (String s : signatureSchemesExclude.split(",")) { + fp.addExclude(s.trim()); + } + } + scp.setSignatureSchemesFilter(fp); + } + scp.setKeyManagers(kmp); + scp.setTrustManagers(tmp); + scp.setServerParameters(scsp); + scp.setSecureRandom(srp); + return scp; + } + +} diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java index 4d643d6ae367..4f8089312fcd 100644 --- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java +++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java @@ -1399,6 +1399,7 @@ public class ModelParser extends BaseParser { case "routeConfiguration": doAdd(doParseRouteConfigurationDefinition(), def.getRouteConfigurations(), def::setRouteConfigurations); break; case "routeTemplate": doAdd(doParseRouteTemplateDefinition(), def.getRouteTemplates(), def::setRouteTemplates); break; case "route": doAdd(doParseRouteDefinition(), def.getRoutes(), def::setRoutes); break; + case "sslContextParameters": doAdd(doParseSSLContextParametersDefinition(), def.getSslContextParameters(), def::setSslContextParameters); break; case "templatedRoute": doAdd(doParseTemplatedRouteDefinition(), def.getTemplatedRoutes(), def::setTemplatedRoutes); break; default: DataFormatDefinition v = doParseDataFormatDefinitionRef(key); @@ -1427,6 +1428,37 @@ public class ModelParser extends BaseParser { default: yield false; }, noElementHandler(), noValueHandler()); } + protected SSLContextParametersDefinition doParseSSLContextParametersDefinition() throws IOException, XmlPullParserException { + return doParse(new SSLContextParametersDefinition(), (def, key, val) -> switch (key) { + case "certAlias": def.setCertAlias(val); yield true; + case "cipherSuites": def.setCipherSuites(val); yield true; + case "cipherSuitesExclude": def.setCipherSuitesExclude(val); yield true; + case "cipherSuitesInclude": def.setCipherSuitesInclude(val); yield true; + case "clientAuthentication": def.setClientAuthentication(val); yield true; + case "id": def.setId(val); yield true; + case "keyManagerAlgorithm": def.setKeyManagerAlgorithm(val); yield true; + case "keyManagerProvider": def.setKeyManagerProvider(val); yield true; + case "keyStore": def.setKeyStore(val); yield true; + case "keyStoreProvider": def.setKeyStoreProvider(val); yield true; + case "keyStoreType": def.setKeyStoreType(val); yield true; + case "keystorePassword": def.setKeystorePassword(val); yield true; + case "namedGroups": def.setNamedGroups(val); yield true; + case "namedGroupsExclude": def.setNamedGroupsExclude(val); yield true; + case "namedGroupsInclude": def.setNamedGroupsInclude(val); yield true; + case "provider": def.setProvider(val); yield true; + case "secureRandomAlgorithm": def.setSecureRandomAlgorithm(val); yield true; + case "secureRandomProvider": def.setSecureRandomProvider(val); yield true; + case "secureSocketProtocol": def.setSecureSocketProtocol(val); yield true; + case "sessionTimeout": def.setSessionTimeout(val); yield true; + case "signatureSchemes": def.setSignatureSchemes(val); yield true; + case "signatureSchemesExclude": def.setSignatureSchemesExclude(val); yield true; + case "signatureSchemesInclude": def.setSignatureSchemesInclude(val); yield true; + case "trustAllCertificates": def.setTrustAllCertificates(val); yield true; + case "trustStore": def.setTrustStore(val); yield true; + case "trustStorePassword": def.setTrustStorePassword(val); yield true; + default: yield false; + }, noElementHandler(), noValueHandler()); + } protected RestConfigurationDefinition doParseRestConfigurationDefinition() throws IOException, XmlPullParserException { return doParse(new RestConfigurationDefinition(), (def, key, val) -> switch (key) { case "apiComponent": def.setApiComponent(val); yield true; diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java index 11f7c4882240..e1f4094baac5 100644 --- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java +++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java @@ -377,6 +377,9 @@ public class ModelWriter extends BaseWriter { public void writeBeansDefinition(BeansDefinition def) throws IOException { doWriteBeansDefinition("beans", def); } + public void writeSSLContextParametersDefinition(SSLContextParametersDefinition def) throws IOException { + doWriteSSLContextParametersDefinition("sslContextParameters", def); + } public void writeBatchResequencerConfig(BatchResequencerConfig def) throws IOException { doWriteBatchResequencerConfig("batchConfig", def); } @@ -2032,6 +2035,7 @@ public class ModelWriter extends BaseWriter { doWriteList(null, "component-scan", def.getComponentScanning(), this::doWriteComponentScanDefinition); doWriteList(null, "bean", def.getBeans(), this::doWriteBeanFactoryDefinition); domElements(def.getSpringOrBlueprintBeans()); + doWriteList(null, "sslContextParameters", def.getSslContextParameters(), this::doWriteSSLContextParametersDefinition); doWriteList("dataFormats", "dataFormat", def.getDataFormats(), this::doWriteDataFormatDefinition); doWriteList(null, "restConfiguration", def.getRestConfigurations(), this::doWriteRestConfigurationDefinition); doWriteList(null, "rest", def.getRests(), this::doWriteRestDefinition); @@ -2050,6 +2054,36 @@ public class ModelWriter extends BaseWriter { doWriteAttribute("base-package", def.getBasePackage(), null); endElement(name); } + protected void doWriteSSLContextParametersDefinition(String name, SSLContextParametersDefinition def) throws IOException { + startElement(name); + doWriteAttribute("id", def.getId(), null); + doWriteAttribute("provider", def.getProvider(), null); + doWriteAttribute("secureSocketProtocol", def.getSecureSocketProtocol(), "TLSv1.3"); + doWriteAttribute("certAlias", def.getCertAlias(), null); + doWriteAttribute("sessionTimeout", def.getSessionTimeout(), "86400"); + doWriteAttribute("cipherSuites", def.getCipherSuites(), null); + doWriteAttribute("cipherSuitesInclude", def.getCipherSuitesInclude(), null); + doWriteAttribute("cipherSuitesExclude", def.getCipherSuitesExclude(), null); + doWriteAttribute("namedGroups", def.getNamedGroups(), null); + doWriteAttribute("namedGroupsInclude", def.getNamedGroupsInclude(), null); + doWriteAttribute("namedGroupsExclude", def.getNamedGroupsExclude(), null); + doWriteAttribute("signatureSchemes", def.getSignatureSchemes(), null); + doWriteAttribute("signatureSchemesInclude", def.getSignatureSchemesInclude(), null); + doWriteAttribute("signatureSchemesExclude", def.getSignatureSchemesExclude(), null); + doWriteAttribute("keyStore", def.getKeyStore(), null); + doWriteAttribute("keyStoreType", def.getKeyStoreType(), null); + doWriteAttribute("keyStoreProvider", def.getKeyStoreProvider(), null); + doWriteAttribute("keystorePassword", def.getKeystorePassword(), null); + doWriteAttribute("trustStore", def.getTrustStore(), null); + doWriteAttribute("trustStorePassword", def.getTrustStorePassword(), null); + doWriteAttribute("trustAllCertificates", def.getTrustAllCertificates(), null); + doWriteAttribute("keyManagerAlgorithm", def.getKeyManagerAlgorithm(), null); + doWriteAttribute("keyManagerProvider", def.getKeyManagerProvider(), null); + doWriteAttribute("secureRandomAlgorithm", def.getSecureRandomAlgorithm(), null); + doWriteAttribute("secureRandomProvider", def.getSecureRandomProvider(), null); + doWriteAttribute("clientAuthentication", def.getClientAuthentication(), "NONE"); + endElement(name); + } protected void doWriteBatchResequencerConfig(String name, BatchResequencerConfig def) throws IOException { startElement(name); doWriteAttribute("batchSize", def.getBatchSize(), "100"); diff --git a/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java b/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java index c32426d57260..fcf6edc8815c 100644 --- a/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java +++ b/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java @@ -46,6 +46,7 @@ import org.apache.camel.model.RoutesDefinition; import org.apache.camel.model.TemplatedRouteDefinition; import org.apache.camel.model.TemplatedRoutesDefinition; import org.apache.camel.model.app.BeansDefinition; +import org.apache.camel.model.app.SSLContextParametersDefinition; import org.apache.camel.model.dataformat.DataFormatsDefinition; import org.apache.camel.model.rest.RestConfigurationDefinition; import org.apache.camel.model.rest.RestDefinition; @@ -55,6 +56,7 @@ import org.apache.camel.spi.Resource; import org.apache.camel.spi.annotations.RoutesLoader; import org.apache.camel.support.CachedResource; import org.apache.camel.support.PluginHelper; +import org.apache.camel.support.jsse.SSLContextParameters; import org.apache.camel.support.scan.PackageScanHelper; import org.apache.camel.xml.io.util.XmlStreamDetector; import org.apache.camel.xml.io.util.XmlStreamInfo; @@ -207,6 +209,19 @@ public class XmlRoutesBuilderLoader extends RouteBuilderLoaderSupport { // org.apache.camel.main.BaseMainSupport.postProcessCamelRegistry() (if given Main implementation // decides to do so) + if (!app.getSslContextParameters().isEmpty()) { + for (SSLContextParametersDefinition def : app.getSslContextParameters()) { + SSLContextParameters scp = def.createSSLContextParameters(getCamelContext()); + if (def.getId() != null) { + getCamelContext().getRegistry().bind(def.getId(), scp); + } + // set the first one as the global default + if (getCamelContext().getSSLContextParameters() == null) { + getCamelContext().setSSLContextParameters(scp); + } + } + } + if (app.getRestConfigurations().size() > 1) { throw new RuntimeException("There should only be one <restConfiguration>"); } diff --git a/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/XmlLoadAppTest.java b/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/XmlLoadAppTest.java index f93b75a7b777..0bc575d9387e 100644 --- a/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/XmlLoadAppTest.java +++ b/dsl/camel-xml-io-dsl/src/test/java/org/apache/camel/dsl/xml/io/XmlLoadAppTest.java @@ -29,6 +29,7 @@ import org.apache.camel.spi.Resource; import org.apache.camel.spi.RestConfiguration; import org.apache.camel.spi.RoutesLoader; import org.apache.camel.support.PluginHelper; +import org.apache.camel.support.jsse.SSLContextParameters; import org.apache.commons.codec.binary.Base64; import org.junit.jupiter.api.Test; @@ -405,4 +406,40 @@ public class XmlLoadAppTest { } } + @Test + public void testLoadCamelAppWithSSLContextParameters() throws Exception { + try (DefaultCamelContext context = new DefaultCamelContext()) { + context.start(); + + Resource resource = PluginHelper.getResourceLoader(context).resolveResource( + "/org/apache/camel/dsl/xml/io/camel-app-ssl.xml"); + + RoutesLoader routesLoader = PluginHelper.getRoutesLoader(context); + routesLoader.preParseRoute(resource, false); + routesLoader.loadRoutes(resource); + + assertNotNull(context.getRoute("sslRoute"), "Loaded sslRoute should be there"); + assertEquals(1, context.getRoutes().size()); + + // verify SSL context parameters were registered in registry + SSLContextParameters sslParams = context.getRegistry().lookupByNameAndType("mySSL", SSLContextParameters.class); + assertNotNull(sslParams, "SSL context parameters should be registered with id mySSL"); + + // verify it was also set as the global default + assertNotNull(context.getSSLContextParameters(), "Global SSL context parameters should be set"); + + // verify key store configuration + assertNotNull(sslParams.getKeyManagers(), "Key managers should be configured"); + assertNotNull(sslParams.getKeyManagers().getKeyStore(), "Key store should be configured"); + assertEquals("server.p12", sslParams.getKeyManagers().getKeyStore().getResource()); + assertEquals("changeit", sslParams.getKeyManagers().getKeyPassword()); + + // verify trust store configuration + assertNotNull(sslParams.getTrustManagers(), "Trust managers should be configured"); + assertNotNull(sslParams.getTrustManagers().getKeyStore(), "Trust store should be configured"); + assertEquals("truststore.p12", sslParams.getTrustManagers().getKeyStore().getResource()); + assertEquals("changeit", sslParams.getTrustManagers().getKeyStore().getPassword()); + } + } + } diff --git a/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app-ssl.xml b/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app-ssl.xml new file mode 100644 index 000000000000..1498a0e269b7 --- /dev/null +++ b/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/camel-app-ssl.xml @@ -0,0 +1,28 @@ +<?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. + +--> +<camel xmlns="http://camel.apache.org/schema/xml-io"> + <sslContextParameters id="mySSL" keyStore="server.p12" keystorePassword="changeit" + trustStore="truststore.p12" trustStorePassword="changeit"/> + + <route id="sslRoute"> + <from uri="direct:ssl"/> + <to uri="mock:ssl"/> + </route> +</camel> diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java index f546c90fc5c8..36d65d89eab9 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java @@ -114,6 +114,7 @@ import org.apache.camel.model.app.BeanConstructorsDefinition; import org.apache.camel.model.app.BeanPropertiesDefinition; import org.apache.camel.model.app.BeanPropertyDefinition; import org.apache.camel.model.app.ComponentScanDefinition; +import org.apache.camel.model.app.SSLContextParametersDefinition; import org.apache.camel.model.config.BatchResequencerConfig; import org.apache.camel.model.config.StreamResequencerConfig; import org.apache.camel.model.dataformat.ASN1DataFormat; @@ -15455,6 +15456,192 @@ public final class ModelDeserializers extends YamlDeserializerSupport { } } + @YamlType( + nodes = "sslContextParameters", + types = org.apache.camel.model.app.SSLContextParametersDefinition.class, + order = org.apache.camel.dsl.yaml.common.YamlDeserializerResolver.ORDER_LOWEST - 1, + properties = { + @YamlProperty(name = "certAlias", type = "string"), + @YamlProperty(name = "cipherSuites", type = "string"), + @YamlProperty(name = "cipherSuitesExclude", type = "string"), + @YamlProperty(name = "cipherSuitesInclude", type = "string"), + @YamlProperty(name = "clientAuthentication", type = "enum:NONE,WANT,REQUIRE"), + @YamlProperty(name = "id", type = "string"), + @YamlProperty(name = "keyManagerAlgorithm", type = "string"), + @YamlProperty(name = "keyManagerProvider", type = "string"), + @YamlProperty(name = "keyStore", type = "string"), + @YamlProperty(name = "keyStoreProvider", type = "string"), + @YamlProperty(name = "keyStoreType", type = "string"), + @YamlProperty(name = "keystorePassword", type = "string"), + @YamlProperty(name = "namedGroups", type = "string"), + @YamlProperty(name = "namedGroupsExclude", type = "string"), + @YamlProperty(name = "namedGroupsInclude", type = "string"), + @YamlProperty(name = "provider", type = "string"), + @YamlProperty(name = "secureRandomAlgorithm", type = "string"), + @YamlProperty(name = "secureRandomProvider", type = "string"), + @YamlProperty(name = "secureSocketProtocol", type = "string"), + @YamlProperty(name = "sessionTimeout", type = "string"), + @YamlProperty(name = "signatureSchemes", type = "string"), + @YamlProperty(name = "signatureSchemesExclude", type = "string"), + @YamlProperty(name = "signatureSchemesInclude", type = "string"), + @YamlProperty(name = "trustAllCertificates", type = "string"), + @YamlProperty(name = "trustStore", type = "string"), + @YamlProperty(name = "trustStorePassword", type = "string") + } + ) + public static class SSLContextParametersDefinitionDeserializer extends YamlDeserializerBase<SSLContextParametersDefinition> { + public SSLContextParametersDefinitionDeserializer() { + super(SSLContextParametersDefinition.class); + } + + @Override + protected SSLContextParametersDefinition newInstance() { + return new SSLContextParametersDefinition(); + } + + @Override + protected boolean setProperty(SSLContextParametersDefinition target, String propertyKey, + String propertyName, Node node) { + propertyKey = org.apache.camel.util.StringHelper.dashToCamelCase(propertyKey); + switch(propertyKey) { + case "certAlias": { + String val = asText(node); + target.setCertAlias(val); + break; + } + case "cipherSuites": { + String val = asText(node); + target.setCipherSuites(val); + break; + } + case "cipherSuitesExclude": { + String val = asText(node); + target.setCipherSuitesExclude(val); + break; + } + case "cipherSuitesInclude": { + String val = asText(node); + target.setCipherSuitesInclude(val); + break; + } + case "clientAuthentication": { + String val = asText(node); + target.setClientAuthentication(val); + break; + } + case "id": { + String val = asText(node); + target.setId(val); + break; + } + case "keyManagerAlgorithm": { + String val = asText(node); + target.setKeyManagerAlgorithm(val); + break; + } + case "keyManagerProvider": { + String val = asText(node); + target.setKeyManagerProvider(val); + break; + } + case "keyStore": { + String val = asText(node); + target.setKeyStore(val); + break; + } + case "keyStoreProvider": { + String val = asText(node); + target.setKeyStoreProvider(val); + break; + } + case "keyStoreType": { + String val = asText(node); + target.setKeyStoreType(val); + break; + } + case "keystorePassword": { + String val = asText(node); + target.setKeystorePassword(val); + break; + } + case "namedGroups": { + String val = asText(node); + target.setNamedGroups(val); + break; + } + case "namedGroupsExclude": { + String val = asText(node); + target.setNamedGroupsExclude(val); + break; + } + case "namedGroupsInclude": { + String val = asText(node); + target.setNamedGroupsInclude(val); + break; + } + case "provider": { + String val = asText(node); + target.setProvider(val); + break; + } + case "secureRandomAlgorithm": { + String val = asText(node); + target.setSecureRandomAlgorithm(val); + break; + } + case "secureRandomProvider": { + String val = asText(node); + target.setSecureRandomProvider(val); + break; + } + case "secureSocketProtocol": { + String val = asText(node); + target.setSecureSocketProtocol(val); + break; + } + case "sessionTimeout": { + String val = asText(node); + target.setSessionTimeout(val); + break; + } + case "signatureSchemes": { + String val = asText(node); + target.setSignatureSchemes(val); + break; + } + case "signatureSchemesExclude": { + String val = asText(node); + target.setSignatureSchemesExclude(val); + break; + } + case "signatureSchemesInclude": { + String val = asText(node); + target.setSignatureSchemesInclude(val); + break; + } + case "trustAllCertificates": { + String val = asText(node); + target.setTrustAllCertificates(val); + break; + } + case "trustStore": { + String val = asText(node); + target.setTrustStore(val); + break; + } + case "trustStorePassword": { + String val = asText(node); + target.setTrustStorePassword(val); + break; + } + default: { + return false; + } + } + return true; + } + } + @YamlType( nodes = "saga", types = org.apache.camel.model.SagaDefinition.class, diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java index 5325f3a98672..9828438e1aca 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java @@ -345,6 +345,8 @@ public final class ModelDeserializersResolver implements YamlDeserializerResolve case "org.apache.camel.model.RoutingSlipDefinition": return new ModelDeserializers.RoutingSlipDefinitionDeserializer(); case "rss": return new ModelDeserializers.RssDataFormatDeserializer(); case "org.apache.camel.model.dataformat.RssDataFormat": return new ModelDeserializers.RssDataFormatDeserializer(); + case "sslContextParameters": return new ModelDeserializers.SSLContextParametersDefinitionDeserializer(); + case "org.apache.camel.model.app.SSLContextParametersDefinition": return new ModelDeserializers.SSLContextParametersDefinitionDeserializer(); case "saga": return new ModelDeserializers.SagaDefinitionDeserializer(); case "org.apache.camel.model.SagaDefinition": return new ModelDeserializers.SagaDefinitionDeserializer(); case "sample": return new ModelDeserializers.SamplingDefinitionDeserializer(); diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json index 16cb7fc3796b..cd0540a1b08d 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json @@ -9346,6 +9346,91 @@ } } }, + "org.apache.camel.model.app.SSLContextParametersDefinition" : { + "type" : "object", + "additionalProperties" : false, + "properties" : { + "certAlias" : { + "type" : "string" + }, + "cipherSuites" : { + "type" : "string" + }, + "cipherSuitesExclude" : { + "type" : "string" + }, + "cipherSuitesInclude" : { + "type" : "string" + }, + "clientAuthentication" : { + "type" : "string", + "enum" : [ "NONE", "WANT", "REQUIRE" ] + }, + "id" : { + "type" : "string" + }, + "keyManagerAlgorithm" : { + "type" : "string" + }, + "keyManagerProvider" : { + "type" : "string" + }, + "keyStore" : { + "type" : "string" + }, + "keyStoreProvider" : { + "type" : "string" + }, + "keyStoreType" : { + "type" : "string" + }, + "keystorePassword" : { + "type" : "string" + }, + "namedGroups" : { + "type" : "string" + }, + "namedGroupsExclude" : { + "type" : "string" + }, + "namedGroupsInclude" : { + "type" : "string" + }, + "provider" : { + "type" : "string" + }, + "secureRandomAlgorithm" : { + "type" : "string" + }, + "secureRandomProvider" : { + "type" : "string" + }, + "secureSocketProtocol" : { + "type" : "string" + }, + "sessionTimeout" : { + "type" : "string" + }, + "signatureSchemes" : { + "type" : "string" + }, + "signatureSchemesExclude" : { + "type" : "string" + }, + "signatureSchemesInclude" : { + "type" : "string" + }, + "trustAllCertificates" : { + "type" : "string" + }, + "trustStore" : { + "type" : "string" + }, + "trustStorePassword" : { + "type" : "string" + } + } + }, "org.apache.camel.model.config.BatchResequencerConfig" : { "title" : "Batch Config", "description" : "Configures batch-processing resequence eip.", diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/YamlRoutesBuilderLoader.java b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/YamlRoutesBuilderLoader.java index 7c323fac5515..0bf4bb4fa375 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/YamlRoutesBuilderLoader.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/YamlRoutesBuilderLoader.java @@ -50,6 +50,7 @@ import org.apache.camel.model.RouteDefinition; import org.apache.camel.model.RouteTemplateDefinition; import org.apache.camel.model.TemplatedRouteDefinition; import org.apache.camel.model.ToDefinition; +import org.apache.camel.model.app.SSLContextParametersDefinition; import org.apache.camel.model.errorhandler.DeadLetterChannelDefinition; import org.apache.camel.model.errorhandler.DefaultErrorHandlerDefinition; import org.apache.camel.model.errorhandler.NoErrorHandlerDefinition; @@ -64,6 +65,7 @@ import org.apache.camel.spi.Resource; import org.apache.camel.spi.annotations.RoutesLoader; import org.apache.camel.support.ObjectHelper; import org.apache.camel.support.PropertyBindingSupport; +import org.apache.camel.support.jsse.SSLContextParameters; import org.apache.camel.util.URISupport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -255,6 +257,16 @@ public class YamlRoutesBuilderLoader extends YamlRoutesBuilderLoaderSupport { getCamelContext(), getCamelContext().getRestConfiguration()); return true; + } else if (item instanceof SSLContextParametersDefinition def) { + SSLContextParameters scp = def.createSSLContextParameters(getCamelContext()); + if (def.getId() != null) { + getCamelContext().getRegistry().bind(def.getId(), scp); + } + // set the first one as the global default + if (getCamelContext().getSSLContextParameters() == null) { + getCamelContext().setSSLContextParameters(scp); + } + return true; } else if (item instanceof TransformersDefinition definition) { if (definition.getTransformers() != null) { getCamelContext().getCamelContextExtension() diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/SSLContextParametersTest.groovy b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/SSLContextParametersTest.groovy new file mode 100644 index 000000000000..6a95929c94b7 --- /dev/null +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/SSLContextParametersTest.groovy @@ -0,0 +1,82 @@ +/* + * 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.dsl.yaml + +import org.apache.camel.dsl.yaml.support.YamlTestSupport +import org.apache.camel.support.jsse.SSLContextParameters + +class SSLContextParametersTest extends YamlTestSupport { + + def "load ssl context parameters"() { + when: + loadRoutesNoValidate """ + - sslContextParameters: + id: mySSL + keyStore: server.p12 + keystorePassword: changeit + trustStore: truststore.p12 + trustStorePassword: changeit + - from: + uri: "direct:ssl" + steps: + - to: "mock:ssl" + """ + then: + // verify SSL context parameters were registered in registry + def sslParams = context.registry.lookupByNameAndType('mySSL', SSLContextParameters) + sslParams != null + + // verify it was also set as the global default + context.getSSLContextParameters() != null + + // verify key store configuration + sslParams.keyManagers != null + sslParams.keyManagers.keyStore != null + sslParams.keyManagers.keyStore.resource == 'server.p12' + sslParams.keyManagers.keyPassword == 'changeit' + + // verify trust store configuration + sslParams.trustManagers != null + sslParams.trustManagers.keyStore != null + sslParams.trustManagers.keyStore.resource == 'truststore.p12' + sslParams.trustManagers.keyStore.password == 'changeit' + } + + def "load ssl context parameters with advanced options"() { + when: + loadRoutesNoValidate """ + - sslContextParameters: + id: myAdvancedSSL + keyStore: server.p12 + keystorePassword: changeit + secureSocketProtocol: TLSv1.3 + certAlias: myAlias + clientAuthentication: WANT + - from: + uri: "direct:ssl" + steps: + - to: "mock:ssl" + """ + then: + def sslParams = context.registry.lookupByNameAndType('myAdvancedSSL', SSLContextParameters) + sslParams != null + sslParams.secureSocketProtocol == 'TLSv1.3' + sslParams.certAlias == 'myAlias' + sslParams.serverParameters != null + sslParams.serverParameters.clientAuthentication == 'WANT' + } +}
