ARTEMIS-3117 Provide CachingOpenSSLContextFactory
to mitigate performance degradation in JDK 11 during TLS connection initialization.
This commit is contained in:
parent
2f5b9325f3
commit
026f3859a2
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 +
|
||||
"]";
|
||||
}
|
||||
}
|
|
@ -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() {
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
org.apache.activemq.artemis.core.remoting.impl.ssl.DefaultOpenSSLContextFactory
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue