@Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
      final NioSocketChannel ch = (NioSocketChannel) e.getChannel();
      final NetSocket sock = socketMap.remove(ch);
      ch.close();
      final Throwable t = e.getCause();

      log.error("Exception on netserver", t);

      if (sock != null && t instanceof Exception) {
        sock.getContext()
            .execute(
                new Runnable() {
                  public void run() {
                    sock.handleException((Exception) t);
                  }
                });
      } else {
        // Ignore - any exceptions not associated with any sock (e.g. failure in ssl handshake) will
        // be communicated explicitly
      }
    }
 @Override
 public void handle(final NetSocket socket) {
   NetClient client = null;
   List<String> paths = serviceMap.getPaths();
   TcpClientRequestFacade requestFacade = new TcpClientRequestFacade(socket);
   String path = pathLoadBalancer.choose(paths, requestFacade);
   if (path != null) {
     List<ServiceDetails> services = serviceMap.getServices(path);
     if (!services.isEmpty()) {
       ServiceDetails serviceDetails = serviceLoadBalancer.choose(services, requestFacade);
       if (serviceDetails != null) {
         List<String> urlStrings = serviceDetails.getServices();
         for (String urlString : urlStrings) {
           if (Strings.notEmpty(urlString)) {
             // lets create a client for this request...
             try {
               URI uri = new URI(urlString);
               // URL url = new URL(urlString);
               String urlProtocol = uri.getScheme();
               if (Objects.equal(protocol, urlProtocol)) {
                 Handler<AsyncResult<NetSocket>> handler =
                     new Handler<AsyncResult<NetSocket>>() {
                       public void handle(final AsyncResult<NetSocket> asyncSocket) {
                         NetSocket clientSocket = asyncSocket.result();
                         Pump.createPump(clientSocket, socket).start();
                         Pump.createPump(socket, clientSocket).start();
                       }
                     };
                 client = createClient(socket, uri, handler);
                 break;
               }
             } catch (MalformedURLException e) {
               LOG.warn("Failed to parse URL: " + urlString + ". " + e, e);
             } catch (URISyntaxException e) {
               LOG.warn("Failed to parse URI: " + urlString + ". " + e, e);
             }
           }
         }
       }
     }
   }
   if (client == null) {
     // fail to route
     LOG.info("No service available for protocol " + protocol + " for paths " + paths);
     socket.close();
   }
 }
 /** Creates a new client for the given URL and handler */
 protected NetClient createClient(
     NetSocket socket, URI url, Handler<AsyncResult<NetSocket>> handler)
     throws MalformedURLException {
   NetClient client = vertx.createNetClient();
   int port = url.getPort();
   String host = url.getHost();
   LOG.info(
       "Connecting "
           + socket.remoteAddress()
           + " to host "
           + host
           + " port "
           + port
           + " protocol "
           + protocol);
   return client.connect(port, host, handler);
 }
 @Override
 public String getClientRequestKey() {
   return socket.localAddress().toString();
 }