static void checkRemoteWhitelist(CharacterRunAutomaton whitelist, RemoteInfo remoteInfo) {
   if (remoteInfo == null) {
     return;
   }
   String check = remoteInfo.getHost() + ':' + remoteInfo.getPort();
   if (whitelist.run(check)) {
     return;
   }
   throw new IllegalArgumentException(
       '[' + check + "] not whitelisted in " + REMOTE_CLUSTER_WHITELIST.getKey());
 }
 @Override
 protected ScrollableHitSource buildScrollableResultSource(BackoffPolicy backoffPolicy) {
   if (mainRequest.getRemoteInfo() != null) {
     RemoteInfo remoteInfo = mainRequest.getRemoteInfo();
     createdThreads = synchronizedList(new ArrayList<>());
     RestClient restClient = buildRestClient(remoteInfo, task.getId(), createdThreads);
     return new RemoteScrollableHitSource(
         logger,
         backoffPolicy,
         threadPool,
         task::countSearchRetry,
         this::finishHim,
         restClient,
         remoteInfo.getQuery(),
         mainRequest.getSearchRequest());
   }
   return super.buildScrollableResultSource(backoffPolicy);
 }
 /**
  * Build the {@link RestClient} used for reindexing from remote clusters.
  *
  * @param remoteInfo connection information for the remote cluster
  * @param taskId the id of the current task. This is added to the thread name for easier tracking
  * @param threadCollector a list in which we collect all the threads created by the client
  */
 static RestClient buildRestClient(
     RemoteInfo remoteInfo, long taskId, List<Thread> threadCollector) {
   Header[] clientHeaders = new Header[remoteInfo.getHeaders().size()];
   int i = 0;
   for (Map.Entry<String, String> header : remoteInfo.getHeaders().entrySet()) {
     clientHeaders[i] = new BasicHeader(header.getKey(), header.getValue());
   }
   return RestClient.builder(
           new HttpHost(remoteInfo.getHost(), remoteInfo.getPort(), remoteInfo.getScheme()))
       .setDefaultHeaders(clientHeaders)
       .setHttpClientConfigCallback(
           c -> {
             // Enable basic auth if it is configured
             if (remoteInfo.getUsername() != null) {
               UsernamePasswordCredentials creds =
                   new UsernamePasswordCredentials(
                       remoteInfo.getUsername(), remoteInfo.getPassword());
               CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
               credentialsProvider.setCredentials(AuthScope.ANY, creds);
               c.setDefaultCredentialsProvider(credentialsProvider);
             }
             // Stick the task id in the thread name so we can track down tasks from stack traces
             AtomicInteger threads = new AtomicInteger();
             c.setThreadFactory(
                 r -> {
                   String name = "es-client-" + taskId + "-" + threads.getAndIncrement();
                   Thread t = new Thread(r, name);
                   threadCollector.add(t);
                   return t;
                 });
             // Limit ourselves to one reactor thread because for now the search process is single
             // threaded.
             c.setDefaultIOReactorConfig(IOReactorConfig.custom().setIoThreadCount(1).build());
             return c;
           })
       .build();
 }