@Test public void testFailoverGood() throws Exception { AbstractClientConnectionFactory factory1 = mock(AbstractClientConnectionFactory.class); AbstractClientConnectionFactory factory2 = mock(AbstractClientConnectionFactory.class); List<AbstractClientConnectionFactory> factories = new ArrayList<AbstractClientConnectionFactory>(); factories.add(factory1); factories.add(factory2); TcpConnectionSupport conn1 = makeMockConnection(); TcpConnectionSupport conn2 = makeMockConnection(); when(factory1.getConnection()).thenReturn(conn1); when(factory2.getConnection()).thenReturn(conn2); when(factory1.isActive()).thenReturn(true); when(factory2.isActive()).thenReturn(true); doThrow(new IOException("fail")).when(conn1).send(Mockito.any(Message.class)); doAnswer( new Answer<Object>() { public Object answer(InvocationOnMock invocation) throws Throwable { return null; } }) .when(conn2) .send(Mockito.any(Message.class)); FailoverClientConnectionFactory failoverFactory = new FailoverClientConnectionFactory(factories); failoverFactory.start(); GenericMessage<String> message = new GenericMessage<String>("foo"); failoverFactory.getConnection().send(message); Mockito.verify(conn2).send(message); }
private Socket getSocket(AbstractClientConnectionFactory client) throws Exception { if (client instanceof TcpNetClientConnectionFactory) { return TestUtils.getPropertyValue(client.getConnection(), "socket", Socket.class); } else { return TestUtils.getPropertyValue( client.getConnection(), "socketChannel", SocketChannel.class) .socket(); } }
@Test public void testEnlargePool() throws Exception { AbstractClientConnectionFactory factory = mock(AbstractClientConnectionFactory.class); when(factory.isRunning()).thenReturn(true); TcpConnectionSupport mockConn1 = makeMockConnection("conn1"); TcpConnectionSupport mockConn2 = makeMockConnection("conn2"); TcpConnectionSupport mockConn3 = makeMockConnection("conn3"); TcpConnectionSupport mockConn4 = makeMockConnection("conn4"); when(factory.getConnection()).thenReturn(mockConn1, mockConn2, mockConn3, mockConn4); CachingClientConnectionFactory cachingFactory = new CachingClientConnectionFactory(factory, 2); cachingFactory.start(); TcpConnection conn1 = cachingFactory.getConnection(); TcpConnection conn2 = cachingFactory.getConnection(); assertNotSame(conn1, conn2); Semaphore semaphore = TestUtils.getPropertyValue( TestUtils.getPropertyValue(cachingFactory, "pool"), "permits", Semaphore.class); assertEquals(0, semaphore.availablePermits()); cachingFactory.setPoolSize(4); TcpConnection conn3 = cachingFactory.getConnection(); TcpConnection conn4 = cachingFactory.getConnection(); assertEquals(0, semaphore.availablePermits()); conn1.close(); conn1.close(); conn2.close(); conn3.close(); conn4.close(); assertEquals(4, semaphore.availablePermits()); }
@Test(expected = IOException.class) public void testFailoverConnectNone() throws Exception { AbstractClientConnectionFactory factory1 = mock(AbstractClientConnectionFactory.class); AbstractClientConnectionFactory factory2 = mock(AbstractClientConnectionFactory.class); List<AbstractClientConnectionFactory> factories = new ArrayList<AbstractClientConnectionFactory>(); factories.add(factory1); factories.add(factory2); when(factory1.getConnection()).thenThrow(new IOException("fail")); when(factory2.getConnection()).thenThrow(new IOException("fail")); when(factory1.isActive()).thenReturn(true); when(factory2.isActive()).thenReturn(true); FailoverClientConnectionFactory failoverFactory = new FailoverClientConnectionFactory(factories); failoverFactory.start(); GenericMessage<String> message = new GenericMessage<String>("foo"); failoverFactory.getConnection().send(message); }
private CachingClientConnectionFactory createCCCFWith2Connections( TcpConnectionSupport conn1, TcpConnectionSupport conn2) throws Exception { AbstractClientConnectionFactory factory = mock(AbstractClientConnectionFactory.class); when(factory.isRunning()).thenReturn(true); when(factory.getConnection()).thenReturn(conn1, conn2); CachingClientConnectionFactory cccf = new CachingClientConnectionFactory(factory, 1); cccf.setConnectionWaitTimeout(1); cccf.start(); return cccf; }
@Test public void testOkAgainAfterCompleteFailure() throws Exception { AbstractClientConnectionFactory factory1 = mock(AbstractClientConnectionFactory.class); AbstractClientConnectionFactory factory2 = mock(AbstractClientConnectionFactory.class); List<AbstractClientConnectionFactory> factories = new ArrayList<AbstractClientConnectionFactory>(); factories.add(factory1); factories.add(factory2); TcpConnectionSupport conn1 = makeMockConnection(); TcpConnectionSupport conn2 = makeMockConnection(); when(factory1.getConnection()).thenReturn(conn1); when(factory2.getConnection()).thenReturn(conn2); when(factory1.isActive()).thenReturn(true); when(factory2.isActive()).thenReturn(true); final AtomicInteger failCount = new AtomicInteger(); doAnswer( new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { if (failCount.incrementAndGet() < 3) { throw new IOException("fail"); } return null; } }) .when(conn1) .send(Mockito.any(Message.class)); doThrow(new IOException("fail")).when(conn2).send(Mockito.any(Message.class)); FailoverClientConnectionFactory failoverFactory = new FailoverClientConnectionFactory(factories); failoverFactory.start(); GenericMessage<String> message = new GenericMessage<String>("foo"); try { failoverFactory.getConnection().send(message); fail("ExpectedFailure"); } catch (IOException e) { } failoverFactory.getConnection().send(message); Mockito.verify(conn2).send(message); Mockito.verify(conn1, times(3)).send(message); }
@Test(expected = IOException.class) public void testFailoverAllDead() throws Exception { AbstractClientConnectionFactory factory1 = mock(AbstractClientConnectionFactory.class); AbstractClientConnectionFactory factory2 = mock(AbstractClientConnectionFactory.class); List<AbstractClientConnectionFactory> factories = new ArrayList<AbstractClientConnectionFactory>(); factories.add(factory1); factories.add(factory2); TcpConnectionSupport conn1 = makeMockConnection(); TcpConnectionSupport conn2 = makeMockConnection(); when(factory1.getConnection()).thenReturn(conn1); when(factory2.getConnection()).thenReturn(conn2); when(factory1.isActive()).thenReturn(true); when(factory2.isActive()).thenReturn(true); doThrow(new IOException("fail")).when(conn1).send(Mockito.any(Message.class)); doThrow(new IOException("fail")).when(conn2).send(Mockito.any(Message.class)); FailoverClientConnectionFactory failoverFactory = new FailoverClientConnectionFactory(factories); failoverFactory.start(); GenericMessage<String> message = new GenericMessage<String>("foo"); failoverFactory.getConnection().send(message); Mockito.verify(conn2).send(message); }
@Test public void testFailoverAllDeadButOriginalOkAgain() throws Exception { AbstractClientConnectionFactory factory1 = mock(AbstractClientConnectionFactory.class); AbstractClientConnectionFactory factory2 = mock(AbstractClientConnectionFactory.class); List<AbstractClientConnectionFactory> factories = new ArrayList<AbstractClientConnectionFactory>(); factories.add(factory1); factories.add(factory2); TcpConnectionSupport conn1 = makeMockConnection(); TcpConnectionSupport conn2 = makeMockConnection(); when(factory1.getConnection()).thenReturn(conn1); when(factory2.getConnection()).thenReturn(conn2); when(factory1.isActive()).thenReturn(true); when(factory2.isActive()).thenReturn(true); final AtomicBoolean failedOnce = new AtomicBoolean(); doAnswer( new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { if (!failedOnce.get()) { failedOnce.set(true); throw new IOException("fail"); } return null; } }) .when(conn1) .send(Mockito.any(Message.class)); doThrow(new IOException("fail")).when(conn2).send(Mockito.any(Message.class)); FailoverClientConnectionFactory failoverFactory = new FailoverClientConnectionFactory(factories); failoverFactory.start(); GenericMessage<String> message = new GenericMessage<String>("foo"); failoverFactory.getConnection().send(message); Mockito.verify(conn2).send(message); Mockito.verify(conn1, times(2)).send(message); }
@Test public void testStop() throws Exception { AbstractClientConnectionFactory factory = mock(AbstractClientConnectionFactory.class); when(factory.isRunning()).thenReturn(true); TcpConnectionSupport mockConn1 = makeMockConnection("conn1"); TcpConnectionSupport mockConn2 = makeMockConnection("conn2"); int i = 3; when(factory.getConnection()) .thenReturn(mockConn1) .thenReturn(mockConn2) .thenReturn(makeMockConnection("conn" + (i++))); CachingClientConnectionFactory cachingFactory = new CachingClientConnectionFactory(factory, 2); cachingFactory.start(); TcpConnection conn1 = cachingFactory.getConnection(); assertEquals("Cached:" + mockConn1.toString(), conn1.toString()); conn1.close(); conn1 = cachingFactory.getConnection(); assertEquals("Cached:" + mockConn1.toString(), conn1.toString()); TcpConnection conn2 = cachingFactory.getConnection(); assertEquals("Cached:" + mockConn2.toString(), conn2.toString()); cachingFactory.stop(); Answer<Object> answer = new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { return null; } }; doAnswer(answer).when(mockConn1).close(); doAnswer(answer).when(mockConn2).close(); when(factory.isRunning()).thenReturn(false); conn1.close(); conn2.close(); verify(mockConn1).close(); verify(mockConn2).close(); when(mockConn1.isOpen()).thenReturn(false); when(mockConn2.isOpen()).thenReturn(false); when(factory.isRunning()).thenReturn(true); TcpConnection conn3 = cachingFactory.getConnection(); assertNotSame( TestUtils.getPropertyValue(conn1, "theConnection"), TestUtils.getPropertyValue(conn3, "theConnection")); assertNotSame( TestUtils.getPropertyValue(conn2, "theConnection"), TestUtils.getPropertyValue(conn3, "theConnection")); }
@Test public void testReuse() throws Exception { AbstractClientConnectionFactory factory = mock(AbstractClientConnectionFactory.class); when(factory.isRunning()).thenReturn(true); TcpConnectionSupport mockConn1 = makeMockConnection("conn1"); TcpConnectionSupport mockConn2 = makeMockConnection("conn2"); when(factory.getConnection()).thenReturn(mockConn1).thenReturn(mockConn2); CachingClientConnectionFactory cachingFactory = new CachingClientConnectionFactory(factory, 2); cachingFactory.start(); TcpConnection conn1 = cachingFactory.getConnection(); assertEquals("Cached:" + mockConn1.toString(), conn1.toString()); conn1.close(); conn1 = cachingFactory.getConnection(); assertEquals("Cached:" + mockConn1.toString(), conn1.toString()); TcpConnection conn2 = cachingFactory.getConnection(); assertEquals("Cached:" + mockConn2.toString(), conn2.toString()); conn1.close(); conn2.close(); }
@Test public void testReducePool() throws Exception { AbstractClientConnectionFactory factory = mock(AbstractClientConnectionFactory.class); when(factory.isRunning()).thenReturn(true); TcpConnectionSupport mockConn1 = makeMockConnection("conn1", true); TcpConnectionSupport mockConn2 = makeMockConnection("conn2", true); TcpConnectionSupport mockConn3 = makeMockConnection("conn3", true); TcpConnectionSupport mockConn4 = makeMockConnection("conn4", true); when(factory.getConnection()) .thenReturn(mockConn1) .thenReturn(mockConn2) .thenReturn(mockConn3) .thenReturn(mockConn4); CachingClientConnectionFactory cachingFactory = new CachingClientConnectionFactory(factory, 4); cachingFactory.start(); TcpConnection conn1 = cachingFactory.getConnection(); TcpConnection conn2 = cachingFactory.getConnection(); TcpConnection conn3 = cachingFactory.getConnection(); TcpConnection conn4 = cachingFactory.getConnection(); Semaphore semaphore = TestUtils.getPropertyValue( TestUtils.getPropertyValue(cachingFactory, "pool"), "permits", Semaphore.class); assertEquals(0, semaphore.availablePermits()); conn1.close(); assertEquals(1, semaphore.availablePermits()); cachingFactory.setPoolSize(2); assertEquals(0, semaphore.availablePermits()); assertEquals(3, cachingFactory.getActiveCount()); conn2.close(); assertEquals(0, semaphore.availablePermits()); assertEquals(2, cachingFactory.getActiveCount()); conn3.close(); assertEquals(1, cachingFactory.getActiveCount()); assertEquals(1, cachingFactory.getIdleCount()); conn4.close(); assertEquals(2, semaphore.availablePermits()); assertEquals(0, cachingFactory.getActiveCount()); assertEquals(2, cachingFactory.getIdleCount()); verify(mockConn1).close(); verify(mockConn2).close(); }
private void testGWPropagatesSocketCloseGuts(final int port, AbstractClientConnectionFactory ccf) throws Exception { final CountDownLatch latch = new CountDownLatch(1); final AtomicBoolean done = new AtomicBoolean(); final AtomicReference<String> lastReceived = new AtomicReference<String>(); final CountDownLatch serverLatch = new CountDownLatch(1); Executors.newSingleThreadExecutor() .execute( new Runnable() { public void run() { try { ServerSocket server = ServerSocketFactory.getDefault().createServerSocket(port); latch.countDown(); int i = 0; while (!done.get()) { Socket socket = server.accept(); i++; while (!socket.isClosed()) { try { ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); String request = (String) ois.readObject(); logger.debug("Read " + request + " closing socket"); socket.close(); lastReceived.set(request); serverLatch.countDown(); } catch (IOException e) { socket.close(); } } } } catch (Exception e) { if (!done.get()) { e.printStackTrace(); } } } }); assertTrue(latch.await(10000, TimeUnit.MILLISECONDS)); final TcpOutboundGateway gateway = new TcpOutboundGateway(); gateway.setConnectionFactory(ccf); gateway.setRequestTimeout(Integer.MAX_VALUE); QueueChannel replyChannel = new QueueChannel(); gateway.setRequiresReply(true); gateway.setOutputChannel(replyChannel); gateway.setRemoteTimeout(5000); gateway.afterPropertiesSet(); gateway.start(); try { gateway.handleMessage(MessageBuilder.withPayload("Test").build()); fail("expected failure"); } catch (Exception e) { assertTrue(e.getCause() instanceof EOFException); } assertEquals(0, TestUtils.getPropertyValue(gateway, "pendingReplies", Map.class).size()); Message<?> reply = replyChannel.receive(0); assertNull(reply); done.set(true); ccf.getConnection(); }
@Test public void testFailoverCached() throws Exception { final int port = SocketUtils.findAvailableServerSocket(); final CountDownLatch latch = new CountDownLatch(1); final AtomicBoolean done = new AtomicBoolean(); final CountDownLatch serverLatch = new CountDownLatch(1); Executors.newSingleThreadExecutor() .execute( new Runnable() { public void run() { try { ServerSocket server = ServerSocketFactory.getDefault().createServerSocket(port); latch.countDown(); while (!done.get()) { Socket socket = server.accept(); while (!socket.isClosed()) { try { ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); String request = (String) ois.readObject(); logger.debug("Read " + request); ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); oos.writeObject("bar"); logger.debug("Replied to " + request); serverLatch.countDown(); } catch (IOException e) { logger.debug("error on write " + e.getClass().getSimpleName()); socket.close(); } } } } catch (Exception e) { if (!done.get()) { e.printStackTrace(); } } } }); assertTrue(latch.await(10000, TimeUnit.MILLISECONDS)); // Cache AbstractClientConnectionFactory factory1 = mock(AbstractClientConnectionFactory.class); TcpConnectionSupport mockConn1 = makeMockConnection(); when(factory1.getConnection()).thenReturn(mockConn1); doThrow(new IOException("fail")).when(mockConn1).send(Mockito.any(Message.class)); CachingClientConnectionFactory cachingFactory1 = new CachingClientConnectionFactory(factory1, 1); AbstractClientConnectionFactory factory2 = new TcpNetClientConnectionFactory("localhost", port); factory2.setSerializer(new DefaultSerializer()); factory2.setDeserializer(new DefaultDeserializer()); factory2.setSoTimeout(10000); factory2.setSingleUse(false); CachingClientConnectionFactory cachingFactory2 = new CachingClientConnectionFactory(factory2, 1); // Failover List<AbstractClientConnectionFactory> factories = new ArrayList<AbstractClientConnectionFactory>(); factories.add(cachingFactory1); factories.add(cachingFactory2); FailoverClientConnectionFactory failoverFactory = new FailoverClientConnectionFactory(factories); failoverFactory.start(); TcpOutboundGateway gateway = new TcpOutboundGateway(); gateway.setConnectionFactory(failoverFactory); PollableChannel outputChannel = new QueueChannel(); gateway.setOutputChannel(outputChannel); gateway.afterPropertiesSet(); gateway.start(); GenericMessage<String> message = new GenericMessage<String>("foo"); gateway.handleMessage(message); Message<?> reply = outputChannel.receive(0); assertNotNull(reply); assertEquals("bar", reply.getPayload()); done.set(true); gateway.stop(); verify(mockConn1).send(Mockito.any(Message.class)); }