private boolean addFailureIfIndexIsUnavailable(
     DocumentRequest request,
     BulkRequest bulkRequest,
     AtomicArray<BulkItemResponse> responses,
     int idx,
     final ConcreteIndices concreteIndices,
     final MetaData metaData) {
   String concreteIndex = concreteIndices.getConcreteIndex(request.index());
   Exception unavailableException = null;
   if (concreteIndex == null) {
     try {
       concreteIndex = concreteIndices.resolveIfAbsent(request);
     } catch (IndexClosedException | IndexNotFoundException ex) {
       // Fix for issue where bulk request references an index that
       // cannot be auto-created see issue #8125
       unavailableException = ex;
     }
   }
   if (unavailableException == null) {
     IndexMetaData indexMetaData = metaData.index(concreteIndex);
     if (indexMetaData.getState() == IndexMetaData.State.CLOSE) {
       unavailableException = new IndexClosedException(metaData.index(request.index()).getIndex());
     }
   }
   if (unavailableException != null) {
     BulkItemResponse.Failure failure =
         new BulkItemResponse.Failure(
             request.index(), request.type(), request.id(), unavailableException);
     String operationType = "unknown";
     if (request instanceof IndexRequest) {
       operationType = "index";
     } else if (request instanceof DeleteRequest) {
       operationType = "delete";
     } else if (request instanceof UpdateRequest) {
       operationType = "update";
     }
     BulkItemResponse bulkItemResponse = new BulkItemResponse(idx, operationType, failure);
     responses.set(idx, bulkItemResponse);
     // make sure the request gets never processed again
     bulkRequest.requests.set(idx, null);
     return true;
   }
   return false;
 }
  @Override
  protected void doExecute(
      final BulkRequest bulkRequest, final ActionListener<BulkResponse> listener) {
    final long startTime = System.currentTimeMillis();
    final AtomicArray<BulkItemResponse> responses = new AtomicArray<>(bulkRequest.requests.size());

    if (autoCreateIndex.needToCheck()) {
      // Keep track of all unique indices and all unique types per index for the create index
      // requests:
      final Map<String, Set<String>> indicesAndTypes = new HashMap<>();
      for (ActionRequest request : bulkRequest.requests) {
        if (request instanceof DocumentRequest) {
          DocumentRequest req = (DocumentRequest) request;
          Set<String> types = indicesAndTypes.get(req.index());
          if (types == null) {
            indicesAndTypes.put(req.index(), types = new HashSet<>());
          }
          types.add(req.type());
        } else {
          throw new ElasticsearchException(
              "Parsed unknown request in bulk actions: " + request.getClass().getSimpleName());
        }
      }
      final AtomicInteger counter = new AtomicInteger(indicesAndTypes.size());
      ClusterState state = clusterService.state();
      for (Map.Entry<String, Set<String>> entry : indicesAndTypes.entrySet()) {
        final String index = entry.getKey();
        if (autoCreateIndex.shouldAutoCreate(index, state)) {
          CreateIndexRequest createIndexRequest = new CreateIndexRequest();
          createIndexRequest.index(index);
          for (String type : entry.getValue()) {
            createIndexRequest.mapping(type);
          }
          createIndexRequest.cause("auto(bulk api)");
          createIndexRequest.masterNodeTimeout(bulkRequest.timeout());
          createIndexAction.execute(
              createIndexRequest,
              new ActionListener<CreateIndexResponse>() {
                @Override
                public void onResponse(CreateIndexResponse result) {
                  if (counter.decrementAndGet() == 0) {
                    try {
                      executeBulk(bulkRequest, startTime, listener, responses);
                    } catch (Throwable t) {
                      listener.onFailure(t);
                    }
                  }
                }

                @Override
                public void onFailure(Throwable e) {
                  if (!(ExceptionsHelper.unwrapCause(e) instanceof IndexAlreadyExistsException)) {
                    // fail all requests involving this index, if create didnt work
                    for (int i = 0; i < bulkRequest.requests.size(); i++) {
                      ActionRequest request = bulkRequest.requests.get(i);
                      if (request != null
                          && setResponseFailureIfIndexMatches(responses, i, request, index, e)) {
                        bulkRequest.requests.set(i, null);
                      }
                    }
                  }
                  if (counter.decrementAndGet() == 0) {
                    try {
                      executeBulk(bulkRequest, startTime, listener, responses);
                    } catch (Throwable t) {
                      listener.onFailure(t);
                    }
                  }
                }
              });
        } else {
          if (counter.decrementAndGet() == 0) {
            executeBulk(bulkRequest, startTime, listener, responses);
          }
        }
      }
    } else {
      executeBulk(bulkRequest, startTime, listener, responses);
    }
  }