From cfbe6c08771d47cb62d3982548dd14eca2dd2014 Mon Sep 17 00:00:00 2001 From: Nhat Nguyen Date: Thu, 18 Jul 2019 16:21:02 -0400 Subject: [PATCH] Return seq_no and primary_term in noop update --- .../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 | 6 +- .../action/update/UpdateResponseTests.java | 13 +- .../elasticsearch/update/UpdateNoopIT.java | 124 +++++++++--------- 12 files changed, 135 insertions(+), 88 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 8805af367a80e..a8317fec83a1a 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 RestChannelConsumer prepareRequest(final RestRequest request, final NodeC 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 47302c41cd611..54b57d3ccfa66 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 @@ 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 af2bf8e9b0cca..13e24a563b398 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 938ff47d60485..8ef6896f0eaeb 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 @@ void doExecute(ActionType action, Request request, ActionListener randomUpdateResponse(XConten // 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 2cb71d9bcbe0a..12201eca1a51c 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 java.io.IOException; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.notNullValue; /** @@ -36,16 +37,16 @@ */ 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 void testTwoFields() throws Exception { 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 void testMap() throws Exception { 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 void testMap() throws Exception { } 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 void testMapAndField() throws Exception { * 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 @@ private XContentBuilder fields(Object... fields) throws IOException { 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 @@ private UpdateResponse update(Boolean detectNoop, long expectedVersion, XContent } UpdateResponse updateResponse = updateRequest.get(); assertThat(updateResponse.getGetResult(), notNullValue()); - assertEquals(expectedVersion, updateResponse.getVersion()); + assertThat(updateResponse.getSeqNo(), equalTo(expectedSeqNo)); + assertThat(updateResponse.getVersion(), equalTo(expectedVersion)); return updateResponse; }