public <Response> void execute(
     NodeListenerCallback<Response> callback, ActionListener<Response> listener)
     throws ElasticsearchException {
   ImmutableList<DiscoveryNode> nodes = this.nodes;
   ensureNodesAreAvailable(nodes);
   int index = getNodeNumber();
   RetryListener<Response> retryListener = new RetryListener<>(callback, listener, nodes, index);
   DiscoveryNode node = nodes.get((index) % nodes.size());
   try {
     callback.doWithNode(node, retryListener);
   } catch (Throwable t) {
     // this exception can't come from the TransportService as it doesn't throw exception at all
     listener.onFailure(t);
   }
 }
 @Override
 public void onFailure(Throwable e) {
   if (ExceptionsHelper.unwrapCause(e) instanceof ConnectTransportException) {
     int i = ++this.i;
     if (i >= nodes.size()) {
       listener.onFailure(
           new NoNodeAvailableException(
               "None of the configured nodes were available: " + nodes, e));
     } else {
       try {
         callback.doWithNode(nodes.get((index + i) % nodes.size()), this);
       } catch (Throwable t) {
         // this exception can't come from the TransportService as it doesn't throw exceptions at
         // all
         listener.onFailure(t);
       }
     }
   } else {
     listener.onFailure(e);
   }
 }