public void verify(
      String repository, String verificationToken, final ActionListener<VerifyResponse> listener) {
    final DiscoveryNodes discoNodes = clusterService.state().nodes();
    final DiscoveryNode localNode = discoNodes.localNode();

    final ObjectContainer<DiscoveryNode> masterAndDataNodes =
        discoNodes.masterAndDataNodes().values();
    final List<DiscoveryNode> nodes = newArrayList();
    for (ObjectCursor<DiscoveryNode> cursor : masterAndDataNodes) {
      DiscoveryNode node = cursor.value;
      Version version = node.getVersion();
      // Verification wasn't supported before v1.4.0 - no reason to send verification request to
      // these nodes
      if (version != null && version.onOrAfter(Version.V_1_4_0)) {
        nodes.add(node);
      }
    }
    final CopyOnWriteArrayList<VerificationFailure> errors = new CopyOnWriteArrayList<>();
    final AtomicInteger counter = new AtomicInteger(nodes.size());
    for (final DiscoveryNode node : nodes) {
      if (node.equals(localNode)) {
        try {
          doVerify(repository, verificationToken);
        } catch (Throwable t) {
          logger.warn("[{}] failed to verify repository", t, repository);
          errors.add(new VerificationFailure(node.id(), ExceptionsHelper.detailedMessage(t)));
        }
        if (counter.decrementAndGet() == 0) {
          finishVerification(listener, nodes, errors);
        }
      } else {
        transportService.sendRequest(
            node,
            ACTION_NAME,
            new VerifyNodeRepositoryRequest(repository, verificationToken),
            new EmptyTransportResponseHandler(ThreadPool.Names.SAME) {
              @Override
              public void handleResponse(TransportResponse.Empty response) {
                if (counter.decrementAndGet() == 0) {
                  finishVerification(listener, nodes, errors);
                }
              }

              @Override
              public void handleException(TransportException exp) {
                errors.add(
                    new VerificationFailure(node.id(), ExceptionsHelper.detailedMessage(exp)));
                if (counter.decrementAndGet() == 0) {
                  finishVerification(listener, nodes, errors);
                }
              }
            });
      }
    }
  }
 private static ImmutableList<ShardRouting> collectAttributeShards(
     AttributesKey key, DiscoveryNodes nodes, ArrayList<ShardRouting> from) {
   final ArrayList<ShardRouting> to = new ArrayList<>();
   for (final String attribute : key.attributes) {
     final String localAttributeValue = nodes.localNode().attributes().get(attribute);
     if (localAttributeValue != null) {
       for (Iterator<ShardRouting> iterator = from.iterator(); iterator.hasNext(); ) {
         ShardRouting fromShard = iterator.next();
         final DiscoveryNode discoveryNode = nodes.get(fromShard.currentNodeId());
         if (discoveryNode == null) {
           iterator.remove(); // node is not present anymore - ignore shard
         } else if (localAttributeValue.equals(discoveryNode.attributes().get(attribute))) {
           iterator.remove();
           to.add(fromShard);
         }
       }
     }
   }
   return ImmutableList.copyOf(to);
 }