public void run() throws IOException {
      final FutureImpl<String> completeFuture = SafeFutureImpl.create();

      // Build HTTP client filter chain
      FilterChainBuilder clientFilterChainBuilder = FilterChainBuilder.newInstance();
      // Add transport filter
      clientFilterChainBuilder.add(new TransportFilter());

      // Add HttpClientFilter, which transforms Buffer <-> HttpContent
      clientFilterChainBuilder.add(new HttpClientFilter());
      // Add ClientFilter
      clientFilterChainBuilder.add(new ClientFilter(completeFuture));

      // Initialize Transport
      final TCPNIOTransport transport = TCPNIOTransportBuilder.newInstance().build();
      // Set filterchain as a Transport Processor
      transport.setFilterChain(clientFilterChainBuilder.build());

      try {
        // start the transport
        transport.start();

        Connection connection = null;

        // Connecting to a remote Web server
        Future<Connection> connectFuture = transport.connect(HOST, PORT);
        try {
          // Wait until the client connect operation will be completed
          // Once connection has been established, the POST will
          // be sent to the server.
          connection = connectFuture.get(10, TimeUnit.SECONDS);

          // Wait no longer than 30 seconds for the response from the
          // server to be complete.
          String result = completeFuture.get(30, TimeUnit.SECONDS);

          // Display the echoed content
          System.out.println("\nEchoed POST Data: " + result + '\n');
        } catch (Exception e) {
          if (connection == null) {
            LOGGER.log(Level.WARNING, "Connection failed.  Server is not listening.");
          } else {
            LOGGER.log(Level.WARNING, "Unexpected error communicating with the server.");
          }
        } finally {
          // Close the client connection
          if (connection != null) {
            connection.closeSilently();
          }
        }
      } finally {
        // shutdownNow the transport
        transport.shutdownNow();
      }
    }
  public void testBlockingRead() throws Exception {
    final String[] clientMsgs = {"XXXXX", "Hello", "from", "client"};

    Connection connection = null;
    int messageNum = 3;

    final BlockingQueue<String> intermResultQueue = DataStructures.getLTQInstance(String.class);

    final PUFilter puFilter = new PUFilter();
    FilterChain subProtocolChain =
        puFilter
            .getPUFilterChainBuilder()
            .add(new MergeFilter(clientMsgs.length, intermResultQueue))
            .add(new EchoFilter())
            .build();

    puFilter.register(new SimpleProtocolFinder(clientMsgs[0]), subProtocolChain);

    FilterChainBuilder filterChainBuilder = FilterChainBuilder.newInstance();
    filterChainBuilder.add(new TransportFilter());
    filterChainBuilder.add(new StringFilter());
    filterChainBuilder.add(puFilter);

    final TCPNIOTransport transport = TCPNIOTransportBuilder.newInstance().build();
    transport.setFilterChain(filterChainBuilder.build());

    try {
      transport.bind(PORT);
      transport.start();

      final BlockingQueue<String> resultQueue = DataStructures.getLTQInstance(String.class);

      Future<Connection> future = transport.connect("localhost", PORT);
      connection = future.get(10, TimeUnit.SECONDS);
      assertTrue(connection != null);

      FilterChainBuilder clientFilterChainBuilder = FilterChainBuilder.newInstance();
      clientFilterChainBuilder.add(new TransportFilter());
      clientFilterChainBuilder.add(new StringFilter());
      clientFilterChainBuilder.add(
          new BaseFilter() {

            @Override
            public NextAction handleRead(FilterChainContext ctx) throws IOException {
              resultQueue.add((String) ctx.getMessage());
              return ctx.getStopAction();
            }
          });
      final FilterChain clientFilterChain = clientFilterChainBuilder.build();

      connection.setFilterChain(clientFilterChain);

      for (int i = 0; i < messageNum; i++) {
        String clientMessage = "";

        for (int j = 0; j < clientMsgs.length; j++) {
          String msg = clientMsgs[j] + "-" + i;
          Future<WriteResult> writeFuture = connection.write(msg);

          assertTrue("Write timeout loop: " + i, writeFuture.get(10, TimeUnit.SECONDS) != null);

          final String srvInterm = intermResultQueue.poll(10, TimeUnit.SECONDS);

          assertEquals("Unexpected interm. response (" + i + ", " + j + ")", msg, srvInterm);

          clientMessage += msg;
        }

        final String message = resultQueue.poll(10, TimeUnit.SECONDS);

        assertEquals("Unexpected response (" + i + ")", clientMessage, message);
      }
    } finally {
      if (connection != null) {
        connection.closeSilently();
      }

      transport.shutdownNow();
    }
  }
  public void testBlockingReadError() throws Exception {
    final String[] clientMsgs = {"ZZZZZ", "Hello", "from", "client"};

    Connection connection = null;

    final BlockingQueue intermResultQueue = DataStructures.getLTQInstance();

    final PUFilter puFilter = new PUFilter();
    FilterChain subProtocolChain =
        puFilter
            .getPUFilterChainBuilder()
            .add(new MergeFilter(clientMsgs.length, intermResultQueue))
            .add(new EchoFilter())
            .build();

    puFilter.register(new SimpleProtocolFinder(clientMsgs[0]), subProtocolChain);

    FilterChainBuilder filterChainBuilder = FilterChainBuilder.newInstance();
    filterChainBuilder.add(new TransportFilter());
    filterChainBuilder.add(new StringFilter());
    filterChainBuilder.add(puFilter);

    TCPNIOTransport transport = TCPNIOTransportBuilder.newInstance().build();
    transport.setFilterChain(filterChainBuilder.build());

    try {
      transport.bind(PORT);
      transport.start();

      Future<Connection> future = transport.connect("localhost", PORT);
      connection = future.get(10, TimeUnit.SECONDS);
      assertTrue(connection != null);

      FilterChainBuilder clientFilterChainBuilder = FilterChainBuilder.newInstance();
      clientFilterChainBuilder.add(new TransportFilter());
      clientFilterChainBuilder.add(new StringFilter());
      final FilterChain clientFilterChain = clientFilterChainBuilder.build();

      connection.setFilterChain(clientFilterChain);

      String msg = clientMsgs[0];
      Future<WriteResult> writeFuture = connection.write(msg);

      assertTrue("Write timeout", writeFuture.get(10, TimeUnit.SECONDS) != null);

      final String srvInterm = (String) intermResultQueue.poll(10, TimeUnit.SECONDS);

      assertEquals("Unexpected interm. response", msg, srvInterm);

      connection.closeSilently();
      connection = null;

      final Exception e = (Exception) intermResultQueue.poll(10, TimeUnit.SECONDS);

      assertTrue(
          "Unexpected response. Exception: " + e.getClass() + ": " + e.getMessage(),
          e instanceof IOException);
    } finally {
      if (connection != null) {
        connection.closeSilently();
      }

      transport.shutdownNow();
    }
  }