From d128188c28c1e1582b9f7eb2652520775d7cbfda Mon Sep 17 00:00:00 2001 From: Nhat Nguyen Date: Fri, 19 Jul 2019 10:57:14 -0400 Subject: [PATCH] Return seq_no and primary_term in noop update (#44603) With this change, we will return primary_term and seq_no of the current document if an update is detected as a noop. We already return the version; hence we should also return seq_no and primary_term. Relates #42497 --- .../noop/action/bulk/RestNoopBulkAction.java | 2 +- .../action/bulk/TransportNoopBulkAction.java | 2 +- docs/reference/docs/update.asciidoc | 2 + .../reindex/AsyncBulkByScrollActionTests.java | 4 +- .../rest-api-spec/test/update/16_noop.yml | 43 ++++++ .../action/DocWriteResponse.java | 8 +- .../action/bulk/TransportBulkAction.java | 4 +- .../action/update/UpdateHelper.java | 6 +- .../action/update/UpdateResponse.java | 9 +- .../bulk/TransportShardBulkActionTests.java | 8 +- .../action/update/UpdateResponseTests.java | 13 +- .../elasticsearch/update/UpdateNoopIT.java | 124 +++++++++--------- 12 files changed, 136 insertions(+), 89 deletions(-) create mode 100644 rest-api-spec/src/main/resources/rest-api-spec/test/update/16_noop.yml diff --git a/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/RestNoopBulkAction.java b/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/RestNoopBulkAction.java index 8805af367a8..a8317fec83a 100644 --- a/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/RestNoopBulkAction.java +++ b/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/RestNoopBulkAction.java @@ -87,7 +87,7 @@ public class RestNoopBulkAction extends BaseRestHandler { private static class BulkRestBuilderListener extends RestBuilderListener { private final BulkItemResponse ITEM_RESPONSE = new BulkItemResponse(1, DocWriteRequest.OpType.UPDATE, - new UpdateResponse(new ShardId("mock", "", 1), "mock_type", "1", 1L, DocWriteResponse.Result.CREATED)); + new UpdateResponse(new ShardId("mock", "", 1), "mock_type", "1", 0L, 1L, 1L, DocWriteResponse.Result.CREATED)); private final RestRequest request; diff --git a/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/TransportNoopBulkAction.java b/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/TransportNoopBulkAction.java index 6580d213548..e7f22e2f598 100644 --- a/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/TransportNoopBulkAction.java +++ b/client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/TransportNoopBulkAction.java @@ -34,7 +34,7 @@ import org.elasticsearch.transport.TransportService; public class TransportNoopBulkAction extends HandledTransportAction { private static final BulkItemResponse ITEM_RESPONSE = new BulkItemResponse(1, DocWriteRequest.OpType.UPDATE, - new UpdateResponse(new ShardId("mock", "", 1), "mock_type", "1", 1L, DocWriteResponse.Result.CREATED)); + new UpdateResponse(new ShardId("mock", "", 1), "mock_type", "1", 0L, 1L, 1L, DocWriteResponse.Result.CREATED)); @Inject public TransportNoopBulkAction(TransportService transportService, ActionFilters actionFilters) { diff --git a/docs/reference/docs/update.asciidoc b/docs/reference/docs/update.asciidoc index 6205dc65371..c0cc88bb4f5 100644 --- a/docs/reference/docs/update.asciidoc +++ b/docs/reference/docs/update.asciidoc @@ -194,6 +194,8 @@ the request was ignored. "_type": "_doc", "_id": "1", "_version": 7, + "_primary_term": 1, + "_seq_no": 6, "result": "noop" } -------------------------------------------------- diff --git a/modules/reindex/src/test/java/org/elasticsearch/index/reindex/AsyncBulkByScrollActionTests.java b/modules/reindex/src/test/java/org/elasticsearch/index/reindex/AsyncBulkByScrollActionTests.java index 938ff47d604..8ef6896f0ea 100644 --- a/modules/reindex/src/test/java/org/elasticsearch/index/reindex/AsyncBulkByScrollActionTests.java +++ b/modules/reindex/src/test/java/org/elasticsearch/index/reindex/AsyncBulkByScrollActionTests.java @@ -885,8 +885,8 @@ public class AsyncBulkByScrollActionTests extends ESTestCase { true); } else if (item instanceof UpdateRequest) { UpdateRequest update = (UpdateRequest) item; - response = new UpdateResponse(shardId, update.type(), update.id(), - randomIntBetween(0, Integer.MAX_VALUE), Result.CREATED); + response = new UpdateResponse(shardId, update.type(), update.id(), randomNonNegativeLong(), + randomIntBetween(1, Integer.MAX_VALUE), randomIntBetween(0, Integer.MAX_VALUE), Result.CREATED); } else if (item instanceof DeleteRequest) { DeleteRequest delete = (DeleteRequest) item; response = diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/update/16_noop.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/update/16_noop.yml new file mode 100644 index 00000000000..bfb56541fb7 --- /dev/null +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/update/16_noop.yml @@ -0,0 +1,43 @@ +--- +"Noop": + - skip: + version: " - 7.3.99" + reason: "Noop does not return seq_no and primary_term until 7.4.0" + - do: + index: + index: test_1 + type: test + id: 1 + body: { foo: bar } + + - match: { _seq_no: 0 } + - match: { _version: 1 } + - match: { _primary_term: 1 } + - match: { result: created } + + - do: + update: + index: test_1 + type: test + id: 1 + body: + doc: { foo: bar } + + - match: { _seq_no: 0 } + - match: { _version: 1 } + - match: { _primary_term: 1 } + - match: { result: noop } + + - do: + update: + index: test_1 + type: test + id: 1 + body: + doc: { foo: bar } + detect_noop: false + + - match: { _seq_no: 1 } + - match: { _primary_term: 1 } + - match: { _version: 2 } + - match: { result: updated } diff --git a/server/src/main/java/org/elasticsearch/action/DocWriteResponse.java b/server/src/main/java/org/elasticsearch/action/DocWriteResponse.java index 3a7a68e083b..129be6857af 100644 --- a/server/src/main/java/org/elasticsearch/action/DocWriteResponse.java +++ b/server/src/main/java/org/elasticsearch/action/DocWriteResponse.java @@ -376,8 +376,8 @@ public abstract class DocWriteResponse extends ReplicationResponse implements Wr protected Result result = null; protected boolean forcedRefresh; protected ShardInfo shardInfo = null; - protected Long seqNo = UNASSIGNED_SEQ_NO; - protected Long primaryTerm = UNASSIGNED_PRIMARY_TERM; + protected long seqNo = UNASSIGNED_SEQ_NO; + protected long primaryTerm = UNASSIGNED_PRIMARY_TERM; public ShardId getShardId() { return shardId; @@ -419,11 +419,11 @@ public abstract class DocWriteResponse extends ReplicationResponse implements Wr this.shardInfo = shardInfo; } - public void setSeqNo(Long seqNo) { + public void setSeqNo(long seqNo) { this.seqNo = seqNo; } - public void setPrimaryTerm(Long primaryTerm) { + public void setPrimaryTerm(long primaryTerm) { this.primaryTerm = primaryTerm; } diff --git a/server/src/main/java/org/elasticsearch/action/bulk/TransportBulkAction.java b/server/src/main/java/org/elasticsearch/action/bulk/TransportBulkAction.java index a156a5c3a1e..253db3f0565 100644 --- a/server/src/main/java/org/elasticsearch/action/bulk/TransportBulkAction.java +++ b/server/src/main/java/org/elasticsearch/action/bulk/TransportBulkAction.java @@ -62,6 +62,7 @@ import org.elasticsearch.index.Index; import org.elasticsearch.index.IndexNotFoundException; import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.VersionType; +import org.elasticsearch.index.seqno.SequenceNumbers; import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.indices.IndexClosedException; import org.elasticsearch.ingest.IngestService; @@ -685,7 +686,8 @@ public class TransportBulkAction extends HandledTransportAction updateRequest = new UpdateRequest("index", "type", "id"); - response = new UpdateResponse(shardId, "type", "id", 1, DocWriteResponse.Result.NOOP); + response = new UpdateResponse(shardId, "type", "id", 0, 1, 1, DocWriteResponse.Result.NOOP); request = new BulkItemRequest(0, updateRequest); request.setPrimaryResponse(new BulkItemResponse(0, DocWriteRequest.OpType.UPDATE, response)); @@ -481,8 +480,7 @@ public class TransportShardBulkActionTests extends IndexShardTestCase { .doc(Requests.INDEX_CONTENT_TYPE, "field", "value"); BulkItemRequest primaryRequest = new BulkItemRequest(0, writeRequest); - DocWriteResponse noopUpdateResponse = new UpdateResponse(shardId, "_doc", "id", 0, - DocWriteResponse.Result.NOOP); + DocWriteResponse noopUpdateResponse = new UpdateResponse(shardId, "_doc", "id", 0, 2, 1, DocWriteResponse.Result.NOOP); IndexShard shard = mock(IndexShard.class); @@ -514,7 +512,7 @@ public class TransportShardBulkActionTests extends IndexShardTestCase { equalTo(DocWriteResponse.Result.NOOP)); assertThat(bulkShardRequest.items().length, equalTo(1)); assertEquals(primaryRequest, bulkShardRequest.items()[0]); // check that bulk item was not mutated - assertThat(primaryResponse.getResponse().getSeqNo(), equalTo(SequenceNumbers.UNASSIGNED_SEQ_NO)); + assertThat(primaryResponse.getResponse().getSeqNo(), equalTo(0L)); } public void testUpdateRequestWithFailure() throws Exception { diff --git a/server/src/test/java/org/elasticsearch/action/update/UpdateResponseTests.java b/server/src/test/java/org/elasticsearch/action/update/UpdateResponseTests.java index babad027691..f904024e83f 100644 --- a/server/src/test/java/org/elasticsearch/action/update/UpdateResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/update/UpdateResponseTests.java @@ -32,6 +32,7 @@ import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.get.GetResult; import org.elasticsearch.index.get.GetResultTests; +import org.elasticsearch.index.seqno.SequenceNumbers; import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.RandomObjects; @@ -54,7 +55,7 @@ public class UpdateResponseTests extends ESTestCase { public void testToXContent() throws IOException { { - UpdateResponse updateResponse = new UpdateResponse(new ShardId("index", "index_uuid", 0), "type", "id", 0, NOT_FOUND); + UpdateResponse updateResponse = new UpdateResponse(new ShardId("index", "index_uuid", 0), "type", "id", -2, 0, 0, NOT_FOUND); String output = Strings.toString(updateResponse); assertEquals("{\"_index\":\"index\",\"_type\":\"type\",\"_id\":\"id\",\"_version\":0,\"result\":\"not_found\"," + "\"_shards\":{\"total\":0,\"successful\":0,\"failed\":0}}", output); @@ -162,21 +163,21 @@ public class UpdateResponseTests extends ESTestCase { // We also want small number values (randomNonNegativeLong() tend to generate high numbers) // in order to catch some conversion error that happen between int/long after parsing. - Long seqNo = randomFrom(randomNonNegativeLong(), (long) randomIntBetween(0, 10_000), null); - long primaryTerm = seqNo == null ? 0 : randomIntBetween(1, 16); + long seqNo = randomFrom(randomNonNegativeLong(), (long) randomIntBetween(0, 10_000), SequenceNumbers.UNASSIGNED_SEQ_NO); + long primaryTerm = seqNo == SequenceNumbers.UNASSIGNED_SEQ_NO ? SequenceNumbers.UNASSIGNED_PRIMARY_TERM : randomIntBetween(1, 16); ShardId actualShardId = new ShardId(index, indexUUid, shardId); ShardId expectedShardId = new ShardId(index, INDEX_UUID_NA_VALUE, -1); UpdateResponse actual, expected; - if (seqNo != null) { + if (seqNo != SequenceNumbers.UNASSIGNED_SEQ_NO) { Tuple shardInfos = RandomObjects.randomShardInfo(random()); actual = new UpdateResponse(shardInfos.v1(), actualShardId, type, id, seqNo, primaryTerm, version, result); expected = new UpdateResponse(shardInfos.v2(), expectedShardId, type, id, seqNo, primaryTerm, version, result); } else { - actual = new UpdateResponse(actualShardId, type, id, version, result); - expected = new UpdateResponse(expectedShardId, type, id, version, result); + actual = new UpdateResponse(actualShardId, type, id, seqNo, primaryTerm, version, result); + expected = new UpdateResponse(expectedShardId, type, id, seqNo, primaryTerm, version, result); } if (actualGetResult.isExists()) { diff --git a/server/src/test/java/org/elasticsearch/update/UpdateNoopIT.java b/server/src/test/java/org/elasticsearch/update/UpdateNoopIT.java index 2cb71d9bcbe..12201eca1a5 100644 --- a/server/src/test/java/org/elasticsearch/update/UpdateNoopIT.java +++ b/server/src/test/java/org/elasticsearch/update/UpdateNoopIT.java @@ -29,6 +29,7 @@ import org.junit.Before; import java.io.IOException; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.notNullValue; /** @@ -36,16 +37,16 @@ import static org.hamcrest.Matchers.notNullValue; */ public class UpdateNoopIT extends ESIntegTestCase { public void testSingleField() throws Exception { - updateAndCheckSource(1, fields("bar", "baz")); - updateAndCheckSource(1, fields("bar", "baz")); - updateAndCheckSource(2, fields("bar", "bir")); - updateAndCheckSource(2, fields("bar", "bir")); - updateAndCheckSource(3, fields("bar", "foo")); - updateAndCheckSource(4, fields("bar", null)); - updateAndCheckSource(4, fields("bar", null)); - updateAndCheckSource(5, fields("bar", "foo")); + updateAndCheckSource(0, 1, fields("bar", "baz")); + updateAndCheckSource(0, 1, fields("bar", "baz")); + updateAndCheckSource(1, 2, fields("bar", "bir")); + updateAndCheckSource(1, 2, fields("bar", "bir")); + updateAndCheckSource(2, 3, fields("bar", "foo")); + updateAndCheckSource(3, 4, fields("bar", null)); + updateAndCheckSource(3, 4, fields("bar", null)); + updateAndCheckSource(4, 5, fields("bar", "foo")); // detect_noop defaults to true - updateAndCheckSource(5, null, fields("bar", "foo")); + updateAndCheckSource(4, 5, null, fields("bar", "foo")); assertEquals(4, totalNoopUpdates()); } @@ -55,36 +56,36 @@ public class UpdateNoopIT extends ESIntegTestCase { String key1 = 1 + randomAlphaOfLength(3); String key2 = 2 + randomAlphaOfLength(3); String key3 = 3 + randomAlphaOfLength(3); - updateAndCheckSource(1, fields(key1, "foo", key2, "baz")); - updateAndCheckSource(1, fields(key1, "foo", key2, "baz")); - updateAndCheckSource(2, fields(key1, "foo", key2, "bir")); - updateAndCheckSource(2, fields(key1, "foo", key2, "bir")); - updateAndCheckSource(3, fields(key1, "foo", key2, "foo")); - updateAndCheckSource(4, fields(key1, "foo", key2, null)); - updateAndCheckSource(4, fields(key1, "foo", key2, null)); - updateAndCheckSource(5, fields(key1, "foo", key2, "foo")); - updateAndCheckSource(6, fields(key1, null, key2, "foo")); - updateAndCheckSource(6, fields(key1, null, key2, "foo")); - updateAndCheckSource(7, fields(key1, null, key2, null)); - updateAndCheckSource(7, fields(key1, null, key2, null)); - updateAndCheckSource(8, fields(key1, null, key2, null, key3, null)); + updateAndCheckSource(0, 1, fields(key1, "foo", key2, "baz")); + updateAndCheckSource(0, 1, fields(key1, "foo", key2, "baz")); + updateAndCheckSource(1, 2, fields(key1, "foo", key2, "bir")); + updateAndCheckSource(1, 2, fields(key1, "foo", key2, "bir")); + updateAndCheckSource(2, 3, fields(key1, "foo", key2, "foo")); + updateAndCheckSource(3, 4, fields(key1, "foo", key2, null)); + updateAndCheckSource(3, 4, fields(key1, "foo", key2, null)); + updateAndCheckSource(4, 5, fields(key1, "foo", key2, "foo")); + updateAndCheckSource(5, 6, fields(key1, null, key2, "foo")); + updateAndCheckSource(5, 6, fields(key1, null, key2, "foo")); + updateAndCheckSource(6, 7, fields(key1, null, key2, null)); + updateAndCheckSource(6, 7, fields(key1, null, key2, null)); + updateAndCheckSource(7, 8, fields(key1, null, key2, null, key3, null)); assertEquals(5, totalNoopUpdates()); } public void testArrayField() throws Exception { - updateAndCheckSource(1, fields("bar", "baz")); - updateAndCheckSource(2, fields("bar", new String[] {"baz", "bort"})); - updateAndCheckSource(2, fields("bar", new String[] {"baz", "bort"})); - updateAndCheckSource(3, fields("bar", "bir")); - updateAndCheckSource(3, fields("bar", "bir")); - updateAndCheckSource(4, fields("bar", new String[] {"baz", "bort"})); - updateAndCheckSource(4, fields("bar", new String[] {"baz", "bort"})); - updateAndCheckSource(5, fields("bar", new String[] {"bir", "bort"})); - updateAndCheckSource(5, fields("bar", new String[] {"bir", "bort"})); - updateAndCheckSource(6, fields("bar", new String[] {"bir", "for"})); - updateAndCheckSource(6, fields("bar", new String[] {"bir", "for"})); - updateAndCheckSource(7, fields("bar", new String[] {"bir", "for", "far"})); + updateAndCheckSource(0, 1, fields("bar", "baz")); + updateAndCheckSource(1, 2, fields("bar", new String[] {"baz", "bort"})); + updateAndCheckSource(1, 2, fields("bar", new String[] {"baz", "bort"})); + updateAndCheckSource(2, 3, fields("bar", "bir")); + updateAndCheckSource(2, 3, fields("bar", "bir")); + updateAndCheckSource(3, 4, fields("bar", new String[] {"baz", "bort"})); + updateAndCheckSource(3, 4, fields("bar", new String[] {"baz", "bort"})); + updateAndCheckSource(4, 5, fields("bar", new String[] {"bir", "bort"})); + updateAndCheckSource(4, 5, fields("bar", new String[] {"bir", "bort"})); + updateAndCheckSource(5, 6, fields("bar", new String[] {"bir", "for"})); + updateAndCheckSource(5, 6, fields("bar", new String[] {"bir", "for"})); + updateAndCheckSource(6, 7, fields("bar", new String[] {"bir", "for", "far"})); assertEquals(5, totalNoopUpdates()); } @@ -94,42 +95,42 @@ public class UpdateNoopIT extends ESIntegTestCase { String key1 = 1 + randomAlphaOfLength(3); String key2 = 2 + randomAlphaOfLength(3); String key3 = 3 + randomAlphaOfLength(3); - updateAndCheckSource(1, XContentFactory.jsonBuilder().startObject() + updateAndCheckSource(0, 1, XContentFactory.jsonBuilder().startObject() .startObject("test") .field(key1, "foo") .field(key2, "baz") .endObject().endObject()); - updateAndCheckSource(1, XContentFactory.jsonBuilder().startObject() + updateAndCheckSource(0, 1, XContentFactory.jsonBuilder().startObject() .startObject("test") .field(key1, "foo") .field(key2, "baz") .endObject().endObject()); - updateAndCheckSource(2, XContentFactory.jsonBuilder().startObject() + updateAndCheckSource(1, 2, XContentFactory.jsonBuilder().startObject() .startObject("test") .field(key1, "foo") .field(key2, "bir") .endObject().endObject()); - updateAndCheckSource(2, XContentFactory.jsonBuilder().startObject() + updateAndCheckSource(1, 2, XContentFactory.jsonBuilder().startObject() .startObject("test") .field(key1, "foo") .field(key2, "bir") .endObject().endObject()); - updateAndCheckSource(3, XContentFactory.jsonBuilder().startObject() + updateAndCheckSource(2, 3, XContentFactory.jsonBuilder().startObject() .startObject("test") .field(key1, "foo") .field(key2, "foo") .endObject().endObject()); - updateAndCheckSource(4, XContentFactory.jsonBuilder().startObject() + updateAndCheckSource(3, 4, XContentFactory.jsonBuilder().startObject() .startObject("test") .field(key1, "foo") .field(key2, (Object) null) .endObject().endObject()); - updateAndCheckSource(4, XContentFactory.jsonBuilder().startObject() + updateAndCheckSource(3, 4, XContentFactory.jsonBuilder().startObject() .startObject("test") .field(key1, "foo") .field(key2, (Object) null) .endObject().endObject()); - updateAndCheckSource(5, XContentFactory.jsonBuilder().startObject() + updateAndCheckSource(4, 5, XContentFactory.jsonBuilder().startObject() .startObject("test") .field(key1, "foo") .field(key2, (Object) null) @@ -140,63 +141,63 @@ public class UpdateNoopIT extends ESIntegTestCase { } public void testMapAndField() throws Exception { - updateAndCheckSource(1, XContentFactory.jsonBuilder().startObject() + updateAndCheckSource(0, 1, XContentFactory.jsonBuilder().startObject() .field("f", "foo") .startObject("m") .field("mf1", "foo") .field("mf2", "baz") .endObject() .endObject()); - updateAndCheckSource(1, XContentFactory.jsonBuilder().startObject() + updateAndCheckSource(0, 1, XContentFactory.jsonBuilder().startObject() .field("f", "foo") .startObject("m") .field("mf1", "foo") .field("mf2", "baz") .endObject() .endObject()); - updateAndCheckSource(2, XContentFactory.jsonBuilder().startObject() + updateAndCheckSource(1, 2, XContentFactory.jsonBuilder().startObject() .field("f", "foo") .startObject("m") .field("mf1", "foo") .field("mf2", "bir") .endObject() .endObject()); - updateAndCheckSource(2, XContentFactory.jsonBuilder().startObject() + updateAndCheckSource(1, 2, XContentFactory.jsonBuilder().startObject() .field("f", "foo") .startObject("m") .field("mf1", "foo") .field("mf2", "bir") .endObject() .endObject()); - updateAndCheckSource(3, XContentFactory.jsonBuilder().startObject() + updateAndCheckSource(2, 3, XContentFactory.jsonBuilder().startObject() .field("f", "foo") .startObject("m") .field("mf1", "foo") .field("mf2", "foo") .endObject() .endObject()); - updateAndCheckSource(4, XContentFactory.jsonBuilder().startObject() + updateAndCheckSource(3, 4, XContentFactory.jsonBuilder().startObject() .field("f", "bar") .startObject("m") .field("mf1", "foo") .field("mf2", "foo") .endObject() .endObject()); - updateAndCheckSource(4, XContentFactory.jsonBuilder().startObject() + updateAndCheckSource(3, 4, XContentFactory.jsonBuilder().startObject() .field("f", "bar") .startObject("m") .field("mf1", "foo") .field("mf2", "foo") .endObject() .endObject()); - updateAndCheckSource(5, XContentFactory.jsonBuilder().startObject() + updateAndCheckSource(4, 5, XContentFactory.jsonBuilder().startObject() .field("f", "baz") .startObject("m") .field("mf1", "foo") .field("mf2", "foo") .endObject() .endObject()); - updateAndCheckSource(6, XContentFactory.jsonBuilder().startObject() + updateAndCheckSource(5, 6, XContentFactory.jsonBuilder().startObject() .field("f", "bop") .startObject("m") .field("mf1", "foo") @@ -212,16 +213,16 @@ public class UpdateNoopIT extends ESIntegTestCase { * its true by default. */ public void testTotallyEmpty() throws Exception { - updateAndCheckSource(1, XContentFactory.jsonBuilder().startObject() + updateAndCheckSource(0, 1, XContentFactory.jsonBuilder().startObject() .field("f", "foo") .startObject("m") .field("mf1", "foo") .field("mf2", "baz") .endObject() .endObject()); - update(true, 1, XContentFactory.jsonBuilder().startObject().endObject()); - update(false, 2, XContentFactory.jsonBuilder().startObject().endObject()); - update(null, 2, XContentFactory.jsonBuilder().startObject().endObject()); + update(true, 0, 1, XContentFactory.jsonBuilder().startObject().endObject()); + update(false, 1, 2, XContentFactory.jsonBuilder().startObject().endObject()); + update(null, 1, 2, XContentFactory.jsonBuilder().startObject().endObject()); } private XContentBuilder fields(Object... fields) throws IOException { @@ -235,16 +236,16 @@ public class UpdateNoopIT extends ESIntegTestCase { return builder; } - private void updateAndCheckSource(long expectedVersion, XContentBuilder xContentBuilder) { - updateAndCheckSource(expectedVersion, true, xContentBuilder); + private void updateAndCheckSource(long expectedSeqNo, long expectedVersion, XContentBuilder xContentBuilder) { + updateAndCheckSource(expectedSeqNo, expectedVersion, true, xContentBuilder); } - private void updateAndCheckSource(long expectedVersion, Boolean detectNoop, XContentBuilder xContentBuilder) { - UpdateResponse updateResponse = update(detectNoop, expectedVersion, xContentBuilder); + private void updateAndCheckSource(long expectedSeqNo, long expectedVersion, Boolean detectNoop, XContentBuilder xContentBuilder) { + UpdateResponse updateResponse = update(detectNoop, expectedSeqNo, expectedVersion, xContentBuilder); assertEquals(updateResponse.getGetResult().sourceRef().utf8ToString(), BytesReference.bytes(xContentBuilder).utf8ToString()); } - private UpdateResponse update(Boolean detectNoop, long expectedVersion, XContentBuilder xContentBuilder) { + private UpdateResponse update(Boolean detectNoop, long expectedSeqNo, long expectedVersion, XContentBuilder xContentBuilder) { UpdateRequestBuilder updateRequest = client().prepareUpdate("test", "type1", "1") .setDoc(xContentBuilder) .setDocAsUpsert(true) @@ -254,7 +255,8 @@ public class UpdateNoopIT extends ESIntegTestCase { } UpdateResponse updateResponse = updateRequest.get(); assertThat(updateResponse.getGetResult(), notNullValue()); - assertEquals(expectedVersion, updateResponse.getVersion()); + assertThat(updateResponse.getSeqNo(), equalTo(expectedSeqNo)); + assertThat(updateResponse.getVersion(), equalTo(expectedVersion)); return updateResponse; }