Add support for connection pooling with Artemis

This commit expands ActiveMQ's connection pooling to artemis. The same
pooling features are now shared by the two brokers and a
PooledConnectionFactory can be auto-configured when the necessary jar is
present.

Closes gh-13523
This commit is contained in:
Stephane Nicoll
2018-06-06 14:44:26 +02:00
parent 28c1bc9986
commit 0ef54a79b1
11 changed files with 413 additions and 195 deletions

View File

@@ -20,7 +20,7 @@ import javax.jms.ConnectionFactory;
import javax.jms.Session;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.pool.PooledConnectionFactory;
import org.apache.activemq.jms.pool.PooledConnectionFactory;
import org.junit.Test;
import org.springframework.beans.BeansException;

View File

@@ -19,7 +19,7 @@ package org.springframework.boot.autoconfigure.jms.activemq;
import javax.jms.ConnectionFactory;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.pool.PooledConnectionFactory;
import org.apache.activemq.jms.pool.PooledConnectionFactory;
import org.junit.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;

View File

@@ -20,6 +20,7 @@ import java.io.File;
import java.io.IOException;
import java.util.UUID;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
@@ -36,6 +37,7 @@ 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;
@@ -291,6 +293,87 @@ public class ArtemisAutoConfigurationTests {
});
}
@Test
public void defaultPooledConnectionFactoryIsApplied() {
this.contextRunner.withPropertyValues("spring.artemis.pool.enabled=true")
.run((context) -> {
assertThat(context.getBeansOfType(PooledConnectionFactory.class))
.hasSize(1);
PooledConnectionFactory connectionFactory = 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 customPooledConnectionFactoryIsApplied() {
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.timeBetweenExpirationCheck=2048",
"spring.artemis.pool.useAnonymousProducers=false")
.run((context) -> {
assertThat(context.getBeansOfType(PooledConnectionFactory.class))
.hasSize(1);
PooledConnectionFactory connectionFactory = context
.getBean(PooledConnectionFactory.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.getMaxConnections()).isEqualTo(256);
assertThat(connectionFactory.getMaximumActiveSessionPerConnection())
.isEqualTo(1024);
assertThat(connectionFactory.isReconnectOnException()).isFalse();
assertThat(connectionFactory.getTimeBetweenExpirationCheckMillis())
.isEqualTo(2048);
assertThat(connectionFactory.isUseAnonymousProducers()).isFalse();
});
}
@Test
public void pooledConnectionFactoryConfiguration() {
this.contextRunner.withPropertyValues("spring.artemis.pool.enabled:true")
.run((context) -> {
ConnectionFactory factory = context.getBean(ConnectionFactory.class);
assertThat(factory).isInstanceOf(PooledConnectionFactory.class);
context.getSourceApplicationContext().close();
assertThat(factory.createConnection()).isNull();
});
}
private TransportConfiguration assertInVmConnectionFactory(
ActiveMQConnectionFactory connectionFactory) {
TransportConfiguration transportConfig = getSingleTransportConfiguration(