This is an automated email from the ASF dual-hosted git repository.
pvillard pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push:
new 41a9406ae6 NIFI-15647 Add SSL configuration support for ActiveMQ
Artemis JMS connections
41a9406ae6 is described below
commit 41a9406ae671c9e7afbb9ccbc9a51f8ee0165bb7
Author: Chaffelson <[email protected]>
AuthorDate: Wed Feb 25 17:08:02 2026 +0000
NIFI-15647 Add SSL configuration support for ActiveMQ Artemis JMS
connections
JMSConnectionFactoryHandler now augments the broker URL with SSL transport
parameters (sslEnabled, trustStorePath, keyStorePath, etc.) when an
SSLContextService is configured and the connection factory implementation
is ActiveMQ Artemis. Previously, Artemis SSL settings were silently ignored
because Artemis does not expose bean-style SSL setters like Classic
ActiveMQ.
This closes #10936.
Signed-off-by: Pierre Villard <[email protected]>
---
.../nifi/jms/cf/JMSConnectionFactoryHandler.java | 70 +++++-
.../nifi/jms/cf/JMSConnectionFactoryProvider.java | 31 +++
.../jms/cf/JMSConnectionFactoryProviderTest.java | 264 +++++++++++++++++++++
3 files changed, 364 insertions(+), 1 deletion(-)
diff --git
a/nifi-extension-bundles/nifi-jms-bundle/nifi-jms-processors/src/main/java/org/apache/nifi/jms/cf/JMSConnectionFactoryHandler.java
b/nifi-extension-bundles/nifi-jms-bundle/nifi-jms-processors/src/main/java/org/apache/nifi/jms/cf/JMSConnectionFactoryHandler.java
index c585b9aad2..b6028afd7b 100644
---
a/nifi-extension-bundles/nifi-jms-bundle/nifi-jms-processors/src/main/java/org/apache/nifi/jms/cf/JMSConnectionFactoryHandler.java
+++
b/nifi-extension-bundles/nifi-jms-bundle/nifi-jms-processors/src/main/java/org/apache/nifi/jms/cf/JMSConnectionFactoryHandler.java
@@ -25,6 +25,8 @@ import org.apache.nifi.processor.ProcessContext;
import org.apache.nifi.ssl.SSLContextService;
import java.lang.reflect.Method;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -125,6 +127,7 @@ public class JMSConnectionFactoryHandler extends
CachedJMSConnectionFactoryHandl
String connectionFactoryValue =
context.getProperty(JMS_CONNECTION_FACTORY_IMPL).evaluateAttributeExpressions().getValue();
if (context.getProperty(JMS_BROKER_URI).isSet()) {
String brokerValue =
context.getProperty(JMS_BROKER_URI).evaluateAttributeExpressions().getValue();
+ // Matches both Classic ActiveMQ and Artemis, which both use
setBrokerURL
if (connectionFactoryValue.startsWith("org.apache.activemq")) {
setProperty(connectionFactory, "brokerURL", brokerValue);
} else if (connectionFactoryValue.startsWith("com.tibco.tibjms")) {
@@ -159,7 +162,9 @@ public class JMSConnectionFactoryHandler extends
CachedJMSConnectionFactoryHandl
SSLContextService sslContextService =
context.getProperty(JMS_SSL_CONTEXT_SERVICE).asControllerService(SSLContextService.class);
if (sslContextService != null) {
SSLContext sslContext = sslContextService.createContext();
- if (connectionFactoryValue.startsWith("org.apache.activemq")) {
+ if
(connectionFactoryValue.startsWith("org.apache.activemq.artemis")) {
+ configureArtemisSSL(connectionFactory, sslContextService);
+ } else if
(connectionFactoryValue.startsWith("org.apache.activemq")) {
if (sslContextService.isTrustStoreConfigured()) {
setProperty(connectionFactory, "trustStore",
sslContextService.getTrustStoreFile());
setProperty(connectionFactory, "trustStorePassword",
sslContextService.getTrustStorePassword());
@@ -188,6 +193,69 @@ public class JMSConnectionFactoryHandler extends
CachedJMSConnectionFactoryHandl
});
}
+ /**
+ * Configures SSL for ActiveMQ Artemis by rebuilding the broker URL with
SSL transport
+ * parameters. Artemis does not expose bean-style SSL setters like Classic
ActiveMQ;
+ * instead, SSL configuration is parsed from the broker URL query string
by the
+ * Artemis {@code ActiveMQConnectionFactory.setBrokerURL(String)} method.
+ * <p>
+ * Note: passwords are embedded in the broker URL as required by Artemis
transport
+ * configuration. The augmented URL is not logged by NiFi, but the Artemis
client
+ * library may log the connection URL internally at DEBUG level.
+ * <p>
+ * Parameter values are URL-encoded per Artemis {@code
URISupport.parseQuery()} which
+ * applies {@code URLDecoder.decode()} when reading parameters back.
+ */
+ private void configureArtemisSSL(final ConnectionFactory
connectionFactory, final SSLContextService sslContextService) {
+ if (!context.getProperty(JMS_BROKER_URI).isSet()) {
+ return;
+ }
+ final String brokerUrl =
context.getProperty(JMS_BROKER_URI).evaluateAttributeExpressions().getValue();
+ final StringBuilder urlBuilder = new StringBuilder(brokerUrl);
+ final List<String> configuredParameters = new ArrayList<>();
+ char separator = brokerUrl.contains("?") ? '&' : '?';
+
+ if (!brokerUrl.matches(".*[?&]sslEnabled=.*")) {
+ urlBuilder.append(separator).append("sslEnabled=true");
+ separator = '&';
+ configuredParameters.add("sslEnabled");
+ }
+
+ if (sslContextService.isTrustStoreConfigured()) {
+ urlBuilder.append(separator).append("trustStorePath=")
+
.append(URLEncoder.encode(sslContextService.getTrustStoreFile(),
StandardCharsets.UTF_8));
+ separator = '&';
+ configuredParameters.add("trustStorePath");
+ urlBuilder.append(separator).append("trustStorePassword=")
+
.append(URLEncoder.encode(sslContextService.getTrustStorePassword(),
StandardCharsets.UTF_8));
+ configuredParameters.add("trustStorePassword");
+ if (sslContextService.getTrustStoreType() != null) {
+ urlBuilder.append(separator).append("trustStoreType=")
+
.append(URLEncoder.encode(sslContextService.getTrustStoreType(),
StandardCharsets.UTF_8));
+ configuredParameters.add("trustStoreType");
+ }
+ }
+
+ if (sslContextService.isKeyStoreConfigured()) {
+ urlBuilder.append(separator).append("keyStorePath=")
+
.append(URLEncoder.encode(sslContextService.getKeyStoreFile(),
StandardCharsets.UTF_8));
+ separator = '&';
+ configuredParameters.add("keyStorePath");
+ urlBuilder.append(separator).append("keyStorePassword=")
+
.append(URLEncoder.encode(sslContextService.getKeyStorePassword(),
StandardCharsets.UTF_8));
+ configuredParameters.add("keyStorePassword");
+ if (sslContextService.getKeyStoreType() != null) {
+ urlBuilder.append(separator).append("keyStoreType=")
+
.append(URLEncoder.encode(sslContextService.getKeyStoreType(),
StandardCharsets.UTF_8));
+ configuredParameters.add("keyStoreType");
+ }
+ }
+
+ final String augmentedUrl = urlBuilder.toString();
+ logger.info("Configured Artemis SSL broker URL with transport
parameters {}", configuredParameters);
+ setProperty(connectionFactory, "brokerURL", augmentedUrl);
+ }
+
/**
* Sets corresponding {@link ConnectionFactory}'s property to a
* 'propertyValue' by invoking a 'setter' method that corresponds to
diff --git
a/nifi-extension-bundles/nifi-jms-bundle/nifi-jms-processors/src/main/java/org/apache/nifi/jms/cf/JMSConnectionFactoryProvider.java
b/nifi-extension-bundles/nifi-jms-bundle/nifi-jms-processors/src/main/java/org/apache/nifi/jms/cf/JMSConnectionFactoryProvider.java
index 1f725ff824..9ba363e8da 100644
---
a/nifi-extension-bundles/nifi-jms-bundle/nifi-jms-processors/src/main/java/org/apache/nifi/jms/cf/JMSConnectionFactoryProvider.java
+++
b/nifi-extension-bundles/nifi-jms-bundle/nifi-jms-processors/src/main/java/org/apache/nifi/jms/cf/JMSConnectionFactoryProvider.java
@@ -25,11 +25,15 @@ import org.apache.nifi.annotation.documentation.SeeAlso;
import org.apache.nifi.annotation.documentation.Tags;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.components.RequiredPermission;
+import org.apache.nifi.components.ValidationContext;
+import org.apache.nifi.components.ValidationResult;
import org.apache.nifi.controller.ConfigurationContext;
import org.apache.nifi.expression.ExpressionLanguageScope;
import org.apache.nifi.logging.ComponentLog;
import org.apache.nifi.migration.PropertyConfiguration;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
/**
@@ -62,6 +66,33 @@ import java.util.List;
)
public class JMSConnectionFactoryProvider extends
AbstractJMSConnectionFactoryProvider {
+ @Override
+ protected Collection<ValidationResult> customValidate(final
ValidationContext validationContext) {
+ final List<ValidationResult> results = new
ArrayList<>(super.customValidate(validationContext));
+
+ final String connectionFactoryImpl =
validationContext.getProperty(JMSConnectionFactoryProperties.JMS_CONNECTION_FACTORY_IMPL).getValue();
+ final boolean sslContextServiceSet =
validationContext.getProperty(JMSConnectionFactoryProperties.JMS_SSL_CONTEXT_SERVICE).isSet();
+ final boolean brokerUriSet =
validationContext.getProperty(JMSConnectionFactoryProperties.JMS_BROKER_URI).isSet();
+
+ if (connectionFactoryImpl != null
+ &&
connectionFactoryImpl.startsWith("org.apache.activemq.artemis")
+ && sslContextServiceSet
+ && brokerUriSet) {
+ final String brokerUriRaw =
validationContext.getProperty(JMSConnectionFactoryProperties.JMS_BROKER_URI).getValue();
+ if (!validationContext.isExpressionLanguagePresent(brokerUriRaw)
+ && brokerUriRaw.matches("(?i).*[?&;]sslEnabled=false.*")) {
+ results.add(new ValidationResult.Builder()
+
.subject(JMSConnectionFactoryProperties.JMS_BROKER_URI.getDisplayName())
+ .valid(false)
+ .explanation("JMS SSL Context Service is configured,
but JMS Broker URI contains sslEnabled=false. "
+ + "Remove sslEnabled=false from the broker URI
or unset the SSL Context Service.")
+ .build());
+ }
+ }
+
+ return results;
+ }
+
@Override
public void migrateProperties(PropertyConfiguration config) {
config.renameProperty(JMSConnectionFactoryProperties.OLD_JMS_CONNECTION_FACTORY_IMPL_PROPERTY_NAME,
JMSConnectionFactoryProperties.JMS_CONNECTION_FACTORY_IMPL.getName());
diff --git
a/nifi-extension-bundles/nifi-jms-bundle/nifi-jms-processors/src/test/java/org/apache/nifi/jms/cf/JMSConnectionFactoryProviderTest.java
b/nifi-extension-bundles/nifi-jms-bundle/nifi-jms-processors/src/test/java/org/apache/nifi/jms/cf/JMSConnectionFactoryProviderTest.java
index 8c6578b775..40b5bfb2aa 100644
---
a/nifi-extension-bundles/nifi-jms-bundle/nifi-jms-processors/src/test/java/org/apache/nifi/jms/cf/JMSConnectionFactoryProviderTest.java
+++
b/nifi-extension-bundles/nifi-jms-bundle/nifi-jms-processors/src/test/java/org/apache/nifi/jms/cf/JMSConnectionFactoryProviderTest.java
@@ -28,6 +28,8 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.net.URISyntaxException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Map;
import javax.net.ssl.SSLContext;
@@ -62,6 +64,8 @@ public class JMSConnectionFactoryProviderTest {
private static final String TEST_CONNECTION_FACTORY_IMPL =
"org.apache.nifi.jms.testcflib.TestConnectionFactory";
private static final String ACTIVEMQ_CONNECTION_FACTORY_IMPL =
"org.apache.activemq.ActiveMQConnectionFactory";
+ private static final String ARTEMIS_CONNECTION_FACTORY_IMPL =
"org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory";
+ private static final String SINGLE_ARTEMIS_BROKER = "tcp://myhost:61616";
private static final String TIBCO_CONNECTION_FACTORY_IMPL =
"com.tibco.tibjms.TibjmsConnectionFactory";
private static final String IBM_MQ_CONNECTION_FACTORY_IMPL =
"com.ibm.mq.jms.MQConnectionFactory";
private static final String QPID_JMS_CONNECTION_FACTORY_IMPL =
"org.apache.qpid.jms.JmsConnectionFactory";
@@ -411,6 +415,92 @@ public class JMSConnectionFactoryProviderTest {
cfProvider.getConfiguredProperties());
}
+ @Test
+ public void propertiesSetOnArtemisWithSslConnectionFactory() throws
Exception {
+ final JMSConnectionFactoryProviderForTest cfProvider = new
JMSConnectionFactoryProviderForTest();
+ runner.addControllerService(CF_PROVIDER_SERVICE_ID, cfProvider);
+
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_BROKER_URI, SINGLE_ARTEMIS_BROKER);
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_CLIENT_LIBRARIES, dummyResource);
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_CONNECTION_FACTORY_IMPL,
ARTEMIS_CONNECTION_FACTORY_IMPL);
+
+ final String trustStoreFile = "/path/to/truststore";
+ final String trustStorePassword = "truststore_password";
+ final String trustStoreType = "JKS";
+ final String keyStoreFile = "/path/to/keystore";
+ final String keyStorePassword = "keystore_password";
+ final String keyStoreType = "PKCS12";
+
+ final SSLContextService sslContextService =
mock(SSLContextService.class);
+
when(sslContextService.getIdentifier()).thenReturn(SSL_CONTEXT_SERVICE_ID);
+
when(sslContextService.createContext()).thenReturn(SSLContext.getDefault());
+ when(sslContextService.isTrustStoreConfigured()).thenReturn(true);
+ when(sslContextService.getTrustStoreFile()).thenReturn(trustStoreFile);
+
when(sslContextService.getTrustStorePassword()).thenReturn(trustStorePassword);
+ when(sslContextService.getTrustStoreType()).thenReturn(trustStoreType);
+ when(sslContextService.isKeyStoreConfigured()).thenReturn(true);
+ when(sslContextService.getKeyStoreFile()).thenReturn(keyStoreFile);
+
when(sslContextService.getKeyStorePassword()).thenReturn(keyStorePassword);
+ when(sslContextService.getKeyStoreType()).thenReturn(keyStoreType);
+
+ runner.addControllerService(SSL_CONTEXT_SERVICE_ID, sslContextService);
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_SSL_CONTEXT_SERVICE, SSL_CONTEXT_SERVICE_ID);
+
+ runner.enableControllerService(cfProvider);
+
+ final Map<String, Object> props = cfProvider.getConfiguredProperties();
+
+ final String expectedUrl = SINGLE_ARTEMIS_BROKER
+ + "?sslEnabled=true"
+ + "&trustStorePath=" + URLEncoder.encode(trustStoreFile,
StandardCharsets.UTF_8)
+ + "&trustStorePassword=" +
URLEncoder.encode(trustStorePassword, StandardCharsets.UTF_8)
+ + "&trustStoreType=" + URLEncoder.encode(trustStoreType,
StandardCharsets.UTF_8)
+ + "&keyStorePath=" + URLEncoder.encode(keyStoreFile,
StandardCharsets.UTF_8)
+ + "&keyStorePassword=" + URLEncoder.encode(keyStorePassword,
StandardCharsets.UTF_8)
+ + "&keyStoreType=" + URLEncoder.encode(keyStoreType,
StandardCharsets.UTF_8);
+
+ assertEquals(expectedUrl, props.get("brokerURL"));
+ }
+
+ @Test
+ public void propertiesSetOnArtemisWithSslPreservesExistingSslEnabled()
throws Exception {
+ final JMSConnectionFactoryProviderForTest cfProvider = new
JMSConnectionFactoryProviderForTest();
+ runner.addControllerService(CF_PROVIDER_SERVICE_ID, cfProvider);
+
+ final String brokerWithSsl = SINGLE_ARTEMIS_BROKER +
"?sslEnabled=true";
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_BROKER_URI, brokerWithSsl);
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_CLIENT_LIBRARIES, dummyResource);
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_CONNECTION_FACTORY_IMPL,
ARTEMIS_CONNECTION_FACTORY_IMPL);
+
+ final String trustStoreFile = "/path/to/truststore";
+ final String trustStorePassword = "truststore_password";
+
+ final SSLContextService sslContextService =
mock(SSLContextService.class);
+
when(sslContextService.getIdentifier()).thenReturn(SSL_CONTEXT_SERVICE_ID);
+
when(sslContextService.createContext()).thenReturn(SSLContext.getDefault());
+ when(sslContextService.isTrustStoreConfigured()).thenReturn(true);
+ when(sslContextService.getTrustStoreFile()).thenReturn(trustStoreFile);
+
when(sslContextService.getTrustStorePassword()).thenReturn(trustStorePassword);
+ when(sslContextService.getTrustStoreType()).thenReturn(null);
+ when(sslContextService.isKeyStoreConfigured()).thenReturn(false);
+
+ runner.addControllerService(SSL_CONTEXT_SERVICE_ID, sslContextService);
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_SSL_CONTEXT_SERVICE, SSL_CONTEXT_SERVICE_ID);
+
+ runner.enableControllerService(cfProvider);
+
+ final Map<String, Object> props = cfProvider.getConfiguredProperties();
+ final String brokerURL = (String) props.get("brokerURL");
+
+ assertNotNull(brokerURL);
+ assertEquals(1, brokerURL.chars().filter(ch -> ch == '?').count(),
+ "Should not duplicate ? separator when sslEnabled already in
URL");
+ assertEquals(brokerWithSsl
+ + "&trustStorePath=" +
URLEncoder.encode(trustStoreFile, StandardCharsets.UTF_8)
+ + "&trustStorePassword=" +
URLEncoder.encode(trustStorePassword, StandardCharsets.UTF_8),
+ brokerURL);
+ }
+
@Test
public void propertiesSetOnSingleTibcoBrokerConnectionFactory() throws
InitializationException {
JMSConnectionFactoryProviderForTest cfProvider = new
JMSConnectionFactoryProviderForTest();
@@ -561,4 +651,178 @@ public class JMSConnectionFactoryProviderTest {
assertEquals(Map.of("remoteURI", SINGLE_QPID_JMS_BROKER, "sslContext",
sslContext), cfProvider.getConfiguredProperties());
}
+
+ @Test
+ public void propertiesSetOnArtemisWithSslAndSpecialCharacters() throws
Exception {
+ final JMSConnectionFactoryProviderForTest cfProvider = new
JMSConnectionFactoryProviderForTest();
+ runner.addControllerService(CF_PROVIDER_SERVICE_ID, cfProvider);
+
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_BROKER_URI, SINGLE_ARTEMIS_BROKER);
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_CLIENT_LIBRARIES, dummyResource);
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_CONNECTION_FACTORY_IMPL,
ARTEMIS_CONNECTION_FACTORY_IMPL);
+
+ final String trustStoreFile = "/path/to/my trust store";
+ final String trustStorePassword = "p&ss=w?rd#1";
+ final String trustStoreType = "JKS";
+ final String keyStoreFile = "/path/to/keystore";
+ final String keyStorePassword = "key&store=pass";
+ final String keyStoreType = "PKCS12";
+
+ final SSLContextService sslContextService =
mock(SSLContextService.class);
+
when(sslContextService.getIdentifier()).thenReturn(SSL_CONTEXT_SERVICE_ID);
+
when(sslContextService.createContext()).thenReturn(SSLContext.getDefault());
+ when(sslContextService.isTrustStoreConfigured()).thenReturn(true);
+ when(sslContextService.getTrustStoreFile()).thenReturn(trustStoreFile);
+
when(sslContextService.getTrustStorePassword()).thenReturn(trustStorePassword);
+ when(sslContextService.getTrustStoreType()).thenReturn(trustStoreType);
+ when(sslContextService.isKeyStoreConfigured()).thenReturn(true);
+ when(sslContextService.getKeyStoreFile()).thenReturn(keyStoreFile);
+
when(sslContextService.getKeyStorePassword()).thenReturn(keyStorePassword);
+ when(sslContextService.getKeyStoreType()).thenReturn(keyStoreType);
+
+ runner.addControllerService(SSL_CONTEXT_SERVICE_ID, sslContextService);
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_SSL_CONTEXT_SERVICE, SSL_CONTEXT_SERVICE_ID);
+
+ runner.enableControllerService(cfProvider);
+
+ final Map<String, Object> props = cfProvider.getConfiguredProperties();
+ final String brokerURL = (String) props.get("brokerURL");
+
+ final String expectedUrl = SINGLE_ARTEMIS_BROKER
+ + "?sslEnabled=true"
+ + "&trustStorePath=" + URLEncoder.encode(trustStoreFile,
StandardCharsets.UTF_8)
+ + "&trustStorePassword=" +
URLEncoder.encode(trustStorePassword, StandardCharsets.UTF_8)
+ + "&trustStoreType=" + URLEncoder.encode(trustStoreType,
StandardCharsets.UTF_8)
+ + "&keyStorePath=" + URLEncoder.encode(keyStoreFile,
StandardCharsets.UTF_8)
+ + "&keyStorePassword=" + URLEncoder.encode(keyStorePassword,
StandardCharsets.UTF_8)
+ + "&keyStoreType=" + URLEncoder.encode(keyStoreType,
StandardCharsets.UTF_8);
+
+ assertEquals(expectedUrl, brokerURL);
+ }
+
+ @Test
+ public void propertiesSetOnArtemisWithSslAndNoBrokerUri() throws Exception
{
+ final JMSConnectionFactoryProviderForTest cfProvider = new
JMSConnectionFactoryProviderForTest();
+ runner.addControllerService(CF_PROVIDER_SERVICE_ID, cfProvider);
+
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_CLIENT_LIBRARIES, dummyResource);
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_CONNECTION_FACTORY_IMPL,
ARTEMIS_CONNECTION_FACTORY_IMPL);
+
+ final SSLContextService sslContextService =
mock(SSLContextService.class);
+
when(sslContextService.getIdentifier()).thenReturn(SSL_CONTEXT_SERVICE_ID);
+
when(sslContextService.createContext()).thenReturn(SSLContext.getDefault());
+ when(sslContextService.isTrustStoreConfigured()).thenReturn(true);
+
when(sslContextService.getTrustStoreFile()).thenReturn("/path/to/truststore");
+ when(sslContextService.getTrustStorePassword()).thenReturn("password");
+ when(sslContextService.isKeyStoreConfigured()).thenReturn(false);
+
+ runner.addControllerService(SSL_CONTEXT_SERVICE_ID, sslContextService);
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_SSL_CONTEXT_SERVICE, SSL_CONTEXT_SERVICE_ID);
+
+ runner.enableControllerService(cfProvider);
+
+ final Map<String, Object> props = cfProvider.getConfiguredProperties();
+ assertNotNull(props);
+ assertEquals(Map.of(), props);
+ }
+
+ @Test
+ public void propertiesSetOnSingleArtemisBrokerConnectionFactory() throws
InitializationException {
+ final JMSConnectionFactoryProviderForTest cfProvider = new
JMSConnectionFactoryProviderForTest();
+ runner.addControllerService(CF_PROVIDER_SERVICE_ID, cfProvider);
+
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_BROKER_URI, SINGLE_ARTEMIS_BROKER);
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_CLIENT_LIBRARIES, dummyResource);
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_CONNECTION_FACTORY_IMPL,
ARTEMIS_CONNECTION_FACTORY_IMPL);
+
+ runner.enableControllerService(cfProvider);
+
+ assertEquals(Map.of("brokerURL", SINGLE_ARTEMIS_BROKER),
cfProvider.getConfiguredProperties());
+ }
+
+ @Test
+ public void invalidWhenArtemisWithSslAndSslEnabledFalse() throws
InitializationException {
+ final JMSConnectionFactoryProvider cfProvider = new
JMSConnectionFactoryProvider();
+ runner.addControllerService(CF_PROVIDER_SERVICE_ID, cfProvider);
+
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_BROKER_URI, SINGLE_ARTEMIS_BROKER +
"?sslEnabled=false");
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_CLIENT_LIBRARIES, dummyResource);
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_CONNECTION_FACTORY_IMPL,
ARTEMIS_CONNECTION_FACTORY_IMPL);
+
+ final SSLContextService sslContextService =
mock(SSLContextService.class);
+
when(sslContextService.getIdentifier()).thenReturn(SSL_CONTEXT_SERVICE_ID);
+
+ runner.addControllerService(SSL_CONTEXT_SERVICE_ID, sslContextService);
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_SSL_CONTEXT_SERVICE, SSL_CONTEXT_SERVICE_ID);
+
+ runner.assertNotValid(cfProvider);
+ }
+
+ @Test
+ public void validWhenArtemisWithSslAndSslEnabledTrue() throws
InitializationException {
+ final JMSConnectionFactoryProvider cfProvider = new
JMSConnectionFactoryProvider();
+ runner.addControllerService(CF_PROVIDER_SERVICE_ID, cfProvider);
+
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_BROKER_URI, SINGLE_ARTEMIS_BROKER +
"?sslEnabled=true");
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_CLIENT_LIBRARIES, dummyResource);
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_CONNECTION_FACTORY_IMPL,
ARTEMIS_CONNECTION_FACTORY_IMPL);
+
+ final SSLContextService sslContextService =
mock(SSLContextService.class);
+
when(sslContextService.getIdentifier()).thenReturn(SSL_CONTEXT_SERVICE_ID);
+
+ runner.addControllerService(SSL_CONTEXT_SERVICE_ID, sslContextService);
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_SSL_CONTEXT_SERVICE, SSL_CONTEXT_SERVICE_ID);
+
+ runner.assertValid(cfProvider);
+ }
+
+ @Test
+ public void validWhenArtemisWithSslEnabledFalseAndNoSsl() throws
InitializationException {
+ final JMSConnectionFactoryProvider cfProvider = new
JMSConnectionFactoryProvider();
+ runner.addControllerService(CF_PROVIDER_SERVICE_ID, cfProvider);
+
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_BROKER_URI, SINGLE_ARTEMIS_BROKER +
"?sslEnabled=false");
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_CLIENT_LIBRARIES, dummyResource);
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_CONNECTION_FACTORY_IMPL,
ARTEMIS_CONNECTION_FACTORY_IMPL);
+
+ runner.assertValid(cfProvider);
+ }
+
+ @Test
+ public void propertiesSetOnArtemisWithSslAndExistingQueryParams() throws
Exception {
+ final JMSConnectionFactoryProviderForTest cfProvider = new
JMSConnectionFactoryProviderForTest();
+ runner.addControllerService(CF_PROVIDER_SERVICE_ID, cfProvider);
+
+ final String brokerWithParams = SINGLE_ARTEMIS_BROKER +
"?clientID=foo";
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_BROKER_URI, brokerWithParams);
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_CLIENT_LIBRARIES, dummyResource);
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_CONNECTION_FACTORY_IMPL,
ARTEMIS_CONNECTION_FACTORY_IMPL);
+
+ final String trustStoreFile = "/path/to/truststore";
+ final String trustStorePassword = "password";
+
+ final SSLContextService sslContextService =
mock(SSLContextService.class);
+
when(sslContextService.getIdentifier()).thenReturn(SSL_CONTEXT_SERVICE_ID);
+
when(sslContextService.createContext()).thenReturn(SSLContext.getDefault());
+ when(sslContextService.isTrustStoreConfigured()).thenReturn(true);
+ when(sslContextService.getTrustStoreFile()).thenReturn(trustStoreFile);
+
when(sslContextService.getTrustStorePassword()).thenReturn(trustStorePassword);
+ when(sslContextService.getTrustStoreType()).thenReturn(null);
+ when(sslContextService.isKeyStoreConfigured()).thenReturn(false);
+
+ runner.addControllerService(SSL_CONTEXT_SERVICE_ID, sslContextService);
+ runner.setProperty(cfProvider,
JMSConnectionFactoryProperties.JMS_SSL_CONTEXT_SERVICE, SSL_CONTEXT_SERVICE_ID);
+
+ runner.enableControllerService(cfProvider);
+
+ final Map<String, Object> props = cfProvider.getConfiguredProperties();
+ final String brokerURL = (String) props.get("brokerURL");
+
+ final String expectedUrl = brokerWithParams
+ + "&sslEnabled=true"
+ + "&trustStorePath=" + URLEncoder.encode(trustStoreFile,
StandardCharsets.UTF_8)
+ + "&trustStorePassword=" +
URLEncoder.encode(trustStorePassword, StandardCharsets.UTF_8);
+
+ assertEquals(expectedUrl, brokerURL);
+ }
}