diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQConnectionFactoryConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQConnectionFactoryConfiguration.java index f0807e6112..e14c245530 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQConnectionFactoryConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQConnectionFactoryConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 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. @@ -39,7 +39,7 @@ class HornetQConnectionFactoryConfiguration { public HornetQConnectionFactory jmsConnectionFactory(ListableBeanFactory beanFactory, HornetQProperties properties) { return new HornetQConnectionFactoryFactory(beanFactory, properties) - .createConnectionFactory(HornetQConnectionFactory.class); + .createConnectionFactory(SpringBootHornetQConnectionFactory.class); } } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQConnectionFactoryFactory.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQConnectionFactoryFactory.java index 6315f79896..2395cce3a2 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQConnectionFactoryFactory.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQConnectionFactoryFactory.java @@ -28,6 +28,7 @@ import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory; import org.hornetq.core.remoting.impl.netty.TransportConstants; import org.hornetq.jms.client.HornetQConnectionFactory; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -111,8 +112,9 @@ class HornetQConnectionFactoryFactory { this.properties.getEmbedded().generateTransportParameters()); ServerLocator serviceLocator = HornetQClient .createServerLocatorWithoutHA(transportConfiguration); - return factoryClass.getConstructor(ServerLocator.class) - .newInstance(serviceLocator); + Constructor constructor = factoryClass.getDeclaredConstructor(HornetQProperties.class, + ServerLocator.class); + return BeanUtils.instantiateClass(constructor, this.properties, serviceLocator); } catch (NoClassDefFoundError ex) { throw new IllegalStateException("Unable to create InVM " @@ -128,9 +130,9 @@ class HornetQConnectionFactoryFactory { params.put(TransportConstants.PORT_PROP_NAME, this.properties.getPort()); TransportConfiguration transportConfiguration = new TransportConfiguration( NettyConnectorFactory.class.getName(), params); - Constructor constructor = factoryClass.getConstructor(boolean.class, - TransportConfiguration[].class); - return constructor.newInstance(false, + Constructor constructor = factoryClass.getDeclaredConstructor(HornetQProperties.class, + boolean.class, TransportConfiguration[].class); + return BeanUtils.instantiateClass(constructor, this.properties, false, new TransportConfiguration[] { transportConfiguration }); } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQProperties.java index d35038fa73..e5512db1cf 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 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. @@ -50,6 +50,16 @@ public class HornetQProperties { */ private int port = 5445; + /** + * Login user of the broker. + */ + private String user; + + /** + * Login password of the broker. + */ + private String password; + private final Embedded embedded = new Embedded(); public HornetQMode getMode() { @@ -76,6 +86,22 @@ public class HornetQProperties { this.port = port; } + public String getUser() { + return this.user; + } + + public void setUser(String user) { + this.user = user; + } + + public String getPassword() { + return this.password; + } + + public void setPassword(String password) { + this.password = password; + } + public Embedded getEmbedded() { return this.embedded; } @@ -188,6 +214,7 @@ public class HornetQProperties { /** * Creates the minimal transport parameters for an embedded transport * configuration. + * * @return the transport parameters * @see TransportConstants#SERVER_ID_PROP_NAME */ diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQXAConnectionFactoryConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQXAConnectionFactoryConfiguration.java index 8842f8e5c6..174c8145fc 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQXAConnectionFactoryConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQXAConnectionFactoryConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 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. @@ -20,7 +20,6 @@ import javax.jms.ConnectionFactory; import javax.transaction.TransactionManager; import org.hornetq.jms.client.HornetQConnectionFactory; -import org.hornetq.jms.client.HornetQXAConnectionFactory; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -47,16 +46,17 @@ class HornetQXAConnectionFactoryConfiguration { @Bean(name = { "jmsConnectionFactory", "xaJmsConnectionFactory" }) public ConnectionFactory jmsConnectionFactory(ListableBeanFactory beanFactory, HornetQProperties properties, XAConnectionFactoryWrapper wrapper) - throws Exception { + throws Exception { return wrapper.wrapConnectionFactory( new HornetQConnectionFactoryFactory(beanFactory, properties) - .createConnectionFactory(HornetQXAConnectionFactory.class)); + .createConnectionFactory( + SpringBootHornetQXAConnectionFactory.class)); } @Bean public HornetQConnectionFactory nonXaJmsConnectionFactory( ListableBeanFactory beanFactory, HornetQProperties properties) { return new HornetQConnectionFactoryFactory(beanFactory, properties) - .createConnectionFactory(HornetQConnectionFactory.class); + .createConnectionFactory(SpringBootHornetQConnectionFactory.class); } } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/SpringBootHornetQConnectionFactory.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/SpringBootHornetQConnectionFactory.java new file mode 100644 index 0000000000..6b6b36dd7b --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/SpringBootHornetQConnectionFactory.java @@ -0,0 +1,58 @@ +/* + * Copyright 2012-2016 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.hornetq; + +import javax.jms.Connection; +import javax.jms.JMSException; + +import org.hornetq.api.core.TransportConfiguration; +import org.hornetq.api.core.client.ServerLocator; +import org.hornetq.jms.client.HornetQConnectionFactory; + +import org.springframework.util.StringUtils; + +/** + * A {@link HornetQConnectionFactory} that manages the credentials of the connection. + * + * @author Stéphane Lagraulet + * @author Stephane Nicoll + */ +class SpringBootHornetQConnectionFactory extends HornetQConnectionFactory { + + private final HornetQProperties properties; + + SpringBootHornetQConnectionFactory(HornetQProperties properties, + ServerLocator serverLocator) { + super(serverLocator); + this.properties = properties; + } + + SpringBootHornetQConnectionFactory(HornetQProperties properties, boolean ha, + TransportConfiguration... initialConnectors) { + super(ha, initialConnectors); + this.properties = properties; + } + + public Connection createConnection() throws JMSException { + String user = this.properties.getUser(); + if (StringUtils.hasText(user)) { + return createConnection(user, this.properties.getPassword()); + } + return super.createConnection(); + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/SpringBootHornetQXAConnectionFactory.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/SpringBootHornetQXAConnectionFactory.java new file mode 100644 index 0000000000..91431ddd02 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/hornetq/SpringBootHornetQXAConnectionFactory.java @@ -0,0 +1,58 @@ +/* + * Copyright 2012-2016 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.hornetq; + +import javax.jms.Connection; +import javax.jms.JMSException; + +import org.hornetq.api.core.TransportConfiguration; +import org.hornetq.api.core.client.ServerLocator; +import org.hornetq.jms.client.HornetQXAConnectionFactory; + +import org.springframework.util.StringUtils; + +/** + * A {@link HornetQXAConnectionFactory} that manages the credentials of the connection. + * + * @author Stéphane Lagraulet + * @author Stephane Nicoll + */ +class SpringBootHornetQXAConnectionFactory extends HornetQXAConnectionFactory { + + private final HornetQProperties properties; + + SpringBootHornetQXAConnectionFactory(HornetQProperties properties, + ServerLocator serverLocator) { + super(serverLocator); + this.properties = properties; + } + + SpringBootHornetQXAConnectionFactory(HornetQProperties properties, boolean ha, + TransportConfiguration... initialConnectors) { + super(ha, initialConnectors); + this.properties = properties; + } + + public Connection createConnection() throws JMSException { + String user = this.properties.getUser(); + if (StringUtils.hasText(user)) { + return createConnection(user, this.properties.getPassword()); + } + return super.createConnection(); + } + +} diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQAutoConfigurationTests.java index cf4896d206..76b3a87739 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/hornetq/HornetQAutoConfigurationTests.java @@ -20,6 +20,7 @@ import java.io.File; import java.io.IOException; import java.util.UUID; +import javax.jms.Connection; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.Message; @@ -55,6 +56,9 @@ import org.springframework.jms.support.destination.DestinationResolver; import org.springframework.jms.support.destination.DynamicDestinationResolver; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; /** * Tests for {@link HornetQAutoConfiguration}. @@ -94,6 +98,22 @@ public class HornetQAutoConfigurationTests { assertNettyConnectionFactory(connectionFactory, "192.168.1.144", 9876); } + @Test + public void nativeConnectionFactoryCredentials() throws JMSException { + load(EmptyConfiguration.class, "spring.hornetq.mode:native", + "spring.hornetq.user:user", "spring.hornetq.password:secret"); + HornetQConnectionFactory connectionFactory = this.context + .getBean(HornetQConnectionFactory.class); + + // Validate the secured variant is invoked + HornetQConnectionFactory testCf = spy(connectionFactory); + Connection connection = mock(Connection.class); + doReturn(connection).when(testCf).createConnection("user", "secret"); + + Connection actual = testCf.createConnection(); + assertThat(actual).isSameAs(connection); + } + @Test public void embeddedConnectionFactory() { load(EmptyConfiguration.class, "spring.hornetq.mode:embedded"); 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 0f27696bef..ecab02671a 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -848,7 +848,9 @@ content into your application; rather pick only the properties that you need. spring.hornetq.embedded.topics= # Comma-separated list of topics to create on startup. spring.hornetq.host=localhost # HornetQ broker host. spring.hornetq.mode= # HornetQ deployment mode, auto-detected by default. Can be explicitly set to "native" or "embedded". + spring.hornetq.password= # Login password of the broker. spring.hornetq.port=5445 # HornetQ broker port. + spring.hornetq.user= # Login user of the broker. # JMS ({sc-spring-boot-autoconfigure}/jms/JmsProperties.{sc-ext}[JmsProperties]) spring.jms.jndi-name= # Connection factory JNDI name. When set, takes precedence to others connection factory auto-configurations. diff --git a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 879e6f0df7..cd838b608e 100644 --- a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -3953,6 +3953,8 @@ HornetQ configuration is controlled by external configuration properties in spring.hornetq.mode=native spring.hornetq.host=192.168.1.210 spring.hornetq.port=9876 + spring.hornetq.user=admin + spring.hornetq.password=secret ---- When embedding the broker, you can choose if you want to enable persistence, and the list