Use an embed HornetQ broker by default
This commit changes the default behavior of the HornetQ auto configuration. Prior to this commit, an embedded broker was only started when it was requested explicitly by a configuration option. This is inconsistent with the ActiveMQ support and boot favors the easiest route. If the necessary classes are available, HornetQ is embedded in the application by default. Fixes gh-1029
This commit is contained in:
@@ -42,8 +42,8 @@ import org.hornetq.jms.server.embedded.EmbeddedJMS;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -53,12 +53,13 @@ import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
* Auto-configuration} to integrate with an HornetQ broker. Connect by default to a broker
|
||||
* available on the local machine with the default settings. If the necessary classes are
|
||||
* present, the broker can also be embedded in the application itself.
|
||||
* Auto-configuration} to integrate with an HornetQ broker. If the necessary
|
||||
* classes are present, embed the broker in the application by default. Otherwise,
|
||||
* connect to a broker available on the local machine with the default settings.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.1.0
|
||||
* @see HornetQProperties
|
||||
*/
|
||||
@Configuration
|
||||
@AutoConfigureBefore(JmsAutoConfiguration.class)
|
||||
@@ -73,9 +74,9 @@ public class HornetQAutoConfiguration {
|
||||
|
||||
/**
|
||||
* Create the {@link ConnectionFactory} to use if none is provided. If no
|
||||
* {@linkplain HornetQProperties#getMode() mode} has been explicitly set, connect to
|
||||
* the embedded server if it has been requested or to a broker available on the local
|
||||
* machine with the default settings otherwise.
|
||||
* {@linkplain HornetQProperties#getMode() mode} has been explicitly set, start an
|
||||
* embedded server unless it has been explicitly disabled, connect to a broker
|
||||
* available on the local machine with the default settings otherwise.
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@@ -131,7 +132,7 @@ public class HornetQAutoConfiguration {
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass(name = EMBEDDED_JMS_CLASS)
|
||||
@ConditionalOnProperty(prefix = "spring.hornetq.embedded", value = "enabled")
|
||||
@ConditionalOnExpression("'${spring.hornetq.embedded.enabled:true}' == 'true'")
|
||||
static class EmbeddedServerConfiguration {
|
||||
|
||||
@Autowired
|
||||
@@ -159,14 +160,14 @@ public class HornetQAutoConfiguration {
|
||||
org.hornetq.core.config.Configuration configuration,
|
||||
JMSConfiguration jmsConfiguration) {
|
||||
EmbeddedJMS server = new EmbeddedJMS();
|
||||
applyCustomizers(configuration);
|
||||
customize(configuration);
|
||||
server.setConfiguration(configuration);
|
||||
server.setJmsConfiguration(jmsConfiguration);
|
||||
server.setRegistry(new HornetQNoOpBindingRegistry());
|
||||
return server;
|
||||
}
|
||||
|
||||
private void applyCustomizers(org.hornetq.core.config.Configuration configuration) {
|
||||
private void customize(org.hornetq.core.config.Configuration configuration) {
|
||||
if (this.configurationCustomizers != null) {
|
||||
AnnotationAwareOrderComparator.sort(this.configurationCustomizers);
|
||||
for (HornetQConfigurationCustomizer customizer : this.configurationCustomizers) {
|
||||
@@ -182,7 +183,7 @@ public class HornetQAutoConfiguration {
|
||||
addAll(configuration.getQueueConfigurations(), this.queuesConfiguration);
|
||||
addAll(configuration.getTopicConfigurations(), this.topicsConfiguration);
|
||||
addQueues(configuration, this.properties.getEmbedded().getQueues());
|
||||
addTopis(configuration, this.properties.getEmbedded().getTopics());
|
||||
addTopics(configuration, this.properties.getEmbedded().getTopics());
|
||||
return configuration;
|
||||
}
|
||||
|
||||
@@ -201,7 +202,7 @@ public class HornetQAutoConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
private void addTopis(JMSConfiguration configuration, String[] topics) {
|
||||
private void addTopics(JMSConfiguration configuration, String[] topics) {
|
||||
for (String topic : topics) {
|
||||
configuration.getTopicConfigurations().add(
|
||||
new TopicConfigurationImpl(topic, "/topic/" + topic));
|
||||
|
||||
@@ -70,7 +70,7 @@ public class HornetQProperties {
|
||||
*/
|
||||
public static class Embedded {
|
||||
|
||||
private boolean enabled;
|
||||
private boolean enabled = true;
|
||||
|
||||
private boolean persistent;
|
||||
|
||||
|
||||
@@ -43,10 +43,6 @@ import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jms.hornetq.HornetQAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jms.hornetq.HornetQConfigurationCustomizer;
|
||||
import org.springframework.boot.autoconfigure.jms.hornetq.HornetQMode;
|
||||
import org.springframework.boot.autoconfigure.jms.hornetq.HornetQProperties;
|
||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
@@ -93,7 +89,8 @@ public class HornetQAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void nativeConnectionFactoryCustomHost() {
|
||||
load(EmptyConfiguration.class, "spring.hornetq.host:192.168.1.144",
|
||||
load(EmptyConfiguration.class, "spring.hornetq.mode:native",
|
||||
"spring.hornetq.host:192.168.1.144",
|
||||
"spring.hornetq.port:9876");
|
||||
HornetQConnectionFactory connectionFactory = this.context
|
||||
.getBean(HornetQConnectionFactory.class);
|
||||
@@ -102,8 +99,7 @@ public class HornetQAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void embeddedConnectionFactory() {
|
||||
load(EmptyConfiguration.class, "spring.hornetq.mode:embedded",
|
||||
"spring.hornetq.embedded.enabled:true");
|
||||
load(EmptyConfiguration.class, "spring.hornetq.mode:embedded");
|
||||
|
||||
HornetQProperties properties = this.context.getBean(HornetQProperties.class);
|
||||
assertEquals(HornetQMode.EMBEDDED, properties.getMode());
|
||||
@@ -121,26 +117,52 @@ public class HornetQAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nativeConnectionFactoryByDefault() {
|
||||
public void embeddedConnectionFactoryByDefault() {
|
||||
// No mode is specified
|
||||
load(EmptyConfiguration.class);
|
||||
HornetQConnectionFactory connectionFactory = this.context
|
||||
.getBean(HornetQConnectionFactory.class);
|
||||
assertNettyConnectionFactory(connectionFactory, "localhost", 5445);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void embeddedConnectionFactoryIfEmbeddedServiceEnabled() {
|
||||
// No mode enabled, embedded server required
|
||||
load(EmptyConfiguration.class, "spring.hornetq.embedded.enabled:true");
|
||||
assertEquals(1, this.context.getBeansOfType(EmbeddedJMS.class).size());
|
||||
org.hornetq.core.config.Configuration configuration = this.context
|
||||
.getBean(org.hornetq.core.config.Configuration.class);
|
||||
assertFalse("Persistence disabled by default",
|
||||
configuration.isPersistenceEnabled());
|
||||
assertFalse("Security disabled by default", configuration.isSecurityEnabled());
|
||||
|
||||
HornetQConnectionFactory connectionFactory = this.context
|
||||
.getBean(HornetQConnectionFactory.class);
|
||||
assertInVmConnectionFactory(connectionFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nativeConnectionFactoryIfEmbeddedServiceDisabledExplicitly() {
|
||||
// No mode is specified
|
||||
load(EmptyConfiguration.class, "spring.hornetq.embedded.enabled:false");
|
||||
|
||||
assertEquals(0, this.context.getBeansOfType(EmbeddedJMS.class).size());
|
||||
|
||||
HornetQConnectionFactory connectionFactory = this.context
|
||||
.getBean(HornetQConnectionFactory.class);
|
||||
assertNettyConnectionFactory(connectionFactory, "localhost", 5445);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void embeddedConnectionFactorEvenIfEmbeddedServiceDisabled() {
|
||||
// No mode is specified
|
||||
load(EmptyConfiguration.class,
|
||||
"spring.hornetq.mode:embedded",
|
||||
"spring.hornetq.embedded.enabled:false");
|
||||
|
||||
assertEquals(0, this.context.getBeansOfType(EmbeddedJMS.class).size());
|
||||
|
||||
HornetQConnectionFactory connectionFactory = this.context
|
||||
.getBean(HornetQConnectionFactory.class);
|
||||
assertInVmConnectionFactory(connectionFactory);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void embeddedServerWithDestinations() {
|
||||
load(EmptyConfiguration.class, "spring.hornetq.embedded.enabled:true",
|
||||
load(EmptyConfiguration.class,
|
||||
"spring.hornetq.embedded.queues=Queue1,Queue2",
|
||||
"spring.hornetq.embedded.topics=Topic1");
|
||||
|
||||
@@ -155,7 +177,7 @@ public class HornetQAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void embeddedServerWithDestinationConfig() {
|
||||
load(DestinationConfiguration.class, "spring.hornetq.embedded.enabled:true");
|
||||
load(DestinationConfiguration.class);
|
||||
|
||||
DestinationChecker checker = new DestinationChecker(this.context);
|
||||
checker.checkQueue("sampleQueue", true);
|
||||
@@ -164,7 +186,7 @@ public class HornetQAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void embeddedServiceWithCustomJmsConfiguration() {
|
||||
load(CustomJmsConfiguration.class, "spring.hornetq.embedded.enabled:true",
|
||||
load(CustomJmsConfiguration.class,
|
||||
"spring.hornetq.embedded.queues=Queue1,Queue2"); // Ignored with custom
|
||||
// config
|
||||
DestinationChecker checker = new DestinationChecker(this.context);
|
||||
@@ -176,7 +198,7 @@ public class HornetQAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void embeddedServiceWithCustomHornetQConfiguration() {
|
||||
load(CustomHornetQConfiguration.class, "spring.hornetq.embedded.enabled:true");
|
||||
load(CustomHornetQConfiguration.class);
|
||||
org.hornetq.core.config.Configuration configuration = this.context
|
||||
.getBean(org.hornetq.core.config.Configuration.class);
|
||||
assertEquals("customFooBar", configuration.getName());
|
||||
@@ -187,7 +209,7 @@ public class HornetQAutoConfigurationTests {
|
||||
File dataFolder = this.folder.newFolder();
|
||||
|
||||
// Start the server and post a message to some queue
|
||||
load(EmptyConfiguration.class, "spring.hornetq.embedded.enabled:true",
|
||||
load(EmptyConfiguration.class,
|
||||
"spring.hornetq.embedded.queues=TestQueue",
|
||||
"spring.hornetq.embedded.persistent:true",
|
||||
"spring.hornetq.embedded.dataDirectory:" + dataFolder.getAbsolutePath());
|
||||
@@ -203,7 +225,7 @@ public class HornetQAutoConfigurationTests {
|
||||
this.context.close(); // Shutdown the broker
|
||||
|
||||
// Start the server again and check if our message is still here
|
||||
load(EmptyConfiguration.class, "spring.hornetq.embedded.enabled:true",
|
||||
load(EmptyConfiguration.class,
|
||||
"spring.hornetq.embedded.queues=TestQueue",
|
||||
"spring.hornetq.embedded.persistent:true",
|
||||
"spring.hornetq.embedded.dataDirectory:" + dataFolder.getAbsolutePath());
|
||||
|
||||
@@ -256,7 +256,7 @@ content into your application; rather pick only the properties that you need.
|
||||
spring.hornetq.embedded.data-directory= # location of data content (when persistence is enabled)
|
||||
spring.hornetq.embedded.queues= # comma separate queues to create on startup
|
||||
spring.hornetq.embedded.topics= # comma separate topics to create on startup
|
||||
spring.hornetq.embedded.cluster-password = # customer password (randomly generated by default)
|
||||
spring.hornetq.embedded.cluster-password= # customer password (randomly generated by default)
|
||||
|
||||
# JMS ({sc-spring-boot-autoconfigure}/jms/JmsTemplateProperties.{sc-ext}[JmsTemplateProperties])
|
||||
spring.jms.pub-sub-domain= # false for queue (default), true for topic
|
||||
|
||||
@@ -1702,11 +1702,14 @@ components require a `ConnectionFactory` to operate.
|
||||
==== HornetQ support
|
||||
|
||||
Spring Boot can auto-configure a `ConnectionFactory` when it detects that
|
||||
HornetQ is available on the classpath. By default, a `ConnectionFactory` using
|
||||
the `netty` transport protocol is configured, connecting to a broker running on
|
||||
the local machine with the default settings. It is also possible to connect to
|
||||
a running broker provided in the container or even embed the container in the
|
||||
application if the necessary classes are present.
|
||||
HornetQ is available on the classpath. If the broker is present, an embedded
|
||||
broker is started and configured automatically unless the mode property has
|
||||
been explicitly set. The supported modes are: `embedded` (to make explicit
|
||||
that an embedded broker is required and should lead to an error if the broker
|
||||
is not available in the classpath), and `native` to connect to a broker
|
||||
using the the `netty` transport protocol. When the latter is configured, boot
|
||||
configures a `ConnectionFactory` connecting to a broker running on the local
|
||||
machine with the default settings.
|
||||
|
||||
NOTE: if you are using `spring-boot-starter-hornetq` the necessary dependencies
|
||||
to connect to an existing HornetQ instance are provided, as well as the Spring
|
||||
@@ -1742,7 +1745,7 @@ names provided through configuration.
|
||||
==== ActiveMQ support
|
||||
|
||||
Spring Boot can also configure a `ConnectionFactory` when it detects that
|
||||
ActiveMQ is available on the classpath. If the complete broker is available,
|
||||
ActiveMQ is available on the classpath. If the broker is present,
|
||||
an embedded broker is started and configured automatically if no broker URL
|
||||
is specified through configuration.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user