package org.springframework.amqp.connection; import com.rabbitmq.client.*; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.BeansException; import org.springframework.util.StringUtils; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.context.ApplicationEventPublisher; import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.Log; import javax.net.SocketFactory; import java.util.Arrays; public class ConnectionFactoryBean extends ConnectionParameters implements ApplicationEventPublisherAware, BeanNameAware, FactoryBean, InitializingBean, DisposableBean { private static final Log log = LogFactory.getLog(ConnectionFactoryBean.class); public static String DEFAULT_HOST_NAME = "localhost"; public static int DEFAULT_PORT = AMQP.PROTOCOL.PORT; public static int DEFAULT_MAX_REDIRECTS = 0; public static int DEFAULT_CONNECTION_CLOSE_TIMEOUT = -1; // infinity private ApplicationEventPublisher applicationEventPublisher; private SocketFactory socketFactory; private Address[] addresses = { new Address(DEFAULT_HOST_NAME, DEFAULT_PORT) }; private int maxRedirects = DEFAULT_MAX_REDIRECTS; private int connectionCloseTimeout = DEFAULT_CONNECTION_CLOSE_TIMEOUT; private Connection connection; private String beanName; public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.applicationEventPublisher = applicationEventPublisher; } public void setBeanName(String beanName) { this.beanName = beanName; } public String getBeanName() { return beanName; } public SocketFactory getSocketFactory() { return socketFactory; } public void setSocketFactory(SocketFactory socketFactory) { this.socketFactory = socketFactory; } public Address[] getAddresses() { return addresses; } public void setAddresses(Address... addresses) { this.addresses = addresses; } public int getMaxRedirects() { return maxRedirects; } public void setMaxRedirects(int maxRedirects) { this.maxRedirects = maxRedirects; } public int getConnectionCloseTimeout() { return connectionCloseTimeout; } public void setConnectionCloseTimeout(int connectionCloseTimeout) { this.connectionCloseTimeout = connectionCloseTimeout; } protected ConnectionFactory newConnectionFactory() throws Exception { ConnectionFactory connectionFactory = new ConnectionFactory(this); if (socketFactory != null) connectionFactory.setSocketFactory(socketFactory); return connectionFactory; } protected String formatPassword(String password) { char[] formatted = new char[password.length()]; for (int i=0; i<formatted.length; i++) formatted[i] = '*'; return new String(formatted); } protected String formatBrokerAddresses(Address[] addresses) { return String.format("AMQP broker%s %s", addresses.length > 1 ? "s" : "", StringUtils.arrayToCommaDelimitedString(addresses)); } public Object getObject() throws Exception { return connection; } public Class getObjectType() { return Connection.class; } public boolean isSingleton() { return true; } public void afterPropertiesSet() throws Exception { if (log.isInfoEnabled()) log.info(String.format("Connecting to %s using credentials ('%s' / '%s') at vhost '%s'", formatBrokerAddresses(addresses), getUserName(), formatPassword(getPassword()), getVirtualHost())); this.connection = newConnectionFactory().newConnection(addresses, maxRedirects); final ConnectionFactoryBean connectionFactoryBean = this; connection.addShutdownListener(new ShutdownListener() { public void shutdownCompleted(ShutdownSignalException cause) { if (log.isInfoEnabled()) log.info("Connection shutdown", cause); applicationEventPublisher.publishEvent(new Shutdown(connectionFactoryBean, cause)); } }); } public void destroy() throws Exception { if (connection != null) { if (log.isInfoEnabled()) log.info(String.format("Destroying connection to %s", formatBrokerAddresses(addresses))); this.connection.close(connectionCloseTimeout); } } }