@Test
 public void testGoodNetGWTimeoutCached() throws Exception {
   final int port = SocketUtils.findAvailableServerSocket();
   AbstractClientConnectionFactory ccf = buildCF(port);
   CachingClientConnectionFactory cccf = new CachingClientConnectionFactory(ccf, 1);
   cccf.start();
   testGoodNetGWTimeoutGuts(port, cccf);
 }
 @Test
 public void testCachedGWPropagatesSocketClose() throws Exception {
   final int port = SocketUtils.findAvailableServerSocket();
   AbstractClientConnectionFactory ccf = new TcpNetClientConnectionFactory("localhost", port);
   ccf.setSerializer(new DefaultSerializer());
   ccf.setDeserializer(new DefaultDeserializer());
   ccf.setSoTimeout(10000);
   ccf.setSingleUse(false);
   CachingClientConnectionFactory cccf = new CachingClientConnectionFactory(ccf, 1);
   cccf.start();
   testGWPropagatesSocketCloseGuts(port, cccf);
 }
  @Test
  public void testCachingFailover() 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));

    // Failover
    AbstractClientConnectionFactory factory1 = mock(AbstractClientConnectionFactory.class);
    TcpConnectionSupport mockConn1 = makeMockConnection();
    when(factory1.getConnection()).thenReturn(mockConn1);
    doThrow(new IOException("fail")).when(mockConn1).send(Mockito.any(Message.class));

    AbstractClientConnectionFactory factory2 = new TcpNetClientConnectionFactory("localhost", port);
    factory2.setSerializer(new DefaultSerializer());
    factory2.setDeserializer(new DefaultDeserializer());
    factory2.setSoTimeout(10000);
    factory2.setSingleUse(false);

    List<AbstractClientConnectionFactory> factories =
        new ArrayList<AbstractClientConnectionFactory>();
    factories.add(factory1);
    factories.add(factory2);
    FailoverClientConnectionFactory failoverFactory =
        new FailoverClientConnectionFactory(factories);
    failoverFactory.start();

    // Cache
    CachingClientConnectionFactory cachingFactory =
        new CachingClientConnectionFactory(failoverFactory, 2);
    cachingFactory.start();
    TcpOutboundGateway gateway = new TcpOutboundGateway();
    gateway.setConnectionFactory(cachingFactory);
    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));
  }