protected String handleRequest(
      Channel channel, StreamInput buffer, long requestId, Version version) throws IOException {
    final String action = buffer.readString();

    final NettyTransportChannel transportChannel =
        new NettyTransportChannel(transport, action, channel, requestId, version);
    try {
      final TransportRequestHandler handler = transportServiceAdapter.handler(action);
      if (handler == null) {
        throw new ActionNotFoundTransportException(action);
      }
      final TransportRequest request = handler.newInstance();
      request.remoteAddress(
          new InetSocketTransportAddress((InetSocketAddress) channel.getRemoteAddress()));
      request.readFrom(buffer);
      if (handler.executor() == ThreadPool.Names.SAME) {
        //noinspection unchecked
        handler.messageReceived(request, transportChannel);
      } else {
        threadPool
            .executor(handler.executor())
            .execute(new RequestHandler(handler, request, transportChannel, action));
      }
    } catch (Throwable e) {
      try {
        transportChannel.sendResponse(e);
      } catch (IOException e1) {
        logger.warn("Failed to send error message back to client for action [" + action + "]", e);
        logger.warn("Actual Exception", e1);
      }
    }
    return action;
  }
 @Override
 public void readFrom(StreamInput in) throws IOException {
   super.readFrom(in);
   shardSearchLocalRequest = new ShardSearchLocalRequest();
   shardSearchLocalRequest.innerReadFrom(in);
   originalIndices = OriginalIndices.readOriginalIndices(in);
 }
 @Override
 public void readFrom(StreamInput in) throws IOException {
   super.readFrom(in);
   fromNode = DiscoveryNode.readNode(in);
   indices = new IndexMetaData[in.readVInt()];
   for (int i = 0; i < indices.length; i++) {
     indices[i] = IndexMetaData.Builder.readFrom(in);
   }
 }
 @Override
 public void writeTo(StreamOutput out) throws IOException {
   super.writeTo(out);
   fromNode.writeTo(out);
   out.writeVInt(indices.length);
   for (IndexMetaData indexMetaData : indices) {
     indexMetaData.writeTo(out);
   }
 }
 @Override
 public void readFrom(StreamInput in) throws IOException {
   super.readFrom(in);
   indicesLevelRequest = readRequestFrom(in);
   int size = in.readVInt();
   shards = new ArrayList<>(size);
   for (int i = 0; i < size; i++) {
     shards.add(ShardRouting.readShardRoutingEntry(in));
   }
   nodeId = in.readString();
 }
 @Override
 public void writeTo(StreamOutput out) throws IOException {
   super.writeTo(out);
   indicesLevelRequest.writeTo(out);
   int size = shards.size();
   out.writeVInt(size);
   for (int i = 0; i < size; i++) {
     shards.get(i).writeTo(out);
   }
   out.writeString(nodeId);
 }
 @Override
 public void readFrom(StreamInput in) throws IOException {
   super.readFrom(in);
   request = newRequest();
   request.readFrom(in);
   if (in.getVersion().onOrAfter(Version.V_1_4_0)) {
     shardId = ShardId.readShardId(in);
   } else {
     // older nodes will send the concrete index as part of the request
     shardId = new ShardId(request.index(), in.readVInt());
   }
 }
 private static void assertSameIndices(
     IndicesRequest originalRequest, boolean optional, String... actions) {
   for (String action : actions) {
     List<TransportRequest> requests = consumeTransportRequests(action);
     if (!optional) {
       assertThat(
           "no internal requests intercepted for action [" + action + "]",
           requests.size(),
           greaterThan(0));
     }
     for (TransportRequest internalRequest : requests) {
       assertThat(internalRequest, instanceOf(IndicesRequest.class));
       assertThat(
           internalRequest.getClass().getName(),
           ((IndicesRequest) internalRequest).indices(),
           equalTo(originalRequest.indices()));
       assertThat(
           ((IndicesRequest) internalRequest).indicesOptions(),
           equalTo(originalRequest.indicesOptions()));
     }
   }
 }
 @Override
 public void writeTo(StreamOutput out) throws IOException {
   super.writeTo(out);
   out.writeLong(recoveryId);
   shardId.writeTo(out);
   out.writeString(metaData.name());
   out.writeVLong(position);
   out.writeVLong(metaData.length());
   out.writeOptionalString(metaData.checksum());
   out.writeBytesReference(content);
   if (out.getVersion().onOrAfter(org.elasticsearch.Version.V_1_3_0)) {
     out.writeOptionalString(metaData.writtenBy() == null ? null : metaData.writtenBy().name());
   }
 }
 @Override
 public void writeTo(StreamOutput out) throws IOException {
   super.writeTo(out);
   if (out.getVersion().before(Version.V_1_4_0)) {
     // older nodes expect the concrete index as part of the request
     request.index(shardId.getIndex());
   }
   request.writeTo(out);
   if (out.getVersion().onOrAfter(Version.V_1_4_0)) {
     shardId.writeTo(out);
   } else {
     out.writeVInt(shardId.id());
   }
 }
 @Override
 public void writeTo(StreamOutput out) throws IOException {
   super.writeTo(out);
   out.writeLong(recoveryId);
   shardId.writeTo(out);
   if (out.getVersion().onOrAfter(Version.V_1_5_0)) {
     snapshotFiles.writeTo(out);
   } else {
     out.writeVInt(snapshotFiles.size());
     for (StoreFileMetaData snapshotFile : snapshotFiles) {
       out.writeString(snapshotFile.name());
     }
   }
 }
 @Override
 public void readFrom(StreamInput in) throws IOException {
   super.readFrom(in);
   recoveryId = in.readLong();
   shardId = ShardId.readShardId(in);
   if (in.getVersion().onOrAfter(Version.V_1_5_0)) {
     snapshotFiles = Store.MetadataSnapshot.read(in);
   } else {
     int size = in.readVInt();
     legacySnapshotFiles = Sets.newHashSetWithExpectedSize(size);
     for (int i = 0; i < size; i++) {
       legacySnapshotFiles.add(in.readString());
     }
   }
 }
 @Override
 public void readFrom(StreamInput in) throws IOException {
   super.readFrom(in);
   recoveryId = in.readLong();
   shardId = ShardId.readShardId(in);
   String name = in.readString();
   position = in.readVLong();
   long length = in.readVLong();
   String checksum = in.readOptionalString();
   content = in.readBytesReference();
   Version writtenBy = null;
   if (in.getVersion().onOrAfter(org.elasticsearch.Version.V_1_3_0)) {
     String versionString = in.readOptionalString();
     writtenBy = versionString == null ? null : Version.parseLeniently(versionString);
   }
   metaData = new StoreFileMetaData(name, length, checksum, writtenBy);
 }
  @Override
  public void sendRequest(
      final DiscoveryNode node,
      final long requestId,
      final String action,
      final TransportRequest request,
      TransportRequestOptions options)
      throws IOException, TransportException {
    final Version version = Version.smallest(node.getVersion(), this.version);

    try (BytesStreamOutput stream = new BytesStreamOutput()) {
      stream.setVersion(version);

      stream.writeLong(requestId);
      byte status = 0;
      status = TransportStatus.setRequest(status);
      stream.writeByte(status); // 0 for request, 1 for response.

      threadPool.getThreadContext().writeTo(stream);
      stream.writeString(action);
      request.writeTo(stream);

      stream.close();

      final LocalTransport targetTransport = connectedNodes.get(node);
      if (targetTransport == null) {
        throw new NodeNotConnectedException(node, "Node not connected");
      }

      final byte[] data = stream.bytes().toBytes();
      transportServiceAdapter.sent(data.length);
      transportServiceAdapter.onRequestSent(node, requestId, action, request, options);
      targetTransport
          .workers()
          .execute(
              () -> {
                ThreadContext threadContext = targetTransport.threadPool.getThreadContext();
                try (ThreadContext.StoredContext context = threadContext.stashContext()) {
                  targetTransport.messageReceived(
                      data, action, LocalTransport.this, version, requestId);
                }
              });
    }
  }
 @Override
 public void writeTo(StreamOutput out) throws IOException {
   super.writeTo(out);
   shardSearchLocalRequest.innerWriteTo(out, false);
   OriginalIndices.writeOriginalIndices(originalIndices, out);
 }
 @Override
 public void readFrom(StreamInput in) throws IOException {
   super.readFrom(in);
   repository = in.readString();
   verificationToken = in.readString();
 }
 @Override
 public void readFrom(StreamInput in) throws IOException {
   super.readFrom(in);
   index = in.readString();
   nodeId = in.readString();
 }
 @Override
 public void writeTo(StreamOutput out) throws IOException {
   super.writeTo(out);
   out.writeString(index);
   out.writeString(nodeId);
 }
 @Override
 public void writeTo(StreamOutput out) throws IOException {
   super.writeTo(out);
   out.writeLong(recoveryId);
   shardId.writeTo(out);
 }
  private void handleRequest(
      StreamInput stream,
      long requestId,
      int messageLengthBytes,
      LocalTransport sourceTransport,
      Version version)
      throws Exception {
    stream = new NamedWriteableAwareStreamInput(stream, namedWriteableRegistry);
    final String action = stream.readString();
    transportServiceAdapter.onRequestReceived(requestId, action);
    inFlightRequestsBreaker()
        .addEstimateBytesAndMaybeBreak(messageLengthBytes, "<transport_request>");
    final LocalTransportChannel transportChannel =
        new LocalTransportChannel(
            this,
            transportServiceAdapter,
            sourceTransport,
            action,
            requestId,
            version,
            messageLengthBytes);
    try {
      final RequestHandlerRegistry reg = transportServiceAdapter.getRequestHandler(action);
      if (reg == null) {
        throw new ActionNotFoundTransportException("Action [" + action + "] not found");
      }
      final TransportRequest request = reg.newRequest();
      request.remoteAddress(sourceTransport.boundAddress.publishAddress());
      request.readFrom(stream);
      if (ThreadPool.Names.SAME.equals(reg.getExecutor())) {
        //noinspection unchecked
        reg.processMessageReceived(request, transportChannel);
      } else {
        threadPool
            .executor(reg.getExecutor())
            .execute(
                new AbstractRunnable() {
                  @Override
                  protected void doRun() throws Exception {
                    //noinspection unchecked
                    reg.processMessageReceived(request, transportChannel);
                  }

                  @Override
                  public boolean isForceExecution() {
                    return reg.isForceExecution();
                  }

                  @Override
                  public void onFailure(Throwable e) {
                    if (lifecycleState() == Lifecycle.State.STARTED) {
                      // we can only send a response transport is started....
                      try {
                        transportChannel.sendResponse(e);
                      } catch (Throwable e1) {
                        logger.warn(
                            "Failed to send error message back to client for action [{}]",
                            e1,
                            action);
                        logger.warn("Actual Exception", e);
                      }
                    }
                  }
                });
      }
    } catch (Throwable e) {
      try {
        transportChannel.sendResponse(e);
      } catch (Throwable e1) {
        logger.warn("Failed to send error message back to client for action [{}]", e, action);
        logger.warn("Actual Exception", e1);
      }
    }
  }
 @Override
 public void readFrom(StreamInput in) throws IOException {
   super.readFrom(in);
   shardRouting = readShardRoutingEntry(in);
   reason = in.readString();
 }
 @Override
 public void writeTo(StreamOutput out) throws IOException {
   super.writeTo(out);
   out.writeOptionalString(fromNodeId);
 }
 @Override
 public void readFrom(StreamInput in) throws IOException {
   super.readFrom(in);
   fromNodeId = in.readOptionalString();
 }
 @Override
 public void writeTo(StreamOutput out) throws IOException {
   super.writeTo(out);
   out.writeString(repository);
   out.writeString(verificationToken);
 }
 @Override
 public void writeTo(StreamOutput out) throws IOException {
   super.writeTo(out);
   shardRouting.writeTo(out);
   out.writeString(reason);
 }
 @Override
 public void readFrom(StreamInput in) throws IOException {
   super.readFrom(in);
   recoveryId = in.readLong();
   shardId = ShardId.readShardId(in);
 }