From 435c47925ec80f4f98e488400d79889eeedab8e3 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 31 Jul 2018 15:19:20 +0200 Subject: [PATCH] Switch JMS pooling to `pooled-jms` This commit removes support for `activemq-pool` in benefit of `pooled-jms`. While the former is not JMS 2 compliant, the latter is and is independent of the ActiveMQ codebase (so potentially reusable in custom code). Closes gh-13927 --- .../spring-boot-autoconfigure/pom.xml | 22 +++--- ...a => JmsPoolConnectionFactoryFactory.java} | 31 ++++---- ...> JmsPoolConnectionFactoryProperties.java} | 24 ++++-- ...ctiveMQConnectionFactoryConfiguration.java | 10 +-- .../jms/activemq/ActiveMQProperties.java | 5 +- ...ArtemisConnectionFactoryConfiguration.java | 10 +-- .../jms/artemis/ArtemisProperties.java | 6 +- ...itional-spring-configuration-metadata.json | 12 +++ .../jms/JmsAutoConfigurationTests.java | 14 ++-- .../ActiveMQAutoConfigurationTests.java | 63 ++++++++++------ .../ArtemisAutoConfigurationTests.java | 74 ++++++++++--------- .../spring-boot-dependencies/pom.xml | 6 ++ .../appendix-application-properties.adoc | 8 +- .../main/asciidoc/spring-boot-features.adoc | 10 +-- 14 files changed, 170 insertions(+), 125 deletions(-) rename spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/{activemq/PooledConnectionFactoryFactory.java => JmsPoolConnectionFactoryFactory.java} (64%) rename spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/{activemq/PooledConnectionFactoryProperties.java => JmsPoolConnectionFactoryProperties.java} (83%) diff --git a/spring-boot-project/spring-boot-autoconfigure/pom.xml b/spring-boot-project/spring-boot-autoconfigure/pom.xml index ff4e84fdbc..ceb8d168dc 100755 --- a/spring-boot-project/spring-boot-autoconfigure/pom.xml +++ b/spring-boot-project/spring-boot-autoconfigure/pom.xml @@ -183,17 +183,6 @@ - - org.apache.activemq - activemq-pool - true - - - geronimo-jms_1.1_spec - org.apache.geronimo.specs - - - org.apache.activemq artemis-jms-client @@ -346,6 +335,17 @@ jboss-transaction-spi true + + org.messaginghub + pooled-jms + true + + + org.apache.geronimo.specs + geronimo-jms_2.0_spec + + + org.mongodb mongodb-driver-async diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/PooledConnectionFactoryFactory.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsPoolConnectionFactoryFactory.java similarity index 64% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/PooledConnectionFactoryFactory.java rename to spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsPoolConnectionFactoryFactory.java index 0a472f9dd8..be11c5733f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/PooledConnectionFactoryFactory.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsPoolConnectionFactoryFactory.java @@ -14,36 +14,37 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.activemq; +package org.springframework.boot.autoconfigure.jms; import javax.jms.ConnectionFactory; -import org.apache.activemq.jms.pool.PooledConnectionFactory; +import org.messaginghub.pooled.jms.JmsPoolConnectionFactory; /** - * Factory to create a {@link PooledConnectionFactory} from properties defined in - * {@link PooledConnectionFactoryProperties}. + * Factory to create a {@link JmsPoolConnectionFactory} from properties defined in + * {@link JmsPoolConnectionFactoryProperties}. * * @author Stephane Nicoll * @since 2.1.0 */ -public class PooledConnectionFactoryFactory { +public class JmsPoolConnectionFactoryFactory { - private final PooledConnectionFactoryProperties properties; + private final JmsPoolConnectionFactoryProperties properties; - public PooledConnectionFactoryFactory(PooledConnectionFactoryProperties properties) { + public JmsPoolConnectionFactoryFactory( + JmsPoolConnectionFactoryProperties properties) { this.properties = properties; } /** - * Create a {@link PooledConnectionFactory} based on the specified + * Create a {@link JmsPoolConnectionFactory} based on the specified * {@link ConnectionFactory}. * @param connectionFactory the connection factory to wrap * @return a pooled connection factory */ - public PooledConnectionFactory createPooledConnectionFactory( + public JmsPoolConnectionFactory createPooledConnectionFactory( ConnectionFactory connectionFactory) { - PooledConnectionFactory pooledConnectionFactory = new PooledConnectionFactory(); + JmsPoolConnectionFactory pooledConnectionFactory = new JmsPoolConnectionFactory(); pooledConnectionFactory.setConnectionFactory(connectionFactory); pooledConnectionFactory @@ -53,14 +54,14 @@ public class PooledConnectionFactoryFactory { this.properties.getBlockIfFullTimeout().toMillis()); } if (this.properties.getIdleTimeout() != null) { - pooledConnectionFactory - .setIdleTimeout((int) this.properties.getIdleTimeout().toMillis()); + pooledConnectionFactory.setConnectionIdleTimeout( + (int) this.properties.getIdleTimeout().toMillis()); } pooledConnectionFactory.setMaxConnections(this.properties.getMaxConnections()); - pooledConnectionFactory.setMaximumActiveSessionPerConnection( - this.properties.getMaximumActiveSessionPerConnection()); + pooledConnectionFactory.setMaxSessionsPerConnection( + this.properties.getMaxSessionsPerConnection()); if (this.properties.getTimeBetweenExpirationCheck() != null) { - pooledConnectionFactory.setTimeBetweenExpirationCheckMillis( + pooledConnectionFactory.setConnectionCheckInterval( this.properties.getTimeBetweenExpirationCheck().toMillis()); } pooledConnectionFactory diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/PooledConnectionFactoryProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsPoolConnectionFactoryProperties.java similarity index 83% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/PooledConnectionFactoryProperties.java rename to spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsPoolConnectionFactoryProperties.java index ad785ca851..427b67d073 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/PooledConnectionFactoryProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsPoolConnectionFactoryProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.jms.activemq; +package org.springframework.boot.autoconfigure.jms; import java.time.Duration; @@ -24,10 +24,10 @@ import java.time.Duration; * @author Stephane Nicoll * @since 2.1.0 */ -public class PooledConnectionFactoryProperties { +public class JmsPoolConnectionFactoryProperties { /** - * Whether a PooledConnectionFactory should be created, instead of a regular + * Whether a JmsPoolConnectionFactory should be created, instead of a regular * ConnectionFactory. */ private boolean enabled; @@ -54,9 +54,9 @@ public class PooledConnectionFactoryProperties { private int maxConnections = 1; /** - * Maximum number of active sessions per connection. + * Maximum number of pooled sessions per connection in the pool. */ - private int maximumActiveSessionPerConnection = 500; + private int maxSessionsPerConnection = 500; /** * Time to sleep between runs of the idle connection eviction thread. When negative, @@ -110,13 +110,23 @@ public class PooledConnectionFactoryProperties { this.maxConnections = maxConnections; } + @Deprecated public int getMaximumActiveSessionPerConnection() { - return this.maximumActiveSessionPerConnection; + return getMaxSessionsPerConnection(); } + @Deprecated public void setMaximumActiveSessionPerConnection( int maximumActiveSessionPerConnection) { - this.maximumActiveSessionPerConnection = maximumActiveSessionPerConnection; + setMaxSessionsPerConnection(maximumActiveSessionPerConnection); + } + + public int getMaxSessionsPerConnection() { + return this.maxSessionsPerConnection; + } + + public void setMaxSessionsPerConnection(int maxSessionsPerConnection) { + this.maxSessionsPerConnection = maxSessionsPerConnection; } public Duration getTimeBetweenExpirationCheck() { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryConfiguration.java index 1901d140c0..3eeaddceb4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryConfiguration.java @@ -21,13 +21,14 @@ import java.util.List; import javax.jms.ConnectionFactory; import org.apache.activemq.ActiveMQConnectionFactory; -import org.apache.activemq.jms.pool.PooledConnectionFactory; import org.apache.commons.pool2.PooledObject; +import org.messaginghub.pooled.jms.JmsPoolConnectionFactory; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.jms.JmsPoolConnectionFactoryFactory; import org.springframework.boot.autoconfigure.jms.JmsProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -94,20 +95,19 @@ class ActiveMQConnectionFactoryConfiguration { } @Configuration - @ConditionalOnClass({ PooledConnectionFactory.class, PooledObject.class }) + @ConditionalOnClass({ JmsPoolConnectionFactory.class, PooledObject.class }) static class PooledConnectionFactoryConfiguration { @Bean(destroyMethod = "stop") @ConditionalOnProperty(prefix = "spring.activemq.pool", name = "enabled", havingValue = "true", matchIfMissing = false) - public PooledConnectionFactory pooledJmsConnectionFactory( + public JmsPoolConnectionFactory pooledJmsConnectionFactory( ActiveMQProperties properties, ObjectProvider> factoryCustomizers) { ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactoryFactory( properties, factoryCustomizers.getIfAvailable()) .createConnectionFactory(ActiveMQConnectionFactory.class); - return new PooledConnectionFactoryFactory(properties.getPool()) + return new JmsPoolConnectionFactoryFactory(properties.getPool()) .createPooledConnectionFactory(connectionFactory); - } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQProperties.java index 8e9352dd83..bf25be69a1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQProperties.java @@ -20,6 +20,7 @@ import java.time.Duration; import java.util.ArrayList; import java.util.List; +import org.springframework.boot.autoconfigure.jms.JmsPoolConnectionFactoryProperties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.NestedConfigurationProperty; @@ -72,7 +73,7 @@ public class ActiveMQProperties { private Duration sendTimeout = Duration.ofMillis(0); @NestedConfigurationProperty - private final PooledConnectionFactoryProperties pool = new PooledConnectionFactoryProperties(); + private final JmsPoolConnectionFactoryProperties pool = new JmsPoolConnectionFactoryProperties(); private final Packages packages = new Packages(); @@ -132,7 +133,7 @@ public class ActiveMQProperties { this.sendTimeout = sendTimeout; } - public PooledConnectionFactoryProperties getPool() { + public JmsPoolConnectionFactoryProperties getPool() { return this.pool; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisConnectionFactoryConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisConnectionFactoryConfiguration.java index 01390df47d..a4b526df82 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisConnectionFactoryConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisConnectionFactoryConfiguration.java @@ -19,15 +19,15 @@ package org.springframework.boot.autoconfigure.jms.artemis; import javax.jms.ConnectionFactory; import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory; -import org.apache.activemq.jms.pool.PooledConnectionFactory; import org.apache.commons.pool2.PooledObject; +import org.messaginghub.pooled.jms.JmsPoolConnectionFactory; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.jms.JmsPoolConnectionFactoryFactory; import org.springframework.boot.autoconfigure.jms.JmsProperties; -import org.springframework.boot.autoconfigure.jms.activemq.PooledConnectionFactoryFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jms.connection.CachingConnectionFactory; @@ -87,17 +87,17 @@ class ArtemisConnectionFactoryConfiguration { } @Configuration - @ConditionalOnClass({ PooledConnectionFactory.class, PooledObject.class }) + @ConditionalOnClass({ JmsPoolConnectionFactory.class, PooledObject.class }) static class PooledConnectionFactoryConfiguration { @Bean(destroyMethod = "stop") @ConditionalOnProperty(prefix = "spring.artemis.pool", name = "enabled", havingValue = "true", matchIfMissing = false) - public PooledConnectionFactory pooledJmsConnectionFactory( + public JmsPoolConnectionFactory pooledJmsConnectionFactory( ListableBeanFactory beanFactory, ArtemisProperties properties) { ActiveMQConnectionFactory connectionFactory = new ArtemisConnectionFactoryFactory( beanFactory, properties) .createConnectionFactory(ActiveMQConnectionFactory.class); - return new PooledConnectionFactoryFactory(properties.getPool()) + return new JmsPoolConnectionFactoryFactory(properties.getPool()) .createPooledConnectionFactory(connectionFactory); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisProperties.java index 0a6fcf4a53..b2791343ba 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisProperties.java @@ -23,7 +23,7 @@ import java.util.concurrent.atomic.AtomicInteger; import org.apache.activemq.artemis.core.remoting.impl.invm.TransportConstants; -import org.springframework.boot.autoconfigure.jms.activemq.PooledConnectionFactoryProperties; +import org.springframework.boot.autoconfigure.jms.JmsPoolConnectionFactoryProperties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.NestedConfigurationProperty; @@ -65,7 +65,7 @@ public class ArtemisProperties { private final Embedded embedded = new Embedded(); @NestedConfigurationProperty - private final PooledConnectionFactoryProperties pool = new PooledConnectionFactoryProperties(); + private final JmsPoolConnectionFactoryProperties pool = new JmsPoolConnectionFactoryProperties(); public ArtemisMode getMode() { return this.mode; @@ -111,7 +111,7 @@ public class ArtemisProperties { return this.embedded; } - public PooledConnectionFactoryProperties getPool() { + public JmsPoolConnectionFactoryProperties getPool() { return this.pool; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index b0f2e0fe1f..1538437dbf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -49,6 +49,18 @@ "description": "Whether subclass-based (CGLIB) proxies are to be created (true), as opposed to standard Java interface-based proxies (false).", "defaultValue": true }, + { + "name": "spring.activemq.pool.maximum-active-session-per-connection", + "deprecation": { + "replacement": "spring.activemq.pool.max-sessions-per-connection" + } + }, + { + "name": "spring.artemis.pool.maximum-active-session-per-connection", + "deprecation": { + "replacement": "spring.artemis.pool.max-sessions-per-connection" + } + }, { "name": "spring.application.admin.enabled", "type": "java.lang.Boolean", diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/JmsAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/JmsAutoConfigurationTests.java index 552afb6b9d..2d3f6dfdba 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/JmsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/JmsAutoConfigurationTests.java @@ -20,8 +20,8 @@ import javax.jms.ConnectionFactory; import javax.jms.Session; import org.apache.activemq.ActiveMQConnectionFactory; -import org.apache.activemq.jms.pool.PooledConnectionFactory; import org.junit.Test; +import org.messaginghub.pooled.jms.JmsPoolConnectionFactory; import org.springframework.beans.BeansException; import org.springframework.beans.DirectFieldAccessor; @@ -369,8 +369,8 @@ public class JmsAutoConfigurationTests { .withPropertyValues("spring.activemq.pool.enabled:true") .run((context) -> { JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class); - PooledConnectionFactory pool = context - .getBean(PooledConnectionFactory.class); + JmsPoolConnectionFactory pool = context + .getBean(JmsPoolConnectionFactory.class); assertThat(jmsTemplate).isNotNull(); assertThat(pool).isNotNull(); assertThat(pool).isEqualTo(jmsTemplate.getConnectionFactory()); @@ -387,8 +387,8 @@ public class JmsAutoConfigurationTests { "spring.activemq.inMemory:false") .run((context) -> { JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class); - PooledConnectionFactory pool = context - .getBean(PooledConnectionFactory.class); + JmsPoolConnectionFactory pool = context + .getBean(JmsPoolConnectionFactory.class); assertThat(jmsTemplate).isNotNull(); assertThat(pool).isNotNull(); assertThat(pool).isEqualTo(jmsTemplate.getConnectionFactory()); @@ -405,8 +405,8 @@ public class JmsAutoConfigurationTests { "spring.activemq.brokerUrl:tcp://remote-host:10000") .run((context) -> { JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class); - PooledConnectionFactory pool = context - .getBean(PooledConnectionFactory.class); + JmsPoolConnectionFactory pool = context + .getBean(JmsPoolConnectionFactory.class); assertThat(jmsTemplate).isNotNull(); assertThat(pool).isNotNull(); assertThat(pool).isEqualTo(jmsTemplate.getConnectionFactory()); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQAutoConfigurationTests.java index b2a74595ef..4194f84cdd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQAutoConfigurationTests.java @@ -19,8 +19,8 @@ package org.springframework.boot.autoconfigure.jms.activemq; import javax.jms.ConnectionFactory; import org.apache.activemq.ActiveMQConnectionFactory; -import org.apache.activemq.jms.pool.PooledConnectionFactory; import org.junit.Test; +import org.messaginghub.pooled.jms.JmsPoolConnectionFactory; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration; @@ -165,71 +165,86 @@ public class ActiveMQAutoConfigurationTests { } @Test - public void defaultPooledConnectionFactoryIsApplied() { + public void defaultPoolConnectionFactoryIsApplied() { this.contextRunner.withUserConfiguration(EmptyConfiguration.class) .withPropertyValues("spring.activemq.pool.enabled=true") .run((context) -> { - assertThat(context.getBeansOfType(PooledConnectionFactory.class)) + assertThat(context.getBeansOfType(JmsPoolConnectionFactory.class)) .hasSize(1); - PooledConnectionFactory connectionFactory = context - .getBean(PooledConnectionFactory.class); - PooledConnectionFactory defaultFactory = new PooledConnectionFactory(); + JmsPoolConnectionFactory connectionFactory = context + .getBean(JmsPoolConnectionFactory.class); + JmsPoolConnectionFactory defaultFactory = new JmsPoolConnectionFactory(); assertThat(connectionFactory.isBlockIfSessionPoolIsFull()) .isEqualTo(defaultFactory.isBlockIfSessionPoolIsFull()); assertThat(connectionFactory.getBlockIfSessionPoolIsFullTimeout()) .isEqualTo( defaultFactory.getBlockIfSessionPoolIsFullTimeout()); - assertThat(connectionFactory.getIdleTimeout()) - .isEqualTo(defaultFactory.getIdleTimeout()); + assertThat(connectionFactory.getConnectionIdleTimeout()) + .isEqualTo(defaultFactory.getConnectionIdleTimeout()); assertThat(connectionFactory.getMaxConnections()) .isEqualTo(defaultFactory.getMaxConnections()); - assertThat(connectionFactory.getMaximumActiveSessionPerConnection()) - .isEqualTo(defaultFactory - .getMaximumActiveSessionPerConnection()); - assertThat(connectionFactory.getTimeBetweenExpirationCheckMillis()) - .isEqualTo( - defaultFactory.getTimeBetweenExpirationCheckMillis()); + assertThat(connectionFactory.getMaxSessionsPerConnection()) + .isEqualTo(defaultFactory.getMaxSessionsPerConnection()); + assertThat(connectionFactory.getConnectionCheckInterval()) + .isEqualTo(defaultFactory.getConnectionCheckInterval()); assertThat(connectionFactory.isUseAnonymousProducers()) .isEqualTo(defaultFactory.isUseAnonymousProducers()); }); } @Test - public void customPooledConnectionFactoryIsApplied() { + public 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.maximumActiveSessionPerConnection=1024", + "spring.activemq.pool.maxSessionsPerConnection=1024", "spring.activemq.pool.timeBetweenExpirationCheck=2048", "spring.activemq.pool.useAnonymousProducers=false") .run((context) -> { - assertThat(context.getBeansOfType(PooledConnectionFactory.class)) + assertThat(context.getBeansOfType(JmsPoolConnectionFactory.class)) .hasSize(1); - PooledConnectionFactory connectionFactory = context - .getBean(PooledConnectionFactory.class); + JmsPoolConnectionFactory connectionFactory = context + .getBean(JmsPoolConnectionFactory.class); assertThat(connectionFactory.isBlockIfSessionPoolIsFull()).isFalse(); assertThat(connectionFactory.getBlockIfSessionPoolIsFullTimeout()) .isEqualTo(64); - assertThat(connectionFactory.getIdleTimeout()).isEqualTo(512); + assertThat(connectionFactory.getConnectionIdleTimeout()) + .isEqualTo(512); assertThat(connectionFactory.getMaxConnections()).isEqualTo(256); - assertThat(connectionFactory.getMaximumActiveSessionPerConnection()) + assertThat(connectionFactory.getMaxSessionsPerConnection()) .isEqualTo(1024); - assertThat(connectionFactory.getTimeBetweenExpirationCheckMillis()) + assertThat(connectionFactory.getConnectionCheckInterval()) .isEqualTo(2048); assertThat(connectionFactory.isUseAnonymousProducers()).isFalse(); }); } @Test - public void pooledConnectionFactoryConfiguration() { + @Deprecated + public void customPoolConnectionFactoryIsAppliedWithDeprecatedSettings() { + this.contextRunner.withUserConfiguration(EmptyConfiguration.class) + .withPropertyValues("spring.activemq.pool.enabled=true", + "spring.activemq.pool.maximumActiveSessionPerConnection=1024") + .run((context) -> { + assertThat(context.getBeansOfType(JmsPoolConnectionFactory.class)) + .hasSize(1); + JmsPoolConnectionFactory connectionFactory = context + .getBean(JmsPoolConnectionFactory.class); + assertThat(connectionFactory.getMaxSessionsPerConnection()) + .isEqualTo(1024); + }); + } + + @Test + public void poolConnectionFactoryConfiguration() { this.contextRunner.withUserConfiguration(EmptyConfiguration.class) .withPropertyValues("spring.activemq.pool.enabled:true") .run((context) -> { ConnectionFactory factory = context.getBean(ConnectionFactory.class); - assertThat(factory).isInstanceOf(PooledConnectionFactory.class); + assertThat(factory).isInstanceOf(JmsPoolConnectionFactory.class); context.getSourceApplicationContext().close(); assertThat(factory.createConnection()).isNull(); }); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisAutoConfigurationTests.java index c65583e6b4..8985127847 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisAutoConfigurationTests.java @@ -37,10 +37,10 @@ import org.apache.activemq.artemis.jms.server.config.impl.JMSConfigurationImpl; import org.apache.activemq.artemis.jms.server.config.impl.JMSQueueConfigurationImpl; import org.apache.activemq.artemis.jms.server.config.impl.TopicConfigurationImpl; import org.apache.activemq.artemis.jms.server.embedded.EmbeddedJMS; -import org.apache.activemq.jms.pool.PooledConnectionFactory; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.messaginghub.pooled.jms.JmsPoolConnectionFactory; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration; @@ -350,81 +350,83 @@ public class ArtemisAutoConfigurationTests { } @Test - public void defaultPooledConnectionFactoryIsApplied() { + public void defaultPoolConnectionFactoryIsApplied() { this.contextRunner.withPropertyValues("spring.artemis.pool.enabled=true") .run((context) -> { - assertThat(context.getBeansOfType(PooledConnectionFactory.class)) + assertThat(context.getBeansOfType(JmsPoolConnectionFactory.class)) .hasSize(1); - PooledConnectionFactory connectionFactory = context - .getBean(PooledConnectionFactory.class); - PooledConnectionFactory defaultFactory = new PooledConnectionFactory(); + JmsPoolConnectionFactory connectionFactory = context + .getBean(JmsPoolConnectionFactory.class); + JmsPoolConnectionFactory defaultFactory = new JmsPoolConnectionFactory(); assertThat(connectionFactory.isBlockIfSessionPoolIsFull()) .isEqualTo(defaultFactory.isBlockIfSessionPoolIsFull()); assertThat(connectionFactory.getBlockIfSessionPoolIsFullTimeout()) .isEqualTo( defaultFactory.getBlockIfSessionPoolIsFullTimeout()); - assertThat(connectionFactory.isCreateConnectionOnStartup()) - .isEqualTo(defaultFactory.isCreateConnectionOnStartup()); - assertThat(connectionFactory.getExpiryTimeout()) - .isEqualTo(defaultFactory.getExpiryTimeout()); - assertThat(connectionFactory.getIdleTimeout()) - .isEqualTo(defaultFactory.getIdleTimeout()); + assertThat(connectionFactory.getConnectionIdleTimeout()) + .isEqualTo(defaultFactory.getConnectionIdleTimeout()); assertThat(connectionFactory.getMaxConnections()) .isEqualTo(defaultFactory.getMaxConnections()); - assertThat(connectionFactory.getMaximumActiveSessionPerConnection()) - .isEqualTo(defaultFactory - .getMaximumActiveSessionPerConnection()); - assertThat(connectionFactory.isReconnectOnException()) - .isEqualTo(defaultFactory.isReconnectOnException()); - assertThat(connectionFactory.getTimeBetweenExpirationCheckMillis()) - .isEqualTo( - defaultFactory.getTimeBetweenExpirationCheckMillis()); + assertThat(connectionFactory.getMaxSessionsPerConnection()) + .isEqualTo(defaultFactory.getMaxSessionsPerConnection()); + assertThat(connectionFactory.getConnectionCheckInterval()) + .isEqualTo(defaultFactory.getConnectionCheckInterval()); assertThat(connectionFactory.isUseAnonymousProducers()) .isEqualTo(defaultFactory.isUseAnonymousProducers()); }); } @Test - public void customPooledConnectionFactoryIsApplied() { + public void customPoolConnectionFactoryIsApplied() { this.contextRunner .withPropertyValues("spring.artemis.pool.enabled=true", "spring.artemis.pool.blockIfFull=false", "spring.artemis.pool.blockIfFullTimeout=64", - "spring.artemis.pool.createConnectionOnStartup=false", - "spring.artemis.pool.expiryTimeout=4096", "spring.artemis.pool.idleTimeout=512", "spring.artemis.pool.maxConnections=256", - "spring.artemis.pool.maximumActiveSessionPerConnection=1024", - "spring.artemis.pool.reconnectOnException=false", + "spring.artemis.pool.maxSessionsPerConnection=1024", "spring.artemis.pool.timeBetweenExpirationCheck=2048", "spring.artemis.pool.useAnonymousProducers=false") .run((context) -> { - assertThat(context.getBeansOfType(PooledConnectionFactory.class)) + assertThat(context.getBeansOfType(JmsPoolConnectionFactory.class)) .hasSize(1); - PooledConnectionFactory connectionFactory = context - .getBean(PooledConnectionFactory.class); + JmsPoolConnectionFactory connectionFactory = context + .getBean(JmsPoolConnectionFactory.class); assertThat(connectionFactory.isBlockIfSessionPoolIsFull()).isFalse(); assertThat(connectionFactory.getBlockIfSessionPoolIsFullTimeout()) .isEqualTo(64); - assertThat(connectionFactory.isCreateConnectionOnStartup()).isFalse(); - assertThat(connectionFactory.getExpiryTimeout()).isEqualTo(4096); - assertThat(connectionFactory.getIdleTimeout()).isEqualTo(512); + assertThat(connectionFactory.getConnectionIdleTimeout()) + .isEqualTo(512); assertThat(connectionFactory.getMaxConnections()).isEqualTo(256); - assertThat(connectionFactory.getMaximumActiveSessionPerConnection()) + assertThat(connectionFactory.getMaxSessionsPerConnection()) .isEqualTo(1024); - assertThat(connectionFactory.isReconnectOnException()).isFalse(); - assertThat(connectionFactory.getTimeBetweenExpirationCheckMillis()) + assertThat(connectionFactory.getConnectionCheckInterval()) .isEqualTo(2048); assertThat(connectionFactory.isUseAnonymousProducers()).isFalse(); }); } @Test - public void pooledConnectionFactoryConfiguration() { + public void customPoolConnectionFactoryIsAppliedWithDeprecatedSettings() { + this.contextRunner + .withPropertyValues("spring.artemis.pool.enabled=true", + "spring.artemis.pool.maximumActiveSessionPerConnection=1024") + .run((context) -> { + assertThat(context.getBeansOfType(JmsPoolConnectionFactory.class)) + .hasSize(1); + JmsPoolConnectionFactory connectionFactory = context + .getBean(JmsPoolConnectionFactory.class); + assertThat(connectionFactory.getMaxSessionsPerConnection()) + .isEqualTo(1024); + }); + } + + @Test + public void poolConnectionFactoryConfiguration() { this.contextRunner.withPropertyValues("spring.artemis.pool.enabled:true") .run((context) -> { ConnectionFactory factory = context.getBean(ConnectionFactory.class); - assertThat(factory).isInstanceOf(PooledConnectionFactory.class); + assertThat(factory).isInstanceOf(JmsPoolConnectionFactory.class); context.getSourceApplicationContext().close(); assertThat(factory.createConnection()).isNull(); }); diff --git a/spring-boot-project/spring-boot-dependencies/pom.xml b/spring-boot-project/spring-boot-dependencies/pom.xml index 8abd765802..081379a4d3 100644 --- a/spring-boot-project/spring-boot-dependencies/pom.xml +++ b/spring-boot-project/spring-boot-dependencies/pom.xml @@ -135,6 +135,7 @@ 4.1.27.Final 2.0.12.Final 1.1.0 + 1.0.2 42.2.4 2.3.0 4.2.1 @@ -2282,6 +2283,11 @@ mariadb-java-client ${mariadb.version} + + org.messaginghub + pooled-jms + ${pooled-jms-version} + org.mockito mockito-core diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index 37231980b6..d56437631d 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -962,10 +962,10 @@ content into your application. Rather, pick only the properties that you need. spring.activemq.packages.trusted= # Comma-separated list of specific packages to trust (when not trusting all packages). spring.activemq.pool.block-if-full=true # Whether to block when a connection is requested and the pool is full. Set it to false to throw a "JMSException" instead. spring.activemq.pool.block-if-full-timeout=-1ms # Blocking period before throwing an exception if the pool is still full. - spring.activemq.pool.enabled=false # Whether a PooledConnectionFactory should be created, instead of a regular ConnectionFactory. + spring.activemq.pool.enabled=false # Whether a JmsPoolConnectionFactory should be created, instead of a regular ConnectionFactory. spring.activemq.pool.idle-timeout=30s # Connection idle timeout. spring.activemq.pool.max-connections=1 # Maximum number of pooled connections. - spring.activemq.pool.maximum-active-session-per-connection=500 # Maximum number of active sessions per connection. + spring.activemq.pool.max-sessions-per-connection=500 # Maximum number of pooled sessions per connection in the pool. spring.activemq.pool.time-between-expiration-check=-1ms # Time to sleep between runs of the idle connection eviction thread. When negative, no idle connection eviction thread runs. spring.activemq.pool.use-anonymous-producers=true # Whether to use only one anonymous "MessageProducer" instance. Set it to false to create one "MessageProducer" every time one is required. @@ -983,11 +983,11 @@ content into your application. Rather, pick only the properties that you need. spring.artemis.pool.block-if-full=true # Whether to block when a connection is requested and the pool is full. Set it to false to throw a "JMSException" instead. spring.artemis.pool.block-if-full-timeout=-1ms # Blocking period before throwing an exception if the pool is still full. spring.artemis.pool.create-connection-on-startup=true # Whether to create a connection on startup. Can be used to warm up the pool on startup. - spring.artemis.pool.enabled=false # Whether a PooledConnectionFactory should be created, instead of a regular ConnectionFactory. + spring.artemis.pool.enabled=false # Whether a JmsPoolConnectionFactory should be created, instead of a regular ConnectionFactory. spring.artemis.pool.expiry-timeout=0ms # Connection expiration timeout. spring.artemis.pool.idle-timeout=30s # Connection idle timeout. spring.artemis.pool.max-connections=1 # Maximum number of pooled connections. - spring.artemis.pool.maximum-active-session-per-connection=500 # Maximum number of active sessions per connection. + spring.artemis.pool.max-sessions-per-connection=500 # Maximum number of pooled sessions per connection in the pool. spring.artemis.pool.reconnect-on-exception=true # Reset the connection when a "JMSException" occurs. spring.artemis.pool.time-between-expiration-check=-1ms # Time to sleep between runs of the idle connection eviction thread. When negative, no idle connection eviction thread runs. spring.artemis.pool.use-anonymous-producers=true # Whether to use only one anonymous "MessageProducer" instance. Set it to false to create one "MessageProducer" every time one is required. diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 85de1dc6e3..a4f257a2d9 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -5110,8 +5110,8 @@ sensible settings that you can control by external configuration properties in ---- If you'd rather use native pooling, you can do so by adding a dependency to -`org.apache.activemq:activemq-jms-pool` and configuring the `PooledConnectionFactory` -accordingly, as shown in the following example: +`org.messaginghub:pooled-jms` and configuring the `JmsPoolConnectionFactory` accordingly, +as shown in the following example: [source,properties,indent=0] ---- @@ -5119,8 +5119,6 @@ accordingly, as shown in the following example: spring.activemq.pool.max-connections=50 ---- -WARNING: `PooledConnectionFactory` is not JMS 2.0 compliant - TIP: See {sc-spring-boot-autoconfigure}/jms/activemq/ActiveMQProperties.{sc-ext}[`ActiveMQProperties`] for more of the supported options. You can also register an arbitrary number of beans @@ -5178,8 +5176,8 @@ sensible settings that you can control by external configuration properties in ---- If you'd rather use native pooling, you can do so by adding a dependency to -`org.apache.activemq:activemq-jms-pool` and configuring the `PooledConnectionFactory` -accordingly, as shown in the following example: +`org.messaginghub:pooled-jms` and configuring the `JmsPoolConnectionFactory` accordingly, +as shown in the following example: [source,properties,indent=0] ----