Пример #1
0
  public void testForce() throws Exception {
    createIndex("test");
    ensureGreen(
        "test"); // we are testing force here which doesn't work if we are recovering at the same
    // time - zzzzz...
    IndexResponse indexResponse =
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_1")
            .setVersion(12)
            .setVersionType(VersionType.FORCE)
            .get();
    assertThat(indexResponse.getVersion(), equalTo(12L));

    indexResponse =
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_2")
            .setVersion(12)
            .setVersionType(VersionType.FORCE)
            .get();
    assertThat(indexResponse.getVersion(), equalTo(12L));

    indexResponse =
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_2")
            .setVersion(14)
            .setVersionType(VersionType.FORCE)
            .get();
    assertThat(indexResponse.getVersion(), equalTo(14L));

    indexResponse =
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_1")
            .setVersion(13)
            .setVersionType(VersionType.FORCE)
            .get();
    assertThat(indexResponse.getVersion(), equalTo(13L));

    client().admin().indices().prepareRefresh().execute().actionGet();
    if (randomBoolean()) {
      refresh();
    }
    for (int i = 0; i < 10; i++) {
      assertThat(client().prepareGet("test", "type", "1").get().getVersion(), equalTo(13L));
    }

    // deleting with a lower version works.
    long v = randomIntBetween(12, 14);
    DeleteResponse deleteResponse =
        client()
            .prepareDelete("test", "type", "1")
            .setVersion(v)
            .setVersionType(VersionType.FORCE)
            .get();
    assertEquals(DocWriteResponse.Operation.DELETE, deleteResponse.getOperation());
    assertThat(deleteResponse.getVersion(), equalTo(v));
  }
Пример #2
0
    @Override
    public String toString() {
      StringBuilder sb = new StringBuilder();
      sb.append("id=");
      sb.append(id);
      sb.append(" version=");
      sb.append(version);
      sb.append(" delete?=");
      sb.append(delete);
      sb.append(" threadID=");
      sb.append(threadID);
      sb.append(" indexStartTime=");
      sb.append(indexStartTime);
      sb.append(" indexFinishTime=");
      sb.append(indexFinishTime);
      sb.append(" versionConflict=");
      sb.append(versionConflict);
      sb.append(" alreadyExists?=");
      sb.append(alreadyExists);

      if (response != null) {
        if (response instanceof DeleteResponse) {
          DeleteResponse deleteResponse = (DeleteResponse) response;
          sb.append(" response:");
          sb.append(" index=");
          sb.append(deleteResponse.getIndex());
          sb.append(" id=");
          sb.append(deleteResponse.getId());
          sb.append(" type=");
          sb.append(deleteResponse.getType());
          sb.append(" version=");
          sb.append(deleteResponse.getVersion());
          sb.append(" found=");
          sb.append(deleteResponse.getOperation() == DocWriteResponse.Operation.DELETE);
        } else if (response instanceof IndexResponse) {
          IndexResponse indexResponse = (IndexResponse) response;
          sb.append(" index=");
          sb.append(indexResponse.getIndex());
          sb.append(" id=");
          sb.append(indexResponse.getId());
          sb.append(" type=");
          sb.append(indexResponse.getType());
          sb.append(" version=");
          sb.append(indexResponse.getVersion());
          sb.append(" created=");
          sb.append(indexResponse.getOperation() == DocWriteResponse.Operation.CREATE);
        } else {
          sb.append("  response: " + response);
        }
      } else {
        sb.append("  response: null");
      }

      return sb.toString();
    }
Пример #3
0
  public void testVersioningWithBulk() {
    createIndex("test");
    ensureGreen();

    BulkResponse bulkResponse =
        client()
            .prepareBulk()
            .add(client().prepareIndex("test", "type", "1").setSource("field1", "value1_1"))
            .execute()
            .actionGet();
    assertThat(bulkResponse.hasFailures(), equalTo(false));
    assertThat(bulkResponse.getItems().length, equalTo(1));
    IndexResponse indexResponse = bulkResponse.getItems()[0].getResponse();
    assertThat(indexResponse.getVersion(), equalTo(1L));
  }
Пример #4
0
  public void testInternalVersioningInitialDelete() throws Exception {
    createIndex("test");
    ensureGreen();

    assertThrows(
        client().prepareDelete("test", "type", "1").setVersion(17).execute(),
        VersionConflictEngineException.class);

    IndexResponse indexResponse =
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_1")
            .setCreate(true)
            .execute()
            .actionGet();
    assertThat(indexResponse.getVersion(), equalTo(1L));
  }
Пример #5
0
  public void testExternalVersioningInitialDelete() throws Exception {
    createIndex("test");
    ensureGreen();

    // Note - external version doesn't throw version conflicts on deletes of non existent records.
    // This is different from internal versioning

    DeleteResponse deleteResponse =
        client()
            .prepareDelete("test", "type", "1")
            .setVersion(17)
            .setVersionType(VersionType.EXTERNAL)
            .execute()
            .actionGet();
    assertEquals(DocWriteResponse.Operation.NOOP, deleteResponse.getOperation());

    // this should conflict with the delete command transaction which told us that the object was
    // deleted at version 17.
    assertThrows(
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_1")
            .setVersion(13)
            .setVersionType(VersionType.EXTERNAL)
            .execute(),
        VersionConflictEngineException.class);

    IndexResponse indexResponse =
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_1")
            .setVersion(18)
            .setVersionType(VersionType.EXTERNAL)
            .execute()
            .actionGet();
    assertThat(indexResponse.getVersion(), equalTo(18L));
  }
  @Test
  public void testIndex() {

    IndexResponse response = null;

    try {
      response =
          client
              .prepareIndex("asdf2014", "asdf", "1")
              .setSource(
                  jsonBuilder().startObject().field("age", 22).field("sex", "male").endObject())
              .execute()
              .actionGet();
    } catch (ElasticsearchException | IOException e) {
      e.printStackTrace();
      throw new RuntimeException(e);
    }

    System.out.println("Index: " + response.getIndex());
    System.out.println("Type: " + response.getType());
    System.out.println("Id: " + response.getId());
    System.err.println("Version: " + response.getVersion());
    System.out.println("IsCreated: " + response.isCreated());
  }
Пример #7
0
  public void testSimpleVersioningWithFlush() throws Exception {
    createIndex("test");
    ensureGreen();

    IndexResponse indexResponse =
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_1")
            .execute()
            .actionGet();
    assertThat(indexResponse.getVersion(), equalTo(1L));

    client().admin().indices().prepareFlush().execute().actionGet();

    indexResponse =
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_2")
            .setVersion(1)
            .execute()
            .actionGet();
    assertThat(indexResponse.getVersion(), equalTo(2L));

    client().admin().indices().prepareFlush().execute().actionGet();

    assertThrows(
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_1")
            .setVersion(1)
            .execute(),
        VersionConflictEngineException.class);

    assertThrows(
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_1")
            .setVersion(1)
            .execute(),
        VersionConflictEngineException.class);

    assertThrows(
        client()
            .prepareIndex("test", "type", "1")
            .setCreate(true)
            .setSource("field1", "value1_1")
            .execute(),
        VersionConflictEngineException.class);

    assertThrows(
        client().prepareDelete("test", "type", "1").setVersion(1).execute(),
        VersionConflictEngineException.class);
    assertThrows(
        client().prepareDelete("test", "type", "1").setVersion(1).execute(),
        VersionConflictEngineException.class);

    client().admin().indices().prepareRefresh().execute().actionGet();
    for (int i = 0; i < 10; i++) {
      assertThat(
          client().prepareGet("test", "type", "1").execute().actionGet().getVersion(), equalTo(2L));
    }

    for (int i = 0; i < 10; i++) {
      SearchResponse searchResponse =
          client().prepareSearch().setQuery(matchAllQuery()).setVersion(true).execute().actionGet();
      assertThat(searchResponse.getHits().getAt(0).version(), equalTo(2L));
    }
  }
Пример #8
0
  public void testInternalVersioning() throws Exception {
    createIndex("test");
    ensureGreen();

    IndexResponse indexResponse =
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_1")
            .execute()
            .actionGet();
    assertThat(indexResponse.getVersion(), equalTo(1L));

    indexResponse =
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_2")
            .setVersion(1)
            .execute()
            .actionGet();
    assertThat(indexResponse.getVersion(), equalTo(2L));

    assertThrows(
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_1")
            .setVersion(1)
            .execute(),
        VersionConflictEngineException.class);

    assertThrows(
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_1")
            .setVersion(1)
            .execute(),
        VersionConflictEngineException.class);

    assertThrows(
        client()
            .prepareIndex("test", "type", "1")
            .setCreate(true)
            .setSource("field1", "value1_1")
            .execute(),
        VersionConflictEngineException.class);

    assertThrows(
        client().prepareDelete("test", "type", "1").setVersion(1).execute(),
        VersionConflictEngineException.class);
    assertThrows(
        client().prepareDelete("test", "type", "1").setVersion(1).execute(),
        VersionConflictEngineException.class);

    client().admin().indices().prepareRefresh().execute().actionGet();
    for (int i = 0; i < 10; i++) {
      assertThat(
          client().prepareGet("test", "type", "1").execute().actionGet().getVersion(), equalTo(2L));
    }

    // search with versioning
    for (int i = 0; i < 10; i++) {
      SearchResponse searchResponse =
          client().prepareSearch().setQuery(matchAllQuery()).setVersion(true).execute().actionGet();
      assertThat(searchResponse.getHits().getAt(0).version(), equalTo(2L));
    }

    // search without versioning
    for (int i = 0; i < 10; i++) {
      SearchResponse searchResponse =
          client().prepareSearch().setQuery(matchAllQuery()).execute().actionGet();
      assertThat(searchResponse.getHits().getAt(0).version(), equalTo(Versions.NOT_FOUND));
    }

    DeleteResponse deleteResponse =
        client().prepareDelete("test", "type", "1").setVersion(2).execute().actionGet();
    assertEquals(DocWriteResponse.Operation.DELETE, deleteResponse.getOperation());
    assertThat(deleteResponse.getVersion(), equalTo(3L));

    assertThrows(
        client().prepareDelete("test", "type", "1").setVersion(2).execute(),
        VersionConflictEngineException.class);

    // This is intricate - the object was deleted but a delete transaction was with the right
    // version. We add another one
    // and thus the transaction is increased.
    deleteResponse =
        client().prepareDelete("test", "type", "1").setVersion(3).execute().actionGet();
    assertEquals(DocWriteResponse.Operation.NOOP, deleteResponse.getOperation());
    assertThat(deleteResponse.getVersion(), equalTo(4L));
  }
Пример #9
0
  public void testExternalVersioning() throws Exception {
    createIndex("test");
    ensureGreen();

    IndexResponse indexResponse =
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_1")
            .setVersion(12)
            .setVersionType(VersionType.EXTERNAL)
            .execute()
            .actionGet();
    assertThat(indexResponse.getVersion(), equalTo(12L));

    indexResponse =
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_1")
            .setVersion(14)
            .setVersionType(VersionType.EXTERNAL)
            .execute()
            .actionGet();
    assertThat(indexResponse.getVersion(), equalTo(14L));

    assertThrows(
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_1")
            .setVersion(13)
            .setVersionType(VersionType.EXTERNAL)
            .execute(),
        VersionConflictEngineException.class);

    if (randomBoolean()) {
      refresh();
    }
    for (int i = 0; i < 10; i++) {
      assertThat(
          client().prepareGet("test", "type", "1").execute().actionGet().getVersion(),
          equalTo(14L));
    }

    // deleting with a lower version fails.
    assertThrows(
        client()
            .prepareDelete("test", "type", "1")
            .setVersion(2)
            .setVersionType(VersionType.EXTERNAL)
            .execute(),
        VersionConflictEngineException.class);

    // Delete with a higher version deletes all versions up to the given one.
    DeleteResponse deleteResponse =
        client()
            .prepareDelete("test", "type", "1")
            .setVersion(17)
            .setVersionType(VersionType.EXTERNAL)
            .execute()
            .actionGet();
    assertEquals(DocWriteResponse.Operation.DELETE, deleteResponse.getOperation());
    assertThat(deleteResponse.getVersion(), equalTo(17L));

    // Deleting with a lower version keeps on failing after a delete.
    assertThrows(
        client()
            .prepareDelete("test", "type", "1")
            .setVersion(2)
            .setVersionType(VersionType.EXTERNAL)
            .execute(),
        VersionConflictEngineException.class);

    // But delete with a higher version is OK.
    deleteResponse =
        client()
            .prepareDelete("test", "type", "1")
            .setVersion(18)
            .setVersionType(VersionType.EXTERNAL)
            .execute()
            .actionGet();
    assertEquals(DocWriteResponse.Operation.NOOP, deleteResponse.getOperation());
    assertThat(deleteResponse.getVersion(), equalTo(18L));

    // TODO: This behavior breaks rest api returning http status 201, good news is that it this is
    // only the case until deletes GC kicks in.
    indexResponse =
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_1")
            .setVersion(19)
            .setVersionType(VersionType.EXTERNAL)
            .execute()
            .actionGet();
    assertThat(indexResponse.getVersion(), equalTo(19L));

    deleteResponse =
        client()
            .prepareDelete("test", "type", "1")
            .setVersion(20)
            .setVersionType(VersionType.EXTERNAL)
            .execute()
            .actionGet();
    assertEquals(DocWriteResponse.Operation.DELETE, deleteResponse.getOperation());
    assertThat(deleteResponse.getVersion(), equalTo(20L));

    // Make sure that the next delete will be GC. Note we do it on the index settings so it will be
    // cleaned up
    HashMap<String, Object> newSettings = new HashMap<>();
    newSettings.put("index.gc_deletes", -1);
    client()
        .admin()
        .indices()
        .prepareUpdateSettings("test")
        .setSettings(newSettings)
        .execute()
        .actionGet();

    Thread.sleep(300); // gc works based on estimated sampled time. Give it a chance...

    // And now we have previous version return -1
    indexResponse =
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_1")
            .setVersion(20)
            .setVersionType(VersionType.EXTERNAL)
            .execute()
            .actionGet();
    assertThat(indexResponse.getVersion(), equalTo(20L));
  }
Пример #10
0
  public void testExternalGTE() throws Exception {
    createIndex("test");

    IndexResponse indexResponse =
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_1")
            .setVersion(12)
            .setVersionType(VersionType.EXTERNAL_GTE)
            .get();
    assertThat(indexResponse.getVersion(), equalTo(12L));

    indexResponse =
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_2")
            .setVersion(12)
            .setVersionType(VersionType.EXTERNAL_GTE)
            .get();
    assertThat(indexResponse.getVersion(), equalTo(12L));

    indexResponse =
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_2")
            .setVersion(14)
            .setVersionType(VersionType.EXTERNAL_GTE)
            .get();
    assertThat(indexResponse.getVersion(), equalTo(14L));

    assertThrows(
        client()
            .prepareIndex("test", "type", "1")
            .setSource("field1", "value1_1")
            .setVersion(13)
            .setVersionType(VersionType.EXTERNAL_GTE),
        VersionConflictEngineException.class);

    client().admin().indices().prepareRefresh().execute().actionGet();
    if (randomBoolean()) {
      refresh();
    }
    for (int i = 0; i < 10; i++) {
      assertThat(client().prepareGet("test", "type", "1").get().getVersion(), equalTo(14L));
    }

    // deleting with a lower version fails.
    assertThrows(
        client()
            .prepareDelete("test", "type", "1")
            .setVersion(2)
            .setVersionType(VersionType.EXTERNAL_GTE),
        VersionConflictEngineException.class);

    // Delete with a higher or equal version deletes all versions up to the given one.
    long v = randomIntBetween(14, 17);
    DeleteResponse deleteResponse =
        client()
            .prepareDelete("test", "type", "1")
            .setVersion(v)
            .setVersionType(VersionType.EXTERNAL_GTE)
            .execute()
            .actionGet();
    assertEquals(DocWriteResponse.Operation.DELETE, deleteResponse.getOperation());
    assertThat(deleteResponse.getVersion(), equalTo(v));

    // Deleting with a lower version keeps on failing after a delete.
    assertThrows(
        client()
            .prepareDelete("test", "type", "1")
            .setVersion(2)
            .setVersionType(VersionType.EXTERNAL_GTE)
            .execute(),
        VersionConflictEngineException.class);

    // But delete with a higher version is OK.
    deleteResponse =
        client()
            .prepareDelete("test", "type", "1")
            .setVersion(18)
            .setVersionType(VersionType.EXTERNAL_GTE)
            .execute()
            .actionGet();
    assertEquals(DocWriteResponse.Operation.NOOP, deleteResponse.getOperation());
    assertThat(deleteResponse.getVersion(), equalTo(18L));
  }
  @Override
  protected Tuple<BulkShardResponse, BulkShardRequest> shardOperationOnPrimary(
      ClusterState clusterState, PrimaryOperationRequest shardRequest) {
    final BulkShardRequest request = shardRequest.request;
    final IndexService indexService = indicesService.indexServiceSafe(request.index());
    final IndexShard indexShard = indexService.shardSafe(shardRequest.shardId.id());

    long[] preVersions = new long[request.items().length];
    VersionType[] preVersionTypes = new VersionType[request.items().length];
    Translog.Location location = null;
    for (int requestIndex = 0; requestIndex < request.items().length; requestIndex++) {
      BulkItemRequest item = request.items()[requestIndex];
      if (item.request() instanceof IndexRequest) {
        IndexRequest indexRequest = (IndexRequest) item.request();
        preVersions[requestIndex] = indexRequest.version();
        preVersionTypes[requestIndex] = indexRequest.versionType();
        try {
          WriteResult<IndexResponse> result =
              shardIndexOperation(request, indexRequest, clusterState, indexShard, true);
          location = locationToSync(location, result.location);
          // add the response
          IndexResponse indexResponse = result.response();
          setResponse(
              item,
              new BulkItemResponse(item.id(), indexRequest.opType().lowercase(), indexResponse));
        } catch (Throwable e) {
          // rethrow the failure if we are going to retry on primary and let parent failure to
          // handle it
          if (retryPrimaryException(e)) {
            // restore updated versions...
            for (int j = 0; j < requestIndex; j++) {
              applyVersion(request.items()[j], preVersions[j], preVersionTypes[j]);
            }
            throw (ElasticsearchException) e;
          }
          if (ExceptionsHelper.status(e) == RestStatus.CONFLICT) {
            logger.trace(
                "{} failed to execute bulk item (index) {}", e, shardRequest.shardId, indexRequest);
          } else {
            logger.debug(
                "{} failed to execute bulk item (index) {}", e, shardRequest.shardId, indexRequest);
          }
          // if its a conflict failure, and we already executed the request on a primary (and we
          // execute it
          // again, due to primary relocation and only processing up to N bulk items when the shard
          // gets closed)
          // then just use the response we got from the successful execution
          if (item.getPrimaryResponse() != null && isConflictException(e)) {
            setResponse(item, item.getPrimaryResponse());
          } else {
            setResponse(
                item,
                new BulkItemResponse(
                    item.id(),
                    indexRequest.opType().lowercase(),
                    new BulkItemResponse.Failure(
                        request.index(), indexRequest.type(), indexRequest.id(), e)));
          }
        }
      } else if (item.request() instanceof DeleteRequest) {
        DeleteRequest deleteRequest = (DeleteRequest) item.request();
        preVersions[requestIndex] = deleteRequest.version();
        preVersionTypes[requestIndex] = deleteRequest.versionType();

        try {
          // add the response
          final WriteResult<DeleteResponse> writeResult =
              shardDeleteOperation(request, deleteRequest, indexShard);
          DeleteResponse deleteResponse = writeResult.response();
          location = locationToSync(location, writeResult.location);
          setResponse(item, new BulkItemResponse(item.id(), OP_TYPE_DELETE, deleteResponse));
        } catch (Throwable e) {
          // rethrow the failure if we are going to retry on primary and let parent failure to
          // handle it
          if (retryPrimaryException(e)) {
            // restore updated versions...
            for (int j = 0; j < requestIndex; j++) {
              applyVersion(request.items()[j], preVersions[j], preVersionTypes[j]);
            }
            throw (ElasticsearchException) e;
          }
          if (ExceptionsHelper.status(e) == RestStatus.CONFLICT) {
            logger.trace(
                "{} failed to execute bulk item (delete) {}",
                e,
                shardRequest.shardId,
                deleteRequest);
          } else {
            logger.debug(
                "{} failed to execute bulk item (delete) {}",
                e,
                shardRequest.shardId,
                deleteRequest);
          }
          // if its a conflict failure, and we already executed the request on a primary (and we
          // execute it
          // again, due to primary relocation and only processing up to N bulk items when the shard
          // gets closed)
          // then just use the response we got from the successful execution
          if (item.getPrimaryResponse() != null && isConflictException(e)) {
            setResponse(item, item.getPrimaryResponse());
          } else {
            setResponse(
                item,
                new BulkItemResponse(
                    item.id(),
                    OP_TYPE_DELETE,
                    new BulkItemResponse.Failure(
                        request.index(), deleteRequest.type(), deleteRequest.id(), e)));
          }
        }
      } else if (item.request() instanceof UpdateRequest) {
        UpdateRequest updateRequest = (UpdateRequest) item.request();
        preVersions[requestIndex] = updateRequest.version();
        preVersionTypes[requestIndex] = updateRequest.versionType();
        //  We need to do the requested retries plus the initial attempt. We don't do <
        // 1+retry_on_conflict because retry_on_conflict may be Integer.MAX_VALUE
        for (int updateAttemptsCount = 0;
            updateAttemptsCount <= updateRequest.retryOnConflict();
            updateAttemptsCount++) {
          UpdateResult updateResult;
          try {
            updateResult = shardUpdateOperation(clusterState, request, updateRequest, indexShard);
          } catch (Throwable t) {
            updateResult = new UpdateResult(null, null, false, t, null);
          }
          if (updateResult.success()) {
            if (updateResult.writeResult != null) {
              location = locationToSync(location, updateResult.writeResult.location);
            }
            switch (updateResult.result.operation()) {
              case UPSERT:
              case INDEX:
                WriteResult<IndexResponse> result = updateResult.writeResult;
                IndexRequest indexRequest = updateResult.request();
                BytesReference indexSourceAsBytes = indexRequest.source();
                // add the response
                IndexResponse indexResponse = result.response();
                UpdateResponse updateResponse =
                    new UpdateResponse(
                        indexResponse.getShardInfo(),
                        indexResponse.getIndex(),
                        indexResponse.getType(),
                        indexResponse.getId(),
                        indexResponse.getVersion(),
                        indexResponse.isCreated());
                if (updateRequest.fields() != null && updateRequest.fields().length > 0) {
                  Tuple<XContentType, Map<String, Object>> sourceAndContent =
                      XContentHelper.convertToMap(indexSourceAsBytes, true);
                  updateResponse.setGetResult(
                      updateHelper.extractGetResult(
                          updateRequest,
                          shardRequest.request.index(),
                          indexResponse.getVersion(),
                          sourceAndContent.v2(),
                          sourceAndContent.v1(),
                          indexSourceAsBytes));
                }
                item =
                    request.items()[requestIndex] =
                        new BulkItemRequest(request.items()[requestIndex].id(), indexRequest);
                setResponse(item, new BulkItemResponse(item.id(), OP_TYPE_UPDATE, updateResponse));
                break;
              case DELETE:
                WriteResult<DeleteResponse> writeResult = updateResult.writeResult;
                DeleteResponse response = writeResult.response();
                DeleteRequest deleteRequest = updateResult.request();
                updateResponse =
                    new UpdateResponse(
                        response.getShardInfo(),
                        response.getIndex(),
                        response.getType(),
                        response.getId(),
                        response.getVersion(),
                        false);
                updateResponse.setGetResult(
                    updateHelper.extractGetResult(
                        updateRequest,
                        shardRequest.request.index(),
                        response.getVersion(),
                        updateResult.result.updatedSourceAsMap(),
                        updateResult.result.updateSourceContentType(),
                        null));
                // Replace the update request to the translated delete request to execute on the
                // replica.
                item =
                    request.items()[requestIndex] =
                        new BulkItemRequest(request.items()[requestIndex].id(), deleteRequest);
                setResponse(item, new BulkItemResponse(item.id(), OP_TYPE_UPDATE, updateResponse));
                break;
              case NONE:
                setResponse(
                    item, new BulkItemResponse(item.id(), OP_TYPE_UPDATE, updateResult.noopResult));
                item.setIgnoreOnReplica(); // no need to go to the replica
                break;
            }
            // NOTE: Breaking out of the retry_on_conflict loop!
            break;
          } else if (updateResult.failure()) {
            Throwable t = updateResult.error;
            if (updateResult.retry) {
              // updateAttemptCount is 0 based and marks current attempt, if it's equal to
              // retryOnConflict we are going out of the iteration
              if (updateAttemptsCount >= updateRequest.retryOnConflict()) {
                setResponse(
                    item,
                    new BulkItemResponse(
                        item.id(),
                        OP_TYPE_UPDATE,
                        new BulkItemResponse.Failure(
                            request.index(), updateRequest.type(), updateRequest.id(), t)));
              }
            } else {
              // rethrow the failure if we are going to retry on primary and let parent failure to
              // handle it
              if (retryPrimaryException(t)) {
                // restore updated versions...
                for (int j = 0; j < requestIndex; j++) {
                  applyVersion(request.items()[j], preVersions[j], preVersionTypes[j]);
                }
                throw (ElasticsearchException) t;
              }
              // if its a conflict failure, and we already executed the request on a primary (and we
              // execute it
              // again, due to primary relocation and only processing up to N bulk items when the
              // shard gets closed)
              // then just use the response we got from the successful execution
              if (item.getPrimaryResponse() != null && isConflictException(t)) {
                setResponse(item, item.getPrimaryResponse());
              } else if (updateResult.result == null) {
                setResponse(
                    item,
                    new BulkItemResponse(
                        item.id(),
                        OP_TYPE_UPDATE,
                        new BulkItemResponse.Failure(
                            shardRequest.request.index(),
                            updateRequest.type(),
                            updateRequest.id(),
                            t)));
              } else {
                switch (updateResult.result.operation()) {
                  case UPSERT:
                  case INDEX:
                    IndexRequest indexRequest = updateResult.request();
                    if (ExceptionsHelper.status(t) == RestStatus.CONFLICT) {
                      logger.trace(
                          "{} failed to execute bulk item (index) {}",
                          t,
                          shardRequest.shardId,
                          indexRequest);
                    } else {
                      logger.debug(
                          "{} failed to execute bulk item (index) {}",
                          t,
                          shardRequest.shardId,
                          indexRequest);
                    }
                    setResponse(
                        item,
                        new BulkItemResponse(
                            item.id(),
                            OP_TYPE_UPDATE,
                            new BulkItemResponse.Failure(
                                request.index(), indexRequest.type(), indexRequest.id(), t)));
                    break;
                  case DELETE:
                    DeleteRequest deleteRequest = updateResult.request();
                    if (ExceptionsHelper.status(t) == RestStatus.CONFLICT) {
                      logger.trace(
                          "{} failed to execute bulk item (delete) {}",
                          t,
                          shardRequest.shardId,
                          deleteRequest);
                    } else {
                      logger.debug(
                          "{} failed to execute bulk item (delete) {}",
                          t,
                          shardRequest.shardId,
                          deleteRequest);
                    }
                    setResponse(
                        item,
                        new BulkItemResponse(
                            item.id(),
                            OP_TYPE_DELETE,
                            new BulkItemResponse.Failure(
                                request.index(), deleteRequest.type(), deleteRequest.id(), t)));
                    break;
                }
              }
              // NOTE: Breaking out of the retry_on_conflict loop!
              break;
            }
          }
        }
      } else {
        throw new IllegalStateException("Unexpected index operation: " + item.request());
      }

      assert item.getPrimaryResponse() != null;
      assert preVersionTypes[requestIndex] != null;
    }

    processAfter(request.refresh(), indexShard, location);
    BulkItemResponse[] responses = new BulkItemResponse[request.items().length];
    BulkItemRequest[] items = request.items();
    for (int i = 0; i < items.length; i++) {
      responses[i] = items[i].getPrimaryResponse();
    }
    return new Tuple<>(
        new BulkShardResponse(shardRequest.shardId, responses), shardRequest.request);
  }