diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryConfiguration.java index 19beb7e808..059e10bea4 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQConnectionFactoryConfiguration.java @@ -24,7 +24,6 @@ import org.apache.activemq.pool.PooledConnectionFactory; 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.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -54,17 +53,28 @@ class ActiveMQConnectionFactoryConfiguration { @Bean(destroyMethod = "stop") @ConditionalOnProperty(prefix = "spring.activemq.pool", name = "enabled", havingValue = "true", matchIfMissing = false) - @ConfigurationProperties(prefix = "spring.activemq.pool.configuration") public PooledConnectionFactory pooledJmsConnectionFactory( ActiveMQProperties properties) { PooledConnectionFactory pooledConnectionFactory = new PooledConnectionFactory( new ActiveMQConnectionFactoryFactory(properties) .createConnectionFactory(ActiveMQConnectionFactory.class)); - ActiveMQProperties.Pool pool = properties.getPool(); - pooledConnectionFactory.setMaxConnections(pool.getMaxConnections()); - pooledConnectionFactory.setIdleTimeout(pool.getIdleTimeout()); + pooledConnectionFactory.setBlockIfSessionPoolIsFull(pool.isBlockIfFull()); + pooledConnectionFactory.setBlockIfSessionPoolIsFullTimeout( + pool.getBlockIfFullTimeout()); + pooledConnectionFactory.setCreateConnectionOnStartup( + pool.isCreateConnectionOnStartup()); pooledConnectionFactory.setExpiryTimeout(pool.getExpiryTimeout()); + pooledConnectionFactory.setIdleTimeout(pool.getIdleTimeout()); + pooledConnectionFactory.setMaxConnections(pool.getMaxConnections()); + pooledConnectionFactory.setMaximumActiveSessionPerConnection( + pool.getMaximumActiveSessionPerConnection()); + pooledConnectionFactory.setReconnectOnException( + pool.isReconnectOnException()); + pooledConnectionFactory.setTimeBetweenExpirationCheckMillis( + pool.getTimeBetweenExpirationCheck()); + pooledConnectionFactory.setUseAnonymousProducers( + pool.isUseAnonymousProducers()); return pooledConnectionFactory; } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQProperties.java index 12aed79db9..d38de7a292 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQProperties.java @@ -110,9 +110,26 @@ public class ActiveMQProperties { private boolean enabled; /** - * Maximum number of pooled connections. + * Block when a connection is requested and the pool is full. Set it to false to + * throw a "JMSException" instead. */ - private int maxConnections = 1; + private boolean blockIfFull = true; + + /** + * Blocking period, in milliseconds, before throwing an exception if the pool + * is still full. + */ + private long blockIfFullTimeout = -1; + + /** + * Create a connection on startup. Can be used to warm-up the pool on startup. + */ + private boolean createConnectionOnStartup = true; + + /** + * Connection expiration timeout in milliseconds. + */ + private long expiryTimeout = 0; /** * Connection idle timeout in milliseconds. @@ -120,9 +137,31 @@ public class ActiveMQProperties { private int idleTimeout = 30000; /** - * Connection expiration timeout in milliseconds. + * Maximum number of pooled connections. */ - private long expiryTimeout = 0; + private int maxConnections = 1; + + /** + * Maximum number of active sessions per connection. + */ + private int maximumActiveSessionPerConnection = 500; + + /** + * Reset the connection when a "JMXException" occurs. + */ + private boolean reconnectOnException = true; + + /** + * Time to sleep, in milliseconds, between runs of the idle connection eviction + * thread. When negative, no idle connection eviction thread runs. + */ + private long timeBetweenExpirationCheck = -1; + + /** + * Use only one anonymous "MessageProducer" instance. Set it to false to create + * one "MessageProducer" every time one is required. + */ + private boolean useAnonymousProducers = true; public boolean isEnabled() { return this.enabled; @@ -132,12 +171,36 @@ public class ActiveMQProperties { this.enabled = enabled; } - public int getMaxConnections() { - return this.maxConnections; + public boolean isBlockIfFull() { + return this.blockIfFull; } - public void setMaxConnections(int maxConnections) { - this.maxConnections = maxConnections; + public void setBlockIfFull(boolean blockIfFull) { + this.blockIfFull = blockIfFull; + } + + public long getBlockIfFullTimeout() { + return this.blockIfFullTimeout; + } + + public void setBlockIfFullTimeout(long blockIfFullTimeout) { + this.blockIfFullTimeout = blockIfFullTimeout; + } + + public boolean isCreateConnectionOnStartup() { + return this.createConnectionOnStartup; + } + + public void setCreateConnectionOnStartup(boolean createConnectionOnStartup) { + this.createConnectionOnStartup = createConnectionOnStartup; + } + + public long getExpiryTimeout() { + return this.expiryTimeout; + } + + public void setExpiryTimeout(long expiryTimeout) { + this.expiryTimeout = expiryTimeout; } public int getIdleTimeout() { @@ -148,12 +211,44 @@ public class ActiveMQProperties { this.idleTimeout = idleTimeout; } - public long getExpiryTimeout() { - return this.expiryTimeout; + public int getMaxConnections() { + return this.maxConnections; } - public void setExpiryTimeout(long expiryTimeout) { - this.expiryTimeout = expiryTimeout; + public void setMaxConnections(int maxConnections) { + this.maxConnections = maxConnections; + } + + public int getMaximumActiveSessionPerConnection() { + return this.maximumActiveSessionPerConnection; + } + + public void setMaximumActiveSessionPerConnection(int maximumActiveSessionPerConnection) { + this.maximumActiveSessionPerConnection = maximumActiveSessionPerConnection; + } + + public boolean isReconnectOnException() { + return this.reconnectOnException; + } + + public void setReconnectOnException(boolean reconnectOnException) { + this.reconnectOnException = reconnectOnException; + } + + public long getTimeBetweenExpirationCheck() { + return this.timeBetweenExpirationCheck; + } + + public void setTimeBetweenExpirationCheck(long timeBetweenExpirationCheck) { + this.timeBetweenExpirationCheck = timeBetweenExpirationCheck; + } + + public boolean isUseAnonymousProducers() { + return this.useAnonymousProducers; + } + + public void setUseAnonymousProducers(boolean useAnonymousProducers) { + this.useAnonymousProducers = useAnonymousProducers; } } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQAutoConfigurationTests.java index a66baef92c..ae6303dbc7 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQAutoConfigurationTests.java @@ -65,26 +65,66 @@ public class ActiveMQAutoConfigurationTests { } @Test - public void customPooledConnectionFactoryConfiguration() { + public void defaultsPooledConnectionFactoryAreApplied() { this.context.withUserConfiguration(EmptyConfiguration.class) - .withPropertyValues("spring.activemq.pool.enabled:true", - "spring.activemq.pool.maxConnections:256", - "spring.activemq.pool.idleTimeout:512", - "spring.activemq.pool.expiryTimeout:4096", - "spring.activemq.pool.configuration.maximumActiveSessionPerConnection:1024", - "spring.activemq.pool.configuration.timeBetweenExpirationCheckMillis:2048") - .run((loaded) -> { - ConnectionFactory factory = loaded.getBean(ConnectionFactory.class); - assertThat(factory).isInstanceOf(PooledConnectionFactory.class); - PooledConnectionFactory pooledFactory = (PooledConnectionFactory) factory; - assertThat(pooledFactory.getMaxConnections()).isEqualTo(256); - assertThat(pooledFactory.getIdleTimeout()).isEqualTo(512); - assertThat(pooledFactory.getMaximumActiveSessionPerConnection()) - .isEqualTo(1024); - assertThat(pooledFactory.getTimeBetweenExpirationCheckMillis()) - .isEqualTo(2048); - assertThat(pooledFactory.getExpiryTimeout()).isEqualTo(4096); - }); + .withPropertyValues("spring.activemq.pool.enabled=true").run((loaded) -> { + assertThat(loaded.getBeansOfType(PooledConnectionFactory.class)).hasSize(1); + PooledConnectionFactory connectionFactory = loaded.getBean( + PooledConnectionFactory.class); + PooledConnectionFactory defaultFactory = new PooledConnectionFactory(); + 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.getMaxConnections()).isEqualTo( + defaultFactory.getMaxConnections()); + assertThat(connectionFactory.getMaximumActiveSessionPerConnection()).isEqualTo( + defaultFactory.getMaximumActiveSessionPerConnection()); + assertThat(connectionFactory.isReconnectOnException()).isEqualTo( + defaultFactory.isReconnectOnException()); + assertThat(connectionFactory.getTimeBetweenExpirationCheckMillis()).isEqualTo( + defaultFactory.getTimeBetweenExpirationCheckMillis()); + assertThat(connectionFactory.isUseAnonymousProducers()).isEqualTo( + defaultFactory.isUseAnonymousProducers()); + }); + } + + @Test + public void customPooledConnectionFactoryAreApplied() { + this.context.withUserConfiguration(EmptyConfiguration.class) + .withPropertyValues("spring.activemq.pool.enabled=true", + "spring.activemq.pool.blockIfFull=false", + "spring.activemq.pool.blockIfFullTimeout=64", + "spring.activemq.pool.createConnectionOnStartup=false", + "spring.activemq.pool.expiryTimeout=4096", + "spring.activemq.pool.idleTimeout=512", + "spring.activemq.pool.maxConnections=256", + "spring.activemq.pool.maximumActiveSessionPerConnection=1024", + "spring.activemq.pool.reconnectOnException=false", + "spring.activemq.pool.timeBetweenExpirationCheck=2048", + "spring.activemq.pool.useAnonymousProducers=false").run((loaded) -> { + assertThat(loaded.getBeansOfType(PooledConnectionFactory.class)).hasSize(1); + PooledConnectionFactory connectionFactory = loaded.getBean( + PooledConnectionFactory.class); + assertThat(connectionFactory.isBlockIfSessionPoolIsFull()).isEqualTo(false); + assertThat(connectionFactory.getBlockIfSessionPoolIsFullTimeout()).isEqualTo(64); + assertThat(connectionFactory.isCreateConnectionOnStartup()).isEqualTo(false); + assertThat(connectionFactory.getExpiryTimeout()).isEqualTo(4096); + assertThat(connectionFactory.getIdleTimeout()).isEqualTo(512); + assertThat(connectionFactory.getMaxConnections()).isEqualTo(256); + assertThat(connectionFactory.getMaximumActiveSessionPerConnection()) + .isEqualTo(1024); + assertThat(connectionFactory.isReconnectOnException()).isEqualTo(false); + assertThat(connectionFactory.getTimeBetweenExpirationCheckMillis()) + .isEqualTo(2048); + assertThat(connectionFactory.isUseAnonymousProducers()).isEqualTo(false); + }); } @Test diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index 1ff477da18..b701498969 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -908,11 +908,17 @@ content into your application; rather pick only the properties that you need. spring.activemq.user= # Login user of the broker. spring.activemq.packages.trust-all=false # Trust all packages. spring.activemq.packages.trusted= # Comma-separated list of specific packages to trust (when not trusting all packages). - spring.activemq.pool.configuration.*= # See PooledConnectionFactory. - spring.activemq.pool.enabled=false # Whether a PooledConnectionFactory should be created instead of a regular ConnectionFactory. - spring.activemq.pool.expiry-timeout=0 # Connection expiration timeout in milliseconds. - spring.activemq.pool.idle-timeout=30000 # Connection idle timeout in milliseconds. - spring.activemq.pool.max-connections=1 # Maximum number of pooled connections. + spring.activemq.pool.block-if-full=true # 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=-1 # Blocking period, in milliseconds, before throwing an exception if the pool is still full. + spring.activemq.pool.create-connection-on-startup=true # Create a connection on startup. Can be used to warm-up the pool on startup. + spring.activemq.pool.enabled=false # Whether a PooledConnectionFactory should be created instead of a regular ConnectionFactory. + spring.activemq.pool.expiry-timeout=0 # Connection expiration timeout in milliseconds. + spring.activemq.pool.idle-timeout=30000 # Connection idle timeout in milliseconds. + 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.reconnect-on-exception=true # Reset the connection when a "JMXException" occurs. + spring.activemq.pool.time-between-expiration-check=-1 # Time to sleep, in milliseconds, between runs of the idle connection eviction thread. When negative, no idle connection eviction thread runs. + spring.activemq.pool.use-anonymous-producers=true # Use only one anonymous "MessageProducer" instance. Set it to false to create one "MessageProducer" every time one is required. # ARTEMIS ({sc-spring-boot-autoconfigure}/jms/artemis/ArtemisProperties.{sc-ext}[ArtemisProperties]) spring.artemis.embedded.cluster-password= # Cluster password. Randomly generated on startup by default. diff --git a/spring-boot-starters/README.adoc b/spring-boot-starters/README.adoc index a3b47af35e..3fd4a680cd 100644 --- a/spring-boot-starters/README.adoc +++ b/spring-boot-starters/README.adoc @@ -73,6 +73,9 @@ do as they were designed before this was clarified. | http://hdiv.org/[HDIV] | https://github.com/hdiv/spring-boot-starter-hdiv +| Hiatus for Spring Boot +| https://github.com/jihor/hiatus-spring-boot + | http://infinispan.org/[Infinispan] | https://github.com/infinispan/infinispan-spring-boot