INT-3646: Add TCP Server Exception Events
JIRA: https://jira.spring.io/browse/INT-3646 Publish `TcpConnectionServerExceptionEvent`s when unexpected exceptions occur on server sockets. INT-3646: Polishing Fix Reactor tests
This commit is contained in:
committed by
Artem Bilan
parent
f248394682
commit
f4e775ec18
@@ -16,25 +16,49 @@
|
||||
|
||||
package org.springframework.integration.ip.tcp.connection;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.endsWith;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.net.BindException;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.net.ServerSocketFactory;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.internal.stubbing.answers.DoesNothing;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.core.serializer.Serializer;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.util.SocketUtils;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
@@ -44,7 +68,7 @@ import org.springframework.messaging.support.GenericMessage;
|
||||
public class ConnectionEventTests {
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
public void testConnectionEvents() throws Exception {
|
||||
Socket socket = mock(Socket.class);
|
||||
final List<TcpConnectionEvent> theEvent = new ArrayList<TcpConnectionEvent>();
|
||||
TcpNetConnection conn = new TcpNetConnection(socket, false, false, new ApplicationEventPublisher() {
|
||||
@@ -56,9 +80,9 @@ public class ConnectionEventTests {
|
||||
|
||||
@Override
|
||||
public void publishEvent(Object event) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}, "foo");
|
||||
/*
|
||||
* Open is not published by the connection itself; the factory publishes it after initialization.
|
||||
@@ -85,7 +109,72 @@ public class ConnectionEventTests {
|
||||
assertSame(toBeThrown, event.getCause());
|
||||
assertTrue(theEvent.size() > 1);
|
||||
assertNotNull(theEvent.get(1));
|
||||
assertTrue(theEvent.get(1).toString().endsWith("[factory=foo, connectionId=" + conn.getConnectionId() + "] **CLOSED**"));
|
||||
assertTrue(theEvent.get(1).toString()
|
||||
.endsWith("[factory=foo, connectionId=" + conn.getConnectionId() + "] **CLOSED**"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNetServerExceptionEvent() throws Exception {
|
||||
int port = SocketUtils.findAvailableTcpPort();
|
||||
AbstractServerConnectionFactory factory = new TcpNetServerConnectionFactory(port);
|
||||
testServerExceptionGuts(port, factory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNioServerExceptionEvent() throws Exception {
|
||||
int port = SocketUtils.findAvailableTcpPort();
|
||||
AbstractServerConnectionFactory factory = new TcpNioServerConnectionFactory(port);
|
||||
testServerExceptionGuts(port, factory);
|
||||
}
|
||||
|
||||
private void testServerExceptionGuts(int port, AbstractServerConnectionFactory factory) throws Exception {
|
||||
ServerSocket ss = ServerSocketFactory.getDefault().createServerSocket(port);
|
||||
final AtomicReference<TcpConnectionServerExceptionEvent> theEvent =
|
||||
new AtomicReference<TcpConnectionServerExceptionEvent>();
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
factory.setApplicationEventPublisher(new ApplicationEventPublisher() {
|
||||
|
||||
@Override
|
||||
public void publishEvent(ApplicationEvent event) {
|
||||
theEvent.set((TcpConnectionServerExceptionEvent) event);
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publishEvent(Object event) {
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
factory.setBeanName("sf");
|
||||
factory.registerListener(new TcpListener() {
|
||||
|
||||
@Override
|
||||
public boolean onMessage(Message<?> message) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
Log logger = spy(TestUtils.getPropertyValue(factory, "logger", Log.class));
|
||||
doAnswer(new DoesNothing()).when(logger).error(anyString(), any(Throwable.class));
|
||||
new DirectFieldAccessor(factory).setPropertyValue("logger", logger);
|
||||
|
||||
factory.start();
|
||||
assertTrue(latch.await(10, TimeUnit.SECONDS));
|
||||
String actual = theEvent.toString();
|
||||
assertThat(actual, containsString("cause=java.net.BindException"));
|
||||
assertThat(actual, containsString("[factory="
|
||||
+ (factory instanceof TcpNetServerConnectionFactory
|
||||
? "tcp-net-server-connection-factory"
|
||||
: "tcp-nio-server-connection-factory")
|
||||
+ ":sf, port=" + port + "]"));
|
||||
|
||||
ArgumentCaptor<String> reasonCaptor = ArgumentCaptor.forClass(String.class);
|
||||
ArgumentCaptor<Throwable> throwableCaptor = ArgumentCaptor.forClass(Throwable.class);
|
||||
verify(logger).error(reasonCaptor.capture(), throwableCaptor.capture());
|
||||
assertThat(reasonCaptor.getValue(), startsWith("Error on Server"));
|
||||
assertThat(reasonCaptor.getValue(), endsWith("; port = " + port));
|
||||
assertThat(throwableCaptor.getValue(), instanceOf(BindException.class));
|
||||
ss.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ log4j.rootCategory=WARN, stdout
|
||||
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d %c{1} [%t] : %m%n
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d %5p %c{1} [%t] : %m%n
|
||||
|
||||
log4j.category.org.springframework.integration=WARN
|
||||
log4j.category.org.springframework.integration.ip=WARN
|
||||
|
||||
Reference in New Issue
Block a user