Add HornetQ JMS support
Provide auto-configuration support for HornetQ JMS broker, along with an additional starter POM. The connection factory connects to a broker available on the local machine by default. A configuration switch allows to enable an embedded mode that starts HornetQ as part of the application. In such a mode, the spring.hornetq.embedded.* properties provide additional options to configure the embedded broker. In particular, message persistence and data directory locations can be specified. It is also possible to define the queue(s) and topic(s) to create on startup. Fixes: gh-765
This commit is contained in:
parent
67beba9464
commit
5a69bb9267
|
@ -111,6 +111,16 @@
|
|||
<artifactId>hibernate-jpa-2.0-api</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hornetq</groupId>
|
||||
<artifactId>hornetq-jms-client</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hornetq</groupId>
|
||||
<artifactId>hornetq-jms-server</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
|
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
* Copyright 2012-2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.jms;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.jms.ConnectionFactory;
|
||||
|
||||
import org.hornetq.api.core.TransportConfiguration;
|
||||
import org.hornetq.api.core.client.HornetQClient;
|
||||
import org.hornetq.api.core.client.ServerLocator;
|
||||
import org.hornetq.api.jms.HornetQJMSClient;
|
||||
import org.hornetq.api.jms.JMSFactoryType;
|
||||
import org.hornetq.core.remoting.impl.invm.InVMConnectorFactory;
|
||||
import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory;
|
||||
import org.hornetq.core.remoting.impl.netty.TransportConstants;
|
||||
import org.hornetq.jms.client.HornetQConnectionFactory;
|
||||
import org.hornetq.jms.server.config.JMSConfiguration;
|
||||
import org.hornetq.jms.server.config.JMSQueueConfiguration;
|
||||
import org.hornetq.jms.server.config.TopicConfiguration;
|
||||
import org.hornetq.jms.server.config.impl.JMSConfigurationImpl;
|
||||
import org.hornetq.jms.server.config.impl.JMSQueueConfigurationImpl;
|
||||
import org.hornetq.jms.server.config.impl.TopicConfigurationImpl;
|
||||
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.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
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.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.1.0
|
||||
*/
|
||||
@Configuration
|
||||
@AutoConfigureBefore(JmsAutoConfiguration.class)
|
||||
@ConditionalOnClass({ ConnectionFactory.class, HornetQJMSClient.class })
|
||||
@EnableConfigurationProperties(HornetQProperties.class)
|
||||
public class HornetQAutoConfiguration {
|
||||
|
||||
private static final String EMBEDDED_JMS_CLASS = "org.hornetq.jms.server.embedded.EmbeddedJMS";
|
||||
|
||||
@Autowired
|
||||
private HornetQProperties properties;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ConnectionFactory jmsConnectionFactory() {
|
||||
HornetQMode mode = this.properties.getMode();
|
||||
if (mode == null) {
|
||||
mode = deduceMode();
|
||||
}
|
||||
if (mode == HornetQMode.EMBEDDED) {
|
||||
return createEmbeddedConnectionFactory();
|
||||
}
|
||||
return createNativeConnectionFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deduce the {@link HornetQMode} to use if none has been set.
|
||||
*/
|
||||
private HornetQMode deduceMode() {
|
||||
if (this.properties.getEmbedded().isEnabled()
|
||||
&& ClassUtils.isPresent(EMBEDDED_JMS_CLASS, null)) {
|
||||
return HornetQMode.EMBEDDED;
|
||||
}
|
||||
return HornetQMode.NATIVE;
|
||||
}
|
||||
|
||||
private ConnectionFactory createEmbeddedConnectionFactory() {
|
||||
try {
|
||||
TransportConfiguration transportConfiguration = new TransportConfiguration(
|
||||
InVMConnectorFactory.class.getName());
|
||||
ServerLocator serviceLocator = HornetQClient
|
||||
.createServerLocatorWithoutHA(transportConfiguration);
|
||||
return new HornetQConnectionFactory(serviceLocator);
|
||||
}
|
||||
catch (NoClassDefFoundError ex) {
|
||||
throw new IllegalStateException("Unable to create InVM "
|
||||
+ "HornetQ connection, ensure that hornet-jms-server.jar "
|
||||
+ "is in the classpath", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private ConnectionFactory createNativeConnectionFactory() {
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
params.put(TransportConstants.HOST_PROP_NAME, this.properties.getHost());
|
||||
params.put(TransportConstants.PORT_PROP_NAME, this.properties.getPort());
|
||||
TransportConfiguration transportConfiguration = new TransportConfiguration(
|
||||
NettyConnectorFactory.class.getName(), params);
|
||||
return HornetQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF,
|
||||
transportConfiguration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration used to create the embedded HornetQ server.
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass(name = EMBEDDED_JMS_CLASS)
|
||||
@ConditionalOnProperty(prefix = "spring.hornetq.embedded", value = "enabled")
|
||||
static class EmbeddedServerConfiguration {
|
||||
|
||||
@Autowired
|
||||
private HornetQProperties properties;
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<HornetQConfigurationCustomizer> configurationCustomizers;
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<JMSQueueConfiguration> queuesConfiguration;
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<TopicConfiguration> topicsConfiguration;
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public org.hornetq.core.config.Configuration hornetQConfiguration() {
|
||||
return new HornetQEmbeddedConfigurationFactory(this.properties)
|
||||
.createConfiguration();
|
||||
}
|
||||
|
||||
@Bean(initMethod = "start", destroyMethod = "stop")
|
||||
@ConditionalOnMissingBean
|
||||
public EmbeddedJMS hornetQServer(
|
||||
org.hornetq.core.config.Configuration configuration,
|
||||
JMSConfiguration jmsConfiguration) {
|
||||
EmbeddedJMS server = new EmbeddedJMS();
|
||||
applyCustomizers(configuration);
|
||||
server.setConfiguration(configuration);
|
||||
server.setJmsConfiguration(jmsConfiguration);
|
||||
server.setRegistry(new HornetQNoOpBindingRegistry());
|
||||
return server;
|
||||
}
|
||||
|
||||
private void applyCustomizers(org.hornetq.core.config.Configuration configuration) {
|
||||
if (this.configurationCustomizers != null) {
|
||||
AnnotationAwareOrderComparator.sort(this.configurationCustomizers);
|
||||
for (HornetQConfigurationCustomizer customizer : this.configurationCustomizers) {
|
||||
customizer.customize(configuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public JMSConfiguration hornetQJmsConfiguration() {
|
||||
JMSConfiguration configuration = new JMSConfigurationImpl();
|
||||
addAll(configuration.getQueueConfigurations(), this.queuesConfiguration);
|
||||
addAll(configuration.getTopicConfigurations(), this.topicsConfiguration);
|
||||
addQueues(configuration, this.properties.getEmbedded().getQueues());
|
||||
addTopis(configuration, this.properties.getEmbedded().getTopics());
|
||||
return configuration;
|
||||
}
|
||||
|
||||
private <T> void addAll(List<T> list, Collection<? extends T> items) {
|
||||
if (items != null) {
|
||||
list.addAll(items);
|
||||
}
|
||||
}
|
||||
|
||||
private void addQueues(JMSConfiguration configuration, String[] queues) {
|
||||
boolean persistent = this.properties.getEmbedded().isPersistent();
|
||||
for (String queue : queues) {
|
||||
configuration.getQueueConfigurations().add(
|
||||
new JMSQueueConfigurationImpl(queue, null, persistent, "/queue/"
|
||||
+ queue));
|
||||
}
|
||||
}
|
||||
|
||||
private void addTopis(JMSConfiguration configuration, String[] topics) {
|
||||
for (String topic : topics) {
|
||||
configuration.getTopicConfigurations().add(
|
||||
new TopicConfigurationImpl(topic, "/topic/" + topic));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2012-2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.jms;
|
||||
|
||||
import org.hornetq.core.config.Configuration;
|
||||
import org.hornetq.jms.server.embedded.EmbeddedJMS;
|
||||
|
||||
/**
|
||||
* Callback interface that can be implemented by beans wishing to customize the HornetQ
|
||||
* JMS server {@link Configuration} before it is used by an auto-configured
|
||||
* {@link EmbeddedJMS} instance.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 1.1.0
|
||||
* @see HornetQAutoConfiguration
|
||||
*/
|
||||
public interface HornetQConfigurationCustomizer {
|
||||
|
||||
/**
|
||||
* Customize the configuration.
|
||||
* @param configuration the configuration to customize
|
||||
*/
|
||||
void customize(Configuration configuration);
|
||||
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright 2012-2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.jms;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.hornetq.api.core.TransportConfiguration;
|
||||
import org.hornetq.core.config.Configuration;
|
||||
import org.hornetq.core.config.impl.ConfigurationImpl;
|
||||
import org.hornetq.core.remoting.impl.invm.InVMAcceptorFactory;
|
||||
import org.hornetq.core.server.JournalType;
|
||||
import org.springframework.boot.autoconfigure.jms.HornetQProperties.Embedded;
|
||||
|
||||
/**
|
||||
* Factory class to create a HornetQ {@link Configuration} from {@link HornetQProperties}.
|
||||
*
|
||||
* @author Stephane Nicol
|
||||
* @author Phillip Webb
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class HornetQEmbeddedConfigurationFactory {
|
||||
|
||||
private Log logger = LogFactory.getLog(HornetQAutoConfiguration.class);
|
||||
|
||||
private final Embedded properties;
|
||||
|
||||
public HornetQEmbeddedConfigurationFactory(HornetQProperties properties) {
|
||||
this.properties = properties.getEmbedded();
|
||||
}
|
||||
|
||||
public Configuration createConfiguration() {
|
||||
ConfigurationImpl configuration = new ConfigurationImpl();
|
||||
configuration.setSecurityEnabled(false);
|
||||
configuration.setPersistenceEnabled(this.properties.isPersistent());
|
||||
|
||||
String dataDir = getDataDir();
|
||||
|
||||
// HORNETQ-1302
|
||||
configuration.setJournalDirectory(dataDir + "/journal");
|
||||
|
||||
if (this.properties.isPersistent()) {
|
||||
configuration.setJournalType(JournalType.NIO);
|
||||
configuration.setLargeMessagesDirectory(dataDir + "/largemessages");
|
||||
configuration.setBindingsDirectory(dataDir + "/bindings");
|
||||
configuration.setPagingDirectory(dataDir + "/paging");
|
||||
}
|
||||
|
||||
TransportConfiguration transportConfiguration = new TransportConfiguration(
|
||||
InVMAcceptorFactory.class.getName());
|
||||
configuration.getAcceptorConfigurations().add(transportConfiguration);
|
||||
|
||||
// HORNETQ-1143
|
||||
if (this.properties.isDefaultClusterPassword()) {
|
||||
this.logger.debug("Using default HornetQ cluster password: "
|
||||
+ this.properties.getClusterPassword());
|
||||
}
|
||||
|
||||
configuration.setClusterPassword(this.properties.getClusterPassword());
|
||||
return configuration;
|
||||
}
|
||||
|
||||
private String getDataDir() {
|
||||
if (this.properties.getDataDirectory() != null) {
|
||||
return this.properties.getDataDirectory();
|
||||
}
|
||||
String tempDirectory = System.getProperty("java.io.tmpdir");
|
||||
return new File(tempDirectory, "hornetq-data").getAbsolutePath();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2012-2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.jms;
|
||||
|
||||
/**
|
||||
* Define the mode in which HornetQ can operate.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public enum HornetQMode {
|
||||
|
||||
/**
|
||||
* Connect to a broker using the native HornetQ protocol (i.e. netty).
|
||||
*/
|
||||
NATIVE,
|
||||
|
||||
/**
|
||||
* Embed (i.e. start) the broker in the application.
|
||||
*/
|
||||
EMBEDDED
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright 2012-2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.jms;
|
||||
|
||||
import org.hornetq.spi.core.naming.BindingRegistry;
|
||||
|
||||
/**
|
||||
* A no-op implementation of the {@link org.hornetq.spi.core.naming.BindingRegistry}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public class HornetQNoOpBindingRegistry implements BindingRegistry {
|
||||
|
||||
@Override
|
||||
public Object lookup(String name) {
|
||||
// This callback is used to check if an entry is present in the context before
|
||||
// creating a queue on the fly. This is actually never used to try to fetch a
|
||||
// destination that is unknown.
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean bind(String name, Object obj) {
|
||||
// This callback is used bind a Destination created on the fly by the embedded
|
||||
// broker using the JNDI name that was specified in the configuration. This does
|
||||
// not look very useful since it's used nowhere. It could be interesting to
|
||||
// autowire a destination to use it but the wiring is a bit "asynchronous" so
|
||||
// better not provide that feature at all.
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unbind(String name) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getContext() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContext(Object ctx) {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* Copyright 2012-2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.jms;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* Configuration properties for HornetQ
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.1.0
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.hornetq")
|
||||
public class HornetQProperties {
|
||||
|
||||
private HornetQMode mode;
|
||||
|
||||
private String host = "localhost";
|
||||
|
||||
private int port = 5445;
|
||||
|
||||
private final Embedded embedded = new Embedded();
|
||||
|
||||
public HornetQMode getMode() {
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
public void setMode(HornetQMode mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return this.host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return this.port;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public Embedded getEmbedded() {
|
||||
return this.embedded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration for an embedded HornetQ server.
|
||||
*/
|
||||
public static class Embedded {
|
||||
|
||||
private boolean enabled;
|
||||
|
||||
private boolean persistent;
|
||||
|
||||
private String dataDirectory;
|
||||
|
||||
private String[] queues = new String[0];
|
||||
|
||||
private String[] topics = new String[0];
|
||||
|
||||
private String clusterPassword = UUID.randomUUID().toString();
|
||||
|
||||
private boolean defaultClusterPassword = true;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isPersistent() {
|
||||
return this.persistent;
|
||||
}
|
||||
|
||||
public void setPersistent(boolean persistent) {
|
||||
this.persistent = persistent;
|
||||
}
|
||||
|
||||
public String getDataDirectory() {
|
||||
return this.dataDirectory;
|
||||
}
|
||||
|
||||
public void setDataDirectory(String dataDirectory) {
|
||||
this.dataDirectory = dataDirectory;
|
||||
}
|
||||
|
||||
public String[] getQueues() {
|
||||
return this.queues;
|
||||
}
|
||||
|
||||
public void setQueues(String[] queues) {
|
||||
this.queues = queues;
|
||||
}
|
||||
|
||||
public String[] getTopics() {
|
||||
return this.topics;
|
||||
}
|
||||
|
||||
public void setTopics(String[] topics) {
|
||||
this.topics = topics;
|
||||
}
|
||||
|
||||
public String getClusterPassword() {
|
||||
return this.clusterPassword;
|
||||
}
|
||||
|
||||
public void setClusterPassword(String clusterPassword) {
|
||||
this.clusterPassword = clusterPassword;
|
||||
this.defaultClusterPassword = false;
|
||||
}
|
||||
|
||||
public boolean isDefaultClusterPassword() {
|
||||
return this.defaultClusterPassword;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure.jms;
|
|||
import javax.jms.ConnectionFactory;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
|
@ -37,6 +38,7 @@ import org.springframework.jms.core.JmsTemplate;
|
|||
@ConditionalOnClass(JmsTemplate.class)
|
||||
@ConditionalOnBean(ConnectionFactory.class)
|
||||
@EnableConfigurationProperties(JmsProperties.class)
|
||||
@AutoConfigureAfter({ HornetQAutoConfiguration.class, ActiveMQAutoConfiguration.class })
|
||||
public class JmsAutoConfiguration {
|
||||
|
||||
@Autowired
|
||||
|
|
|
@ -19,6 +19,7 @@ org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,
|
|||
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.jms.ActiveMQAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.jms.HornetQAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
|
||||
|
|
|
@ -30,6 +30,7 @@ import static org.junit.Assert.assertEquals;
|
|||
public class ActiveMQPropertiesTests {
|
||||
|
||||
private final ActiveMQProperties properties = new ActiveMQProperties();
|
||||
|
||||
private final StandardEnvironment environment = new StandardEnvironment();
|
||||
|
||||
@Test
|
||||
|
|
|
@ -0,0 +1,341 @@
|
|||
/*
|
||||
* Copyright 2012-2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.jms;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.jms.Destination;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.Session;
|
||||
import javax.jms.TextMessage;
|
||||
|
||||
import org.hornetq.api.core.TransportConfiguration;
|
||||
import org.hornetq.core.remoting.impl.invm.InVMConnectorFactory;
|
||||
import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory;
|
||||
import org.hornetq.jms.client.HornetQConnectionFactory;
|
||||
import org.hornetq.jms.server.config.JMSConfiguration;
|
||||
import org.hornetq.jms.server.config.JMSQueueConfiguration;
|
||||
import org.hornetq.jms.server.config.TopicConfiguration;
|
||||
import org.hornetq.jms.server.config.impl.JMSConfigurationImpl;
|
||||
import org.hornetq.jms.server.config.impl.JMSQueueConfigurationImpl;
|
||||
import org.hornetq.jms.server.config.impl.TopicConfigurationImpl;
|
||||
import org.hornetq.jms.server.embedded.EmbeddedJMS;
|
||||
import org.junit.After;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jms.core.JmsTemplate;
|
||||
import org.springframework.jms.core.MessageCreator;
|
||||
import org.springframework.jms.core.SessionCallback;
|
||||
import org.springframework.jms.support.destination.DestinationResolver;
|
||||
import org.springframework.jms.support.destination.DynamicDestinationResolver;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* Tests for {@link HornetQAutoConfiguration}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class HornetQAutoConfigurationTests {
|
||||
|
||||
@Rule
|
||||
public final TemporaryFolder folder = new TemporaryFolder();
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nativeConnectionFactory() {
|
||||
load(EmptyConfiguration.class, "spring.hornetq.mode:native");
|
||||
JmsTemplate jmsTemplate = this.context.getBean(JmsTemplate.class);
|
||||
HornetQConnectionFactory connectionFactory = this.context
|
||||
.getBean(HornetQConnectionFactory.class);
|
||||
assertEquals(jmsTemplate.getConnectionFactory(), connectionFactory);
|
||||
assertNettyConnectionFactory(connectionFactory, "localhost", 5445);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nativeConnectionFactoryCustomHost() {
|
||||
load(EmptyConfiguration.class, "spring.hornetq.host:192.168.1.144",
|
||||
"spring.hornetq.port:9876");
|
||||
HornetQConnectionFactory connectionFactory = this.context
|
||||
.getBean(HornetQConnectionFactory.class);
|
||||
assertNettyConnectionFactory(connectionFactory, "192.168.1.144", 9876);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void embeddedConnectionFactory() {
|
||||
load(EmptyConfiguration.class, "spring.hornetq.mode:embedded",
|
||||
"spring.hornetq.embedded.enabled:true");
|
||||
|
||||
HornetQProperties properties = this.context.getBean(HornetQProperties.class);
|
||||
assertEquals(HornetQMode.EMBEDDED, properties.getMode());
|
||||
|
||||
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 nativeConnectionFactoryByDefault() {
|
||||
// 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");
|
||||
HornetQConnectionFactory connectionFactory = this.context
|
||||
.getBean(HornetQConnectionFactory.class);
|
||||
assertInVmConnectionFactory(connectionFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void embeddedServerWithDestinations() {
|
||||
load(EmptyConfiguration.class, "spring.hornetq.embedded.enabled:true",
|
||||
"spring.hornetq.embedded.queues=Queue1,Queue2",
|
||||
"spring.hornetq.embedded.topics=Topic1");
|
||||
|
||||
DestinationChecker checker = new DestinationChecker(this.context);
|
||||
checker.checkQueue("Queue1", true);
|
||||
checker.checkQueue("Queue2", true);
|
||||
checker.checkQueue("QueueDoesNotExist", false);
|
||||
|
||||
checker.checkTopic("Topic1", true);
|
||||
checker.checkTopic("TopicDoesNotExist", false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void embeddedServerWithDestinationConfig() {
|
||||
load(DestinationConfiguration.class, "spring.hornetq.embedded.enabled:true");
|
||||
|
||||
DestinationChecker checker = new DestinationChecker(this.context);
|
||||
checker.checkQueue("sampleQueue", true);
|
||||
checker.checkTopic("sampleTopic", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void embeddedServiceWithCustomJmsConfiguration() {
|
||||
load(CustomJmsConfiguration.class, "spring.hornetq.embedded.enabled:true",
|
||||
"spring.hornetq.embedded.queues=Queue1,Queue2"); // Ignored with custom
|
||||
// config
|
||||
DestinationChecker checker = new DestinationChecker(this.context);
|
||||
checker.checkQueue("custom", true); // See CustomJmsConfiguration
|
||||
|
||||
checker.checkQueue("Queue1", false);
|
||||
checker.checkQueue("Queue2", false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void embeddedServiceWithCustomHornetQConfiguration() {
|
||||
load(CustomHornetQConfiguration.class, "spring.hornetq.embedded.enabled:true");
|
||||
org.hornetq.core.config.Configuration configuration = this.context
|
||||
.getBean(org.hornetq.core.config.Configuration.class);
|
||||
assertEquals("customFooBar", configuration.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void embeddedWithPersistentMode() throws IOException, JMSException {
|
||||
File dataFolder = this.folder.newFolder();
|
||||
|
||||
// Start the server and post a message to some queue
|
||||
load(EmptyConfiguration.class, "spring.hornetq.embedded.enabled:true",
|
||||
"spring.hornetq.embedded.queues=TestQueue",
|
||||
"spring.hornetq.embedded.persistent:true",
|
||||
"spring.hornetq.embedded.dataDirectory:" + dataFolder.getAbsolutePath());
|
||||
|
||||
final String msgId = UUID.randomUUID().toString();
|
||||
JmsTemplate jmsTemplate = this.context.getBean(JmsTemplate.class);
|
||||
jmsTemplate.send("TestQueue", new MessageCreator() {
|
||||
@Override
|
||||
public Message createMessage(Session session) throws JMSException {
|
||||
return session.createTextMessage(msgId);
|
||||
}
|
||||
});
|
||||
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",
|
||||
"spring.hornetq.embedded.queues=TestQueue",
|
||||
"spring.hornetq.embedded.persistent:true",
|
||||
"spring.hornetq.embedded.dataDirectory:" + dataFolder.getAbsolutePath());
|
||||
|
||||
JmsTemplate jmsTemplate2 = this.context.getBean(JmsTemplate.class);
|
||||
jmsTemplate2.setReceiveTimeout(1000L);
|
||||
Message message = jmsTemplate2.receive("TestQueue");
|
||||
assertNotNull("No message on persistent queue", message);
|
||||
assertEquals("Invalid message received on queue", msgId,
|
||||
((TextMessage) message).getText());
|
||||
}
|
||||
|
||||
private TransportConfiguration assertInVmConnectionFactory(
|
||||
HornetQConnectionFactory connectionFactory) {
|
||||
TransportConfiguration transportConfig = getSingleTransportConfiguration(connectionFactory);
|
||||
assertEquals(InVMConnectorFactory.class.getName(),
|
||||
transportConfig.getFactoryClassName());
|
||||
return transportConfig;
|
||||
}
|
||||
|
||||
private TransportConfiguration assertNettyConnectionFactory(
|
||||
HornetQConnectionFactory connectionFactory, String host, int port) {
|
||||
TransportConfiguration transportConfig = getSingleTransportConfiguration(connectionFactory);
|
||||
assertEquals(NettyConnectorFactory.class.getName(),
|
||||
transportConfig.getFactoryClassName());
|
||||
assertEquals(host, transportConfig.getParams().get("host"));
|
||||
assertEquals(port, transportConfig.getParams().get("port"));
|
||||
return transportConfig;
|
||||
}
|
||||
|
||||
private TransportConfiguration getSingleTransportConfiguration(
|
||||
HornetQConnectionFactory connectionFactory) {
|
||||
TransportConfiguration[] transportConfigurations = connectionFactory
|
||||
.getServerLocator().getStaticTransportConfigurations();
|
||||
assertEquals(1, transportConfigurations.length);
|
||||
return transportConfigurations[0];
|
||||
}
|
||||
|
||||
private void load(Class<?> config, String... environment) {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
this.context.register(config);
|
||||
this.context.register(HornetQAutoConfiguration.class, JmsAutoConfiguration.class);
|
||||
EnvironmentTestUtils.addEnvironment(this.context, environment);
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
private static class DestinationChecker {
|
||||
|
||||
private final JmsTemplate jmsTemplate;
|
||||
|
||||
private final DestinationResolver destinationResolver;
|
||||
|
||||
private DestinationChecker(ApplicationContext applicationContext) {
|
||||
this.jmsTemplate = applicationContext.getBean(JmsTemplate.class);
|
||||
this.destinationResolver = new DynamicDestinationResolver();
|
||||
}
|
||||
|
||||
public void checkQueue(String name, boolean shouldExist) {
|
||||
checkDestination(name, false, shouldExist);
|
||||
}
|
||||
|
||||
public void checkTopic(String name, boolean shouldExist) {
|
||||
checkDestination(name, true, shouldExist);
|
||||
}
|
||||
|
||||
public void checkDestination(final String name, final boolean pubSub,
|
||||
final boolean shouldExist) {
|
||||
this.jmsTemplate.execute(new SessionCallback<Void>() {
|
||||
@Override
|
||||
public Void doInJms(Session session) throws JMSException {
|
||||
try {
|
||||
Destination destination = DestinationChecker.this.destinationResolver
|
||||
.resolveDestinationName(session, name, pubSub);
|
||||
if (!shouldExist) {
|
||||
throw new IllegalStateException("Destination '" + name
|
||||
+ "' was not expected but got " + destination);
|
||||
}
|
||||
}
|
||||
catch (JMSException e) {
|
||||
if (shouldExist) {
|
||||
throw new IllegalStateException("Destination '" + name
|
||||
+ "' was expected but got " + e.getMessage());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class EmptyConfiguration {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class DestinationConfiguration {
|
||||
|
||||
@Bean
|
||||
JMSQueueConfiguration sampleQueueConfiguration() {
|
||||
return new JMSQueueConfigurationImpl("sampleQueue", "foo=bar", false,
|
||||
"/queue/1");
|
||||
}
|
||||
|
||||
@Bean
|
||||
TopicConfiguration sampleTopicConfiguration() {
|
||||
return new TopicConfigurationImpl("sampleTopic", "/topic/1");
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class CustomJmsConfiguration {
|
||||
|
||||
@Bean
|
||||
public JMSConfiguration myJmsConfiguration() {
|
||||
JMSConfiguration config = new JMSConfigurationImpl();
|
||||
config.getQueueConfigurations().add(
|
||||
new JMSQueueConfigurationImpl("custom", null, false));
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class CustomHornetQConfiguration {
|
||||
|
||||
@Autowired
|
||||
private HornetQProperties properties;
|
||||
|
||||
@Bean
|
||||
public HornetQConfigurationCustomizer myHornetQCustomize() {
|
||||
return new HornetQConfigurationCustomizer() {
|
||||
@Override
|
||||
public void customize(org.hornetq.core.config.Configuration configuration) {
|
||||
configuration.setClusterPassword("Foobar");
|
||||
configuration.setName("customFooBar");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright 2012-2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.jms;
|
||||
|
||||
import org.hornetq.core.config.Configuration;
|
||||
import org.hornetq.core.server.JournalType;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.endsWith;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link HornetQEmbeddedConfigurationFactory}.
|
||||
*
|
||||
* @author Stephane Nicol
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class HornetQEmbeddedConfigurationFactoryTests {
|
||||
|
||||
@Test
|
||||
public void defaultDataDir() {
|
||||
HornetQProperties properties = new HornetQProperties();
|
||||
properties.getEmbedded().setPersistent(true);
|
||||
Configuration configuration = new HornetQEmbeddedConfigurationFactory(properties)
|
||||
.createConfiguration();
|
||||
assertThat(configuration.getJournalDirectory(),
|
||||
startsWith(System.getProperty("java.io.tmpdir")));
|
||||
assertThat(configuration.getJournalDirectory(), endsWith("/journal"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistenceSetup() {
|
||||
HornetQProperties properties = new HornetQProperties();
|
||||
properties.getEmbedded().setPersistent(true);
|
||||
Configuration configuration = new HornetQEmbeddedConfigurationFactory(properties)
|
||||
.createConfiguration();
|
||||
assertThat(configuration.isPersistenceEnabled(), equalTo(true));
|
||||
assertThat(configuration.getJournalType(), equalTo(JournalType.NIO));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void generatedClusterPassoword() throws Exception {
|
||||
HornetQProperties properties = new HornetQProperties();
|
||||
Configuration configuration = new HornetQEmbeddedConfigurationFactory(properties)
|
||||
.createConfiguration();
|
||||
assertThat(configuration.getClusterPassword().length(), equalTo(36));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void specificClusterPassoword() throws Exception {
|
||||
HornetQProperties properties = new HornetQProperties();
|
||||
properties.getEmbedded().setClusterPassword("password");
|
||||
Configuration configuration = new HornetQEmbeddedConfigurationFactory(properties)
|
||||
.createConfiguration();
|
||||
assertThat(configuration.getClusterPassword(), equalTo("password"));
|
||||
}
|
||||
|
||||
}
|
|
@ -68,6 +68,7 @@
|
|||
<hikaricp.version>1.3.8</hikaricp.version>
|
||||
<httpclient.version>4.3.3</httpclient.version>
|
||||
<httpasyncclient.version>4.0.1</httpasyncclient.version>
|
||||
<hornetq.version>2.4.1.Final</hornetq.version>
|
||||
<hsqldb.version>2.3.2</hsqldb.version>
|
||||
<jackson.version>2.3.3</jackson.version>
|
||||
<javassist.version>3.18.1-GA</javassist.version> <!-- Same as Hibernate -->
|
||||
|
@ -212,6 +213,11 @@
|
|||
<artifactId>spring-boot-starter-groovy-templates</artifactId>
|
||||
<version>1.1.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-hornetq</artifactId>
|
||||
<version>1.1.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-integration</artifactId>
|
||||
|
@ -714,6 +720,16 @@
|
|||
<artifactId>hibernate-jpa-2.0-api</artifactId>
|
||||
<version>${hibernate-jpa-api.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hornetq</groupId>
|
||||
<artifactId>hornetq-jms-server</artifactId>
|
||||
<version>${hornetq.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hornetq</groupId>
|
||||
<artifactId>hornetq-jms-client</artifactId>
|
||||
<version>${hornetq.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
|
|
|
@ -242,6 +242,17 @@ content into your application; rather pick only the properties that you need.
|
|||
spring.activemq.in-memory=true # broker kind to create if no broker-url is specified
|
||||
spring.activemq.pooled=false
|
||||
|
||||
# HornetQ ({sc-spring-boot-autoconfigure}/jms/HornetQProperties.{sc-ext}[HornetQProperties])
|
||||
spring.hornetq.mode= # connection mode (native, embedded)
|
||||
spring.hornetq.host=localhost # hornetQ host (native mode)
|
||||
spring.hornetq.port=5445 # hornetQ port (native mode)
|
||||
spring.hornetq.embedded.enabled=true # if the embedded server is enabled (needs hornetq-jms-server.jar)
|
||||
spring.hornetq.embedded.persistent=false # message persistence
|
||||
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)
|
||||
|
||||
# JMS ({sc-spring-boot-autoconfigure}/jms/JmsTemplateProperties.{sc-ext}[JmsTemplateProperties])
|
||||
spring.jms.pub-sub-domain= # false for queue (default), true for topic
|
||||
|
||||
|
|
|
@ -53,6 +53,12 @@ The following auto-configuration classes are from the `spring-boot-autoconfigure
|
|||
|{sc-spring-boot-autoconfigure}/web/HttpMessageConvertersAutoConfiguration.{sc-ext}[HttpMessageConvertersAutoConfiguration]
|
||||
|{dc-spring-boot-autoconfigure}/web/HttpMessageConvertersAutoConfiguration.{dc-ext}[javadoc]
|
||||
|
||||
|{sc-spring-boot-autoconfigure}/jms/ActiveMQAutoConfiguration.{sc-ext}[ActiveMQAutoConfiguration]
|
||||
|{dc-spring-boot-autoconfigure}/jms/ActiveMQAutoConfiguration.{dc-ext}[javadoc]
|
||||
|
||||
|{sc-spring-boot-autoconfigure}/jms/HornetQAutoConfiguration.{sc-ext}[HornetQAutoConfiguration]
|
||||
|{dc-spring-boot-autoconfigure}/jms/HornetQAutoConfiguration.{dc-ext}[javadoc]
|
||||
|
||||
|{sc-spring-boot-autoconfigure}/jms/JmsTemplateAutoConfiguration.{sc-ext}[JmsTemplateAutoConfiguration]
|
||||
|{dc-spring-boot-autoconfigure}/jms/JmsTemplateAutoConfiguration.{dc-ext}[javadoc]
|
||||
|
||||
|
|
|
@ -245,6 +245,9 @@ and Hibernate.
|
|||
|`spring-boot-starter-groovy-templates`
|
||||
|Support for the Groovy templating engine
|
||||
|
||||
|`spring-boot-starter-hornetq`
|
||||
|Support for ``Java Message Service API'' via HornetQ.
|
||||
|
||||
|`spring-boot-starter-integration`
|
||||
|Support for common `spring-integration` modules.
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
<module>spring-boot-sample-data-rest</module>
|
||||
<module>spring-boot-sample-data-solr</module>
|
||||
<module>spring-boot-sample-flyway</module>
|
||||
<module>spring-boot-sample-hornetq</module>
|
||||
<module>spring-boot-sample-integration</module>
|
||||
<module>spring-boot-sample-jetty</module>
|
||||
<module>spring-boot-sample-liquibase</module>
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<!-- Your own application should inherit from spring-boot-starter-parent -->
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-samples</artifactId>
|
||||
<version>1.1.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>spring-boot-sample-hornetq</artifactId>
|
||||
<name>Spring Boot HornetQ Sample</name>
|
||||
<description>Spring Boot HornetQ Sample</description>
|
||||
<url>http://projects.spring.io/spring-boot/</url>
|
||||
<organization>
|
||||
<name>Pivotal Software, Inc.</name>
|
||||
<url>http://www.spring.io</url>
|
||||
</organization>
|
||||
<properties>
|
||||
<main.basedir>${basedir}/../..</main.basedir>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-hornetq</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hornetq</groupId>
|
||||
<artifactId>hornetq-jms-server</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright 2012-2013 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.hornetq;
|
||||
|
||||
import javax.jms.ConnectionFactory;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageListener;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jms.listener.DefaultMessageListenerContainer;
|
||||
import org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor;
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan
|
||||
public class SampleHornetQApplication {
|
||||
|
||||
@Autowired
|
||||
private ConnectionFactory connectionFactory;
|
||||
|
||||
@Bean
|
||||
public ScheduledAnnotationBeanPostProcessor scheduledAnnotationBeanPostProcessor() {
|
||||
return new ScheduledAnnotationBeanPostProcessor();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DefaultMessageListenerContainer messageListener() {
|
||||
DefaultMessageListenerContainer container = new DefaultMessageListenerContainer();
|
||||
container.setConnectionFactory(this.connectionFactory);
|
||||
container.setDestinationName("testQueue");
|
||||
container.setMessageListener(new MessageListener() {
|
||||
@Override
|
||||
public void onMessage(Message message) {
|
||||
try {
|
||||
System.out.println(message.getBody(Object.class));
|
||||
}
|
||||
catch (JMSException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
return container;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SpringApplication.run(SampleHornetQApplication.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2012-2013 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package sample.hornetq;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jms.core.JmsTemplate;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class Sender {
|
||||
|
||||
@Autowired
|
||||
private JmsTemplate jmsTemplate;
|
||||
|
||||
@Scheduled(fixedDelay = 1000L)
|
||||
public void send() {
|
||||
this.jmsTemplate.convertAndSend("testQueue", "Hello");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
spring.hornetq.mode=embedded
|
||||
spring.hornetq.embedded.enabled=true
|
||||
spring.hornetq.embedded.queues=testQueue,anotherQueue
|
|
@ -31,6 +31,7 @@
|
|||
<module>spring-boot-starter-data-solr</module>
|
||||
<module>spring-boot-starter-freemarker</module>
|
||||
<module>spring-boot-starter-groovy-templates</module>
|
||||
<module>spring-boot-starter-hornetq</module>
|
||||
<module>spring-boot-starter-integration</module>
|
||||
<module>spring-boot-starter-jdbc</module>
|
||||
<module>spring-boot-starter-jetty</module>
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starters</artifactId>
|
||||
<version>1.1.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>spring-boot-starter-hornetq</artifactId>
|
||||
<name>Spring Boot HornetQ Starter</name>
|
||||
<description>Spring Boot HornetQ Starter</description>
|
||||
<url>http://projects.spring.io/spring-boot/</url>
|
||||
<organization>
|
||||
<name>Pivotal Software, Inc.</name>
|
||||
<url>http://www.spring.io</url>
|
||||
</organization>
|
||||
<properties>
|
||||
<main.basedir>${basedir}/../..</main.basedir>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jms</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hornetq</groupId>
|
||||
<artifactId>hornetq-jms-client</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
Loading…
Reference in New Issue