From 078fd4ce36eb051b6fa06a8511462c942fc824bb Mon Sep 17 00:00:00 2001 From: Gary Russell Date: Fri, 3 Apr 2015 17:21:14 +0100 Subject: [PATCH] AMQP-467: INFO Log When Connection is Opened JIRA: https://jira.spring.io/browse/AMQP-467 Log at INFO level when a new connection is established; useful when recovering a connection after a broker loss. --- .../connection/AbstractConnectionFactory.java | 19 +++++++++++++++---- .../rabbit/connection/SimpleConnection.java | 13 ++++++++++++- .../AbstractConnectionFactoryTests.java | 19 +++++++++++++++++++ 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/connection/AbstractConnectionFactory.java b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/connection/AbstractConnectionFactory.java index 6c40d2f8..efdcc288 100644 --- a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/connection/AbstractConnectionFactory.java +++ b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/connection/AbstractConnectionFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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 @@ -73,6 +73,7 @@ public abstract class AbstractConnectionFactory implements ConnectionFactory, Di this.rabbitConnectionFactory.setHost(host); } + @Override public String getHost() { return this.rabbitConnectionFactory.getHost(); } @@ -81,6 +82,7 @@ public abstract class AbstractConnectionFactory implements ConnectionFactory, Di this.rabbitConnectionFactory.setVirtualHost(virtualHost); } + @Override public String getVirtualHost() { return rabbitConnectionFactory.getVirtualHost(); } @@ -97,6 +99,7 @@ public abstract class AbstractConnectionFactory implements ConnectionFactory, Di this.rabbitConnectionFactory.setConnectionTimeout(connectionTimeout); } + @Override public int getPort() { return this.rabbitConnectionFactory.getPort(); } @@ -134,6 +137,7 @@ public abstract class AbstractConnectionFactory implements ConnectionFactory, Di this.connectionListener.setDelegates(listeners); } + @Override public void addConnectionListener(ConnectionListener listener) { this.connectionListener.addDelegate(listener); } @@ -195,15 +199,21 @@ public abstract class AbstractConnectionFactory implements ConnectionFactory, Di protected final Connection createBareConnection() { try { + Connection connection = null; if (this.addresses != null) { - return new SimpleConnection(this.rabbitConnectionFactory.newConnection(this.executorService, this.addresses), + connection = new SimpleConnection(this.rabbitConnectionFactory.newConnection(this.executorService, this.addresses), this.closeTimeout); } else { - return new SimpleConnection(this.rabbitConnectionFactory.newConnection(this.executorService), + connection = new SimpleConnection(this.rabbitConnectionFactory.newConnection(this.executorService), this.closeTimeout); } - } catch (IOException e) { + if (logger.isInfoEnabled()) { + logger.info("Created new connection: " + connection); + } + return connection; + } + catch (IOException e) { throw RabbitExceptionTranslator.convertRabbitAccessException(e); } } @@ -221,6 +231,7 @@ public abstract class AbstractConnectionFactory implements ConnectionFactory, Di return temp; } + @Override public void destroy() { } } diff --git a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/connection/SimpleConnection.java b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/connection/SimpleConnection.java index 7cc9f93b..792faf0b 100755 --- a/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/connection/SimpleConnection.java +++ b/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/connection/SimpleConnection.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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 @@ -15,6 +15,7 @@ package org.springframework.amqp.rabbit.connection; import java.io.IOException; import org.springframework.amqp.rabbit.support.RabbitExceptionTranslator; +import org.springframework.util.ObjectUtils; import com.rabbitmq.client.Channel; @@ -37,6 +38,7 @@ public class SimpleConnection implements Connection { this.closeTimeout = closeTimeout; } + @Override public Channel createChannel(boolean transactional) { try { Channel channel = delegate.createChannel(); @@ -50,6 +52,7 @@ public class SimpleConnection implements Connection { } } + @Override public void close() { try { // let the physical close time out if necessary @@ -59,9 +62,17 @@ public class SimpleConnection implements Connection { } } + @Override public boolean isOpen() { return delegate != null && (delegate.isOpen() || this.delegate.getClass().getSimpleName().contains("AutorecoveringConnection")); } + @Override + public String toString() { + return "SimpleConnection@" + + ObjectUtils.getIdentityHexString(this) + + " [delegate=" + delegate + "]"; + } + } diff --git a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/connection/AbstractConnectionFactoryTests.java b/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/connection/AbstractConnectionFactoryTests.java index 8f4e8dc3..6975d8f4 100644 --- a/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/connection/AbstractConnectionFactoryTests.java +++ b/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/connection/AbstractConnectionFactoryTests.java @@ -1,10 +1,13 @@ package org.springframework.amqp.rabbit.connection; +import static org.hamcrest.Matchers.containsString; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -14,7 +17,12 @@ import java.util.Arrays; import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicInteger; +import org.apache.commons.logging.Log; import org.junit.Test; +import org.mockito.ArgumentCaptor; + +import org.springframework.amqp.utils.test.TestUtils; +import org.springframework.beans.DirectFieldAccessor; import com.rabbitmq.client.ConnectionFactory; @@ -24,6 +32,7 @@ import com.rabbitmq.client.ConnectionFactory; public abstract class AbstractConnectionFactoryTests { protected abstract AbstractConnectionFactory createConnectionFactory(ConnectionFactory mockConnectionFactory); + @Test public void testWithListener() throws IOException { @@ -35,16 +44,24 @@ public abstract class AbstractConnectionFactoryTests { final AtomicInteger called = new AtomicInteger(0); AbstractConnectionFactory connectionFactory = createConnectionFactory(mockConnectionFactory); connectionFactory.setConnectionListeners(Arrays.asList(new ConnectionListener() { + @Override public void onCreate(Connection connection) { called.incrementAndGet(); } + @Override public void onClose(Connection connection) { called.decrementAndGet(); } })); + Log logger = spy(TestUtils.getPropertyValue(connectionFactory, "logger", Log.class)); + when(logger.isInfoEnabled()).thenReturn(true); + new DirectFieldAccessor(connectionFactory).setPropertyValue("logger", logger); Connection con = connectionFactory.createConnection(); assertEquals(1, called.get()); + ArgumentCaptor captor = ArgumentCaptor.forClass(String.class); + verify(logger).info(captor.capture()); + assertThat(captor.getValue(), containsString("Created new connection: SimpleConnection")); con.close(); assertEquals(1, called.get()); @@ -75,9 +92,11 @@ public abstract class AbstractConnectionFactoryTests { assertEquals(0, called.get()); connectionFactory.setConnectionListeners(Arrays.asList(new ConnectionListener() { + @Override public void onCreate(Connection connection) { called.incrementAndGet(); } + @Override public void onClose(Connection connection) { called.decrementAndGet(); }