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..0e79bde66c 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 @@ -60,11 +60,23 @@ class ActiveMQConnectionFactoryConfiguration { 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 6cd2fa7b1d..ec2d555be7 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-2017 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. @@ -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/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index fd20b74564..7a544ac03a 100644 --- a/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -33,6 +33,78 @@ "description": "Enable the default error page displayed in browsers in case of a server error.", "defaultValue": true }, + { + "name": "spring.activemq.pool.configuration.block-if-session-pool-is-full", + "deprecation": { + "replacement": "spring.activemq.pool.block-if-full" + } + }, + { + "name": "spring.activemq.pool.configuration.block-if-session-pool-is-full-timeout", + "deprecation": { + "replacement": "spring.activemq.pool.block-if-full-timeout" + } + }, + { + "name": "spring.activemq.pool.configuration.connection-factory", + "deprecation": { + "reason": "This third party property cannot be set via the Environment." + } + }, + { + "name": "spring.activemq.pool.configuration.create-connection-on-startup", + "deprecation": { + "replacement": "spring.activemq.pool.create-connection-on-startup" + } + }, + { + "name": "spring.activemq.pool.configuration.expiry-timeout", + "deprecation": { + "replacement": "spring.activemq.pool.expiry-timeout" + } + }, + { + "name": "spring.activemq.pool.configuration.idle-timeout", + "deprecation": { + "replacement": "spring.activemq.pool.idle-timeout" + } + }, + { + "name": "spring.activemq.pool.configuration.max-connections", + "deprecation": { + "replacement": "spring.activemq.pool.max-connections" + } + }, + { + "name": "spring.activemq.pool.configuration.maximum-active-session-per-connection", + "deprecation": { + "replacement": "spring.activemq.pool.maximum-active-session-per-connection" + } + }, + { + "name": "spring.activemq.pool.configuration.properties", + "deprecation": { + "reason": "This third party property cannot be set via the Environment." + } + }, + { + "name": "spring.activemq.pool.configuration.reconnect-on-exception", + "deprecation": { + "replacement": "spring.activemq.pool.reconnect-on-exception" + } + }, + { + "name": "spring.activemq.pool.configuration.time-between-expiration-check-millis", + "deprecation": { + "replacement": "spring.activemq.pool.time-between-expiration-check" + } + }, + { + "name": "spring.activemq.pool.configuration.use-anonymous-producers", + "deprecation": { + "replacement": "spring.activemq.pool.use-anonymous-producers" + } + }, { "name": "spring.aop.auto", "type": "java.lang.Boolean", 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 9daa5a93ff..df0b9c5ff5 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-2017 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. @@ -62,24 +62,93 @@ public class ActiveMQAutoConfigurationTests { } @Test - public void customPooledConnectionFactoryConfiguration() { - load(EmptyConfiguration.class, "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"); - ConnectionFactory connectionFactory = this.context - .getBean(ConnectionFactory.class); - assertThat(connectionFactory).isInstanceOf(PooledConnectionFactory.class); - PooledConnectionFactory pooledConnectionFactory = (PooledConnectionFactory) connectionFactory; - assertThat(pooledConnectionFactory.getMaxConnections()).isEqualTo(256); - assertThat(pooledConnectionFactory.getIdleTimeout()).isEqualTo(512); - assertThat(pooledConnectionFactory.getMaximumActiveSessionPerConnection()) + public void defaultsPooledConnectionFactoryAreApplied() { + load(EmptyConfiguration.class, "spring.activemq.pool.enabled=true"); + assertThat(this.context.getBeansOfType(PooledConnectionFactory.class)).hasSize(1); + PooledConnectionFactory connectionFactory = this.context.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() { + load(EmptyConfiguration.class, "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"); + assertThat(this.context.getBeansOfType(PooledConnectionFactory.class)).hasSize(1); + PooledConnectionFactory connectionFactory = this.context.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(pooledConnectionFactory.getTimeBetweenExpirationCheckMillis()) + assertThat(connectionFactory.isReconnectOnException()).isEqualTo(false); + assertThat(connectionFactory.getTimeBetweenExpirationCheckMillis()) .isEqualTo(2048); - assertThat(pooledConnectionFactory.getExpiryTimeout()).isEqualTo(4096); + assertThat(connectionFactory.isUseAnonymousProducers()).isEqualTo(false); + } + + @Test + @Deprecated + public void customPooledConnectionFactoryOnTargetInstanceAreApplied() { + load(EmptyConfiguration.class, "spring.activemq.pool.enabled=true", + "spring.activemq.pool.configuration.blockIfSessionPoolIsFull=false", + "spring.activemq.pool.configuration.blockIfSessionPoolIsFullTimeout=64", + "spring.activemq.pool.configuration.createConnectionOnStartup=false", + "spring.activemq.pool.expiryTimeout=4096", + "spring.activemq.pool.idleTimeout=512", + "spring.activemq.pool.maxConnections=256", + "spring.activemq.pool.configuration.maximumActiveSessionPerConnection=1024", + "spring.activemq.pool.configuration.reconnectOnException=false", + "spring.activemq.pool.configuration.timeBetweenExpirationCheckMillis=2048", + "spring.activemq.pool.configuration.useAnonymousProducers=false"); + assertThat(this.context.getBeansOfType(PooledConnectionFactory.class)).hasSize(1); + PooledConnectionFactory connectionFactory = this.context.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 43164eb751..c681daa5f0 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -843,11 +843,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.