Provide an alternative to spring.activemq.pool.configuration

This commit expands the support of PooledConnectionFactory so that
binding the third party object is no longer necessary. All 3rd party
properties are now deprecated in favour of our explicit support.

The main reason behind this change is that a `connection-factory` and
`properties` property were exposed. The former is used to set the
`ConnectionFactory` and makes no sense as a key. The latter is
rebuilding the underlying `ActiveMQConnectionFactory` at each call
without reusing any existing settings.

Closes gh-9837
This commit is contained in:
Stephane Nicoll 2017-07-24 13:48:53 +02:00
parent 0680c4ce2b
commit 9a34d952e9
5 changed files with 292 additions and 38 deletions

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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",

View File

@ -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

View File

@ -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.