Merge pull request #6071 from stephlag:1.3.x

* pr/6071:
  Polish "Secured HornetQ" contribution
  Add a secured connection factory for Hornetq.
pull/6452/head
Stephane Nicoll 9 years ago
commit 731d326799

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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, public HornetQConnectionFactory jmsConnectionFactory(ListableBeanFactory beanFactory,
HornetQProperties properties) { HornetQProperties properties) {
return new HornetQConnectionFactoryFactory(beanFactory, properties) return new HornetQConnectionFactoryFactory(beanFactory, properties)
.createConnectionFactory(HornetQConnectionFactory.class); .createConnectionFactory(SpringBootHornetQConnectionFactory.class);
} }
} }

@ -28,6 +28,7 @@ import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory;
import org.hornetq.core.remoting.impl.netty.TransportConstants; import org.hornetq.core.remoting.impl.netty.TransportConstants;
import org.hornetq.jms.client.HornetQConnectionFactory; import org.hornetq.jms.client.HornetQConnectionFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
@ -111,8 +112,9 @@ class HornetQConnectionFactoryFactory {
this.properties.getEmbedded().generateTransportParameters()); this.properties.getEmbedded().generateTransportParameters());
ServerLocator serviceLocator = HornetQClient ServerLocator serviceLocator = HornetQClient
.createServerLocatorWithoutHA(transportConfiguration); .createServerLocatorWithoutHA(transportConfiguration);
return factoryClass.getConstructor(ServerLocator.class) Constructor<T> constructor = factoryClass.getDeclaredConstructor(HornetQProperties.class,
.newInstance(serviceLocator); ServerLocator.class);
return BeanUtils.instantiateClass(constructor, this.properties, serviceLocator);
} }
catch (NoClassDefFoundError ex) { catch (NoClassDefFoundError ex) {
throw new IllegalStateException("Unable to create InVM " throw new IllegalStateException("Unable to create InVM "
@ -128,9 +130,9 @@ class HornetQConnectionFactoryFactory {
params.put(TransportConstants.PORT_PROP_NAME, this.properties.getPort()); params.put(TransportConstants.PORT_PROP_NAME, this.properties.getPort());
TransportConfiguration transportConfiguration = new TransportConfiguration( TransportConfiguration transportConfiguration = new TransportConfiguration(
NettyConnectorFactory.class.getName(), params); NettyConnectorFactory.class.getName(), params);
Constructor<T> constructor = factoryClass.getConstructor(boolean.class, Constructor<T> constructor = factoryClass.getDeclaredConstructor(HornetQProperties.class,
TransportConfiguration[].class); boolean.class, TransportConfiguration[].class);
return constructor.newInstance(false, return BeanUtils.instantiateClass(constructor, this.properties, false,
new TransportConfiguration[] { transportConfiguration }); new TransportConfiguration[] { transportConfiguration });
} }

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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; 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(); private final Embedded embedded = new Embedded();
public HornetQMode getMode() { public HornetQMode getMode() {
@ -76,6 +86,22 @@ public class HornetQProperties {
this.port = port; 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() { public Embedded getEmbedded() {
return this.embedded; return this.embedded;
} }
@ -188,6 +214,7 @@ public class HornetQProperties {
/** /**
* Creates the minimal transport parameters for an embedded transport * Creates the minimal transport parameters for an embedded transport
* configuration. * configuration.
*
* @return the transport parameters * @return the transport parameters
* @see TransportConstants#SERVER_ID_PROP_NAME * @see TransportConstants#SERVER_ID_PROP_NAME
*/ */

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 javax.transaction.TransactionManager;
import org.hornetq.jms.client.HornetQConnectionFactory; import org.hornetq.jms.client.HornetQConnectionFactory;
import org.hornetq.jms.client.HornetQXAConnectionFactory;
import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
@ -47,16 +46,17 @@ class HornetQXAConnectionFactoryConfiguration {
@Bean(name = { "jmsConnectionFactory", "xaJmsConnectionFactory" }) @Bean(name = { "jmsConnectionFactory", "xaJmsConnectionFactory" })
public ConnectionFactory jmsConnectionFactory(ListableBeanFactory beanFactory, public ConnectionFactory jmsConnectionFactory(ListableBeanFactory beanFactory,
HornetQProperties properties, XAConnectionFactoryWrapper wrapper) HornetQProperties properties, XAConnectionFactoryWrapper wrapper)
throws Exception { throws Exception {
return wrapper.wrapConnectionFactory( return wrapper.wrapConnectionFactory(
new HornetQConnectionFactoryFactory(beanFactory, properties) new HornetQConnectionFactoryFactory(beanFactory, properties)
.createConnectionFactory(HornetQXAConnectionFactory.class)); .createConnectionFactory(
SpringBootHornetQXAConnectionFactory.class));
} }
@Bean @Bean
public HornetQConnectionFactory nonXaJmsConnectionFactory( public HornetQConnectionFactory nonXaJmsConnectionFactory(
ListableBeanFactory beanFactory, HornetQProperties properties) { ListableBeanFactory beanFactory, HornetQProperties properties) {
return new HornetQConnectionFactoryFactory(beanFactory, properties) return new HornetQConnectionFactoryFactory(beanFactory, properties)
.createConnectionFactory(HornetQConnectionFactory.class); .createConnectionFactory(SpringBootHornetQConnectionFactory.class);
} }
} }

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

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

@ -20,6 +20,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.UUID; import java.util.UUID;
import javax.jms.Connection;
import javax.jms.Destination; import javax.jms.Destination;
import javax.jms.JMSException; import javax.jms.JMSException;
import javax.jms.Message; import javax.jms.Message;
@ -55,6 +56,9 @@ import org.springframework.jms.support.destination.DestinationResolver;
import org.springframework.jms.support.destination.DynamicDestinationResolver; import org.springframework.jms.support.destination.DynamicDestinationResolver;
import static org.assertj.core.api.Assertions.assertThat; 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}. * Tests for {@link HornetQAutoConfiguration}.
@ -94,6 +98,22 @@ public class HornetQAutoConfigurationTests {
assertNettyConnectionFactory(connectionFactory, "192.168.1.144", 9876); 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 @Test
public void embeddedConnectionFactory() { public void embeddedConnectionFactory() {
load(EmptyConfiguration.class, "spring.hornetq.mode:embedded"); load(EmptyConfiguration.class, "spring.hornetq.mode:embedded");

@ -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.embedded.topics= # Comma-separated list of topics to create on startup.
spring.hornetq.host=localhost # HornetQ broker host. 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.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.port=5445 # HornetQ broker port.
spring.hornetq.user= # Login user of the broker.
# JMS ({sc-spring-boot-autoconfigure}/jms/JmsProperties.{sc-ext}[JmsProperties]) # 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. spring.jms.jndi-name= # Connection factory JNDI name. When set, takes precedence to others connection factory auto-configurations.

@ -3953,6 +3953,8 @@ HornetQ configuration is controlled by external configuration properties in
spring.hornetq.mode=native spring.hornetq.mode=native
spring.hornetq.host=192.168.1.210 spring.hornetq.host=192.168.1.210
spring.hornetq.port=9876 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 When embedding the broker, you can choose if you want to enable persistence, and the list

Loading…
Cancel
Save