This is an automated email from the ASF dual-hosted git repository.

pvillard31 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/main by this push:
     new 8ac3c9a8465 NIFI-16207 Switched CaptureChangeMySQL to 
SSLContextProvider (#11551)
8ac3c9a8465 is described below

commit 8ac3c9a84659a7f55a640f9866c979ea33fa4554
Author: David Handermann <[email protected]>
AuthorDate: Sat Aug 15 07:20:04 2026 -0500

    NIFI-16207 Switched CaptureChangeMySQL to SSLContextProvider (#11551)
    
    - Required MySQL Connector/J 8.1.0 as the minimum version
    - Added DelegatingSSLContextProvider for configuring supplied SSLContext 
from SSLContextProvider
---
 .../nifi-cdc-mysql-processors/pom.xml              |  15 +-
 .../cdc/mysql/processors/CaptureChangeMySQL.java   |  71 +++++++--
 .../ssl/DelegatingSSLContextProvider.java          |  58 +++++++
 .../processors/ssl/DelegatingSSLContextSpi.java    |  77 +++++++++
 .../cdc/mysql/processors/ssl/SecurityProperty.java |  32 +---
 .../ssl/StandardConnectionPropertiesProvider.java  |  63 +-------
 .../mysql/processors/CaptureChangeMySQLTest.java   |  48 ++++--
 .../DelegatingSSLContextProviderMySQLDriverIT.java | 175 +++++++++++++++++++++
 .../StandardConnectionPropertiesProviderTest.java  | 131 ++-------------
 9 files changed, 435 insertions(+), 235 deletions(-)

diff --git 
a/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/pom.xml
 
b/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/pom.xml
index 2d686772204..ac6fe48abbb 100644
--- 
a/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/pom.xml
+++ 
b/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/pom.xml
@@ -29,10 +29,6 @@ language governing permissions and limitations under the 
License. -->
             <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-distributed-cache-client-service-api</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.apache.nifi</groupId>
-            <artifactId>nifi-security-utils-api</artifactId>
-        </dependency>
         <dependency>
             <groupId>io.debezium</groupId>
             <artifactId>mysql-binlog-connector-java</artifactId>
@@ -62,5 +58,16 @@ language governing permissions and limitations under the 
License. -->
             <version>2.12.0-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>testcontainers-mysql</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.mysql</groupId>
+            <artifactId>mysql-connector-j</artifactId>
+            <version>26.7.0</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git 
a/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/main/java/org/apache/nifi/cdc/mysql/processors/CaptureChangeMySQL.java
 
b/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/main/java/org/apache/nifi/cdc/mysql/processors/CaptureChangeMySQL.java
index 6aa92467aed..82db4a52577 100644
--- 
a/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/main/java/org/apache/nifi/cdc/mysql/processors/CaptureChangeMySQL.java
+++ 
b/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/main/java/org/apache/nifi/cdc/mysql/processors/CaptureChangeMySQL.java
@@ -61,6 +61,8 @@ import 
org.apache.nifi.cdc.mysql.event.handler.UpdateEventHandler;
 import org.apache.nifi.cdc.mysql.event.io.AbstractBinlogEventWriter;
 import org.apache.nifi.cdc.mysql.processors.ssl.BinaryLogSSLSocketFactory;
 import org.apache.nifi.cdc.mysql.processors.ssl.ConnectionPropertiesProvider;
+import org.apache.nifi.cdc.mysql.processors.ssl.DelegatingSSLContextProvider;
+import org.apache.nifi.cdc.mysql.processors.ssl.SecurityProperty;
 import 
org.apache.nifi.cdc.mysql.processors.ssl.StandardConnectionPropertiesProvider;
 import org.apache.nifi.components.AllowableValue;
 import org.apache.nifi.components.PropertyDescriptor;
@@ -84,11 +86,11 @@ import org.apache.nifi.processor.Relationship;
 import org.apache.nifi.processor.exception.ProcessException;
 import org.apache.nifi.processor.util.StandardValidators;
 import org.apache.nifi.reporting.InitializationException;
-import org.apache.nifi.security.util.TlsConfiguration;
-import org.apache.nifi.ssl.SSLContextService;
+import org.apache.nifi.ssl.SSLContextProvider;
 
 import java.io.IOException;
 import java.net.InetSocketAddress;
+import java.security.Security;
 import java.sql.Connection;
 import java.sql.Driver;
 import java.sql.DriverManager;
@@ -109,6 +111,7 @@ import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicLong;
 import java.util.logging.Logger;
 import java.util.regex.Pattern;
 import javax.net.ssl.SSLContext;
@@ -155,6 +158,12 @@ public class CaptureChangeMySQL extends 
AbstractSessionFactoryProcessor {
 
     private static final int DEFAULT_MYSQL_PORT = 3306;
 
+    // MySQL Connector/J 8.x driver class. Connections require Connector/J 
8.1.0 or later when an SSLContextProvider is configured
+    private static final String MYSQL_DRIVER_CLASS_NAME = 
"com.mysql.cj.jdbc.Driver";
+
+    // Legacy MySQL Connector/J 5.1.x driver class replaced by 
MYSQL_DRIVER_CLASS_NAME during property migration
+    private static final String LEGACY_MYSQL_DRIVER_CLASS_NAME = 
"com.mysql.jdbc.Driver";
+
     // A regular expression matching multiline comments, used when parsing DDL 
statements
     private static final Pattern MULTI_COMMENT_PATTERN = 
Pattern.compile("/\\*.*?\\*/", Pattern.DOTALL);
 
@@ -233,7 +242,7 @@ public class CaptureChangeMySQL extends 
AbstractSessionFactoryProcessor {
     public static final PropertyDescriptor DRIVER_NAME = new 
PropertyDescriptor.Builder()
             .name("MySQL Driver Class Name")
             .description("The class name of the MySQL database driver class")
-            .defaultValue("com.mysql.jdbc.Driver")
+            .defaultValue(MYSQL_DRIVER_CLASS_NAME)
             .required(true)
             .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
             .expressionLanguageSupported(ExpressionLanguageScope.ENVIRONMENT)
@@ -241,8 +250,10 @@ public class CaptureChangeMySQL extends 
AbstractSessionFactoryProcessor {
 
     public static final PropertyDescriptor DRIVER_LOCATION = new 
PropertyDescriptor.Builder()
             .name("MySQL Driver Locations")
-            .description("Comma-separated list of files/folders and/or URLs 
containing the MySQL driver JAR and its dependencies (if any). "
-                    + "For example 
'/var/tmp/mysql-connector-java-5.1.38-bin.jar'")
+            .description("""
+                    Comma-separated list of files/folders and/or URLs 
containing the MySQL driver JAR and its dependencies (if any). \
+                    MySQL Connector/J 8.1.0 or later is required when an SSL 
Context Provider is configured. \
+                    For example '/var/tmp/mysql-connector-j-8.4.0.jar'""")
             .required(false)
             .identifiesExternalResource(ResourceCardinality.MULTIPLE, 
ResourceType.FILE, ResourceType.DIRECTORY, ResourceType.URL)
             .expressionLanguageSupported(ExpressionLanguageScope.ENVIRONMENT)
@@ -404,9 +415,9 @@ public class CaptureChangeMySQL extends 
AbstractSessionFactoryProcessor {
 
     public static final PropertyDescriptor SSL_CONTEXT_SERVICE = new 
PropertyDescriptor.Builder()
             .name("SSL Context Service")
-            .description("SSL Context Service supporting encrypted socket 
communication")
+            .description("SSL Context Provider supporting encrypted socket 
communication")
             .required(false)
-            .identifiesControllerService(SSLContextService.class)
+            .identifiesControllerService(SSLContextProvider.class)
             .dependsOn(SSL_MODE,
                     SSL_MODE_PREFERRED,
                     SSL_MODE_REQUIRED,
@@ -487,6 +498,9 @@ public class CaptureChangeMySQL extends 
AbstractSessionFactoryProcessor {
         config.renameProperty("capture-change-mysql-max-wait-time", 
CONNECT_TIMEOUT.getName());
         config.renameProperty("capture-change-mysql-hosts", HOSTS.getName());
         config.renameProperty("capture-change-mysql-driver-class", 
DRIVER_NAME.getName());
+        config.getRawPropertyValue(DRIVER_NAME.getName())
+                .filter(LEGACY_MYSQL_DRIVER_CLASS_NAME::equals)
+                .ifPresent(legacyDriverClassName -> 
config.setProperty(DRIVER_NAME.getName(), MYSQL_DRIVER_CLASS_NAME));
         List.of("capture-change-mysql-driver-locations", "MySQL Driver 
Location(s)").forEach(
                 oldNameProperty ->  config.renameProperty(oldNameProperty, 
DRIVER_LOCATION.getName()));
         config.renameProperty("capture-change-mysql-username", 
USERNAME.getName());
@@ -632,7 +646,7 @@ public class CaptureChangeMySQL extends 
AbstractSessionFactoryProcessor {
         }
 
         final SSLMode sslMode = 
SSLMode.valueOf(context.getProperty(SSL_MODE).getValue());
-        final SSLContextService sslContextService = sslMode == 
SSLMode.DISABLED ? null : 
context.getProperty(SSL_CONTEXT_SERVICE).asControllerService(SSLContextService.class);
+        final SSLContextProvider sslContextProvider = sslMode == 
SSLMode.DISABLED ? null : 
context.getProperty(SSL_CONTEXT_SERVICE).asControllerService(SSLContextProvider.class);
 
         // Save off MySQL cluster and JDBC driver information, will be used to 
connect for event enrichment as well as for the binlog connector
         try {
@@ -653,7 +667,7 @@ public class CaptureChangeMySQL extends 
AbstractSessionFactoryProcessor {
 
             Long serverId = 
context.getProperty(SERVER_ID).evaluateAttributeExpressions().asLong();
 
-            connect(hosts, username, password, serverId, driverLocation, 
driverName, connectTimeout, sslContextService, sslMode);
+            connect(hosts, username, password, serverId, driverLocation, 
driverName, connectTimeout, sslContextProvider, sslMode);
         } catch (IOException | IllegalStateException e) {
             if (eventListener != null) {
                 eventListener.stop();
@@ -754,12 +768,13 @@ public class CaptureChangeMySQL extends 
AbstractSessionFactoryProcessor {
 
     protected void connect(List<InetSocketAddress> hosts, String username, 
String password, Long serverId,
                            String driverLocation, String driverName, long 
connectTimeout,
-                           final SSLContextService sslContextService, final 
SSLMode sslMode) throws IOException {
+                           final SSLContextProvider sslContextProvider, final 
SSLMode sslMode) throws IOException {
 
         int connectionAttempts = 0;
         final int numHosts = hosts.size();
         InetSocketAddress connectedHost = null;
         Exception lastConnectException = new Exception("Unknown connection 
error");
+        final SSLContext sslContext = sslContextProvider == null ? null : 
sslContextProvider.createContext();
 
         try {
             // Ensure driverLocation and driverName are correct before 
establishing binlog connection
@@ -804,8 +819,7 @@ public class CaptureChangeMySQL extends 
AbstractSessionFactoryProcessor {
             }
 
             binlogClient.setSSLMode(sslMode);
-            if (sslContextService != null) {
-                final SSLContext sslContext = 
sslContextService.createContext();
+            if (sslContext != null) {
                 final BinaryLogSSLSocketFactory sslSocketFactory = new 
BinaryLogSSLSocketFactory(sslContext.getSocketFactory());
                 binlogClient.setSslSocketFactory(sslSocketFactory);
             }
@@ -838,10 +852,9 @@ public class CaptureChangeMySQL extends 
AbstractSessionFactoryProcessor {
             throw new IOException("Could not connect binlog client to any of 
the specified hosts due to: " + lastConnectException.getMessage(), 
lastConnectException);
         }
 
-        final TlsConfiguration tlsConfiguration = sslContextService == null ? 
null : sslContextService.createTlsConfiguration();
-        final ConnectionPropertiesProvider connectionPropertiesProvider = new 
StandardConnectionPropertiesProvider(sslMode, tlsConfiguration);
+        final ConnectionPropertiesProvider connectionPropertiesProvider = new 
StandardConnectionPropertiesProvider(sslMode);
         final Map<String, String> jdbcConnectionProperties = 
connectionPropertiesProvider.getConnectionProperties();
-        jdbcConnectionHolder = new JDBCConnectionHolder(connectedHost, 
username, password, jdbcConnectionProperties, connectTimeout);
+        jdbcConnectionHolder = new JDBCConnectionHolder(connectedHost, 
username, password, jdbcConnectionProperties, connectTimeout, sslContext, 
getIdentifier());
         try {
             // Ensure connection can be created.
             getJdbcConnection();
@@ -1253,10 +1266,14 @@ public class CaptureChangeMySQL extends 
AbstractSessionFactoryProcessor {
         private final String connectionUrl;
         private final Properties connectionProps = new Properties();
         private final long connectionTimeoutMillis;
+        private final SSLContext sslContext;
+        private final String sslContextProviderNamePrefix;
+        private final AtomicLong sslContextProviderNameCounter = new 
AtomicLong();
 
         private Connection connection;
 
-        private JDBCConnectionHolder(InetSocketAddress host, String username, 
String password, Map<String, String> customProperties, long 
connectionTimeoutMillis) {
+        private JDBCConnectionHolder(InetSocketAddress host, String username, 
String password, Map<String, String> customProperties, long 
connectionTimeoutMillis,
+                                     final SSLContext sslContext, final String 
componentId) {
             this.connectionUrl = "jdbc:mysql://" + host.getHostString() + ":" 
+ host.getPort();
             connectionProps.putAll(customProperties);
             if (username != null) {
@@ -1267,6 +1284,8 @@ public class CaptureChangeMySQL extends 
AbstractSessionFactoryProcessor {
             }
 
             this.connectionTimeoutMillis = connectionTimeoutMillis;
+            this.sslContext = sslContext;
+            this.sslContextProviderNamePrefix = 
CaptureChangeMySQL.this.getClass().getSimpleName() + "-" + componentId;
         }
 
         private Connection getConnection() throws SQLException {
@@ -1279,10 +1298,28 @@ public class CaptureChangeMySQL extends 
AbstractSessionFactoryProcessor {
             close();
 
             getLogger().trace("Creating a new JDBC connection.");
-            connection = DriverManager.getConnection(connectionUrl, 
connectionProps);
+            connection = createConnection();
             return connection;
         }
 
+        private Connection createConnection() throws SQLException {
+            if (sslContext == null) {
+                return DriverManager.getConnection(connectionUrl, 
connectionProps);
+            }
+
+            // Register a uniquely named security provider that exposes the 
configured SSLContext and direct MySQL Connector/J to it
+            // for the duration of the connection attempt. Registration is 
scoped to the connection attempt so that the JVM-wide
+            // security provider registry does not retain a reference to this 
instance ClassLoader after the connection is established.
+            final String sslContextProviderName = sslContextProviderNamePrefix 
+ "-" + sslContextProviderNameCounter.incrementAndGet();
+            
connectionProps.setProperty(SecurityProperty.SSL_CONTEXT_PROVIDER.getProperty(),
 sslContextProviderName);
+            Security.addProvider(new 
DelegatingSSLContextProvider(sslContextProviderName, sslContext));
+            try {
+                return DriverManager.getConnection(connectionUrl, 
connectionProps);
+            } finally {
+                Security.removeProvider(sslContextProviderName);
+            }
+        }
+
         private void close() {
             if (connection != null) {
                 try {
diff --git 
a/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/main/java/org/apache/nifi/cdc/mysql/processors/ssl/DelegatingSSLContextProvider.java
 
b/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/main/java/org/apache/nifi/cdc/mysql/processors/ssl/DelegatingSSLContextProvider.java
new file mode 100644
index 00000000000..bb16ada35f7
--- /dev/null
+++ 
b/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/main/java/org/apache/nifi/cdc/mysql/processors/ssl/DelegatingSSLContextProvider.java
@@ -0,0 +1,58 @@
+/*
+ * 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.nifi.cdc.mysql.processors.ssl;
+
+import java.security.Provider;
+import java.util.List;
+import java.util.Map;
+import javax.net.ssl.SSLContext;
+
+/**
+ * Java Security Provider that exposes a single pre-initialized {@link 
SSLContext} under the standard TLS algorithm.
+ * MySQL Connector/J can be directed to this provider using the {@code 
sslContextProvider} connection property, which
+ * allows an in-memory SSLContext to be used for JDBC connections without 
configuring keystore or truststore files.
+ * Instances are expected to be registered under a unique name for the 
duration of a connection attempt and removed
+ * afterward to avoid retaining references in the JVM-wide security provider 
registry.
+ */
+public final class DelegatingSSLContextProvider extends Provider {
+
+    private static final String PROVIDER_VERSION = "1.0";
+
+    private static final String SERVICE_TYPE = "SSLContext";
+
+    private static final String TLS_ALGORITHM = "TLS";
+
+    public DelegatingSSLContextProvider(final String name, final SSLContext 
sslContext) {
+        super(name, PROVIDER_VERSION, "Delegates the TLS SSLContext to a 
pre-initialized instance");
+        putService(new DelegatingService(this, sslContext));
+    }
+
+    private static final class DelegatingService extends Service {
+
+        private final SSLContext sslContext;
+
+        private DelegatingService(final Provider provider, final SSLContext 
sslContext) {
+            super(provider, SERVICE_TYPE, TLS_ALGORITHM, 
DelegatingSSLContextSpi.class.getName(), List.of(), Map.of());
+            this.sslContext = sslContext;
+        }
+
+        @Override
+        public Object newInstance(final Object constructorParameter) {
+            return new DelegatingSSLContextSpi(sslContext);
+        }
+    }
+}
diff --git 
a/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/main/java/org/apache/nifi/cdc/mysql/processors/ssl/DelegatingSSLContextSpi.java
 
b/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/main/java/org/apache/nifi/cdc/mysql/processors/ssl/DelegatingSSLContextSpi.java
new file mode 100644
index 00000000000..c7d358182d7
--- /dev/null
+++ 
b/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/main/java/org/apache/nifi/cdc/mysql/processors/ssl/DelegatingSSLContextSpi.java
@@ -0,0 +1,77 @@
+/*
+ * 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.nifi.cdc.mysql.processors.ssl;
+
+import java.security.SecureRandom;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLContextSpi;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSessionContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+
+/**
+ * SSLContextSpi implementation that delegates all operations to a 
pre-initialized SSLContext. Initialization
+ * parameters supplied by the caller are ignored because the delegated 
SSLContext already contains the configured
+ * key and trust material. This allows MySQL Connector/J to obtain a fully 
configured SSLContext from a
+ * {@link DelegatingSSLContextProvider} rather than building one from keystore 
and truststore files.
+ */
+final class DelegatingSSLContextSpi extends SSLContextSpi {
+
+    private final SSLContext sslContext;
+
+    DelegatingSSLContextSpi(final SSLContext sslContext) {
+        this.sslContext = sslContext;
+    }
+
+    @Override
+    protected void engineInit(final KeyManager[] keyManagers, final 
TrustManager[] trustManagers, final SecureRandom secureRandom) {
+        // The delegated SSLContext is already initialized, so the key and 
trust managers provided by the caller are ignored
+    }
+
+    @Override
+    protected SSLSocketFactory engineGetSocketFactory() {
+        return sslContext.getSocketFactory();
+    }
+
+    @Override
+    protected SSLServerSocketFactory engineGetServerSocketFactory() {
+        return sslContext.getServerSocketFactory();
+    }
+
+    @Override
+    protected SSLEngine engineCreateSSLEngine() {
+        return sslContext.createSSLEngine();
+    }
+
+    @Override
+    protected SSLEngine engineCreateSSLEngine(final String host, final int 
port) {
+        return sslContext.createSSLEngine(host, port);
+    }
+
+    @Override
+    protected SSLSessionContext engineGetServerSessionContext() {
+        return sslContext.getServerSessionContext();
+    }
+
+    @Override
+    protected SSLSessionContext engineGetClientSessionContext() {
+        return sslContext.getClientSessionContext();
+    }
+}
diff --git 
a/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/main/java/org/apache/nifi/cdc/mysql/processors/ssl/SecurityProperty.java
 
b/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/main/java/org/apache/nifi/cdc/mysql/processors/ssl/SecurityProperty.java
index 82d8027c1d9..460c48c9bed 100644
--- 
a/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/main/java/org/apache/nifi/cdc/mysql/processors/ssl/SecurityProperty.java
+++ 
b/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/main/java/org/apache/nifi/cdc/mysql/processors/ssl/SecurityProperty.java
@@ -20,35 +20,11 @@ package org.apache.nifi.cdc.mysql.processors.ssl;
  * MySQL Connector/J Security Properties
  */
 public enum SecurityProperty {
-    /** Deprecated alias for tlsVersions */
-    ENABLED_TLS_PROTOCOLS("enabledTLSProtocols"),
+    /** Preferred SSL Mode selection introduced in MySQL Connector/J 8.0.13 */
+    SSL_MODE("sslMode"),
 
-    /** Added in MySQL 5.1.0 */
-    TRUST_CERTIFICATE_KEY_STORE_URL("trustsCertificateKeyStoreUrl"),
-
-    /** Added in MySQL 5.1.0 and defaults to JKS */
-    TRUST_CERTIFICATE_KEY_STORE_TYPE("trustCertificateKeyStoreType"),
-
-    /** Added in MySQL 5.1.0 */
-    TRUST_CERTIFICATE_KEY_STORE_PASSWORD("trustCertificateKeyStorePassword"),
-
-    /** Added in MySQL 5.1.0 */
-    CLIENT_CERTIFICATE_KEY_STORE_URL("clientCertificateKeyStoreUrl"),
-
-    /** Added in MySQL 5.1.0 and defaults to JKS */
-    CLIENT_CERTIFICATE_KEY_STORE_TYPE("clientCertificateKeyStoreType"),
-
-    /** Added in MySQL 5.1.0 */
-    CLIENT_CERTIFICATE_KEY_STORE_PASSWORD("clientCertificateKeyStorePassword"),
-
-    /** Deprecated in favor of sslMode and evaluated when useSSL is enabled */
-    REQUIRE_SSL("requireSSL"),
-
-    /** Deprecated in favor of sslMode and defaults to true in 8.0.13 and 
later */
-    USE_SSL("useSSL"),
-
-    /** Deprecated in favor of sslMode and defaults to false in 8.0.13 and 
later */
-    VERIFY_SERVER_CERTIFICATE("verifyServerCertificate");
+    /** Name of a registered java.security.Provider supplying the SSLContext 
introduced in MySQL Connector/J 8.1.0 */
+    SSL_CONTEXT_PROVIDER("sslContextProvider");
 
     private final String property;
 
diff --git 
a/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/main/java/org/apache/nifi/cdc/mysql/processors/ssl/StandardConnectionPropertiesProvider.java
 
b/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/main/java/org/apache/nifi/cdc/mysql/processors/ssl/StandardConnectionPropertiesProvider.java
index 4a3ea797a88..fce5d690217 100644
--- 
a/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/main/java/org/apache/nifi/cdc/mysql/processors/ssl/StandardConnectionPropertiesProvider.java
+++ 
b/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/main/java/org/apache/nifi/cdc/mysql/processors/ssl/StandardConnectionPropertiesProvider.java
@@ -17,8 +17,6 @@
 package org.apache.nifi.cdc.mysql.processors.ssl;
 
 import com.github.shyiko.mysql.binlog.network.SSLMode;
-import org.apache.nifi.security.util.TlsConfiguration;
-import org.apache.nifi.security.util.TlsPlatform;
 
 import java.util.LinkedHashMap;
 import java.util.Map;
@@ -28,77 +26,22 @@ import java.util.Objects;
  * Standard implementation of Connection Properties Provider
  */
 public class StandardConnectionPropertiesProvider implements 
ConnectionPropertiesProvider {
-    private static final String COMMA_SEPARATOR = ",";
 
     private final SSLMode sslMode;
 
-    private final TlsConfiguration tlsConfiguration;
-
-    public StandardConnectionPropertiesProvider(
-            final SSLMode sslMode,
-            final TlsConfiguration tlsConfiguration
-    ) {
+    public StandardConnectionPropertiesProvider(final SSLMode sslMode) {
         this.sslMode = Objects.requireNonNull(sslMode, "SSL Mode required");
-        this.tlsConfiguration = tlsConfiguration;
     }
 
     /**
-     * Get Connection Properties based on SSL Mode and TLS Configuration
+     * Get Connection Properties based on the configured SSL Mode
      *
      * @return JDBC Connection Properties
      */
     @Override
     public Map<String, String> getConnectionProperties() {
         final Map<String, String> properties = new LinkedHashMap<>();
-
-        if (SSLMode.DISABLED == sslMode) {
-            properties.put(SecurityProperty.USE_SSL.getProperty(), 
Boolean.FALSE.toString());
-        } else {
-            // Enable TLS negotiation for all modes
-            properties.put(SecurityProperty.USE_SSL.getProperty(), 
Boolean.TRUE.toString());
-
-            if (SSLMode.PREFERRED == sslMode) {
-                properties.put(SecurityProperty.REQUIRE_SSL.getProperty(), 
Boolean.FALSE.toString());
-            } else {
-                // Modes other than preferred require SSL
-                properties.put(SecurityProperty.REQUIRE_SSL.getProperty(), 
Boolean.TRUE.toString());
-            }
-
-            if (SSLMode.VERIFY_IDENTITY == sslMode) {
-                
properties.put(SecurityProperty.VERIFY_SERVER_CERTIFICATE.getProperty(), 
Boolean.TRUE.toString());
-            }
-
-            if (tlsConfiguration == null) {
-                // Set preferred protocols based on Java platform configuration
-                final String protocols = String.join(COMMA_SEPARATOR, 
TlsPlatform.getPreferredProtocols());
-                
properties.put(SecurityProperty.ENABLED_TLS_PROTOCOLS.getProperty(), protocols);
-            } else {
-                final Map<String, String> certificateProperties = 
getCertificateProperties();
-                properties.putAll(certificateProperties);
-            }
-        }
-
-        return properties;
-    }
-
-    private Map<String, String> getCertificateProperties() {
-        final Map<String, String> properties = new LinkedHashMap<>();
-
-        final String protocols = String.join(COMMA_SEPARATOR, 
tlsConfiguration.getEnabledProtocols());
-        properties.put(SecurityProperty.ENABLED_TLS_PROTOCOLS.getProperty(), 
protocols);
-
-        if (tlsConfiguration.isKeystorePopulated()) {
-            
properties.put(SecurityProperty.CLIENT_CERTIFICATE_KEY_STORE_URL.getProperty(), 
tlsConfiguration.getKeystorePath());
-            
properties.put(SecurityProperty.CLIENT_CERTIFICATE_KEY_STORE_TYPE.getProperty(),
 tlsConfiguration.getKeystoreType().getType());
-            
properties.put(SecurityProperty.CLIENT_CERTIFICATE_KEY_STORE_PASSWORD.getProperty(),
 tlsConfiguration.getKeystorePassword());
-        }
-
-        if (tlsConfiguration.isTruststorePopulated()) {
-            
properties.put(SecurityProperty.TRUST_CERTIFICATE_KEY_STORE_URL.getProperty(), 
tlsConfiguration.getTruststorePath());
-            
properties.put(SecurityProperty.TRUST_CERTIFICATE_KEY_STORE_TYPE.getProperty(), 
tlsConfiguration.getTruststoreType().getType());
-            
properties.put(SecurityProperty.TRUST_CERTIFICATE_KEY_STORE_PASSWORD.getProperty(),
 tlsConfiguration.getTruststorePassword());
-        }
-
+        properties.put(SecurityProperty.SSL_MODE.getProperty(), 
sslMode.toString());
         return properties;
     }
 }
diff --git 
a/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/test/java/org/apache/nifi/cdc/mysql/processors/CaptureChangeMySQLTest.java
 
b/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/test/java/org/apache/nifi/cdc/mysql/processors/CaptureChangeMySQLTest.java
index a245243a0c2..ed7e68a249f 100644
--- 
a/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/test/java/org/apache/nifi/cdc/mysql/processors/CaptureChangeMySQLTest.java
+++ 
b/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/test/java/org/apache/nifi/cdc/mysql/processors/CaptureChangeMySQLTest.java
@@ -47,8 +47,9 @@ import org.apache.nifi.flowfile.attributes.CoreAttributes;
 import org.apache.nifi.processor.exception.ProcessException;
 import org.apache.nifi.provenance.ProvenanceEventType;
 import org.apache.nifi.reporting.InitializationException;
-import org.apache.nifi.ssl.SSLContextService;
+import org.apache.nifi.ssl.SSLContextProvider;
 import org.apache.nifi.util.MockFlowFile;
+import org.apache.nifi.util.MockPropertyConfiguration;
 import org.apache.nifi.util.PropertyMigrationResult;
 import org.apache.nifi.util.TestRunner;
 import org.apache.nifi.util.TestRunners;
@@ -126,6 +127,9 @@ public class CaptureChangeMySQLTest {
     private static final String FOUR = "4";
     private static final String TEN = "10";
     private static final ObjectMapper MAPPER = new ObjectMapper();
+    private static final String LEGACY_DRIVER_CLASS_NAME = 
"com.mysql.jdbc.Driver";
+    private static final String CURRENT_DRIVER_CLASS_NAME = 
"com.mysql.cj.jdbc.Driver";
+    private static final String CUSTOM_DRIVER_CLASS_NAME = 
"com.example.CustomDriver";
 
     private MockCaptureChangeMySQL processor;
     private TestRunner testRunner;
@@ -153,32 +157,32 @@ public class CaptureChangeMySQLTest {
     }
 
     @Test
-    public void testSslModeRequiredSslContextServiceConfigured(@Mock 
SSLContextService sslContextService) throws InitializationException {
+    public void testSslModeRequiredSslContextServiceConfigured(@Mock 
SSLContextProvider sslContextProvider) throws InitializationException {
         testRunner.setProperty(CaptureChangeMySQL.HOSTS, 
LOCAL_HOST_DEFAULT_PORT);
         testRunner.setProperty(CaptureChangeMySQL.SSL_MODE, 
SSLMode.REQUIRED.toString());
 
-        String identifier = SSLContextService.class.getName();
-        when(sslContextService.getIdentifier()).thenReturn(identifier);
-        testRunner.addControllerService(identifier, sslContextService);
-        testRunner.enableControllerService(sslContextService);
+        String identifier = SSLContextProvider.class.getName();
+        when(sslContextProvider.getIdentifier()).thenReturn(identifier);
+        testRunner.addControllerService(identifier, sslContextProvider);
+        testRunner.enableControllerService(sslContextProvider);
 
         testRunner.setProperty(CaptureChangeMySQL.SSL_CONTEXT_SERVICE, 
identifier);
         testRunner.assertValid();
     }
 
     @Test
-    public void testSslModeRequiredSslContextServiceConnected(@Mock 
SSLContextService sslContextService) throws NoSuchAlgorithmException, 
InitializationException {
+    public void testSslModeRequiredSslContextServiceConnected(@Mock 
SSLContextProvider sslContextProvider) throws NoSuchAlgorithmException, 
InitializationException {
         testRunner.setProperty(CaptureChangeMySQL.HOSTS, 
LOCAL_HOST_DEFAULT_PORT);
         SSLMode sslMode = SSLMode.REQUIRED;
         testRunner.setProperty(CaptureChangeMySQL.SSL_MODE, 
sslMode.toString());
 
         SSLContext sslContext = SSLContext.getDefault();
-        String identifier = SSLContextService.class.getName();
-        when(sslContextService.getIdentifier()).thenReturn(identifier);
-        doReturn(sslContext).when(sslContextService).createContext();
+        String identifier = SSLContextProvider.class.getName();
+        when(sslContextProvider.getIdentifier()).thenReturn(identifier);
+        doReturn(sslContext).when(sslContextProvider).createContext();
 
-        testRunner.addControllerService(identifier, sslContextService);
-        testRunner.enableControllerService(sslContextService);
+        testRunner.addControllerService(identifier, sslContextProvider);
+        testRunner.enableControllerService(sslContextProvider);
         testRunner.setProperty(CaptureChangeMySQL.SSL_CONTEXT_SERVICE, 
identifier);
         testRunner.assertValid();
 
@@ -1350,6 +1354,26 @@ public class CaptureChangeMySQLTest {
         assertEquals(expectedRemoved, 
propertyMigrationResult.getPropertiesRemoved());
     }
 
+    @Test
+    void testMigrationReplacesLegacyDriverClassName() {
+        final MockPropertyConfiguration config = new MockPropertyConfiguration(
+                Map.of(CaptureChangeMySQL.DRIVER_NAME.getName(), 
LEGACY_DRIVER_CLASS_NAME));
+
+        processor.migrateProperties(config);
+
+        assertEquals(CURRENT_DRIVER_CLASS_NAME, 
config.getRawPropertyValue(CaptureChangeMySQL.DRIVER_NAME.getName()).orElse(null));
+    }
+
+    @Test
+    void testMigrationRetainsCustomDriverClassName() {
+        final MockPropertyConfiguration config = new MockPropertyConfiguration(
+                Map.of(CaptureChangeMySQL.DRIVER_NAME.getName(), 
CUSTOM_DRIVER_CLASS_NAME));
+
+        processor.migrateProperties(config);
+
+        assertEquals(CUSTOM_DRIVER_CLASS_NAME, 
config.getRawPropertyValue(CaptureChangeMySQL.DRIVER_NAME.getName()).orElse(null));
+    }
+
     /********************************
      * Mock and helper classes below
      ********************************/
diff --git 
a/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/test/java/org/apache/nifi/cdc/mysql/processors/ssl/DelegatingSSLContextProviderMySQLDriverIT.java
 
b/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/test/java/org/apache/nifi/cdc/mysql/processors/ssl/DelegatingSSLContextProviderMySQLDriverIT.java
new file mode 100644
index 00000000000..efae9e3f854
--- /dev/null
+++ 
b/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/test/java/org/apache/nifi/cdc/mysql/processors/ssl/DelegatingSSLContextProviderMySQLDriverIT.java
@@ -0,0 +1,175 @@
+/*
+ * 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.nifi.cdc.mysql.processors.ssl;
+
+import com.github.shyiko.mysql.binlog.network.SSLMode;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.testcontainers.mysql.MySQLContainer;
+import org.testcontainers.utility.DockerImageName;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Map;
+import java.util.Properties;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class DelegatingSSLContextProviderMySQLDriverIT {
+
+    private static final String MYSQL_IMAGE = "mysql:8.4";
+
+    private static final String SSL_CONTEXT_PROTOCOL = "TLS";
+
+    private static final String MYSQL_CA_PATH = "/var/lib/mysql/ca.pem";
+
+    private static final String CERTIFICATE_TYPE = "X.509";
+
+    private static final String SSL_CIPHER_STATUS_QUERY = "SHOW SESSION STATUS 
LIKE 'Ssl_cipher'";
+
+    private static MySQLContainer mysql;
+
+    @BeforeAll
+    static void startContainer() {
+        mysql = new MySQLContainer(DockerImageName.parse(MYSQL_IMAGE));
+        mysql.start();
+    }
+
+    @AfterAll
+    static void stopContainer() {
+        if (mysql != null) {
+            mysql.stop();
+        }
+    }
+
+    @Test
+    void testRequiredModeUsesInjectedSslContext() throws Exception {
+        final AtomicBoolean trustManagerInvoked = new AtomicBoolean(false);
+        final SSLContext sslContext = 
SSLContext.getInstance(SSL_CONTEXT_PROTOCOL);
+        sslContext.init(null, new TrustManager[]{new 
RecordingTrustManager(trustManagerInvoked)}, new SecureRandom());
+
+        try (Connection connection = connect(SSLMode.REQUIRED, sslContext)) {
+            assertTlsActive(connection);
+        }
+
+        assertTrue(trustManagerInvoked.get());
+    }
+
+    @Test
+    void testVerifyCaSucceedsWhenInjectedContextTrustsServerAuthority() throws 
Exception {
+        final SSLContext sslContext = buildContextTrusting(readServerCa());
+
+        try (Connection connection = connect(SSLMode.VERIFY_CA, sslContext)) {
+            assertTlsActive(connection);
+        }
+    }
+
+    @Test
+    void testVerifyCaFailsWhenInjectedContextDoesNotTrustServerAuthority() 
throws Exception {
+        final SSLContext sslContext = buildContextTrusting(null);
+
+        assertThrows(SQLException.class, () -> connect(SSLMode.VERIFY_CA, 
sslContext));
+    }
+
+    private Connection connect(final SSLMode sslMode, final SSLContext 
sslContext) throws SQLException {
+        final Map<String, String> sslProperties = new 
StandardConnectionPropertiesProvider(sslMode).getConnectionProperties();
+
+        final Properties properties = new Properties();
+        properties.putAll(sslProperties);
+        properties.setProperty("user", mysql.getUsername());
+        properties.setProperty("password", mysql.getPassword());
+
+        final String providerName = 
DelegatingSSLContextProvider.class.getSimpleName() + UUID.randomUUID();
+        
properties.setProperty(SecurityProperty.SSL_CONTEXT_PROVIDER.getProperty(), 
providerName);
+        final Provider provider = new 
DelegatingSSLContextProvider(providerName, sslContext);
+        Security.addProvider(provider);
+        try {
+            return DriverManager.getConnection(mysql.getJdbcUrl(), properties);
+        } finally {
+            Security.removeProvider(providerName);
+        }
+    }
+
+    private void assertTlsActive(final Connection connection) throws 
SQLException {
+        try (Statement statement = connection.createStatement();
+             ResultSet resultSet = 
statement.executeQuery(SSL_CIPHER_STATUS_QUERY)) {
+            assertTrue(resultSet.next());
+            final String cipher = resultSet.getString(2);
+            assertNotNull(cipher);
+            assertFalse(cipher.isEmpty(), "Connection is not using TLS");
+        }
+    }
+
+    private X509Certificate readServerCa() throws Exception {
+        final byte[] caBytes = mysql.copyFileFromContainer(MYSQL_CA_PATH, 
InputStream::readAllBytes);
+        final CertificateFactory certificateFactory = 
CertificateFactory.getInstance(CERTIFICATE_TYPE);
+        return (X509Certificate) certificateFactory.generateCertificate(new 
ByteArrayInputStream(caBytes));
+    }
+
+    private SSLContext buildContextTrusting(final X509Certificate 
trustedCertificate) throws Exception {
+        final KeyStore trustStore = 
KeyStore.getInstance(KeyStore.getDefaultType());
+        trustStore.load(null, null);
+        if (trustedCertificate != null) {
+            trustStore.setCertificateEntry("mysql-ca", trustedCertificate);
+        }
+
+        final TrustManagerFactory trustManagerFactory = 
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+        trustManagerFactory.init(trustStore);
+
+        final SSLContext sslContext = 
SSLContext.getInstance(SSL_CONTEXT_PROTOCOL);
+        sslContext.init(null, trustManagerFactory.getTrustManagers(), new 
SecureRandom());
+        return sslContext;
+    }
+
+    private record RecordingTrustManager(AtomicBoolean invoked) implements 
X509TrustManager {
+
+        @Override
+        public void checkClientTrusted(final X509Certificate[] chain, final 
String authType) {
+        }
+
+        @Override
+        public void checkServerTrusted(final X509Certificate[] chain, final 
String authType) {
+            invoked.set(true);
+        }
+
+        @Override
+        public X509Certificate[] getAcceptedIssuers() {
+            return new X509Certificate[0];
+        }
+    }
+}
diff --git 
a/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/test/java/org/apache/nifi/cdc/mysql/processors/ssl/StandardConnectionPropertiesProviderTest.java
 
b/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/test/java/org/apache/nifi/cdc/mysql/processors/ssl/StandardConnectionPropertiesProviderTest.java
index 3784067ce28..d189ecb31fa 100644
--- 
a/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/test/java/org/apache/nifi/cdc/mysql/processors/ssl/StandardConnectionPropertiesProviderTest.java
+++ 
b/nifi-extension-bundles/nifi-cdc/nifi-cdc-mysql-bundle/nifi-cdc-mysql-processors/src/test/java/org/apache/nifi/cdc/mysql/processors/ssl/StandardConnectionPropertiesProviderTest.java
@@ -17,150 +17,53 @@
 package org.apache.nifi.cdc.mysql.processors.ssl;
 
 import com.github.shyiko.mysql.binlog.network.SSLMode;
-import org.apache.nifi.security.util.KeystoreType;
-import org.apache.nifi.security.util.TlsConfiguration;
-import org.apache.nifi.security.util.TlsPlatform;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
 
 import java.util.Map;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.mockito.Mockito.when;
 
-@ExtendWith(MockitoExtension.class)
-public class StandardConnectionPropertiesProviderTest {
-    private static final String KEY_STORE_PATH = "keystore.p12";
+class StandardConnectionPropertiesProviderTest {
 
-    private static final KeystoreType KEY_STORE_TYPE = KeystoreType.PKCS12;
+    private static final String SSL_MODE_PROPERTY = 
SecurityProperty.SSL_MODE.getProperty();
 
-    private static final String KEY_STORE_PASSWORD = String.class.getName();
-
-    private static final String TRUST_STORE_PATH = "cacerts";
-
-    private static final KeystoreType TRUST_STORE_TYPE = KeystoreType.PKCS12;
-
-    private static final String TRUST_STORE_PASSWORD = Integer.class.getName();
-
-    @Mock
-    TlsConfiguration tlsConfiguration;
+    private static final String SSL_CONTEXT_PROVIDER_PROPERTY = 
SecurityProperty.SSL_CONTEXT_PROVIDER.getProperty();
 
     @Test
     void testGetConnectionPropertiesSslModeDisabled() {
-        final StandardConnectionPropertiesProvider provider = new 
StandardConnectionPropertiesProvider(SSLMode.DISABLED, null);
-
-        final Map<String, String> properties = 
provider.getConnectionProperties();
-
-        assertNotNull(properties);
-
-        final String useSsl = 
properties.get(SecurityProperty.USE_SSL.getProperty());
-        assertEquals(Boolean.FALSE.toString(), useSsl);
+        assertSslModeMapped(SSLMode.DISABLED);
     }
 
     @Test
     void testGetConnectionPropertiesSslModePreferred() {
-        final StandardConnectionPropertiesProvider provider = new 
StandardConnectionPropertiesProvider(SSLMode.PREFERRED, null);
-
-        final Map<String, String> properties = 
provider.getConnectionProperties();
-
-        assertNotNull(properties);
-
-        final String useSsl = 
properties.get(SecurityProperty.USE_SSL.getProperty());
-        assertEquals(Boolean.TRUE.toString(), useSsl);
-
-        final String requireSsl = 
properties.get(SecurityProperty.REQUIRE_SSL.getProperty());
-        assertEquals(Boolean.FALSE.toString(), requireSsl);
-
-        final String protocols = 
properties.get(SecurityProperty.ENABLED_TLS_PROTOCOLS.getProperty());
-        assertNotNull(protocols);
+        assertSslModeMapped(SSLMode.PREFERRED);
     }
 
     @Test
     void testGetConnectionPropertiesSslModeRequired() {
-        final StandardConnectionPropertiesProvider provider = new 
StandardConnectionPropertiesProvider(SSLMode.REQUIRED, null);
-
-        final Map<String, String> properties = 
provider.getConnectionProperties();
-
-        assertNotNull(properties);
-
-        final String useSsl = 
properties.get(SecurityProperty.USE_SSL.getProperty());
-        assertEquals(Boolean.TRUE.toString(), useSsl);
-
-        final String requireSsl = 
properties.get(SecurityProperty.REQUIRE_SSL.getProperty());
-        assertEquals(Boolean.TRUE.toString(), requireSsl);
-
-        final String protocols = 
properties.get(SecurityProperty.ENABLED_TLS_PROTOCOLS.getProperty());
-        assertNotNull(protocols);
+        assertSslModeMapped(SSLMode.REQUIRED);
     }
 
     @Test
-    void testGetConnectionPropertiesSslModeVerifyIdentity() {
-        final StandardConnectionPropertiesProvider provider = new 
StandardConnectionPropertiesProvider(SSLMode.VERIFY_IDENTITY, null);
-
-        final Map<String, String> properties = 
provider.getConnectionProperties();
-
-        assertNotNull(properties);
-
-        final String useSsl = 
properties.get(SecurityProperty.USE_SSL.getProperty());
-        assertEquals(Boolean.TRUE.toString(), useSsl);
-
-        final String requireSsl = 
properties.get(SecurityProperty.REQUIRE_SSL.getProperty());
-        assertEquals(Boolean.TRUE.toString(), requireSsl);
-
-        final String protocols = 
properties.get(SecurityProperty.ENABLED_TLS_PROTOCOLS.getProperty());
-        assertNotNull(protocols);
-
-        final String verifyServerCertificate = 
properties.get(SecurityProperty.VERIFY_SERVER_CERTIFICATE.getProperty());
-        assertEquals(Boolean.TRUE.toString(), verifyServerCertificate);
+    void testGetConnectionPropertiesSslModeVerifyCa() {
+        assertSslModeMapped(SSLMode.VERIFY_CA);
     }
 
     @Test
-    void testGetConnectionPropertiesSslModeRequiredTlsConfiguration() {
-        final String latestProtocol = TlsPlatform.getLatestProtocol();
-        when(tlsConfiguration.getEnabledProtocols()).thenReturn(new 
String[]{latestProtocol});
-        when(tlsConfiguration.isKeystorePopulated()).thenReturn(true);
-        when(tlsConfiguration.getKeystorePath()).thenReturn(KEY_STORE_PATH);
-        when(tlsConfiguration.getKeystoreType()).thenReturn(KEY_STORE_TYPE);
-        
when(tlsConfiguration.getKeystorePassword()).thenReturn(KEY_STORE_PASSWORD);
-        when(tlsConfiguration.isTruststorePopulated()).thenReturn(true);
-        
when(tlsConfiguration.getTruststorePath()).thenReturn(TRUST_STORE_PATH);
-        
when(tlsConfiguration.getTruststoreType()).thenReturn(TRUST_STORE_TYPE);
-        
when(tlsConfiguration.getTruststorePassword()).thenReturn(TRUST_STORE_PASSWORD);
+    void testGetConnectionPropertiesSslModeVerifyIdentity() {
+        assertSslModeMapped(SSLMode.VERIFY_IDENTITY);
+    }
 
-        final StandardConnectionPropertiesProvider provider = new 
StandardConnectionPropertiesProvider(SSLMode.REQUIRED, tlsConfiguration);
+    private void assertSslModeMapped(final SSLMode sslMode) {
+        final StandardConnectionPropertiesProvider provider = new 
StandardConnectionPropertiesProvider(sslMode);
 
         final Map<String, String> properties = 
provider.getConnectionProperties();
 
         assertNotNull(properties);
-
-        final String useSsl = 
properties.get(SecurityProperty.USE_SSL.getProperty());
-        assertEquals(Boolean.TRUE.toString(), useSsl);
-
-        final String requireSsl = 
properties.get(SecurityProperty.REQUIRE_SSL.getProperty());
-        assertEquals(Boolean.TRUE.toString(), requireSsl);
-
-        final String protocols = 
properties.get(SecurityProperty.ENABLED_TLS_PROTOCOLS.getProperty());
-        assertEquals(latestProtocol, protocols);
-
-        final String clientCertificateUrl = 
properties.get(SecurityProperty.CLIENT_CERTIFICATE_KEY_STORE_URL.getProperty());
-        assertEquals(KEY_STORE_PATH, clientCertificateUrl);
-
-        final String clientCertificateType = 
properties.get(SecurityProperty.CLIENT_CERTIFICATE_KEY_STORE_TYPE.getProperty());
-        assertEquals(KEY_STORE_TYPE.getType(), clientCertificateType);
-
-        final String clientCertificatePassword = 
properties.get(SecurityProperty.CLIENT_CERTIFICATE_KEY_STORE_PASSWORD.getProperty());
-        assertEquals(KEY_STORE_PASSWORD, clientCertificatePassword);
-
-        final String trustCertificateUrl = 
properties.get(SecurityProperty.TRUST_CERTIFICATE_KEY_STORE_URL.getProperty());
-        assertEquals(TRUST_STORE_PATH, trustCertificateUrl);
-
-        final String trustCertificateType = 
properties.get(SecurityProperty.TRUST_CERTIFICATE_KEY_STORE_TYPE.getProperty());
-        assertEquals(TRUST_STORE_TYPE.getType(), trustCertificateType);
-
-        final String trustCertificatePassword = 
properties.get(SecurityProperty.TRUST_CERTIFICATE_KEY_STORE_PASSWORD.getProperty());
-        assertEquals(TRUST_STORE_PASSWORD, trustCertificatePassword);
+        assertEquals(sslMode.toString(), properties.get(SSL_MODE_PROPERTY));
+        assertFalse(properties.containsKey(SSL_CONTEXT_PROVIDER_PROPERTY),
+                "The SSLContext provider name is registered per connection 
attempt and must not be produced by the properties provider");
     }
 }

Reply via email to