Create spring-boot-activemq module
This commit is contained in:
committed by
Phillip Webb
parent
f78a6fa37a
commit
e1c3e50192
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.springframework.boot.activemq.autoconfigure;
|
||||
|
||||
import jakarta.jms.ConnectionFactory;
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.jms.autoconfigure.JmsAutoConfiguration;
|
||||
import org.springframework.boot.jms.autoconfigure.JmsProperties;
|
||||
import org.springframework.boot.jms.autoconfigure.JndiConnectionFactoryAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} to integrate with an ActiveMQ
|
||||
* broker.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Phillip Webb
|
||||
* @author Eddú Meléndez
|
||||
* @since 3.1.0
|
||||
*/
|
||||
@AutoConfiguration(before = JmsAutoConfiguration.class, after = JndiConnectionFactoryAutoConfiguration.class)
|
||||
@ConditionalOnClass({ ConnectionFactory.class, ActiveMQConnectionFactory.class })
|
||||
@ConditionalOnMissingBean(ConnectionFactory.class)
|
||||
@EnableConfigurationProperties({ ActiveMQProperties.class, JmsProperties.class })
|
||||
@Import({ ActiveMQXAConnectionFactoryConfiguration.class, ActiveMQConnectionFactoryConfiguration.class })
|
||||
public class ActiveMQAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
ActiveMQConnectionDetails activemqConnectionDetails(ActiveMQProperties properties) {
|
||||
return new PropertiesActiveMQConnectionDetails(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapts {@link ActiveMQProperties} to {@link ActiveMQConnectionDetails}.
|
||||
*/
|
||||
static class PropertiesActiveMQConnectionDetails implements ActiveMQConnectionDetails {
|
||||
|
||||
private final ActiveMQProperties properties;
|
||||
|
||||
PropertiesActiveMQConnectionDetails(ActiveMQProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBrokerUrl() {
|
||||
return this.properties.determineBrokerUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUser() {
|
||||
return this.properties.getUser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return this.properties.getPassword();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.springframework.boot.activemq.autoconfigure;
|
||||
|
||||
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
|
||||
|
||||
/**
|
||||
* Details required to establish a connection to an ActiveMQ service.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
* @author Stephane Nicoll
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public interface ActiveMQConnectionDetails extends ConnectionDetails {
|
||||
|
||||
/**
|
||||
* Broker URL to use.
|
||||
* @return the url of the broker
|
||||
*/
|
||||
String getBrokerUrl();
|
||||
|
||||
/**
|
||||
* Login user to authenticate to the broker.
|
||||
* @return the login user to authenticate to the broker or {@code null}
|
||||
*/
|
||||
String getUser();
|
||||
|
||||
/**
|
||||
* Login to authenticate against the broker.
|
||||
* @return the login to authenticate against the broker or {@code null}
|
||||
*/
|
||||
String getPassword();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.springframework.boot.activemq.autoconfigure;
|
||||
|
||||
import jakarta.jms.ConnectionFactory;
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.commons.pool2.PooledObject;
|
||||
import org.messaginghub.pooled.jms.JmsPoolConnectionFactory;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryFactory;
|
||||
import org.springframework.boot.jms.autoconfigure.JmsProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jms.connection.CachingConnectionFactory;
|
||||
|
||||
/**
|
||||
* Configuration for ActiveMQ {@link ConnectionFactory}.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @author Stephane Nicoll
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
* @author Aurélien Leboulanger
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnMissingBean(ConnectionFactory.class)
|
||||
class ActiveMQConnectionFactoryConfiguration {
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnBooleanProperty(name = "spring.activemq.pool.enabled", havingValue = false, matchIfMissing = true)
|
||||
static class SimpleConnectionFactoryConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBooleanProperty(name = "spring.jms.cache.enabled", havingValue = false)
|
||||
ActiveMQConnectionFactory jmsConnectionFactory(ActiveMQProperties properties,
|
||||
ObjectProvider<ActiveMQConnectionFactoryCustomizer> factoryCustomizers,
|
||||
ActiveMQConnectionDetails connectionDetails) {
|
||||
return createJmsConnectionFactory(properties, factoryCustomizers, connectionDetails);
|
||||
}
|
||||
|
||||
private static ActiveMQConnectionFactory createJmsConnectionFactory(ActiveMQProperties properties,
|
||||
ObjectProvider<ActiveMQConnectionFactoryCustomizer> factoryCustomizers,
|
||||
ActiveMQConnectionDetails connectionDetails) {
|
||||
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(connectionDetails.getUser(),
|
||||
connectionDetails.getPassword(), connectionDetails.getBrokerUrl());
|
||||
new ActiveMQConnectionFactoryConfigurer(properties, factoryCustomizers.orderedStream().toList())
|
||||
.configure(connectionFactory);
|
||||
return connectionFactory;
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(CachingConnectionFactory.class)
|
||||
@ConditionalOnBooleanProperty(name = "spring.jms.cache.enabled", matchIfMissing = true)
|
||||
static class CachingConnectionFactoryConfiguration {
|
||||
|
||||
@Bean
|
||||
CachingConnectionFactory jmsConnectionFactory(JmsProperties jmsProperties, ActiveMQProperties properties,
|
||||
ObjectProvider<ActiveMQConnectionFactoryCustomizer> factoryCustomizers,
|
||||
ActiveMQConnectionDetails connectionDetails) {
|
||||
JmsProperties.Cache cacheProperties = jmsProperties.getCache();
|
||||
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(
|
||||
createJmsConnectionFactory(properties, factoryCustomizers, connectionDetails));
|
||||
connectionFactory.setCacheConsumers(cacheProperties.isConsumers());
|
||||
connectionFactory.setCacheProducers(cacheProperties.isProducers());
|
||||
connectionFactory.setSessionCacheSize(cacheProperties.getSessionCacheSize());
|
||||
return connectionFactory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ JmsPoolConnectionFactory.class, PooledObject.class })
|
||||
static class PooledConnectionFactoryConfiguration {
|
||||
|
||||
@Bean(destroyMethod = "stop")
|
||||
@ConditionalOnBooleanProperty("spring.activemq.pool.enabled")
|
||||
JmsPoolConnectionFactory jmsConnectionFactory(ActiveMQProperties properties,
|
||||
ObjectProvider<ActiveMQConnectionFactoryCustomizer> factoryCustomizers,
|
||||
ActiveMQConnectionDetails connectionDetails) {
|
||||
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(connectionDetails.getUser(),
|
||||
connectionDetails.getPassword(), connectionDetails.getBrokerUrl());
|
||||
new ActiveMQConnectionFactoryConfigurer(properties, factoryCustomizers.orderedStream().toList())
|
||||
.configure(connectionFactory);
|
||||
return new JmsPoolConnectionFactoryFactory(properties.getPool())
|
||||
.createPooledConnectionFactory(connectionFactory);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.springframework.boot.activemq.autoconfigure;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
|
||||
import org.springframework.boot.activemq.autoconfigure.ActiveMQProperties.Packages;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Class to configure an {@link ActiveMQConnectionFactory} instance from properties
|
||||
* defined in {@link ActiveMQProperties} and any
|
||||
* {@link ActiveMQConnectionFactoryCustomizer customizers}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Venil Noronha
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
class ActiveMQConnectionFactoryConfigurer {
|
||||
|
||||
private final ActiveMQProperties properties;
|
||||
|
||||
private final List<ActiveMQConnectionFactoryCustomizer> factoryCustomizers;
|
||||
|
||||
ActiveMQConnectionFactoryConfigurer(ActiveMQProperties properties,
|
||||
List<ActiveMQConnectionFactoryCustomizer> factoryCustomizers) {
|
||||
Assert.notNull(properties, "'properties' must not be null");
|
||||
this.properties = properties;
|
||||
this.factoryCustomizers = (factoryCustomizers != null) ? factoryCustomizers : Collections.emptyList();
|
||||
}
|
||||
|
||||
void configure(ActiveMQConnectionFactory factory) {
|
||||
if (this.properties.getCloseTimeout() != null) {
|
||||
factory.setCloseTimeout((int) this.properties.getCloseTimeout().toMillis());
|
||||
}
|
||||
factory.setNonBlockingRedelivery(this.properties.isNonBlockingRedelivery());
|
||||
if (this.properties.getSendTimeout() != null) {
|
||||
factory.setSendTimeout((int) this.properties.getSendTimeout().toMillis());
|
||||
}
|
||||
Packages packages = this.properties.getPackages();
|
||||
if (packages.getTrustAll() != null) {
|
||||
factory.setTrustAllPackages(packages.getTrustAll());
|
||||
}
|
||||
if (!packages.getTrusted().isEmpty()) {
|
||||
factory.setTrustedPackages(packages.getTrusted());
|
||||
}
|
||||
customize(factory);
|
||||
}
|
||||
|
||||
private void customize(ActiveMQConnectionFactory connectionFactory) {
|
||||
for (ActiveMQConnectionFactoryCustomizer factoryCustomizer : this.factoryCustomizers) {
|
||||
factoryCustomizer.customize(connectionFactory);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.springframework.boot.activemq.autoconfigure;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
|
||||
/**
|
||||
* Callback interface that can be implemented by beans wishing to customize the
|
||||
* {@link ActiveMQConnectionFactory} whilst retaining default auto-configuration.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 3.1.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ActiveMQConnectionFactoryCustomizer {
|
||||
|
||||
/**
|
||||
* Customize the {@link ActiveMQConnectionFactory}.
|
||||
* @param factory the factory to customize
|
||||
*/
|
||||
void customize(ActiveMQConnectionFactory factory);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.springframework.boot.activemq.autoconfigure;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
import org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties;
|
||||
|
||||
/**
|
||||
* Configuration properties for ActiveMQ.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @author Stephane Nicoll
|
||||
* @author Aurélien Leboulanger
|
||||
* @author Venil Noronha
|
||||
* @author Eddú Meléndez
|
||||
* @since 3.1.0
|
||||
*/
|
||||
@ConfigurationProperties("spring.activemq")
|
||||
public class ActiveMQProperties {
|
||||
|
||||
private static final String DEFAULT_EMBEDDED_BROKER_URL = "vm://localhost?broker.persistent=false";
|
||||
|
||||
private static final String DEFAULT_NETWORK_BROKER_URL = "tcp://localhost:61616";
|
||||
|
||||
/**
|
||||
* URL of the ActiveMQ broker. Auto-generated by default.
|
||||
*/
|
||||
private String brokerUrl;
|
||||
|
||||
/**
|
||||
* Login user of the broker.
|
||||
*/
|
||||
private String user;
|
||||
|
||||
/**
|
||||
* Login password of the broker.
|
||||
*/
|
||||
private String password;
|
||||
|
||||
private final Embedded embedded = new Embedded();
|
||||
|
||||
/**
|
||||
* Time to wait before considering a close complete.
|
||||
*/
|
||||
private Duration closeTimeout = Duration.ofSeconds(15);
|
||||
|
||||
/**
|
||||
* Whether to stop message delivery before re-delivering messages from a rolled back
|
||||
* transaction. This implies that message order is not preserved when this is enabled.
|
||||
*/
|
||||
private boolean nonBlockingRedelivery = false;
|
||||
|
||||
/**
|
||||
* Time to wait on message sends for a response. Set it to 0 to wait forever.
|
||||
*/
|
||||
private Duration sendTimeout = Duration.ofMillis(0);
|
||||
|
||||
@NestedConfigurationProperty
|
||||
private final JmsPoolConnectionFactoryProperties pool = new JmsPoolConnectionFactoryProperties();
|
||||
|
||||
private final Packages packages = new Packages();
|
||||
|
||||
public String getBrokerUrl() {
|
||||
return this.brokerUrl;
|
||||
}
|
||||
|
||||
public void setBrokerUrl(String brokerUrl) {
|
||||
this.brokerUrl = brokerUrl;
|
||||
}
|
||||
|
||||
public String getUser() {
|
||||
return this.user;
|
||||
}
|
||||
|
||||
public void setUser(String user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public Embedded getEmbedded() {
|
||||
return this.embedded;
|
||||
}
|
||||
|
||||
public Duration getCloseTimeout() {
|
||||
return this.closeTimeout;
|
||||
}
|
||||
|
||||
public void setCloseTimeout(Duration closeTimeout) {
|
||||
this.closeTimeout = closeTimeout;
|
||||
}
|
||||
|
||||
public boolean isNonBlockingRedelivery() {
|
||||
return this.nonBlockingRedelivery;
|
||||
}
|
||||
|
||||
public void setNonBlockingRedelivery(boolean nonBlockingRedelivery) {
|
||||
this.nonBlockingRedelivery = nonBlockingRedelivery;
|
||||
}
|
||||
|
||||
public Duration getSendTimeout() {
|
||||
return this.sendTimeout;
|
||||
}
|
||||
|
||||
public void setSendTimeout(Duration sendTimeout) {
|
||||
this.sendTimeout = sendTimeout;
|
||||
}
|
||||
|
||||
public JmsPoolConnectionFactoryProperties getPool() {
|
||||
return this.pool;
|
||||
}
|
||||
|
||||
public Packages getPackages() {
|
||||
return this.packages;
|
||||
}
|
||||
|
||||
String determineBrokerUrl() {
|
||||
if (this.brokerUrl != null) {
|
||||
return this.brokerUrl;
|
||||
}
|
||||
if (this.embedded.isEnabled()) {
|
||||
return DEFAULT_EMBEDDED_BROKER_URL;
|
||||
}
|
||||
return DEFAULT_NETWORK_BROKER_URL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration for an embedded ActiveMQ broker.
|
||||
*/
|
||||
public static class Embedded {
|
||||
|
||||
/**
|
||||
* Whether to enable embedded mode if the ActiveMQ Broker is available.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Packages {
|
||||
|
||||
/**
|
||||
* Whether to trust all packages.
|
||||
*/
|
||||
private Boolean trustAll;
|
||||
|
||||
/**
|
||||
* List of specific packages to trust (when not trusting all packages).
|
||||
*/
|
||||
private List<String> trusted = new ArrayList<>();
|
||||
|
||||
public Boolean getTrustAll() {
|
||||
return this.trustAll;
|
||||
}
|
||||
|
||||
public void setTrustAll(Boolean trustAll) {
|
||||
this.trustAll = trustAll;
|
||||
}
|
||||
|
||||
public List<String> getTrusted() {
|
||||
return this.trusted;
|
||||
}
|
||||
|
||||
public void setTrusted(List<String> trusted) {
|
||||
this.trusted = trusted;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.springframework.boot.activemq.autoconfigure;
|
||||
|
||||
import jakarta.jms.ConnectionFactory;
|
||||
import jakarta.transaction.TransactionManager;
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.ActiveMQXAConnectionFactory;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.jms.XAConnectionFactoryWrapper;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
|
||||
/**
|
||||
* Configuration for ActiveMQ XA {@link ConnectionFactory}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Aurélien Leboulanger
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(TransactionManager.class)
|
||||
@ConditionalOnBean(XAConnectionFactoryWrapper.class)
|
||||
@ConditionalOnMissingBean(ConnectionFactory.class)
|
||||
class ActiveMQXAConnectionFactoryConfiguration {
|
||||
|
||||
@Primary
|
||||
@Bean(name = { "jmsConnectionFactory", "xaJmsConnectionFactory" })
|
||||
ConnectionFactory jmsConnectionFactory(ActiveMQProperties properties,
|
||||
ObjectProvider<ActiveMQConnectionFactoryCustomizer> factoryCustomizers, XAConnectionFactoryWrapper wrapper,
|
||||
ActiveMQConnectionDetails connectionDetails) throws Exception {
|
||||
ActiveMQXAConnectionFactory connectionFactory = new ActiveMQXAConnectionFactory(connectionDetails.getUser(),
|
||||
connectionDetails.getPassword(), connectionDetails.getBrokerUrl());
|
||||
new ActiveMQConnectionFactoryConfigurer(properties, factoryCustomizers.orderedStream().toList())
|
||||
.configure(connectionFactory);
|
||||
return wrapper.wrapConnectionFactory(connectionFactory);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBooleanProperty(name = "spring.activemq.pool.enabled", havingValue = false, matchIfMissing = true)
|
||||
ActiveMQConnectionFactory nonXaJmsConnectionFactory(ActiveMQProperties properties,
|
||||
ObjectProvider<ActiveMQConnectionFactoryCustomizer> factoryCustomizers,
|
||||
ActiveMQConnectionDetails connectionDetails) {
|
||||
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(connectionDetails.getUser(),
|
||||
connectionDetails.getPassword(), connectionDetails.getBrokerUrl());
|
||||
new ActiveMQConnectionFactoryConfigurer(properties, factoryCustomizers.orderedStream().toList())
|
||||
.configure(connectionFactory);
|
||||
return connectionFactory;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for ActiveMQ.
|
||||
*/
|
||||
package org.springframework.boot.activemq.autoconfigure;
|
||||
@@ -0,0 +1,94 @@
|
||||
{
|
||||
"groups": [],
|
||||
"properties": [
|
||||
{
|
||||
"name": "spring.activemq.pool.block-if-full",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "Whether to block when a connection is requested and the pool is full. Set it to false to throw a \"JMSException\" instead.",
|
||||
"sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"name": "spring.activemq.pool.block-if-full-timeout",
|
||||
"type": "java.time.Duration",
|
||||
"description": "Blocking period before throwing an exception if the pool is still full.",
|
||||
"sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties",
|
||||
"defaultValue": "-1ms"
|
||||
},
|
||||
{
|
||||
"name": "spring.activemq.pool.create-connection-on-startup",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "Whether to create a connection on startup. Can be used to warm up the pool on startup.",
|
||||
"defaultValue": true,
|
||||
"deprecation": {
|
||||
"level": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spring.activemq.pool.enabled",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "Whether a JmsPoolConnectionFactory should be created, instead of a regular ConnectionFactory.",
|
||||
"sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"name": "spring.activemq.pool.expiry-timeout",
|
||||
"type": "java.time.Duration",
|
||||
"description": "Connection expiration timeout.",
|
||||
"defaultValue": "0ms",
|
||||
"deprecation": {
|
||||
"level": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spring.activemq.pool.idle-timeout",
|
||||
"type": "java.time.Duration",
|
||||
"description": "Connection idle timeout.",
|
||||
"sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties",
|
||||
"defaultValue": "30s"
|
||||
},
|
||||
{
|
||||
"name": "spring.activemq.pool.max-connections",
|
||||
"type": "java.lang.Integer",
|
||||
"description": "Maximum number of pooled connections.",
|
||||
"sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties",
|
||||
"defaultValue": 1
|
||||
},
|
||||
{
|
||||
"name": "spring.activemq.pool.max-sessions-per-connection",
|
||||
"type": "java.lang.Integer",
|
||||
"description": "Maximum number of pooled sessions per connection in the pool.",
|
||||
"sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties",
|
||||
"defaultValue": 500
|
||||
},
|
||||
{
|
||||
"name": "spring.activemq.pool.maximum-active-session-per-connection",
|
||||
"deprecation": {
|
||||
"replacement": "spring.activemq.pool.max-sessions-per-connection"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spring.activemq.pool.reconnect-on-exception",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "Reset the connection when a \"JMSException\" occurs.",
|
||||
"defaultValue": true,
|
||||
"deprecation": {
|
||||
"level": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spring.activemq.pool.time-between-expiration-check",
|
||||
"type": "java.time.Duration",
|
||||
"description": "Time to sleep between runs of the idle connection eviction thread. When negative, no idle connection eviction thread runs.",
|
||||
"sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties",
|
||||
"defaultValue": "-1ms"
|
||||
},
|
||||
{
|
||||
"name": "spring.activemq.pool.use-anonymous-producers",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "Whether to use only one anonymous \"MessageProducer\" instance. Set it to false to create one \"MessageProducer\" every time one is required.",
|
||||
"sourceType": "org.springframework.boot.jms.autoconfigure.JmsPoolConnectionFactoryProperties",
|
||||
"defaultValue": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
org.springframework.boot.activemq.autoconfigure.ActiveMQAutoConfiguration
|
||||
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.springframework.boot.activemq.autoconfigure;
|
||||
|
||||
import jakarta.jms.ConnectionFactory;
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.messaginghub.pooled.jms.JmsPoolConnectionFactory;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.jms.autoconfigure.JmsAutoConfiguration;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jms.connection.CachingConnectionFactory;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.mockingDetails;
|
||||
|
||||
/**
|
||||
* Tests for {@link ActiveMQAutoConfiguration}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Aurélien Leboulanger
|
||||
* @author Stephane Nicoll
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
class ActiveMQAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(ActiveMQAutoConfiguration.class, JmsAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void brokerIsEmbeddedByDefault() {
|
||||
this.contextRunner.withUserConfiguration(EmptyConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(CachingConnectionFactory.class).hasBean("jmsConnectionFactory");
|
||||
CachingConnectionFactory connectionFactory = context.getBean(CachingConnectionFactory.class);
|
||||
assertThat(context.getBean("jmsConnectionFactory")).isSameAs(connectionFactory);
|
||||
assertThat(connectionFactory.getTargetConnectionFactory()).isInstanceOf(ActiveMQConnectionFactory.class);
|
||||
assertThat(((ActiveMQConnectionFactory) connectionFactory.getTargetConnectionFactory()).getBrokerURL())
|
||||
.isEqualTo("vm://localhost?broker.persistent=false");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void configurationBacksOffWhenCustomConnectionFactoryExists() {
|
||||
this.contextRunner.withUserConfiguration(CustomConnectionFactoryConfiguration.class)
|
||||
.run((context) -> assertThat(mockingDetails(context.getBean(ConnectionFactory.class)).isMock()).isTrue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void connectionFactoryIsCachedByDefault() {
|
||||
this.contextRunner.withUserConfiguration(EmptyConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(ConnectionFactory.class)
|
||||
.hasSingleBean(CachingConnectionFactory.class)
|
||||
.hasBean("jmsConnectionFactory");
|
||||
CachingConnectionFactory connectionFactory = context.getBean(CachingConnectionFactory.class);
|
||||
assertThat(context.getBean("jmsConnectionFactory")).isSameAs(connectionFactory);
|
||||
assertThat(connectionFactory.getTargetConnectionFactory()).isInstanceOf(ActiveMQConnectionFactory.class);
|
||||
assertThat(connectionFactory.isCacheConsumers()).isFalse();
|
||||
assertThat(connectionFactory.isCacheProducers()).isTrue();
|
||||
assertThat(connectionFactory.getSessionCacheSize()).isEqualTo(1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void connectionFactoryCachingCanBeCustomized() {
|
||||
this.contextRunner.withUserConfiguration(EmptyConfiguration.class)
|
||||
.withPropertyValues("spring.jms.cache.consumers=true", "spring.jms.cache.producers=false",
|
||||
"spring.jms.cache.session-cache-size=10")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(ConnectionFactory.class)
|
||||
.hasSingleBean(CachingConnectionFactory.class)
|
||||
.hasBean("jmsConnectionFactory");
|
||||
CachingConnectionFactory connectionFactory = context.getBean(CachingConnectionFactory.class);
|
||||
assertThat(context.getBean("jmsConnectionFactory")).isSameAs(connectionFactory);
|
||||
assertThat(connectionFactory.isCacheConsumers()).isTrue();
|
||||
assertThat(connectionFactory.isCacheProducers()).isFalse();
|
||||
assertThat(connectionFactory.getSessionCacheSize()).isEqualTo(10);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void connectionFactoryCachingCanBeDisabled() {
|
||||
this.contextRunner.withUserConfiguration(EmptyConfiguration.class)
|
||||
.withPropertyValues("spring.jms.cache.enabled=false")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(ConnectionFactory.class)
|
||||
.hasSingleBean(ActiveMQConnectionFactory.class)
|
||||
.hasBean("jmsConnectionFactory");
|
||||
ActiveMQConnectionFactory connectionFactory = context.getBean(ActiveMQConnectionFactory.class);
|
||||
assertThat(context.getBean("jmsConnectionFactory")).isSameAs(connectionFactory);
|
||||
ActiveMQConnectionFactory defaultFactory = new ActiveMQConnectionFactory(
|
||||
"vm://localhost?broker.persistent=false");
|
||||
assertThat(connectionFactory.getUserName()).isEqualTo(defaultFactory.getUserName());
|
||||
assertThat(connectionFactory.getPassword()).isEqualTo(defaultFactory.getPassword());
|
||||
assertThat(connectionFactory.getCloseTimeout()).isEqualTo(defaultFactory.getCloseTimeout());
|
||||
assertThat(connectionFactory.isNonBlockingRedelivery())
|
||||
.isEqualTo(defaultFactory.isNonBlockingRedelivery());
|
||||
assertThat(connectionFactory.getSendTimeout()).isEqualTo(defaultFactory.getSendTimeout());
|
||||
assertThat(connectionFactory.isTrustAllPackages()).isEqualTo(defaultFactory.isTrustAllPackages());
|
||||
assertThat(connectionFactory.getTrustedPackages())
|
||||
.containsExactly(StringUtils.toStringArray(defaultFactory.getTrustedPackages()));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void customConnectionFactoryIsApplied() {
|
||||
this.contextRunner.withUserConfiguration(EmptyConfiguration.class)
|
||||
.withPropertyValues("spring.jms.cache.enabled=false",
|
||||
"spring.activemq.brokerUrl=vm://localhost?useJmx=false&broker.persistent=false",
|
||||
"spring.activemq.user=foo", "spring.activemq.password=bar", "spring.activemq.closeTimeout=500",
|
||||
"spring.activemq.nonBlockingRedelivery=true", "spring.activemq.sendTimeout=1000",
|
||||
"spring.activemq.packages.trust-all=false", "spring.activemq.packages.trusted=com.example.acme")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(ConnectionFactory.class)
|
||||
.hasSingleBean(ActiveMQConnectionFactory.class)
|
||||
.hasBean("jmsConnectionFactory");
|
||||
ActiveMQConnectionFactory connectionFactory = context.getBean(ActiveMQConnectionFactory.class);
|
||||
assertThat(context.getBean("jmsConnectionFactory")).isSameAs(connectionFactory);
|
||||
assertThat(connectionFactory.getUserName()).isEqualTo("foo");
|
||||
assertThat(connectionFactory.getPassword()).isEqualTo("bar");
|
||||
assertThat(connectionFactory.getCloseTimeout()).isEqualTo(500);
|
||||
assertThat(connectionFactory.isNonBlockingRedelivery()).isTrue();
|
||||
assertThat(connectionFactory.getSendTimeout()).isEqualTo(1000);
|
||||
assertThat(connectionFactory.isTrustAllPackages()).isFalse();
|
||||
assertThat(connectionFactory.getTrustedPackages()).containsExactly("com.example.acme");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void defaultPoolConnectionFactoryIsApplied() {
|
||||
this.contextRunner.withUserConfiguration(EmptyConfiguration.class)
|
||||
.withPropertyValues("spring.activemq.pool.enabled=true")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(ConnectionFactory.class)
|
||||
.hasSingleBean(JmsPoolConnectionFactory.class)
|
||||
.hasBean("jmsConnectionFactory");
|
||||
JmsPoolConnectionFactory connectionFactory = context.getBean(JmsPoolConnectionFactory.class);
|
||||
assertThat(context.getBean("jmsConnectionFactory")).isSameAs(connectionFactory);
|
||||
JmsPoolConnectionFactory defaultFactory = new JmsPoolConnectionFactory();
|
||||
assertThat(connectionFactory.isBlockIfSessionPoolIsFull())
|
||||
.isEqualTo(defaultFactory.isBlockIfSessionPoolIsFull());
|
||||
assertThat(connectionFactory.getBlockIfSessionPoolIsFullTimeout())
|
||||
.isEqualTo(defaultFactory.getBlockIfSessionPoolIsFullTimeout());
|
||||
assertThat(connectionFactory.getConnectionIdleTimeout())
|
||||
.isEqualTo(defaultFactory.getConnectionIdleTimeout());
|
||||
assertThat(connectionFactory.getMaxConnections()).isEqualTo(defaultFactory.getMaxConnections());
|
||||
assertThat(connectionFactory.getMaxSessionsPerConnection())
|
||||
.isEqualTo(defaultFactory.getMaxSessionsPerConnection());
|
||||
assertThat(connectionFactory.getConnectionCheckInterval())
|
||||
.isEqualTo(defaultFactory.getConnectionCheckInterval());
|
||||
assertThat(connectionFactory.isUseAnonymousProducers())
|
||||
.isEqualTo(defaultFactory.isUseAnonymousProducers());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void customPoolConnectionFactoryIsApplied() {
|
||||
this.contextRunner.withUserConfiguration(EmptyConfiguration.class)
|
||||
.withPropertyValues("spring.activemq.pool.enabled=true", "spring.activemq.pool.blockIfFull=false",
|
||||
"spring.activemq.pool.blockIfFullTimeout=64", "spring.activemq.pool.idleTimeout=512",
|
||||
"spring.activemq.pool.maxConnections=256", "spring.activemq.pool.maxSessionsPerConnection=1024",
|
||||
"spring.activemq.pool.timeBetweenExpirationCheck=2048",
|
||||
"spring.activemq.pool.useAnonymousProducers=false")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(ConnectionFactory.class)
|
||||
.hasSingleBean(JmsPoolConnectionFactory.class)
|
||||
.hasBean("jmsConnectionFactory");
|
||||
JmsPoolConnectionFactory connectionFactory = context.getBean(JmsPoolConnectionFactory.class);
|
||||
assertThat(context.getBean("jmsConnectionFactory")).isSameAs(connectionFactory);
|
||||
assertThat(connectionFactory.isBlockIfSessionPoolIsFull()).isFalse();
|
||||
assertThat(connectionFactory.getBlockIfSessionPoolIsFullTimeout()).isEqualTo(64);
|
||||
assertThat(connectionFactory.getConnectionIdleTimeout()).isEqualTo(512);
|
||||
assertThat(connectionFactory.getMaxConnections()).isEqualTo(256);
|
||||
assertThat(connectionFactory.getMaxSessionsPerConnection()).isEqualTo(1024);
|
||||
assertThat(connectionFactory.getConnectionCheckInterval()).isEqualTo(2048);
|
||||
assertThat(connectionFactory.isUseAnonymousProducers()).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void poolConnectionFactoryConfiguration() {
|
||||
this.contextRunner.withUserConfiguration(EmptyConfiguration.class)
|
||||
.withPropertyValues("spring.activemq.pool.enabled:true")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(ConnectionFactory.class)
|
||||
.hasSingleBean(JmsPoolConnectionFactory.class)
|
||||
.hasBean("jmsConnectionFactory");
|
||||
ConnectionFactory factory = context.getBean(ConnectionFactory.class);
|
||||
assertThat(context.getBean("jmsConnectionFactory")).isSameAs(factory);
|
||||
assertThat(factory).isInstanceOf(JmsPoolConnectionFactory.class);
|
||||
context.getSourceApplicationContext().close();
|
||||
assertThat(factory.createConnection()).isNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void cachingConnectionFactoryNotOnTheClasspathThenSimpleConnectionFactoryAutoConfigured() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader(CachingConnectionFactory.class))
|
||||
.withPropertyValues("spring.activemq.pool.enabled=false", "spring.jms.cache.enabled=false")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(ConnectionFactory.class)
|
||||
.hasSingleBean(ActiveMQConnectionFactory.class)
|
||||
.hasBean("jmsConnectionFactory");
|
||||
ActiveMQConnectionFactory connectionFactory = context.getBean(ActiveMQConnectionFactory.class);
|
||||
assertThat(context.getBean("jmsConnectionFactory")).isSameAs(connectionFactory);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void cachingConnectionFactoryNotOnTheClasspathAndCacheEnabledThenSimpleConnectionFactoryNotConfigured() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader(CachingConnectionFactory.class))
|
||||
.withPropertyValues("spring.activemq.pool.enabled=false", "spring.jms.cache.enabled=true")
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(ConnectionFactory.class)
|
||||
.doesNotHaveBean(ActiveMQConnectionFactory.class)
|
||||
.doesNotHaveBean("jmsConnectionFactory"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void definesPropertiesBasedConnectionDetailsByDefault() {
|
||||
this.contextRunner.run((context) -> assertThat(context)
|
||||
.hasSingleBean(ActiveMQAutoConfiguration.PropertiesActiveMQConnectionDetails.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConnectionFactoryWithOverridesWhenUsingCustomConnectionDetails() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader(CachingConnectionFactory.class))
|
||||
.withPropertyValues("spring.activemq.pool.enabled=false", "spring.jms.cache.enabled=false")
|
||||
.withUserConfiguration(TestConnectionDetailsConfiguration.class)
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(ActiveMQConnectionDetails.class)
|
||||
.doesNotHaveBean(ActiveMQAutoConfiguration.PropertiesActiveMQConnectionDetails.class);
|
||||
ActiveMQConnectionFactory connectionFactory = context.getBean(ActiveMQConnectionFactory.class);
|
||||
assertThat(connectionFactory.getBrokerURL()).isEqualTo("tcp://localhost:12345");
|
||||
assertThat(connectionFactory.getUserName()).isEqualTo("springuser");
|
||||
assertThat(connectionFactory.getPassword()).isEqualTo("spring");
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class EmptyConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomConnectionFactoryConfiguration {
|
||||
|
||||
@Bean
|
||||
ConnectionFactory connectionFactory() {
|
||||
return mock(ConnectionFactory.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
ActiveMQConnectionFactoryCustomizer activeMQConnectionFactoryCustomizer() {
|
||||
return (factory) -> {
|
||||
factory.setBrokerURL("vm://localhost?useJmx=false&broker.persistent=false");
|
||||
factory.setUserName("foobar");
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TestConnectionDetailsConfiguration {
|
||||
|
||||
@Bean
|
||||
ActiveMQConnectionDetails activemqConnectionDetails() {
|
||||
return new ActiveMQConnectionDetails() {
|
||||
|
||||
@Override
|
||||
public String getBrokerUrl() {
|
||||
return "tcp://localhost:12345";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUser() {
|
||||
return "springuser";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return "spring";
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.springframework.boot.activemq.autoconfigure;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ActiveMQProperties} and {@link ActiveMQConnectionFactoryConfigurer}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Aurélien Leboulanger
|
||||
* @author Venil Noronha
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
class ActiveMQPropertiesTests {
|
||||
|
||||
private static final String DEFAULT_EMBEDDED_BROKER_URL = "vm://localhost?broker.persistent=false";
|
||||
|
||||
private static final String DEFAULT_NETWORK_BROKER_URL = "tcp://localhost:61616";
|
||||
|
||||
private final ActiveMQProperties properties = new ActiveMQProperties();
|
||||
|
||||
@Test
|
||||
void getBrokerUrlIsEmbeddedByDefault() {
|
||||
assertThat(this.properties.determineBrokerUrl()).isEqualTo(DEFAULT_EMBEDDED_BROKER_URL);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getBrokerUrlUseExplicitBrokerUrl() {
|
||||
this.properties.setBrokerUrl("tcp://activemq.example.com:71717");
|
||||
assertThat(this.properties.determineBrokerUrl()).isEqualTo("tcp://activemq.example.com:71717");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getBrokerUrlWithEmbeddedSetToFalse() {
|
||||
this.properties.getEmbedded().setEnabled(false);
|
||||
assertThat(this.properties.determineBrokerUrl()).isEqualTo(DEFAULT_NETWORK_BROKER_URL);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getExplicitBrokerUrlAlwaysWins() {
|
||||
this.properties.setBrokerUrl("tcp://activemq.example.com:71717");
|
||||
this.properties.getEmbedded().setEnabled(false);
|
||||
assertThat(this.properties.determineBrokerUrl()).isEqualTo("tcp://activemq.example.com:71717");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setTrustAllPackages() {
|
||||
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
|
||||
this.properties.getPackages().setTrustAll(true);
|
||||
new ActiveMQConnectionFactoryConfigurer(this.properties, null).configure(factory);
|
||||
assertThat(factory.isTrustAllPackages()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void setTrustedPackages() {
|
||||
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
|
||||
this.properties.getPackages().setTrustAll(false);
|
||||
this.properties.getPackages().getTrusted().add("trusted.package");
|
||||
new ActiveMQConnectionFactoryConfigurer(this.properties, null).configure(factory);
|
||||
assertThat(factory.isTrustAllPackages()).isFalse();
|
||||
assertThat(factory.getTrustedPackages()).hasSize(1);
|
||||
assertThat(factory.getTrustedPackages().get(0)).isEqualTo("trusted.package");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user