This is an automated email from the ASF dual-hosted git repository.
jbertram pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git
The following commit(s) were added to refs/heads/master by this push:
new 026f385 ARTEMIS-3117 Provide CachingOpenSSLContextFactory to mitigate
performance degradation in JDK 11 during TLS connection initialization.
new c0055dd This closes #3459
026f385 is described below
commit 026f3859a2c8b27975aabf95451d061f8a11314f
Author: sebthom <[email protected]>
AuthorDate: Fri Feb 19 13:04:37 2021 +0100
ARTEMIS-3117 Provide CachingOpenSSLContextFactory
to mitigate performance degradation in JDK 11 during TLS connection
initialization.
---
.../core/remoting/impl/netty/NettyConnector.java | 62 +++---
.../impl/ssl/CachingOpenSSLContextFactory.java | 75 +++++++
.../impl/ssl/CachingSSLContextFactory.java | 73 ++++---
.../impl/ssl/DefaultOpenSSLContextFactory.java | 61 ++++++
.../impl/ssl/DefaultSSLContextFactory.java | 43 ++--
.../artemis/core/remoting/impl/ssl/SSLSupport.java | 16 ++
.../core/remoting/ssl/OpenSSLContextFactory.java | 65 ++++++
.../ssl/OpenSSLContextFactoryProvider.java | 46 +++++
.../spi/core/remoting/ssl/SSLContextConfig.java | 220 +++++++++++++++++++++
.../spi/core/remoting/ssl/SSLContextFactory.java | 49 +++--
...mis.spi.core.remoting.ssl.OpenSSLContextFactory | 1 +
.../ssl/OpenSSLContextFactoryProviderTest.java | 31 +++
.../core/remoting/impl/netty/NettyAcceptor.java | 36 ++--
.../remoting/server/impl/RemotingServiceImpl.java | 2 +
docs/user-manual/en/configuring-transports.md | 33 +++-
15 files changed, 668 insertions(+), 145 deletions(-)
diff --git
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector.java
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector.java
index abad1a4..5592293 100644
---
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector.java
+++
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyConnector.java
@@ -104,6 +104,7 @@ import io.netty.util.ResourceLeakDetector;
import io.netty.util.ResourceLeakDetector.Level;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GlobalEventExecutor;
+import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.core.client.ActiveMQClientLogger;
import org.apache.activemq.artemis.core.client.ActiveMQClientMessageBundle;
@@ -116,6 +117,9 @@ import
org.apache.activemq.artemis.spi.core.remoting.BufferHandler;
import
org.apache.activemq.artemis.spi.core.remoting.ClientConnectionLifeCycleListener;
import org.apache.activemq.artemis.spi.core.remoting.ClientProtocolManager;
import org.apache.activemq.artemis.spi.core.remoting.Connection;
+import
org.apache.activemq.artemis.spi.core.remoting.ssl.OpenSSLContextFactoryProvider;
+import org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextConfig;
+import
org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextFactoryProvider;
import org.apache.activemq.artemis.utils.ConfigurationHelper;
import org.apache.activemq.artemis.utils.FutureLatch;
import org.apache.activemq.artemis.utils.IPV6Util;
@@ -123,9 +127,6 @@ import org.jboss.logging.Logger;
import static org.apache.activemq.artemis.utils.Base64.encodeBytes;
-import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
-import
org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextFactoryProvider;
-
public class NettyConnector extends AbstractConnector {
public static String NIO_CONNECTOR_TYPE = "NIO";
@@ -621,11 +622,23 @@ public class NettyConnector extends AbstractConnector {
if (sslEnabled && !useServlet) {
- SSLEngine engine;
+ final SSLContextConfig sslContextConfig =
SSLContextConfig.builder()
+ .keystoreProvider(realKeyStoreProvider)
+ .keystorePath(realKeyStorePath)
+ .keystorePassword(realKeyStorePassword)
+ .truststoreProvider(realTrustStoreProvider)
+ .truststorePath(realTrustStorePath)
+ .truststorePassword(realTrustStorePassword)
+ .trustManagerFactoryPlugin(trustManagerFactoryPlugin)
+ .crlPath(crlPath)
+ .trustAll(trustAll)
+ .build();
+
+ final SSLEngine engine;
if (sslProvider.equals(TransportConstants.OPENSSL_PROVIDER)) {
- engine = loadOpenSslEngine(channel.alloc(),
realKeyStoreProvider, realKeyStorePath, realKeyStorePassword,
realTrustStoreProvider, realTrustStorePath, realTrustStorePassword);
+ engine = loadOpenSslEngine(channel.alloc(),
sslContextConfig);
} else {
- engine = loadJdkSslEngine(realKeyStoreProvider,
realKeyStorePath, realKeyStorePassword, realTrustStoreProvider,
realTrustStorePath, realTrustStorePassword);
+ engine = loadJdkSslEngine(sslContextConfig);
}
engine.setUseClientMode(true);
@@ -710,16 +723,10 @@ public class NettyConnector extends AbstractConnector {
ActiveMQClientLogger.LOGGER.startedNettyConnector(connectorType,
TransportConstants.NETTY_VERSION, host, port);
}
- private SSLEngine loadJdkSslEngine(String keystoreProvider,
- String keystorePath,
- String keystorePassword,
- String truststoreProvider,
- String truststorePath,
- String truststorePassword) throws
Exception {
- SSLContext context =
SSLContextFactoryProvider.getSSLContextFactory().getSSLContext(configuration,
- keystoreProvider, keystorePath, keystorePassword,
- truststoreProvider, truststorePath, truststorePassword,
- crlPath, trustManagerFactoryPlugin, trustAll);
+ private SSLEngine loadJdkSslEngine(final SSLContextConfig sslContextConfig)
throws Exception {
+ final SSLContext context =
SSLContextFactoryProvider.getSSLContextFactory()
+ .getSSLContext(sslContextConfig, configuration);
+
Subject subject = null;
if (kerb5Config != null) {
LoginContext loginContext = new LoginContext(kerb5Config);
@@ -741,26 +748,9 @@ public class NettyConnector extends AbstractConnector {
return engine;
}
- private SSLEngine loadOpenSslEngine(ByteBufAllocator alloc,
- String keystoreProvider,
- String keystorePath,
- String keystorePassword,
- String truststoreProvider,
- String truststorePath,
- String truststorePassword) throws
Exception {
-
-
- SslContext context = new SSLSupport()
- .setKeystoreProvider(keystoreProvider)
- .setKeystorePath(keystorePath)
- .setKeystorePassword(keystorePassword)
- .setTruststoreProvider(truststoreProvider)
- .setTruststorePath(truststorePath)
- .setTruststorePassword(truststorePassword)
- .setSslProvider(sslProvider)
- .setTrustAll(trustAll)
- .setTrustManagerFactoryPlugin(trustManagerFactoryPlugin)
- .createNettyClientContext();
+ private SSLEngine loadOpenSslEngine(final ByteBufAllocator alloc, final
SSLContextConfig sslContextConfig) throws Exception {
+ final SslContext context =
OpenSSLContextFactoryProvider.getOpenSSLContextFactory()
+ .getClientSslContext(sslContextConfig, configuration);
Subject subject = null;
if (kerb5Config != null) {
diff --git
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/CachingOpenSSLContextFactory.java
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/CachingOpenSSLContextFactory.java
new file mode 100644
index 0000000..7b9abd3
--- /dev/null
+++
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/CachingOpenSSLContextFactory.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2021 The Apache Software Foundation.
+ *
+ * Licensed 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.activemq.artemis.core.remoting.impl.ssl;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import io.netty.handler.ssl.SslContext;
+import org.apache.activemq.artemis.spi.core.remoting.ssl.OpenSSLContextFactory;
+import org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextConfig;
+
+/**
+ * {@link OpenSSLContextFactory} providing a cache of {@link SslContext}.
+ * Since {@link SslContext} should be reused instead of recreated and are
thread safe.
+ * To activate it you need to allow this Service to be discovered by having a
+ *
<code>META-INF/services/org.apache.activemq.artemis.spi.core.remoting.ssl.OpenSSLContextFactory</code>
+ * file with
<code>org.apache.activemq.artemis.core.remoting.impl.ssl.CachingOpenSSLContextFactory</code>
+ * as value.
+ */
+public class CachingOpenSSLContextFactory extends DefaultOpenSSLContextFactory
{
+
+ private final ConcurrentMap<SSLContextConfig, SslContext>
clientSslContextCache = new ConcurrentHashMap<>(2);
+ private final ConcurrentMap<SSLContextConfig, SslContext>
serversSslContextCache = new ConcurrentHashMap<>(2);
+
+ @Override
+ public void clearSslContexts() {
+ clientSslContextCache.clear();
+ serversSslContextCache.clear();
+ }
+
+ @Override
+ public SslContext getClientSslContext(final SSLContextConfig config, final
Map<String, Object> additionalOpts) throws Exception {
+ return clientSslContextCache.computeIfAbsent(config,
this::getClientSslContext);
+ }
+
+ private SslContext getClientSslContext(final SSLContextConfig config) {
+ try {
+ return super.getClientSslContext(config, null);
+ } catch (final Exception ex) {
+ throw new RuntimeException("An unexpected exception occured while
creating Client OpenSSL Context with " + config, ex);
+ }
+ }
+
+ @Override
+ public SslContext getServerSslContext(final SSLContextConfig config, final
Map<String, Object> additionalOpts) throws Exception {
+ return clientSslContextCache.computeIfAbsent(config,
this::getServerSslContext);
+ }
+
+ private SslContext getServerSslContext(final SSLContextConfig config) {
+ try {
+ return super.getServerSslContext(config, null);
+ } catch (final Exception ex) {
+ throw new RuntimeException("An unexpected exception occured while
creating Server OpenSSL Context " + config, ex);
+ }
+ }
+
+ @Override
+ public int getPriority() {
+ return 10;
+ }
+}
diff --git
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/CachingSSLContextFactory.java
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/CachingSSLContextFactory.java
index 8fce20b..24b3b41 100644
---
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/CachingSSLContextFactory.java
+++
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/CachingSSLContextFactory.java
@@ -15,66 +15,61 @@
*/
package org.apache.activemq.artemis.core.remoting.impl.ssl;
-import java.util.Collections;
-import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import javax.net.ssl.SSLContext;
+
+import io.netty.handler.ssl.SslContext;
import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
+import org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextConfig;
+import org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextFactory;
import org.apache.activemq.artemis.utils.ConfigurationHelper;
/**
- * SSLContextFactory providing a cache of SSLContext.
- * Since SSLContext should be reused instead of recreated and are thread safe.
- * To activate it uou need to allow this Service to be discovered by having a
+ * {@link SSLContextFactory} providing a cache of {@link SSLContext}.
+ * Since {@link SSLContext} should be reused instead of recreated and are
thread safe.
+ * To activate it you need to allow this Service to be discovered by having a
*
<code>META-INF/services/org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextFactory</code>
- * file with <code>
org.apache.activemq.artemis.core.remoting.impl.ssl.CachingSSLContextFactory</code>
+ * file with
<code>org.apache.activemq.artemis.core.remoting.impl.ssl.CachingSSLContextFactory</code>
* as value.
*/
public class CachingSSLContextFactory extends DefaultSSLContextFactory {
- private static final Map<String, SSLContext> SSL_CONTEXTS =
Collections.synchronizedMap(new HashMap<>());
+ private static final ConcurrentMap<Object, SSLContext> sslContextCache =
new ConcurrentHashMap<>(2);
@Override
public void clearSSLContexts() {
- SSL_CONTEXTS.clear();
+ sslContextCache.clear();
}
@Override
- public SSLContext getSSLContext(Map<String, Object> configuration,
- String keystoreProvider, String keystorePath, String
keystorePassword,
- String truststoreProvider, String truststorePath, String
truststorePassword,
- String crlPath, String trustManagerFactoryPlugin, boolean trustAll)
throws Exception {
- String sslContextName = getSSLContextName(configuration, keystorePath,
keystoreProvider, truststorePath, truststoreProvider);
- if (!SSL_CONTEXTS.containsKey(sslContextName)) {
- SSL_CONTEXTS.put(sslContextName, createSSLContext(configuration,
- keystoreProvider, keystorePath, keystorePassword,
- truststoreProvider, truststorePath, truststorePassword,
- crlPath, trustManagerFactoryPlugin, trustAll));
- }
- return SSL_CONTEXTS.get(sslContextName);
+ public SSLContext getSSLContext(final SSLContextConfig config, final
Map<String, Object> additionalOpts) throws Exception {
+ final Object cacheKey = getCacheKey(config, additionalOpts);
+ return sslContextCache.computeIfAbsent(cacheKey, key -> {
+ try {
+ return CachingSSLContextFactory.super.getSSLContext(config,
additionalOpts);
+ } catch (final Exception ex) {
+ throw new RuntimeException("An unexpected exception occured while
creating JDK SSLContext with " + config, ex);
+ }
+ });
}
/**
- * Obtain the sslContextName :
- * - if available the 'sslContext' from the configuration
- * - otherwise if available the keyStorePath + '_' + keystoreProvider
- * - otherwise the truststorePath + '_' + truststoreProvider.
- * @param configuration
- * @param keyStorePath
- * @param keystoreProvider
- * @param truststorePath
- * @param truststoreProvider
- * @return the ley associated to the SSLContext.
+ * Obtains/calculates a cache key for the corresponding {@link SslContext}.
+ * <ol>
+ * <li>If <code>config</code> contains an entry with key "sslContext", the
associated value is returned
+ * <li>Otherwise, the provided {@link SSLContextConfig} is used as cache
key.
+ * </ol>
+ *
+ * @return the SSL context name to cache/retrieve the {@link SslContext}.
*/
- protected String getSSLContextName(Map<String, Object> configuration,
String keyStorePath, String keystoreProvider, String truststorePath, String
truststoreProvider) {
- String sslContextName =
ConfigurationHelper.getStringProperty(TransportConstants.SSL_CONTEXT_PROP_NAME,
null, configuration);
- if (sslContextName == null) {
- if (keyStorePath != null) {
- return keyStorePath + '_' + keystoreProvider;
- }
- return truststorePath + '_' + truststoreProvider;
- }
- return sslContextName;
+ protected Object getCacheKey(final SSLContextConfig config, final
Map<String, Object> additionalOpts) {
+ final Object cacheKey =
ConfigurationHelper.getStringProperty(TransportConstants.SSL_CONTEXT_PROP_NAME,
null, additionalOpts);
+ if (cacheKey != null)
+ return cacheKey;
+
+ return config;
}
@Override
diff --git
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/DefaultOpenSSLContextFactory.java
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/DefaultOpenSSLContextFactory.java
new file mode 100644
index 0000000..b5ce683
--- /dev/null
+++
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/DefaultOpenSSLContextFactory.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2021 The Apache Software Foundation.
+ *
+ * Licensed 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.activemq.artemis.core.remoting.impl.ssl;
+
+import java.util.Map;
+
+import io.netty.handler.ssl.SslContext;
+import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector;
+import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
+import org.apache.activemq.artemis.spi.core.remoting.ssl.OpenSSLContextFactory;
+import org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextConfig;
+
+/**
+ * Default {@link OpenSSLContextFactory} for use in {@link NettyConnector} and
NettyAcceptor.
+ */
+public class DefaultOpenSSLContextFactory implements OpenSSLContextFactory {
+
+ /**
+ * @param additionalOpts not used by this implementation
+ *
+ * @return an {@link SslContext} instance for the given configuration.
+ */
+ @Override
+ public SslContext getClientSslContext(final SSLContextConfig config, final
Map<String, Object> additionalOpts) throws Exception {
+ log.debugf("Creating Client OpenSSL Context with %s", config);
+ return new SSLSupport(config)
+ .setSslProvider(TransportConstants.OPENSSL_PROVIDER)
+ .createNettyClientContext();
+ }
+
+ /**
+ * @param additionalOpts not used by this implementation
+ *
+ * @return an {@link SslContext} instance for the given configuration.
+ */
+ @Override
+ public SslContext getServerSslContext(final SSLContextConfig config, final
Map<String, Object> additionalOpts) throws Exception {
+ log.debugf("Creating Server OpenSSL Context with %s", config);
+ return new SSLSupport(config)
+ .setSslProvider(TransportConstants.OPENSSL_PROVIDER)
+ .createNettyContext();
+ }
+
+ @Override
+ public int getPriority() {
+ return 5;
+ }
+}
diff --git
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/DefaultSSLContextFactory.java
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/DefaultSSLContextFactory.java
index 46ce450..462d6d6 100644
---
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/DefaultSSLContextFactory.java
+++
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/DefaultSSLContextFactory.java
@@ -18,6 +18,7 @@ package org.apache.activemq.artemis.core.remoting.impl.ssl;
import java.util.Map;
import javax.net.ssl.SSLContext;
import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
+import org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextConfig;
import org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextFactory;
import org.apache.activemq.artemis.utils.ConfigurationHelper;
@@ -26,43 +27,23 @@ import
org.apache.activemq.artemis.utils.ConfigurationHelper;
*/
public class DefaultSSLContextFactory implements SSLContextFactory {
-
@Override
- public SSLContext getSSLContext(Map<String, Object> configuration,
- String keystoreProvider, String keystorePath, String
keystorePassword,
- String truststoreProvider, String truststorePath, String
truststorePassword,
- String crlPath, String trustManagerFactoryPlugin, boolean trustAll)
throws Exception {
- return createSSLContext(configuration,
- keystoreProvider, keystorePath, keystorePassword,
- truststoreProvider, truststorePath, truststorePassword,
- crlPath, trustManagerFactoryPlugin, trustAll);
- }
+ public SSLContext getSSLContext(final SSLContextConfig config, final
Map<String, Object> additionalOpts) throws Exception {
+ final boolean useDefaultSslContext =
ConfigurationHelper.getBooleanProperty(
+ TransportConstants.USE_DEFAULT_SSL_CONTEXT_PROP_NAME,
+ TransportConstants.DEFAULT_USE_DEFAULT_SSL_CONTEXT,
+ additionalOpts
+ );
- protected SSLContext createSSLContext(Map<String, Object> configuration,
- String keystoreProvider, String keystorePath, String
keystorePassword,
- String truststoreProvider, String truststorePath, String
truststorePassword,
- String crlPath, String trustManagerFactoryPlugin, boolean trustAll)
throws Exception {
- if (log.isDebugEnabled()) {
- final StringBuilder builder = new StringBuilder();
- configuration.forEach((k, v) ->
builder.append("\r\n").append(k).append("=").append(k.toLowerCase().contains("password")
? "****" : v));
- log.debugf("Creating SSL context with configuration %s",
builder.toString());
- }
- boolean useDefaultSslContext =
ConfigurationHelper.getBooleanProperty(TransportConstants.USE_DEFAULT_SSL_CONTEXT_PROP_NAME,
TransportConstants.DEFAULT_USE_DEFAULT_SSL_CONTEXT, configuration);
if (useDefaultSslContext) {
+ log.debug("Using the Default JDK SSLContext.");
return SSLContext.getDefault();
}
- return new SSLSupport()
- .setKeystoreProvider(keystoreProvider)
- .setKeystorePath(keystorePath)
- .setKeystorePassword(keystorePassword)
- .setTruststoreProvider(truststoreProvider)
- .setTruststorePath(truststorePath)
- .setTruststorePassword(truststorePassword)
- .setTrustAll(trustAll)
- .setCrlPath(crlPath)
- .setTrustManagerFactoryPlugin(trustManagerFactoryPlugin)
- .createContext();
+
+ log.debugf("Creating JDK SSLContext with %s", config);
+ return new SSLSupport(config).createContext();
}
+
@Override
public int getPriority() {
return 5;
diff --git
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/SSLSupport.java
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/SSLSupport.java
index 9e2d319..8e59b06 100644
---
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/SSLSupport.java
+++
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/ssl/SSLSupport.java
@@ -46,6 +46,7 @@ import io.netty.handler.ssl.SslProvider;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import org.apache.activemq.artemis.api.core.TrustManagerFactoryPlugin;
import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
+import org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextConfig;
import org.apache.activemq.artemis.utils.ClassloadingUtil;
/**
@@ -66,6 +67,21 @@ public class SSLSupport {
private boolean trustAll = TransportConstants.DEFAULT_TRUST_ALL;
private String trustManagerFactoryPlugin =
TransportConstants.DEFAULT_TRUST_MANAGER_FACTORY_PLUGIN;
+ public SSLSupport() {
+ }
+
+ public SSLSupport(final SSLContextConfig config) {
+ keystoreProvider = config.getKeystoreProvider();
+ keystorePath = config.getKeystorePath();
+ keystorePassword = config.getKeystorePassword();
+ truststoreProvider = config.getTruststoreProvider();
+ truststorePath = config.getTruststorePath();
+ truststorePassword = config.getTruststorePassword();
+ crlPath = config.getCrlPath();
+ trustAll = config.isTrustAll();
+ trustManagerFactoryPlugin = config.getTrustManagerFactoryPlugin();
+ }
+
public String getKeystoreProvider() {
return keystoreProvider;
}
diff --git
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/remoting/ssl/OpenSSLContextFactory.java
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/remoting/ssl/OpenSSLContextFactory.java
new file mode 100644
index 0000000..8266ec7
--- /dev/null
+++
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/remoting/ssl/OpenSSLContextFactory.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2021 The Apache Software Foundation.
+ *
+ * Licensed 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.activemq.artemis.spi.core.remoting.ssl;
+
+import java.util.Map;
+
+import io.netty.handler.ssl.SslContext;
+import org.jboss.logging.Logger;
+
+/**
+ * Service interface to create an {@link SslContext} for a configuration.
+ * This is ONLY used with OpenSSL.
+ * To create and use your own implementation you need to create a file
+ *
<code>META-INF/services/org.apache.activemq.artemis.spi.core.remoting.ssl.OpenSSLContextFactory</code>
+ * in your jar and fill it with the full qualified name of your implementation.
+ */
+public interface OpenSSLContextFactory extends
Comparable<OpenSSLContextFactory> {
+
+ Logger log = Logger.getLogger(OpenSSLContextFactory.class);
+
+ /**
+ * Release any cached {@link SslContext} instances.
+ */
+ default void clearSslContexts() {
+ }
+
+ @Override
+ default int compareTo(final OpenSSLContextFactory other) {
+ return this.getPriority() - other.getPriority();
+ }
+
+ /**
+ * @param additionalOpts implementation specific additional options.
+ *
+ * @return an {@link SslContext} instance for the given configuration.
+ */
+ SslContext getClientSslContext(SSLContextConfig config, Map<String, Object>
additionalOpts) throws Exception;
+
+ /**
+ * @param additionalOpts implementation specific additional options.
+ *
+ * @return an {@link SslContext} instance for the given configuration.
+ */
+ SslContext getServerSslContext(SSLContextConfig config, Map<String, Object>
additionalOpts) throws Exception;
+
+ /**
+ * The priority for the {@link OpenSSLContextFactory} when resolving the
service to get the implementation.
+ * This is used when selecting the implementation when several
implementations are loaded.
+ * The highest priority implementation will be used.
+ */
+ int getPriority();
+}
diff --git
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/remoting/ssl/OpenSSLContextFactoryProvider.java
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/remoting/ssl/OpenSSLContextFactoryProvider.java
new file mode 100644
index 0000000..fbad75a
--- /dev/null
+++
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/remoting/ssl/OpenSSLContextFactoryProvider.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2021 The Apache Software Foundation.
+ *
+ * Licensed 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.activemq.artemis.spi.core.remoting.ssl;
+
+import java.util.ServiceLoader;
+
+/**
+ * Provider that loads all registered {@link OpenSSLContextFactory} services
and returns the one with the highest priority.
+ */
+public class OpenSSLContextFactoryProvider {
+
+ private static final OpenSSLContextFactory FACTORY;
+ static {
+ OpenSSLContextFactory factoryWithHighestPrio = null;
+ for (OpenSSLContextFactory factory :
ServiceLoader.load(OpenSSLContextFactory.class)) {
+ if (factoryWithHighestPrio == null || factory.getPriority() >
factoryWithHighestPrio.getPriority()) {
+ factoryWithHighestPrio = factory;
+ }
+ }
+
+ if (factoryWithHighestPrio == null)
+ throw new IllegalStateException("No OpenSSLContextFactory
registered!");
+
+ FACTORY = factoryWithHighestPrio;
+ }
+
+ /**
+ * @return the {@link OpenSSLContextFactory} with the higher priority.
+ */
+ public static OpenSSLContextFactory getOpenSSLContextFactory() {
+ return FACTORY;
+ }
+}
diff --git
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/remoting/ssl/SSLContextConfig.java
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/remoting/ssl/SSLContextConfig.java
new file mode 100644
index 0000000..12b79e8
--- /dev/null
+++
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/remoting/ssl/SSLContextConfig.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2021 The Apache Software Foundation.
+ *
+ * Licensed 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.activemq.artemis.spi.core.remoting.ssl;
+
+import java.util.Objects;
+
+import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
+
+/**
+ * This class holds configuration parameters for SSL context initialization.
+ * To be used with {@link SSLContextFactory} and {@link OpenSSLContextFactory}.
+ * <br>
+ * Use {@link SSLContextConfig#builder()} to create new immutable instances.
+ */
+public final class SSLContextConfig {
+
+ public static final class Builder {
+ private String keystorePath = TransportConstants.DEFAULT_KEYSTORE_PATH;
+ private String keystorePassword =
TransportConstants.DEFAULT_KEYSTORE_PASSWORD;
+ private String keystoreProvider =
TransportConstants.DEFAULT_KEYSTORE_PROVIDER;
+ private String truststorePath =
TransportConstants.DEFAULT_TRUSTSTORE_PATH;
+ private String truststorePassword =
TransportConstants.DEFAULT_TRUSTSTORE_PASSWORD;
+ private String truststoreProvider =
TransportConstants.DEFAULT_TRUSTSTORE_PROVIDER;
+ private String crlPath = TransportConstants.DEFAULT_CRL_PATH;
+ private String trustManagerFactoryPlugin =
TransportConstants.DEFAULT_TRUST_MANAGER_FACTORY_PLUGIN;
+ private boolean trustAll = TransportConstants.DEFAULT_TRUST_ALL;
+
+ private Builder() {
+ }
+
+ public Builder from(final SSLContextConfig config) {
+ if (config == null)
+ return this;
+
+ keystorePath = config.getKeystorePath();
+ keystorePassword = config.getKeystorePassword();
+ keystoreProvider = config.getKeystoreProvider();
+ truststorePath = config.getTruststorePath();
+ truststorePassword = config.getTruststorePassword();
+ crlPath = config.getCrlPath();
+ truststoreProvider = config.getTruststoreProvider();
+ trustAll = config.trustAll;
+ return this;
+ }
+
+ public SSLContextConfig build() {
+ return new SSLContextConfig(
+ keystoreProvider, keystorePath, keystorePassword,
+ truststoreProvider, truststorePath, truststorePassword,
+ crlPath, trustManagerFactoryPlugin, trustAll
+ );
+ }
+
+ public Builder keystorePath(final String keystorePath) {
+ this.keystorePath = keystorePath;
+ return this;
+ }
+
+ public Builder keystorePassword(final String keystorePassword) {
+ this.keystorePassword = keystorePassword;
+ return this;
+ }
+
+ public Builder keystoreProvider(final String keystoreProvider) {
+ this.keystoreProvider = keystoreProvider;
+ return this;
+ }
+
+ public Builder truststorePath(final String truststorePath) {
+ this.truststorePath = truststorePath;
+ return this;
+ }
+
+ public Builder truststorePassword(final String truststorePassword) {
+ this.truststorePassword = truststorePassword;
+ return this;
+ }
+
+ public Builder truststoreProvider(final String truststoreProvider) {
+ this.truststoreProvider = truststoreProvider;
+ return this;
+ }
+
+ public Builder crlPath(final String crlPath) {
+ this.crlPath = crlPath;
+ return this;
+ }
+
+ public Builder trustAll(final boolean trustAll) {
+ this.trustAll = trustAll;
+ return this;
+ }
+
+ public Builder trustManagerFactoryPlugin(final String
trustManagerFactoryPlugin) {
+ this.trustManagerFactoryPlugin = trustManagerFactoryPlugin;
+ return this;
+ }
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ private final String keystorePath;
+ private final String keystorePassword;
+ private final String keystoreProvider;
+ private final String truststorePath;
+ private final String truststorePassword;
+ private final String truststoreProvider;
+ private final String trustManagerFactoryPlugin;
+ private final String crlPath;
+ private final boolean trustAll;
+ private final int hashCode;
+
+ private SSLContextConfig(
+ final String keystoreProvider, final String keystorePath, final String
keystorePassword,
+ final String truststoreProvider, final String truststorePath, final
String truststorePassword,
+ final String crlPath, final String trustManagerFactoryPlugin, final
boolean trustAll
+ ) {
+ this.keystorePath = keystorePath;
+ this.keystoreProvider = keystoreProvider;
+ this.keystorePassword = keystorePassword;
+ this.truststorePath = truststorePath;
+ this.truststorePassword = truststorePassword;
+ this.truststoreProvider = truststoreProvider;
+ this.trustManagerFactoryPlugin = trustManagerFactoryPlugin;
+ this.crlPath = crlPath;
+ this.trustAll = trustAll;
+ hashCode = Objects.hash(
+ keystorePath, keystoreProvider,
+ truststorePath, truststoreProvider,
+ crlPath, trustManagerFactoryPlugin, trustAll
+ );
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null || getClass() != obj.getClass())
+ return false;
+ final SSLContextConfig other = (SSLContextConfig) obj;
+ return Objects.equals(keystorePath, other.keystorePath)
+ && Objects.equals(keystoreProvider, other.keystoreProvider)
+ && Objects.equals(truststorePath, other.truststorePath)
+ && Objects.equals(truststoreProvider, other.truststoreProvider)
+ && Objects.equals(crlPath, other.crlPath)
+ && Objects.equals(trustManagerFactoryPlugin,
other.trustManagerFactoryPlugin)
+ && trustAll == other.trustAll;
+ }
+
+ public String getCrlPath() {
+ return crlPath;
+ }
+
+ public String getKeystorePassword() {
+ return keystorePassword;
+ }
+
+ public String getKeystorePath() {
+ return keystorePath;
+ }
+
+ public String getKeystoreProvider() {
+ return keystoreProvider;
+ }
+
+ public String getTrustManagerFactoryPlugin() {
+ return trustManagerFactoryPlugin;
+ }
+
+ public String getTruststorePassword() {
+ return truststorePassword;
+ }
+
+ public String getTruststorePath() {
+ return truststorePath;
+ }
+
+ public String getTruststoreProvider() {
+ return truststoreProvider;
+ }
+
+ @Override
+ public int hashCode() {
+ return hashCode;
+ }
+
+ public boolean isTrustAll() {
+ return trustAll;
+ }
+
+ @Override
+ public String toString() {
+ return "SSLSupport [" +
+ "keystoreProvider=" + keystoreProvider +
+ ", keystorePath=" + keystorePath +
+ ", keystorePassword=" + (keystorePassword == null ? null : "******") +
+ ", truststoreProvider=" + truststoreProvider +
+ ", truststorePath=" + truststorePath +
+ ", truststorePassword=" + (truststorePassword == null ? null :
"******") +
+ ", crlPath=" + crlPath +
+ ", trustAll=" + trustAll +
+ ", trustManagerFactoryPlugin=" + trustManagerFactoryPlugin +
+ "]";
+ }
+}
diff --git
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/remoting/ssl/SSLContextFactory.java
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/remoting/ssl/SSLContextFactory.java
index 436092d..389e9eb 100644
---
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/remoting/ssl/SSLContextFactory.java
+++
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/remoting/ssl/SSLContextFactory.java
@@ -30,24 +30,43 @@ public interface SSLContextFactory extends
Comparable<SSLContextFactory> {
Logger log = Logger.getLogger(SSLContextFactory.class);
/**
- * Obtain a SSLContext from the configuration.
- * @param configuration
- * @param keystoreProvider
- * @param keystorePath
- * @param keystorePassword
- * @param truststoreProvider
- * @param truststorePath
- * @param truststorePassword
- * @param crlPath
- * @param trustManagerFactoryPlugin
- * @param trustAll
- * @return a SSLContext instance.
- * @throws Exception
+ * @return an {@link SSLContext} for the given configuration.
+ *
+ * @deprecated use {@link #getSSLContext(SSLContextConfig, Map)} instead
*/
- SSLContext getSSLContext(Map<String, Object> configuration,
+ @SuppressWarnings("unused")
+ @Deprecated
+ default SSLContext getSSLContext(Map<String, Object> configuration,
String keystoreProvider, String keystorePath, String
keystorePassword,
String truststoreProvider, String truststorePath, String
truststorePassword,
- String crlPath, String trustManagerFactoryPlugin, boolean trustAll)
throws Exception;
+ String crlPath, String trustManagerFactoryPlugin, boolean trustAll)
throws Exception {
+
+ final SSLContextConfig sslContextConfig = SSLContextConfig.builder()
+ .keystoreProvider(keystoreProvider)
+ .keystorePath(keystorePath)
+ .keystorePassword(keystorePassword)
+ .truststoreProvider(truststoreProvider)
+ .truststorePath(truststorePath)
+ .truststorePassword(truststorePassword)
+ .trustManagerFactoryPlugin(trustManagerFactoryPlugin)
+ .crlPath(crlPath)
+ .build();
+
+ return getSSLContext(sslContextConfig, configuration);
+ }
+
+ /**
+ * @param additionalOpts implementation specific additional options.
+ *
+ * @return an {@link SSLContext} for the given configuration.
+ */
+ default SSLContext getSSLContext(SSLContextConfig config, Map<String,
Object> additionalOpts) throws Exception {
+ return getSSLContext(additionalOpts,
+ config.getKeystoreProvider(), config.getKeystorePath(),
config.getKeystorePassword(),
+ config.getTruststoreProvider(), config.getTruststorePath(),
config.getTruststorePassword(),
+ config.getCrlPath(), config.getTrustManagerFactoryPlugin(),
config.isTrustAll()
+ );
+ }
default void clearSSLContexts() {
}
diff --git
a/artemis-core-client/src/main/resources/META-INF/services/org.apache.activemq.artemis.spi.core.remoting.ssl.OpenSSLContextFactory
b/artemis-core-client/src/main/resources/META-INF/services/org.apache.activemq.artemis.spi.core.remoting.ssl.OpenSSLContextFactory
new file mode 100644
index 0000000..a63f0dd
--- /dev/null
+++
b/artemis-core-client/src/main/resources/META-INF/services/org.apache.activemq.artemis.spi.core.remoting.ssl.OpenSSLContextFactory
@@ -0,0 +1 @@
+org.apache.activemq.artemis.core.remoting.impl.ssl.DefaultOpenSSLContextFactory
diff --git
a/artemis-core-client/src/test/java/org/apache/activemq/artemis/spi/core/remoting/ssl/OpenSSLContextFactoryProviderTest.java
b/artemis-core-client/src/test/java/org/apache/activemq/artemis/spi/core/remoting/ssl/OpenSSLContextFactoryProviderTest.java
new file mode 100644
index 0000000..b7530e5
--- /dev/null
+++
b/artemis-core-client/src/test/java/org/apache/activemq/artemis/spi/core/remoting/ssl/OpenSSLContextFactoryProviderTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 The Apache Software Foundation.
+ *
+ * Licensed 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.activemq.artemis.spi.core.remoting.ssl;
+
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+
+public class OpenSSLContextFactoryProviderTest {
+
+ /**
+ * Test to retrieve a {@link OpenSSLContextFactory} registered via
META-INF/services.
+ */
+ @Test
+ public void testGetOpenSSLContextFactory() {
+ assertNotNull(OpenSSLContextFactoryProvider.getOpenSSLContextFactory());
+ }
+}
diff --git
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
index ff10893..8cb43d3 100644
---
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
+++
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
@@ -92,6 +92,8 @@ import
org.apache.activemq.artemis.spi.core.protocol.ProtocolManager;
import org.apache.activemq.artemis.spi.core.remoting.BufferHandler;
import org.apache.activemq.artemis.spi.core.remoting.Connection;
import
org.apache.activemq.artemis.spi.core.remoting.ServerConnectionLifeCycleListener;
+import
org.apache.activemq.artemis.spi.core.remoting.ssl.OpenSSLContextFactoryProvider;
+import org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextConfig;
import
org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextFactoryProvider;
import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
import org.apache.activemq.artemis.utils.ConfigurationHelper;
@@ -167,6 +169,8 @@ public class NettyAcceptor extends AbstractAcceptor {
private final String crlPath;
+ private SSLContextConfig sslContextConfig;
+
private final String enabledCipherSuites;
private final String enabledProtocols;
@@ -229,7 +233,6 @@ public class NettyAcceptor extends AbstractAcceptor {
private final boolean autoStart;
-
final AtomicBoolean warningPrinted = new AtomicBoolean(false);
final Executor failureExecutor;
@@ -309,6 +312,17 @@ public class NettyAcceptor extends AbstractAcceptor {
sniHost =
ConfigurationHelper.getStringProperty(TransportConstants.SNIHOST_PROP_NAME,
TransportConstants.DEFAULT_SNIHOST_CONFIG, configuration);
trustManagerFactoryPlugin =
ConfigurationHelper.getStringProperty(TransportConstants.TRUST_MANAGER_FACTORY_PLUGIN_PROP_NAME,
TransportConstants.DEFAULT_TRUST_MANAGER_FACTORY_PLUGIN, configuration);
+
+ sslContextConfig = SSLContextConfig.builder()
+ .keystoreProvider(keyStoreProvider)
+ .keystorePath(keyStorePath)
+ .keystorePassword(keyStorePassword)
+ .truststoreProvider(trustStoreProvider)
+ .truststorePath(trustStorePath)
+ .truststorePassword(trustStorePassword)
+ .trustManagerFactoryPlugin(trustManagerFactoryPlugin)
+ .crlPath(crlPath)
+ .build();
} else {
keyStoreProvider = TransportConstants.DEFAULT_KEYSTORE_PROVIDER;
keyStorePath = TransportConstants.DEFAULT_KEYSTORE_PATH;
@@ -498,6 +512,10 @@ public class NettyAcceptor extends AbstractAcceptor {
public void setKeyStorePath(String keyStorePath) {
this.keyStorePath = keyStorePath;
this.configuration.put(TransportConstants.KEYSTORE_PATH_PROP_NAME,
keyStorePath);
+ sslContextConfig = SSLContextConfig.builder()
+ .from(sslContextConfig)
+ .keystorePath(keyStorePath)
+ .build();
}
/**
@@ -604,10 +622,7 @@ public class NettyAcceptor extends AbstractAcceptor {
final SSLContext context;
try {
checkSSLConfiguration();
- context =
SSLContextFactoryProvider.getSSLContextFactory().getSSLContext(configuration,
- keyStoreProvider, keyStorePath, keyStorePassword,
- trustStoreProvider, trustStorePath, trustStorePassword,
- crlPath, trustManagerFactoryPlugin,
TransportConstants.DEFAULT_TRUST_ALL);
+ context =
SSLContextFactoryProvider.getSSLContextFactory().getSSLContext(sslContextConfig,
configuration);
} catch (Exception e) {
IllegalStateException ise = new IllegalStateException("Unable to
create NettyAcceptor for " + host + ":" + port, e);
throw ise;
@@ -645,16 +660,7 @@ public class NettyAcceptor extends AbstractAcceptor {
final SslContext context;
try {
checkSSLConfiguration();
- context = new SSLSupport()
- .setKeystoreProvider(keyStoreProvider)
- .setKeystorePath(keyStorePath)
- .setKeystorePassword(keyStorePassword)
- .setTruststoreProvider(trustStoreProvider)
- .setTruststorePath(trustStorePath)
- .setTruststorePassword(trustStorePassword)
- .setSslProvider(sslProvider)
- .setTrustManagerFactoryPlugin(trustManagerFactoryPlugin)
- .createNettyContext();
+ context =
OpenSSLContextFactoryProvider.getOpenSSLContextFactory().getServerSslContext(sslContextConfig,
configuration);
} catch (Exception e) {
IllegalStateException ise = new IllegalStateException("Unable to
create NettyAcceptor for " + host + ":" + port, e);
throw ise;
diff --git
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/server/impl/RemotingServiceImpl.java
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/server/impl/RemotingServiceImpl.java
index 6a1c0f3..e53fd01 100644
---
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/server/impl/RemotingServiceImpl.java
+++
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/server/impl/RemotingServiceImpl.java
@@ -71,6 +71,7 @@ import
org.apache.activemq.artemis.spi.core.remoting.AcceptorFactory;
import org.apache.activemq.artemis.spi.core.remoting.BufferHandler;
import org.apache.activemq.artemis.spi.core.remoting.Connection;
import
org.apache.activemq.artemis.spi.core.remoting.ServerConnectionLifeCycleListener;
+import
org.apache.activemq.artemis.spi.core.remoting.ssl.OpenSSLContextFactoryProvider;
import
org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextFactoryProvider;
import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
import org.apache.activemq.artemis.utils.ConfigurationHelper;
@@ -386,6 +387,7 @@ public class RemotingServiceImpl implements
RemotingService, ServerConnectionLif
return;
}
SSLContextFactoryProvider.getSSLContextFactory().clearSSLContexts();
+
OpenSSLContextFactoryProvider.getOpenSSLContextFactory().clearSslContexts();
failureCheckAndFlushThread.close(criticalError);
diff --git a/docs/user-manual/en/configuring-transports.md
b/docs/user-manual/en/configuring-transports.md
index 652e404..f596653 100644
--- a/docs/user-manual/en/configuring-transports.md
+++ b/docs/user-manual/en/configuring-transports.md
@@ -318,9 +318,12 @@ additional properties:
- `sslContext`
-A key that can be used in conjunction with
`org.apache.activemq.artemis.core.remoting.impl.ssl.CachingSSLContextFactory`
-to cache created SSLContext and avoid recreating. Look [Configuring a
SSLContextFactory](#Configuring a SSLContextFactory)
-for more details.
+ An optional cache key only evaluated if
`org.apache.activemq.artemis.core.remoting.impl.ssl.CachingSSLContextFactory`
+ is active, to cache the initial created SSL context and reuse it. If not
+ specified CachingSSLContextFactory will automatically calculate a cache key
based on
+ the given keystore/truststore parameters.
+ See [Configuring an SSLContextFactory](#Configuring an SSLContextFactory)
+ for more details.
- `sslEnabled`
@@ -499,22 +502,34 @@ for more details.
[broker's classpath](using-server.md#adding-runtime-dependencies).
-#### Configuring a SSLContextFactory
+#### Configuring an SSLContextFactory
-If you have a `JDK` provider you can configure which SSLContextFactory to use.
-Currently we provide two implementations:
+If you use `JDK` as SSL provider (the default), you can configure which
+SSLContextFactory to use.
+Currently the following two implementations are provided:
- `org.apache.activemq.artemis.core.remoting.impl.ssl.DefaultSSLContextFactory`
+ (registered by the default)
- `org.apache.activemq.artemis.core.remoting.impl.ssl.CachingSSLContextFactory`
-but you can also add your own implementation of
`org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextFactory`.
-The implementations are loaded by a ServiceLoader, thus you need to declare
your implementation in
+You may also create your own implementation of
+`org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextFactory`.
+
+The implementations are loaded by a `java.util.ServiceLoader`, thus you need
to declare your implementation in
a
`META-INF/services/org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextFactory`
file.
If several implementations are available, the one with the highest `priority`
will be selected.
+
So for example, if you want to use
`org.apache.activemq.artemis.core.remoting.impl.ssl.CachingSSLContextFactory`
you need to add a
`META-INF/services/org.apache.activemq.artemis.spi.core.remoting.ssl.SSLContextFactory`
file
to your classpath with the content
`org.apache.activemq.artemis.core.remoting.impl.ssl.CachingSSLContextFactory`.
-**Note:** This mechanism doesn't work if you have selected `OPENSSL` as
provider.
+A similar mechanism exists for the `OPENSSL` SSL provider in which case you
can configure an OpenSSLContextFactory.
+Currently the following two implementations are provided:
+-
`org.apache.activemq.artemis.core.remoting.impl.ssl.DefaultOpenSSLContextFactory`
+ (registered by the default)
+-
`org.apache.activemq.artemis.core.remoting.impl.ssl.CachingOpenSSLContextFactory`
+
+You may also create your own implementation of
+`org.apache.activemq.artemis.spi.core.remoting.ssl.OpenSSLContextFactory`.
### Configuring Netty HTTP