Add doc's sequence number + primary term to GetResult and use it for updates (#36680)

This commit adds the last sequence number and primary term of the last operation that have
modified a document to `GetResult` and uses it to power the Update API.

Relates #36148 
Relates #10708
This commit is contained in:
Boaz Leskes 2018-12-17 15:22:13 +01:00 committed by GitHub
parent a181a25226
commit e356b8cb95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 262 additions and 119 deletions

View File

@ -63,6 +63,8 @@ Returns this:
"_type": "_doc", "_type": "_doc",
"_id": "my_id", "_id": "my_id",
"_version": 1, "_version": 1,
"_seq_no": 22,
"_primary_term": 1,
"_source": { "_source": {
"data": "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0=", "data": "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0=",
"attachment": { "attachment": {
@ -74,7 +76,7 @@ Returns this:
} }
} }
-------------------------------------------------- --------------------------------------------------
// TESTRESPONSE // TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
To specify only some fields to be extracted: To specify only some fields to be extracted:
@ -146,6 +148,8 @@ Returns this:
"_type": "_doc", "_type": "_doc",
"_id": "my_id", "_id": "my_id",
"_version": 1, "_version": 1,
"_seq_no": 35,
"_primary_term": 1,
"_source": { "_source": {
"data": "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0=", "data": "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0=",
"attachment": { "attachment": {
@ -157,7 +161,7 @@ Returns this:
} }
} }
-------------------------------------------------- --------------------------------------------------
// TESTRESPONSE // TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
[source,js] [source,js]
@ -194,6 +198,8 @@ Returns this:
"_type": "_doc", "_type": "_doc",
"_id": "my_id_2", "_id": "my_id_2",
"_version": 1, "_version": 1,
"_seq_no": 40,
"_primary_term": 1,
"_source": { "_source": {
"data": "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0=", "data": "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0=",
"max_size": 5, "max_size": 5,
@ -206,7 +212,7 @@ Returns this:
} }
} }
-------------------------------------------------- --------------------------------------------------
// TESTRESPONSE // TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
[[ingest-attachment-with-arrays]] [[ingest-attachment-with-arrays]]
@ -285,6 +291,8 @@ Returns this:
"_type" : "_doc", "_type" : "_doc",
"_id" : "my_id", "_id" : "my_id",
"_version" : 1, "_version" : 1,
"_seq_no" : 50,
"_primary_term" : 1,
"found" : true, "found" : true,
"_source" : { "_source" : {
"attachments" : [ "attachments" : [
@ -312,7 +320,7 @@ Returns this:
} }
} }
-------------------------------------------------- --------------------------------------------------
// TESTRESPONSE // TESTRESPONSE[s/"_seq_no" : \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
Note that the `target_field` needs to be set, otherwise the Note that the `target_field` needs to be set, otherwise the

View File

@ -75,6 +75,8 @@ Which returns:
"_type": "_doc", "_type": "_doc",
"_id": "my_id", "_id": "my_id",
"_version": 1, "_version": 1,
"_seq_no": 55,
"_primary_term": 1,
"_source": { "_source": {
"ip": "8.8.8.8", "ip": "8.8.8.8",
"geoip": { "geoip": {
@ -85,7 +87,7 @@ Which returns:
} }
} }
-------------------------------------------------- --------------------------------------------------
// TESTRESPONSE // TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term":1/"_primary_term" : $body._primary_term/]
Here is an example that uses the default country database and adds the Here is an example that uses the default country database and adds the
geographical information to the `geo` field based on the `ip` field`. Note that geographical information to the `geo` field based on the `ip` field`. Note that
@ -124,6 +126,8 @@ returns this:
"_type": "_doc", "_type": "_doc",
"_id": "my_id", "_id": "my_id",
"_version": 1, "_version": 1,
"_seq_no": 65,
"_primary_term": 1,
"_source": { "_source": {
"ip": "8.8.8.8", "ip": "8.8.8.8",
"geo": { "geo": {
@ -133,7 +137,7 @@ returns this:
} }
} }
-------------------------------------------------- --------------------------------------------------
// TESTRESPONSE // TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
Not all IP addresses find geo information from the database, When this Not all IP addresses find geo information from the database, When this
@ -174,13 +178,15 @@ Which returns:
"_type" : "_doc", "_type" : "_doc",
"_id" : "my_id", "_id" : "my_id",
"_version" : 1, "_version" : 1,
"_seq_no" : 71,
"_primary_term": 1,
"found" : true, "found" : true,
"_source" : { "_source" : {
"ip" : "80.231.5.0" "ip" : "80.231.5.0"
} }
} }
-------------------------------------------------- --------------------------------------------------
// TESTRESPONSE // TESTRESPONSE[s/"_seq_no" : \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
[[ingest-geoip-mappings-note]] [[ingest-geoip-mappings-note]]
===== Recognizing Location as a Geopoint ===== Recognizing Location as a Geopoint

View File

@ -57,6 +57,8 @@ Which returns
"_type": "_doc", "_type": "_doc",
"_id": "my_id", "_id": "my_id",
"_version": 1, "_version": 1,
"_seq_no": 22,
"_primary_term": 1,
"_source": { "_source": {
"agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36", "agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",
"user_agent": { "user_agent": {
@ -73,7 +75,7 @@ Which returns
} }
} }
-------------------------------------------------- --------------------------------------------------
// TESTRESPONSE // TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term": 1/"_primary_term" : $body._primary_term/]
===== Using a custom regex file ===== Using a custom regex file
To use a custom regex file for parsing the user agents, that file has to be put into the `config/ingest-user-agent` directory and To use a custom regex file for parsing the user agents, that file has to be put into the `config/ingest-user-agent` directory and

View File

@ -21,6 +21,8 @@ The result of the above get operation is:
"_type" : "_doc", "_type" : "_doc",
"_id" : "0", "_id" : "0",
"_version" : 1, "_version" : 1,
"_seq_no" : 10,
"_primary_term" : 1,
"found": true, "found": true,
"_source" : { "_source" : {
"user" : "kimchy", "user" : "kimchy",
@ -30,7 +32,7 @@ The result of the above get operation is:
} }
} }
-------------------------------------------------- --------------------------------------------------
// TESTRESPONSE // TESTRESPONSE[s/"_seq_no" : \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
The above result includes the `_index`, `_type`, `_id` and `_version` The above result includes the `_index`, `_type`, `_id` and `_version`
of the document we wish to retrieve, including the actual `_source` of the document we wish to retrieve, including the actual `_source`
@ -156,6 +158,8 @@ The result of the above get operation is:
"_type": "_doc", "_type": "_doc",
"_id": "1", "_id": "1",
"_version": 1, "_version": 1,
"_seq_no" : 22,
"_primary_term" : 1,
"found": true, "found": true,
"fields": { "fields": {
"tags": [ "tags": [
@ -164,7 +168,7 @@ The result of the above get operation is:
} }
} }
-------------------------------------------------- --------------------------------------------------
// TESTRESPONSE // TESTRESPONSE[s/"_seq_no" : \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
Field values fetched from the document itself are always returned as an array. Field values fetched from the document itself are always returned as an array.
@ -199,6 +203,8 @@ The result of the above get operation is:
"_type": "_doc", "_type": "_doc",
"_id": "2", "_id": "2",
"_version": 1, "_version": 1,
"_seq_no" : 13,
"_primary_term" : 1,
"_routing": "user1", "_routing": "user1",
"found": true, "found": true,
"fields": { "fields": {
@ -208,7 +214,7 @@ The result of the above get operation is:
} }
} }
-------------------------------------------------- --------------------------------------------------
// TESTRESPONSE // TESTRESPONSE[s/"_seq_no" : \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
Also only leaf fields can be returned via the `stored_field` option. So object fields can't be returned and such requests Also only leaf fields can be returned via the `stored_field` option. So object fields can't be returned and such requests
will fail. will fail.

View File

@ -870,13 +870,15 @@ which will return:
"_index": "test2", "_index": "test2",
"_type": "_doc", "_type": "_doc",
"_version": 1, "_version": 1,
"_seq_no": 44,
"_primary_term": 1,
"_source": { "_source": {
"text": "words words", "text": "words words",
"tag": "foo" "tag": "foo"
} }
} }
-------------------------------------------------- --------------------------------------------------
// TESTRESPONSE // TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term": 1/"_primary_term" : $body._primary_term/]
[float] [float]
[[docs-reindex-slice]] [[docs-reindex-slice]]

View File

@ -421,7 +421,7 @@ And the response:
"_primary_term" : 1 "_primary_term" : 1
} }
-------------------------------------------------- --------------------------------------------------
// TESTRESPONSE[s/"_seq_no" : 0/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/] // TESTRESPONSE[s/"_seq_no" : \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
From the above, we can see that a new customer document was successfully created inside the customer index. The document also has an internal id of 1 which we specified at index time. From the above, we can see that a new customer document was successfully created inside the customer index. The document also has an internal id of 1 which we specified at index time.
@ -445,11 +445,13 @@ And the response:
"_type" : "_doc", "_type" : "_doc",
"_id" : "1", "_id" : "1",
"_version" : 1, "_version" : 1,
"_seq_no" : 25,
"_primary_term" : 1,
"found" : true, "found" : true,
"_source" : { "name": "John Doe" } "_source" : { "name": "John Doe" }
} }
-------------------------------------------------- --------------------------------------------------
// TESTRESPONSE // TESTRESPONSE[s/"_seq_no" : \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
Nothing out of the ordinary here other than a field, `found`, stating that we found a document with the requested ID 1 and another field, `_source`, which returns the full JSON document that we indexed from the previous step. Nothing out of the ordinary here other than a field, `found`, stating that we found a document with the requested ID 1 and another field, `_source`, which returns the full JSON document that we indexed from the previous step.

View File

@ -730,13 +730,15 @@ GET test/_doc/2
"_type": "_doc", "_type": "_doc",
"_id": "2", "_id": "2",
"_version": 1, "_version": 1,
"_seq_no": 22,
"_primary_term": 1,
"found": true, "found": true,
"_source": { "_source": {
"foo": "bar" "foo": "bar"
} }
} }
-------------------------------------------------- --------------------------------------------------
// TESTRESPONSE // TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term": 1/"_primary_term" : $body._primary_term/]
//// ////
The source document can also use dot delimited fields to represent nested fields. The source document can also use dot delimited fields to represent nested fields.
@ -967,6 +969,8 @@ GET test/_doc/2
"_type": "_doc", "_type": "_doc",
"_id": "2", "_id": "2",
"_version": 1, "_version": 1,
"_seq_no": 34,
"_primary_term": 1,
"found": true, "found": true,
"_source": { "_source": {
"tags": [ "tags": [
@ -976,7 +980,7 @@ GET test/_doc/2
} }
} }
-------------------------------------------------- --------------------------------------------------
// TESTRESPONSE // TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
//// ////
@ -1088,6 +1092,8 @@ GET test/_doc/1
"_type": "_doc", "_type": "_doc",
"_id": "1", "_id": "1",
"_version": 1, "_version": 1,
"_seq_no": 60,
"_primary_term": 1,
"found": true, "found": true,
"_source": { "_source": {
"href": { "href": {
@ -1097,7 +1103,7 @@ GET test/_doc/1
} }
} }
-------------------------------------------------- --------------------------------------------------
// TESTRESPONSE // TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
Regular expressions can be expensive and should be avoided if viable Regular expressions can be expensive and should be avoided if viable
@ -1548,11 +1554,11 @@ PUT /myindex/_doc/1?pipeline=monthlyindex
"successful" : 1, "successful" : 1,
"failed" : 0 "failed" : 0
}, },
"_seq_no" : 0, "_seq_no" : 55,
"_primary_term" : 1 "_primary_term" : 1
} }
-------------------------------------------------- --------------------------------------------------
// TESTRESPONSE // TESTRESPONSE[s/"_seq_no" : \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
The above request will not index this document into the `myindex` index, but into the `myindex-2016-04-01` index because The above request will not index this document into the `myindex` index, but into the `myindex-2016-04-01` index because
@ -2787,11 +2793,11 @@ Response from the index request:
"successful": 1, "successful": 1,
"failed": 0 "failed": 0
}, },
"_seq_no": 0, "_seq_no": 66,
"_primary_term": 1, "_primary_term": 1,
} }
-------------------------------------------------- --------------------------------------------------
// TESTRESPONSE // TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
Indexed document: Indexed document:
@ -2963,11 +2969,11 @@ The response from the above index request:
"successful": 1, "successful": 1,
"failed": 0 "failed": 0
}, },
"_seq_no": 0, "_seq_no": 89,
"_primary_term": 1, "_primary_term": 1,
} }
-------------------------------------------------- --------------------------------------------------
// TESTRESPONSE // TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
In the above response, you can see that our document was actually indexed into `my_index` instead of In the above response, you can see that our document was actually indexed into `my_index` instead of
`any_index`. This type of manipulation is often convenient in pipelines that have various branches of transformation, `any_index`. This type of manipulation is often convenient in pipelines that have various branches of transformation,

View File

@ -54,6 +54,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import static org.elasticsearch.index.seqno.SequenceNumbers.UNASSIGNED_SEQ_NO;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
public class PercolateQueryBuilderTests extends AbstractQueryTestCase<PercolateQueryBuilder> { public class PercolateQueryBuilderTests extends AbstractQueryTestCase<PercolateQueryBuilder> {
@ -152,12 +153,13 @@ public class PercolateQueryBuilderTests extends AbstractQueryTestCase<PercolateQ
assertThat(getRequest.version(), Matchers.equalTo(indexedDocumentVersion)); assertThat(getRequest.version(), Matchers.equalTo(indexedDocumentVersion));
if (indexedDocumentExists) { if (indexedDocumentExists) {
return new GetResponse( return new GetResponse(
new GetResult(indexedDocumentIndex, indexedDocumentType, indexedDocumentId, 0L, true, new GetResult(indexedDocumentIndex, indexedDocumentType, indexedDocumentId, 0, 1, 0L, true,
documentSource.iterator().next(), Collections.emptyMap()) documentSource.iterator().next(), Collections.emptyMap())
); );
} else { } else {
return new GetResponse( return new GetResponse(
new GetResult(indexedDocumentIndex, indexedDocumentType, indexedDocumentId, -1, false, null, Collections.emptyMap()) new GetResult(indexedDocumentIndex, indexedDocumentType, indexedDocumentId, UNASSIGNED_SEQ_NO, 0, -1,
false, null, Collections.emptyMap())
); );
} }
} }

View File

@ -307,6 +307,7 @@ public class TransportShardBulkAction extends TransportWriteAction<BulkShardRequ
final Tuple<XContentType, Map<String, Object>> sourceAndContent = final Tuple<XContentType, Map<String, Object>> sourceAndContent =
XContentHelper.convertToMap(indexSourceAsBytes, true, updateIndexRequest.getContentType()); XContentHelper.convertToMap(indexSourceAsBytes, true, updateIndexRequest.getContentType());
updateResponse.setGetResult(UpdateHelper.extractGetResult(updateRequest, concreteIndex, updateResponse.setGetResult(UpdateHelper.extractGetResult(updateRequest, concreteIndex,
indexResponse.getSeqNo(), indexResponse.getPrimaryTerm(),
indexResponse.getVersion(), sourceAndContent.v2(), sourceAndContent.v1(), indexSourceAsBytes)); indexResponse.getVersion(), sourceAndContent.v2(), sourceAndContent.v1(), indexSourceAsBytes));
} }
} else if (translatedResult == DocWriteResponse.Result.DELETED) { } else if (translatedResult == DocWriteResponse.Result.DELETED) {
@ -315,7 +316,8 @@ public class TransportShardBulkAction extends TransportWriteAction<BulkShardRequ
deleteResponse.getType(), deleteResponse.getId(), deleteResponse.getSeqNo(), deleteResponse.getPrimaryTerm(), deleteResponse.getType(), deleteResponse.getId(), deleteResponse.getSeqNo(), deleteResponse.getPrimaryTerm(),
deleteResponse.getVersion(), deleteResponse.getResult()); deleteResponse.getVersion(), deleteResponse.getResult());
final GetResult getResult = UpdateHelper.extractGetResult(updateRequest, concreteIndex, deleteResponse.getVersion(), final GetResult getResult = UpdateHelper.extractGetResult(updateRequest, concreteIndex,
deleteResponse.getSeqNo(), deleteResponse.getPrimaryTerm(), deleteResponse.getVersion(),
translate.updatedSourceAsMap(), translate.updateSourceContentType(), null); translate.updatedSourceAsMap(), translate.updateSourceContentType(), null);
updateResponse.setGetResult(getResult); updateResponse.setGetResult(getResult);

View File

@ -90,6 +90,20 @@ public class GetResponse extends ActionResponse implements Iterable<DocumentFiel
return getResult.getVersion(); return getResult.getVersion();
} }
/**
* The sequence number assigned to the last operation to have changed this document, if found.
*/
public long getSeqNo() {
return getResult.getSeqNo();
}
/**
* The primary term of the last primary that has changed this document, if found.
*/
public long getPrimaryTerm() {
return getResult.getPrimaryTerm();
}
/** /**
* The source of the document if exists. * The source of the document if exists.
*/ */

View File

@ -19,6 +19,7 @@
package org.elasticsearch.action.update; package org.elasticsearch.action.update;
import org.elasticsearch.ResourceAlreadyExistsException;
import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.ActionRunnable; import org.elasticsearch.action.ActionRunnable;
import org.elasticsearch.action.RoutingMissingException; import org.elasticsearch.action.RoutingMissingException;
@ -50,7 +51,6 @@ import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.engine.VersionConflictEngineException; import org.elasticsearch.index.engine.VersionConflictEngineException;
import org.elasticsearch.index.shard.IndexShard; import org.elasticsearch.index.shard.IndexShard;
import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.ResourceAlreadyExistsException;
import org.elasticsearch.indices.IndicesService; import org.elasticsearch.indices.IndicesService;
import org.elasticsearch.tasks.Task; import org.elasticsearch.tasks.Task;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
@ -185,8 +185,9 @@ public class TransportUpdateAction extends TransportInstanceSingleOperationActio
if (request.fetchSource() != null && request.fetchSource().fetchSource()) { if (request.fetchSource() != null && request.fetchSource().fetchSource()) {
Tuple<XContentType, Map<String, Object>> sourceAndContent = Tuple<XContentType, Map<String, Object>> sourceAndContent =
XContentHelper.convertToMap(upsertSourceBytes, true, upsertRequest.getContentType()); XContentHelper.convertToMap(upsertSourceBytes, true, upsertRequest.getContentType());
update.setGetResult(UpdateHelper.extractGetResult(request, request.concreteIndex(), response.getVersion(), update.setGetResult(UpdateHelper.extractGetResult(request, request.concreteIndex(),
sourceAndContent.v2(), sourceAndContent.v1(), upsertSourceBytes)); response.getSeqNo(), response.getPrimaryTerm(), response.getVersion(), sourceAndContent.v2(),
sourceAndContent.v1(), upsertSourceBytes));
} else { } else {
update.setGetResult(null); update.setGetResult(null);
} }
@ -205,7 +206,8 @@ public class TransportUpdateAction extends TransportInstanceSingleOperationActio
UpdateResponse update = new UpdateResponse(response.getShardInfo(), response.getShardId(), UpdateResponse update = new UpdateResponse(response.getShardInfo(), response.getShardId(),
response.getType(), response.getId(), response.getSeqNo(), response.getPrimaryTerm(), response.getType(), response.getId(), response.getSeqNo(), response.getPrimaryTerm(),
response.getVersion(), response.getResult()); response.getVersion(), response.getResult());
update.setGetResult(UpdateHelper.extractGetResult(request, request.concreteIndex(), response.getVersion(), update.setGetResult(UpdateHelper.extractGetResult(request, request.concreteIndex(),
response.getSeqNo(), response.getPrimaryTerm(), response.getVersion(),
result.updatedSourceAsMap(), result.updateSourceContentType(), indexSourceBytes)); result.updatedSourceAsMap(), result.updateSourceContentType(), indexSourceBytes));
update.setForcedRefresh(response.forcedRefresh()); update.setForcedRefresh(response.forcedRefresh());
listener.onResponse(update); listener.onResponse(update);
@ -216,10 +218,11 @@ public class TransportUpdateAction extends TransportInstanceSingleOperationActio
DeleteRequest deleteRequest = result.action(); DeleteRequest deleteRequest = result.action();
client.bulk(toSingleItemBulkRequest(deleteRequest), wrapBulkResponse( client.bulk(toSingleItemBulkRequest(deleteRequest), wrapBulkResponse(
ActionListener.<DeleteResponse>wrap(response -> { ActionListener.<DeleteResponse>wrap(response -> {
UpdateResponse update = new UpdateResponse(response.getShardInfo(), response.getShardId(), UpdateResponse update = new UpdateResponse(response.getShardInfo(), response.getShardId(), response.getType(),
response.getType(), response.getId(), response.getSeqNo(), response.getPrimaryTerm(), response.getId(), response.getSeqNo(), response.getPrimaryTerm(), response.getVersion(),
response.getVersion(), response.getResult()); response.getResult());
update.setGetResult(UpdateHelper.extractGetResult(request, request.concreteIndex(), response.getVersion(), update.setGetResult(UpdateHelper.extractGetResult(request, request.concreteIndex(),
response.getSeqNo(), response.getPrimaryTerm(), response.getVersion(),
result.updatedSourceAsMap(), result.updateSourceContentType(), null)); result.updatedSourceAsMap(), result.updateSourceContentType(), null));
update.setForcedRefresh(response.forcedRefresh()); update.setForcedRefresh(response.forcedRefresh());
listener.onResponse(update); listener.onResponse(update);

View File

@ -209,8 +209,8 @@ public class UpdateHelper {
if (detectNoop && noop) { if (detectNoop && noop) {
UpdateResponse update = new UpdateResponse(shardId, getResult.getType(), getResult.getId(), UpdateResponse update = new UpdateResponse(shardId, getResult.getType(), getResult.getId(),
getResult.getVersion(), DocWriteResponse.Result.NOOP); getResult.getVersion(), DocWriteResponse.Result.NOOP);
update.setGetResult(extractGetResult(request, request.index(), getResult.getVersion(), updatedSourceAsMap, update.setGetResult(extractGetResult(request, request.index(), getResult.getSeqNo(), getResult.getPrimaryTerm(),
updateSourceContentType, getResult.internalSourceRef())); getResult.getVersion(), updatedSourceAsMap, updateSourceContentType, getResult.internalSourceRef()));
return new Result(update, DocWriteResponse.Result.NOOP, updatedSourceAsMap, updateSourceContentType); return new Result(update, DocWriteResponse.Result.NOOP, updatedSourceAsMap, updateSourceContentType);
} else { } else {
final IndexRequest finalIndexRequest = Requests.indexRequest(request.index()) final IndexRequest finalIndexRequest = Requests.indexRequest(request.index())
@ -270,10 +270,9 @@ public class UpdateHelper {
// If it was neither an INDEX or DELETE operation, treat it as a noop // If it was neither an INDEX or DELETE operation, treat it as a noop
UpdateResponse update = new UpdateResponse(shardId, getResult.getType(), getResult.getId(), UpdateResponse update = new UpdateResponse(shardId, getResult.getType(), getResult.getId(),
getResult.getVersion(), DocWriteResponse.Result.NOOP); getResult.getVersion(), DocWriteResponse.Result.NOOP);
update.setGetResult(extractGetResult(request, request.index(), getResult.getVersion(), updatedSourceAsMap, update.setGetResult(extractGetResult(request, request.index(), getResult.getSeqNo(), getResult.getPrimaryTerm(),
updateSourceContentType, getResult.internalSourceRef())); getResult.getVersion(), updatedSourceAsMap, updateSourceContentType, getResult.internalSourceRef()));
return new Result(update, DocWriteResponse.Result.NOOP, updatedSourceAsMap, updateSourceContentType); return new Result(update, DocWriteResponse.Result.NOOP, updatedSourceAsMap, updateSourceContentType);
} }
} }
@ -293,7 +292,7 @@ public class UpdateHelper {
/** /**
* Applies {@link UpdateRequest#fetchSource()} to the _source of the updated document to be returned in a update response. * Applies {@link UpdateRequest#fetchSource()} to the _source of the updated document to be returned in a update response.
*/ */
public static GetResult extractGetResult(final UpdateRequest request, String concreteIndex, long version, public static GetResult extractGetResult(final UpdateRequest request, String concreteIndex, long seqNo, long primaryTerm, long version,
final Map<String, Object> source, XContentType sourceContentType, final Map<String, Object> source, XContentType sourceContentType,
@Nullable final BytesReference sourceAsBytes) { @Nullable final BytesReference sourceAsBytes) {
if (request.fetchSource() == null || request.fetchSource().fetchSource() == false) { if (request.fetchSource() == null || request.fetchSource().fetchSource() == false) {
@ -318,7 +317,8 @@ public class UpdateHelper {
} }
// TODO when using delete/none, we can still return the source as bytes by generating it (using the sourceContentType) // TODO when using delete/none, we can still return the source as bytes by generating it (using the sourceContentType)
return new GetResult(concreteIndex, request.type(), request.id(), version, true, sourceFilteredAsBytes, Collections.emptyMap()); return new GetResult(concreteIndex, request.type(), request.id(), seqNo, primaryTerm, version, true, sourceFilteredAsBytes,
Collections.emptyMap());
} }
public static class Result { public static class Result {

View File

@ -162,8 +162,9 @@ public class UpdateResponse extends DocWriteResponse {
update = new UpdateResponse(shardId, type, id, version, result); update = new UpdateResponse(shardId, type, id, version, result);
} }
if (getResult != null) { if (getResult != null) {
update.setGetResult(new GetResult(update.getIndex(), update.getType(), update.getId(), update.getVersion(), update.setGetResult(new GetResult(update.getIndex(), update.getType(), update.getId(),
getResult.isExists(),getResult.internalSourceRef(), getResult.getFields())); getResult.getSeqNo(), getResult.getPrimaryTerm(), update.getVersion(),
getResult.isExists(), getResult.internalSourceRef(), getResult.getFields()));
} }
update.setForcedRefresh(forcedRefresh); update.setForcedRefresh(forcedRefresh);
return update; return update;

View File

@ -20,6 +20,7 @@
package org.elasticsearch.index.get; package org.elasticsearch.index.get;
import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.Version;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.compress.CompressorFactory; import org.elasticsearch.common.compress.CompressorFactory;
@ -33,6 +34,7 @@ import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.IgnoredFieldMapper; import org.elasticsearch.index.mapper.IgnoredFieldMapper;
import org.elasticsearch.index.mapper.SourceFieldMapper; import org.elasticsearch.index.mapper.SourceFieldMapper;
import org.elasticsearch.index.seqno.SequenceNumbers;
import org.elasticsearch.search.lookup.SourceLookup; import org.elasticsearch.search.lookup.SourceLookup;
import java.io.IOException; import java.io.IOException;
@ -53,6 +55,8 @@ public class GetResult implements Streamable, Iterable<DocumentField>, ToXConten
public static final String _TYPE = "_type"; public static final String _TYPE = "_type";
public static final String _ID = "_id"; public static final String _ID = "_id";
private static final String _VERSION = "_version"; private static final String _VERSION = "_version";
private static final String _SEQ_NO = "_seq_no";
private static final String _PRIMARY_TERM = "_primary_term";
private static final String FOUND = "found"; private static final String FOUND = "found";
private static final String FIELDS = "fields"; private static final String FIELDS = "fields";
@ -60,6 +64,8 @@ public class GetResult implements Streamable, Iterable<DocumentField>, ToXConten
private String type; private String type;
private String id; private String id;
private long version; private long version;
private long seqNo;
private long primaryTerm;
private boolean exists; private boolean exists;
private Map<String, DocumentField> fields; private Map<String, DocumentField> fields;
private Map<String, Object> sourceAsMap; private Map<String, Object> sourceAsMap;
@ -69,11 +75,17 @@ public class GetResult implements Streamable, Iterable<DocumentField>, ToXConten
GetResult() { GetResult() {
} }
public GetResult(String index, String type, String id, long version, boolean exists, BytesReference source, public GetResult(String index, String type, String id, long seqNo, long primaryTerm, long version, boolean exists,
Map<String, DocumentField> fields) { BytesReference source, Map<String, DocumentField> fields) {
this.index = index; this.index = index;
this.type = type; this.type = type;
this.id = id; this.id = id;
this.seqNo = seqNo;
this.primaryTerm = primaryTerm;
assert (seqNo == SequenceNumbers.UNASSIGNED_SEQ_NO && primaryTerm == 0) || (seqNo >= 0 && primaryTerm >= 1) :
"seqNo: " + seqNo + " primaryTerm: " + primaryTerm;
assert exists || (seqNo == SequenceNumbers.UNASSIGNED_SEQ_NO && primaryTerm == 0) :
"doc not found but seqNo/primaryTerm are set";
this.version = version; this.version = version;
this.exists = exists; this.exists = exists;
this.source = source; this.source = source;
@ -118,6 +130,20 @@ public class GetResult implements Streamable, Iterable<DocumentField>, ToXConten
return version; return version;
} }
/**
* The sequence number assigned to the last operation to have changed this document, if found.
*/
public long getSeqNo() {
return seqNo;
}
/**
* The primary term of the last primary that has changed this document, if found.
*/
public long getPrimaryTerm() {
return primaryTerm;
}
/** /**
* The source of the document if exists. * The source of the document if exists.
*/ */
@ -213,6 +239,11 @@ public class GetResult implements Streamable, Iterable<DocumentField>, ToXConten
} }
public XContentBuilder toXContentEmbedded(XContentBuilder builder, Params params) throws IOException { public XContentBuilder toXContentEmbedded(XContentBuilder builder, Params params) throws IOException {
if (seqNo != SequenceNumbers.UNASSIGNED_SEQ_NO) { // seqNo may not be assigned if read from an old node
builder.field(_SEQ_NO, seqNo);
builder.field(_PRIMARY_TERM, primaryTerm);
}
List<DocumentField> metaFields = new ArrayList<>(); List<DocumentField> metaFields = new ArrayList<>();
List<DocumentField> otherFields = new ArrayList<>(); List<DocumentField> otherFields = new ArrayList<>();
if (fields != null && !fields.isEmpty()) { if (fields != null && !fields.isEmpty()) {
@ -282,6 +313,8 @@ public class GetResult implements Streamable, Iterable<DocumentField>, ToXConten
String currentFieldName = parser.currentName(); String currentFieldName = parser.currentName();
long version = -1; long version = -1;
long seqNo = SequenceNumbers.UNASSIGNED_SEQ_NO;
long primaryTerm = 0;
Boolean found = null; Boolean found = null;
BytesReference source = null; BytesReference source = null;
Map<String, DocumentField> fields = new HashMap<>(); Map<String, DocumentField> fields = new HashMap<>();
@ -297,6 +330,10 @@ public class GetResult implements Streamable, Iterable<DocumentField>, ToXConten
id = parser.text(); id = parser.text();
} else if (_VERSION.equals(currentFieldName)) { } else if (_VERSION.equals(currentFieldName)) {
version = parser.longValue(); version = parser.longValue();
} else if (_SEQ_NO.equals(currentFieldName)) {
seqNo = parser.longValue();
} else if (_PRIMARY_TERM.equals(currentFieldName)) {
primaryTerm = parser.longValue();
} else if (FOUND.equals(currentFieldName)) { } else if (FOUND.equals(currentFieldName)) {
found = parser.booleanValue(); found = parser.booleanValue();
} else { } else {
@ -326,7 +363,7 @@ public class GetResult implements Streamable, Iterable<DocumentField>, ToXConten
} }
} }
} }
return new GetResult(index, type, id, version, found, source, fields); return new GetResult(index, type, id, seqNo, primaryTerm, version, found, source, fields);
} }
public static GetResult fromXContent(XContentParser parser) throws IOException { public static GetResult fromXContent(XContentParser parser) throws IOException {
@ -347,6 +384,13 @@ public class GetResult implements Streamable, Iterable<DocumentField>, ToXConten
index = in.readString(); index = in.readString();
type = in.readOptionalString(); type = in.readOptionalString();
id = in.readString(); id = in.readString();
if (in.getVersion().onOrAfter(Version.V_7_0_0)) {
seqNo = in.readZLong();
primaryTerm = in.readVLong();
} else {
seqNo = SequenceNumbers.UNASSIGNED_SEQ_NO;
primaryTerm = 0L;
}
version = in.readLong(); version = in.readLong();
exists = in.readBoolean(); exists = in.readBoolean();
if (exists) { if (exists) {
@ -372,6 +416,10 @@ public class GetResult implements Streamable, Iterable<DocumentField>, ToXConten
out.writeString(index); out.writeString(index);
out.writeOptionalString(type); out.writeOptionalString(type);
out.writeString(id); out.writeString(id);
if (out.getVersion().onOrAfter(Version.V_7_0_0)) {
out.writeZLong(seqNo);
out.writeVLong(primaryTerm);
}
out.writeLong(version); out.writeLong(version);
out.writeBoolean(exists); out.writeBoolean(exists);
if (exists) { if (exists) {
@ -397,6 +445,8 @@ public class GetResult implements Streamable, Iterable<DocumentField>, ToXConten
} }
GetResult getResult = (GetResult) o; GetResult getResult = (GetResult) o;
return version == getResult.version && return version == getResult.version &&
seqNo == getResult.seqNo &&
primaryTerm == getResult.primaryTerm &&
exists == getResult.exists && exists == getResult.exists &&
Objects.equals(index, getResult.index) && Objects.equals(index, getResult.index) &&
Objects.equals(type, getResult.type) && Objects.equals(type, getResult.type) &&
@ -407,7 +457,7 @@ public class GetResult implements Streamable, Iterable<DocumentField>, ToXConten
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(version, exists, index, type, id, fields, sourceAsMap()); return Objects.hash(version, seqNo, primaryTerm, exists, index, type, id, fields, sourceAsMap());
} }
@Override @Override

View File

@ -45,6 +45,7 @@ import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.RoutingFieldMapper; import org.elasticsearch.index.mapper.RoutingFieldMapper;
import org.elasticsearch.index.mapper.SourceFieldMapper; import org.elasticsearch.index.mapper.SourceFieldMapper;
import org.elasticsearch.index.mapper.Uid; import org.elasticsearch.index.mapper.Uid;
import org.elasticsearch.index.seqno.SequenceNumbers;
import org.elasticsearch.index.shard.AbstractIndexShardComponent; import org.elasticsearch.index.shard.AbstractIndexShardComponent;
import org.elasticsearch.index.shard.IndexShard; import org.elasticsearch.index.shard.IndexShard;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext; import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
@ -112,7 +113,7 @@ public final class ShardGetService extends AbstractIndexShardComponent {
public GetResult get(Engine.GetResult engineGetResult, String id, String type, public GetResult get(Engine.GetResult engineGetResult, String id, String type,
String[] fields, FetchSourceContext fetchSourceContext) { String[] fields, FetchSourceContext fetchSourceContext) {
if (!engineGetResult.exists()) { if (!engineGetResult.exists()) {
return new GetResult(shardId.getIndexName(), type, id, -1, false, null, null); return new GetResult(shardId.getIndexName(), type, id, SequenceNumbers.UNASSIGNED_SEQ_NO, 0, -1, false, null, null);
} }
currentMetric.inc(); currentMetric.inc();
@ -168,7 +169,7 @@ public final class ShardGetService extends AbstractIndexShardComponent {
} }
if (get == null || get.exists() == false) { if (get == null || get.exists() == false) {
return new GetResult(shardId.getIndexName(), type, id, -1, false, null, null); return new GetResult(shardId.getIndexName(), type, id, SequenceNumbers.UNASSIGNED_SEQ_NO, 0, -1, false, null, null);
} }
try { try {
@ -233,7 +234,8 @@ public final class ShardGetService extends AbstractIndexShardComponent {
} }
} }
return new GetResult(shardId.getIndexName(), type, id, get.version(), get.exists(), source, fields); return new GetResult(shardId.getIndexName(), type, id, get.docIdAndVersion().seqNo, get.docIdAndVersion().primaryTerm,
get.version(), get.exists(), source, fields);
} }
private static FieldsVisitor buildFieldsVisitors(String[] fields, FetchSourceContext fetchSourceContext) { private static FieldsVisitor buildFieldsVisitors(String[] fields, FetchSourceContext fetchSourceContext) {

View File

@ -65,7 +65,7 @@ public class ExplainResponseTests extends AbstractStreamableXContentTestCase<Exp
GetResult getResult = new GetResult(randomAlphaOfLengthBetween(3, 10), GetResult getResult = new GetResult(randomAlphaOfLengthBetween(3, 10),
randomAlphaOfLengthBetween(3, 10), randomAlphaOfLengthBetween(3, 10),
randomAlphaOfLengthBetween(3, 10), randomAlphaOfLengthBetween(3, 10),
randomNonNegativeLong(), 0, 1, randomNonNegativeLong(),
true, true,
RandomObjects.randomSource(random()), RandomObjects.randomSource(random()),
singletonMap(fieldName, new DocumentField(fieldName, values))); singletonMap(fieldName, new DocumentField(fieldName, values)));
@ -83,7 +83,7 @@ public class ExplainResponseTests extends AbstractStreamableXContentTestCase<Exp
String id = "1"; String id = "1";
boolean exist = true; boolean exist = true;
Explanation explanation = Explanation.match(1.0f, "description", Collections.emptySet()); Explanation explanation = Explanation.match(1.0f, "description", Collections.emptySet());
GetResult getResult = new GetResult(null, null, null, -1, true, new BytesArray("{ \"field1\" : " + GetResult getResult = new GetResult(null, null, null, 0, 1, -1, true, new BytesArray("{ \"field1\" : " +
"\"value1\", \"field2\":\"value2\"}"), singletonMap("field1", new DocumentField("field1", "\"value1\", \"field2\":\"value2\"}"), singletonMap("field1", new DocumentField("field1",
singletonList("value1")))); singletonList("value1"))));
ExplainResponse response = new ExplainResponse(index, type, id, exist, explanation, getResult); ExplainResponse response = new ExplainResponse(index, type, id, exist, explanation, getResult);
@ -105,6 +105,8 @@ public class ExplainResponseTests extends AbstractStreamableXContentTestCase<Exp
" \"details\":[]\n" + " \"details\":[]\n" +
" },\n" + " },\n" +
" \"get\":{\n" + " \"get\":{\n" +
" \"_seq_no\":0," +
" \"_primary_term\":1," +
" \"found\":true,\n" + " \"found\":true,\n" +
" \"_source\":{\n" + " \"_source\":{\n" +
" \"field1\":\"value1\",\n" + " \"field1\":\"value1\",\n" +

View File

@ -39,6 +39,7 @@ import static org.elasticsearch.common.xcontent.XContentHelper.toXContent;
import static org.elasticsearch.index.get.GetResultTests.copyGetResult; import static org.elasticsearch.index.get.GetResultTests.copyGetResult;
import static org.elasticsearch.index.get.GetResultTests.mutateGetResult; import static org.elasticsearch.index.get.GetResultTests.mutateGetResult;
import static org.elasticsearch.index.get.GetResultTests.randomGetResult; import static org.elasticsearch.index.get.GetResultTests.randomGetResult;
import static org.elasticsearch.index.seqno.SequenceNumbers.UNASSIGNED_SEQ_NO;
import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode; import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode;
import static org.elasticsearch.test.XContentTestUtils.insertRandomFields; import static org.elasticsearch.test.XContentTestUtils.insertRandomFields;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertToXContentEquivalent; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertToXContentEquivalent;
@ -91,26 +92,28 @@ public class GetResponseTests extends ESTestCase {
public void testToXContent() { public void testToXContent() {
{ {
GetResponse getResponse = new GetResponse(new GetResult("index", "type", "id", 1, true, new BytesArray("{ \"field1\" : " + GetResponse getResponse = new GetResponse(new GetResult("index", "type", "id", 0, 1, 1, true, new BytesArray("{ \"field1\" : " +
"\"value1\", \"field2\":\"value2\"}"), Collections.singletonMap("field1", new DocumentField("field1", "\"value1\", \"field2\":\"value2\"}"), Collections.singletonMap("field1", new DocumentField("field1",
Collections.singletonList("value1"))))); Collections.singletonList("value1")))));
String output = Strings.toString(getResponse); String output = Strings.toString(getResponse);
assertEquals("{\"_index\":\"index\",\"_type\":\"type\",\"_id\":\"id\",\"_version\":1,\"found\":true,\"_source\":{ \"field1\" " + assertEquals("{\"_index\":\"index\",\"_type\":\"type\",\"_id\":\"id\",\"_version\":1,\"_seq_no\":0,\"_primary_term\":1," +
": \"value1\", \"field2\":\"value2\"},\"fields\":{\"field1\":[\"value1\"]}}", output); "\"found\":true,\"_source\":{ \"field1\" : \"value1\", \"field2\":\"value2\"},\"fields\":{\"field1\":[\"value1\"]}}",
output);
} }
{ {
GetResponse getResponse = new GetResponse(new GetResult("index", "type", "id", 1, false, null, null)); GetResponse getResponse = new GetResponse(new GetResult("index", "type", "id", UNASSIGNED_SEQ_NO, 0, 1, false, null, null));
String output = Strings.toString(getResponse); String output = Strings.toString(getResponse);
assertEquals("{\"_index\":\"index\",\"_type\":\"type\",\"_id\":\"id\",\"found\":false}", output); assertEquals("{\"_index\":\"index\",\"_type\":\"type\",\"_id\":\"id\",\"found\":false}", output);
} }
} }
public void testToString() { public void testToString() {
GetResponse getResponse = new GetResponse( GetResponse getResponse = new GetResponse(new GetResult("index", "type", "id", 0, 1, 1, true,
new GetResult("index", "type", "id", 1, true, new BytesArray("{ \"field1\" : " + "\"value1\", \"field2\":\"value2\"}"), new BytesArray("{ \"field1\" : " + "\"value1\", \"field2\":\"value2\"}"),
Collections.singletonMap("field1", new DocumentField("field1", Collections.singletonList("value1"))))); Collections.singletonMap("field1", new DocumentField("field1", Collections.singletonList("value1")))));
assertEquals("{\"_index\":\"index\",\"_type\":\"type\",\"_id\":\"id\",\"_version\":1,\"found\":true,\"_source\":{ \"field1\" " assertEquals("{\"_index\":\"index\",\"_type\":\"type\",\"_id\":\"id\",\"_version\":1,\"_seq_no\":0,\"_primary_term\":1," +
+ ": \"value1\", \"field2\":\"value2\"},\"fields\":{\"field1\":[\"value1\"]}}", getResponse.toString()); "\"found\":true,\"_source\":{ \"field1\" : \"value1\", \"field2\":\"value2\"},\"fields\":{\"field1\":[\"value1\"]}}",
getResponse.toString());
} }
public void testEqualsAndHashcode() { public void testEqualsAndHashcode() {
@ -119,7 +122,8 @@ public class GetResponseTests extends ESTestCase {
} }
public void testFromXContentThrowsParsingException() throws IOException { public void testFromXContentThrowsParsingException() throws IOException {
GetResponse getResponse = new GetResponse(new GetResult(null, null, null, randomIntBetween(1, 5), randomBoolean(), null, null)); GetResponse getResponse =
new GetResponse(new GetResult(null, null, null, UNASSIGNED_SEQ_NO, 0, randomIntBetween(1, 5), randomBoolean(), null, null));
XContentType xContentType = randomFrom(XContentType.values()); XContentType xContentType = randomFrom(XContentType.values());
BytesReference originalBytes = toShuffledXContent(getResponse, xContentType, ToXContent.EMPTY_PARAMS, randomBoolean()); BytesReference originalBytes = toShuffledXContent(getResponse, xContentType, ToXContent.EMPTY_PARAMS, randomBoolean());

View File

@ -70,7 +70,7 @@ public class MultiGetResponseTests extends ESTestCase {
for (int i = 0; i < items.length; i++) { for (int i = 0; i < items.length; i++) {
if (randomBoolean()) { if (randomBoolean()) {
items[i] = new MultiGetItemResponse(new GetResponse(new GetResult( items[i] = new MultiGetItemResponse(new GetResponse(new GetResult(
randomAlphaOfLength(4), randomAlphaOfLength(4), randomAlphaOfLength(4), randomNonNegativeLong(), randomAlphaOfLength(4), randomAlphaOfLength(4), randomAlphaOfLength(4), 0, 1, randomNonNegativeLong(),
true, null, null true, null, null
)), null); )), null);
} else { } else {

View File

@ -60,6 +60,7 @@ import java.util.function.Function;
import static java.util.Collections.emptyMap; import static java.util.Collections.emptyMap;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.common.xcontent.XContentHelper.toXContent; import static org.elasticsearch.common.xcontent.XContentHelper.toXContent;
import static org.elasticsearch.index.seqno.SequenceNumbers.UNASSIGNED_SEQ_NO;
import static org.elasticsearch.script.MockScriptEngine.mockInlineScript; import static org.elasticsearch.script.MockScriptEngine.mockInlineScript;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertToXContentEquivalent; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertToXContentEquivalent;
import static org.hamcrest.CoreMatchers.hasItems; import static org.hamcrest.CoreMatchers.hasItems;
@ -359,7 +360,7 @@ public class UpdateRequestTests extends ESTestCase {
.scriptedUpsert(true); .scriptedUpsert(true);
long nowInMillis = randomNonNegativeLong(); long nowInMillis = randomNonNegativeLong();
// We simulate that the document is not existing yet // We simulate that the document is not existing yet
GetResult getResult = new GetResult("test", "type1", "2", 0, false, null, null); GetResult getResult = new GetResult("test", "type1", "2", UNASSIGNED_SEQ_NO, 0, 0, false, null, null);
UpdateHelper.Result result = updateHelper.prepare(new ShardId("test", "_na_", 0), updateRequest, getResult, () -> nowInMillis); UpdateHelper.Result result = updateHelper.prepare(new ShardId("test", "_na_", 0), updateRequest, getResult, () -> nowInMillis);
Streamable action = result.action(); Streamable action = result.action();
assertThat(action, instanceOf(IndexRequest.class)); assertThat(action, instanceOf(IndexRequest.class));
@ -372,7 +373,7 @@ public class UpdateRequestTests extends ESTestCase {
.script(mockInlineScript("ctx._timestamp = ctx._now")) .script(mockInlineScript("ctx._timestamp = ctx._now"))
.scriptedUpsert(true); .scriptedUpsert(true);
// We simulate that the document is not existing yet // We simulate that the document is not existing yet
GetResult getResult = new GetResult("test", "type1", "2", 0, true, new BytesArray("{}"), null); GetResult getResult = new GetResult("test", "type1", "2", 0, 1, 0, true, new BytesArray("{}"), null);
UpdateHelper.Result result = updateHelper.prepare(new ShardId("test", "_na_", 0), updateRequest, getResult, () -> 42L); UpdateHelper.Result result = updateHelper.prepare(new ShardId("test", "_na_", 0), updateRequest, getResult, () -> 42L);
Streamable action = result.action(); Streamable action = result.action();
assertThat(action, instanceOf(IndexRequest.class)); assertThat(action, instanceOf(IndexRequest.class));
@ -381,7 +382,7 @@ public class UpdateRequestTests extends ESTestCase {
public void testIndexTimeout() { public void testIndexTimeout() {
final GetResult getResult = final GetResult getResult =
new GetResult("test", "type", "1", 0, true, new BytesArray("{\"f\":\"v\"}"), null); new GetResult("test", "type", "1", 0, 1, 0, true, new BytesArray("{\"f\":\"v\"}"), null);
final UpdateRequest updateRequest = final UpdateRequest updateRequest =
new UpdateRequest("test", "type", "1") new UpdateRequest("test", "type", "1")
.script(mockInlineScript("return")) .script(mockInlineScript("return"))
@ -391,7 +392,7 @@ public class UpdateRequestTests extends ESTestCase {
public void testDeleteTimeout() { public void testDeleteTimeout() {
final GetResult getResult = final GetResult getResult =
new GetResult("test", "type", "1", 0, true, new BytesArray("{\"f\":\"v\"}"), null); new GetResult("test", "type", "1", 0, 1, 0, true, new BytesArray("{\"f\":\"v\"}"), null);
final UpdateRequest updateRequest = final UpdateRequest updateRequest =
new UpdateRequest("test", "type", "1") new UpdateRequest("test", "type", "1")
.script(mockInlineScript("ctx.op = delete")) .script(mockInlineScript("ctx.op = delete"))
@ -402,7 +403,7 @@ public class UpdateRequestTests extends ESTestCase {
public void testUpsertTimeout() throws IOException { public void testUpsertTimeout() throws IOException {
final boolean exists = randomBoolean(); final boolean exists = randomBoolean();
final BytesReference source = exists ? new BytesArray("{\"f\":\"v\"}") : null; final BytesReference source = exists ? new BytesArray("{\"f\":\"v\"}") : null;
final GetResult getResult = new GetResult("test", "type", "1", 0, exists, source, null); final GetResult getResult = new GetResult("test", "type", "1", UNASSIGNED_SEQ_NO, 0, 0, exists, source, null);
final XContentBuilder sourceBuilder = jsonBuilder(); final XContentBuilder sourceBuilder = jsonBuilder();
sourceBuilder.startObject(); sourceBuilder.startObject();
{ {
@ -535,7 +536,7 @@ public class UpdateRequestTests extends ESTestCase {
} }
public void testRoutingExtraction() throws Exception { public void testRoutingExtraction() throws Exception {
GetResult getResult = new GetResult("test", "type", "1", 0, false, null, null); GetResult getResult = new GetResult("test", "type", "1", UNASSIGNED_SEQ_NO, 0, 0, false, null, null);
IndexRequest indexRequest = new IndexRequest("test", "type", "1"); IndexRequest indexRequest = new IndexRequest("test", "type", "1");
// There is no routing and parent because the document doesn't exist // There is no routing and parent because the document doesn't exist
@ -545,7 +546,7 @@ public class UpdateRequestTests extends ESTestCase {
assertNull(UpdateHelper.calculateRouting(getResult, indexRequest)); assertNull(UpdateHelper.calculateRouting(getResult, indexRequest));
// Doc exists but has no source or fields // Doc exists but has no source or fields
getResult = new GetResult("test", "type", "1", 0, true, null, null); getResult = new GetResult("test", "type", "1", 0, 1, 0, true, null, null);
// There is no routing and parent on either request // There is no routing and parent on either request
assertNull(UpdateHelper.calculateRouting(getResult, indexRequest)); assertNull(UpdateHelper.calculateRouting(getResult, indexRequest));
@ -554,7 +555,7 @@ public class UpdateRequestTests extends ESTestCase {
fields.put("_routing", new DocumentField("_routing", Collections.singletonList("routing1"))); fields.put("_routing", new DocumentField("_routing", Collections.singletonList("routing1")));
// Doc exists and has the parent and routing fields // Doc exists and has the parent and routing fields
getResult = new GetResult("test", "type", "1", 0, true, null, fields); getResult = new GetResult("test", "type", "1", 0, 1, 0, true, null, fields);
// Use the get result parent and routing // Use the get result parent and routing
assertThat(UpdateHelper.calculateRouting(getResult, indexRequest), equalTo("routing1")); assertThat(UpdateHelper.calculateRouting(getResult, indexRequest), equalTo("routing1"));
@ -563,7 +564,7 @@ public class UpdateRequestTests extends ESTestCase {
@SuppressWarnings("deprecated") // VersionType.FORCE is deprecated @SuppressWarnings("deprecated") // VersionType.FORCE is deprecated
public void testCalculateUpdateVersion() throws Exception { public void testCalculateUpdateVersion() throws Exception {
long randomVersion = randomIntBetween(0, 100); long randomVersion = randomIntBetween(0, 100);
GetResult getResult = new GetResult("test", "type", "1", randomVersion, true, new BytesArray("{}"), null); GetResult getResult = new GetResult("test", "type", "1", 0, 1, randomVersion, true, new BytesArray("{}"), null);
UpdateRequest request = new UpdateRequest("test", "type1", "1"); UpdateRequest request = new UpdateRequest("test", "type1", "1");
long version = UpdateHelper.calculateUpdateVersion(request, getResult); long version = UpdateHelper.calculateUpdateVersion(request, getResult);
@ -580,7 +581,7 @@ public class UpdateRequestTests extends ESTestCase {
public void testNoopDetection() throws Exception { public void testNoopDetection() throws Exception {
ShardId shardId = new ShardId("test", "", 0); ShardId shardId = new ShardId("test", "", 0);
GetResult getResult = new GetResult("test", "type", "1", 0, true, GetResult getResult = new GetResult("test", "type", "1", 0, 1, 0, true,
new BytesArray("{\"body\": \"foo\"}"), new BytesArray("{\"body\": \"foo\"}"),
null); null);
@ -611,7 +612,7 @@ public class UpdateRequestTests extends ESTestCase {
public void testUpdateScript() throws Exception { public void testUpdateScript() throws Exception {
ShardId shardId = new ShardId("test", "", 0); ShardId shardId = new ShardId("test", "", 0);
GetResult getResult = new GetResult("test", "type", "1", 0, true, GetResult getResult = new GetResult("test", "type", "1", 0, 1, 0, true,
new BytesArray("{\"body\": \"bar\"}"), new BytesArray("{\"body\": \"bar\"}"),
null); null);

View File

@ -74,11 +74,12 @@ public class UpdateResponseTests extends ESTestCase {
UpdateResponse updateResponse = new UpdateResponse(new ReplicationResponse.ShardInfo(3, 2), UpdateResponse updateResponse = new UpdateResponse(new ReplicationResponse.ShardInfo(3, 2),
new ShardId("books", "books_uuid", 2), "book", "1", 7, 17, 2, UPDATED); new ShardId("books", "books_uuid", 2), "book", "1", 7, 17, 2, UPDATED);
updateResponse.setGetResult(new GetResult("books", "book", "1", 2, true, source, fields)); updateResponse.setGetResult(new GetResult("books", "book", "1",0, 1, 2, true, source, fields));
String output = Strings.toString(updateResponse); String output = Strings.toString(updateResponse);
assertEquals("{\"_index\":\"books\",\"_type\":\"book\",\"_id\":\"1\",\"_version\":2,\"result\":\"updated\"," + assertEquals("{\"_index\":\"books\",\"_type\":\"book\",\"_id\":\"1\",\"_version\":2,\"result\":\"updated\"," +
"\"_shards\":{\"total\":3,\"successful\":2,\"failed\":0},\"_seq_no\":7,\"_primary_term\":17,\"get\":{\"found\":true," + "\"_shards\":{\"total\":3,\"successful\":2,\"failed\":0},\"_seq_no\":7,\"_primary_term\":17,\"get\":{" +
"\"_seq_no\":0,\"_primary_term\":1,\"found\":true," +
"\"_source\":{\"title\":\"Book title\",\"isbn\":\"ABC-123\"},\"fields\":{\"isbn\":[\"ABC-123\"],\"title\":[\"Book " + "\"_source\":{\"title\":\"Book title\",\"isbn\":\"ABC-123\"},\"fields\":{\"isbn\":[\"ABC-123\"],\"title\":[\"Book " +
"title\"]}}}", output); "title\"]}}}", output);
} }

View File

@ -44,6 +44,7 @@ import static java.util.Collections.singletonMap;
import static org.elasticsearch.common.xcontent.XContentHelper.toXContent; import static org.elasticsearch.common.xcontent.XContentHelper.toXContent;
import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken; import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken;
import static org.elasticsearch.index.get.DocumentFieldTests.randomDocumentField; import static org.elasticsearch.index.get.DocumentFieldTests.randomDocumentField;
import static org.elasticsearch.index.seqno.SequenceNumbers.UNASSIGNED_SEQ_NO;
import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode; import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertToXContentEquivalent; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertToXContentEquivalent;
@ -72,15 +73,16 @@ public class GetResultTests extends ESTestCase {
public void testToXContent() throws IOException { public void testToXContent() throws IOException {
{ {
GetResult getResult = new GetResult("index", "type", "id", 1, true, new BytesArray("{ \"field1\" : " + GetResult getResult = new GetResult("index", "type", "id", 0, 1, 1, true, new BytesArray("{ \"field1\" : " +
"\"value1\", \"field2\":\"value2\"}"), singletonMap("field1", new DocumentField("field1", "\"value1\", \"field2\":\"value2\"}"), singletonMap("field1", new DocumentField("field1",
singletonList("value1")))); singletonList("value1"))));
String output = Strings.toString(getResult); String output = Strings.toString(getResult);
assertEquals("{\"_index\":\"index\",\"_type\":\"type\",\"_id\":\"id\",\"_version\":1,\"found\":true,\"_source\":{ \"field1\" " + assertEquals("{\"_index\":\"index\",\"_type\":\"type\",\"_id\":\"id\",\"_version\":1,\"_seq_no\":0,\"_primary_term\":1," +
": \"value1\", \"field2\":\"value2\"},\"fields\":{\"field1\":[\"value1\"]}}", output); "\"found\":true,\"_source\":{ \"field1\" : \"value1\", \"field2\":\"value2\"},\"fields\":{\"field1\":[\"value1\"]}}",
output);
} }
{ {
GetResult getResult = new GetResult("index", "type", "id", 1, false, null, null); GetResult getResult = new GetResult("index", "type", "id", UNASSIGNED_SEQ_NO, 0, 1, false, null, null);
String output = Strings.toString(getResult); String output = Strings.toString(getResult);
assertEquals("{\"_index\":\"index\",\"_type\":\"type\",\"_id\":\"id\",\"found\":false}", output); assertEquals("{\"_index\":\"index\",\"_type\":\"type\",\"_id\":\"id\",\"found\":false}", output);
} }
@ -92,7 +94,7 @@ public class GetResultTests extends ESTestCase {
GetResult getResult = tuple.v1(); GetResult getResult = tuple.v1();
// We don't expect to retrieve the index/type/id of the GetResult because they are not rendered // We don't expect to retrieve the index/type/id of the GetResult because they are not rendered
// by the toXContentEmbedded method. // by the toXContentEmbedded method.
GetResult expectedGetResult = new GetResult(null, null, null, -1, GetResult expectedGetResult = new GetResult(null, null, null, tuple.v2().getSeqNo(), tuple.v2().getPrimaryTerm(), -1,
tuple.v2().isExists(), tuple.v2().sourceRef(), tuple.v2().getFields()); tuple.v2().isExists(), tuple.v2().sourceRef(), tuple.v2().getFields());
boolean humanReadable = randomBoolean(); boolean humanReadable = randomBoolean();
@ -118,16 +120,16 @@ public class GetResultTests extends ESTestCase {
fields.put("foo", new DocumentField("foo", singletonList("bar"))); fields.put("foo", new DocumentField("foo", singletonList("bar")));
fields.put("baz", new DocumentField("baz", Arrays.asList("baz_0", "baz_1"))); fields.put("baz", new DocumentField("baz", Arrays.asList("baz_0", "baz_1")));
GetResult getResult = new GetResult("index", "type", "id", 2, true, GetResult getResult = new GetResult("index", "type", "id", 0, 1, 2, true,
new BytesArray("{\"foo\":\"bar\",\"baz\":[\"baz_0\",\"baz_1\"]}"), fields); new BytesArray("{\"foo\":\"bar\",\"baz\":[\"baz_0\",\"baz_1\"]}"), fields);
BytesReference originalBytes = toXContentEmbedded(getResult, XContentType.JSON, false); BytesReference originalBytes = toXContentEmbedded(getResult, XContentType.JSON, false);
assertEquals("{\"found\":true,\"_source\":{\"foo\":\"bar\",\"baz\":[\"baz_0\",\"baz_1\"]}," + assertEquals("{\"_seq_no\":0,\"_primary_term\":1,\"found\":true,\"_source\":{\"foo\":\"bar\",\"baz\":[\"baz_0\",\"baz_1\"]}," +
"\"fields\":{\"foo\":[\"bar\"],\"baz\":[\"baz_0\",\"baz_1\"]}}", originalBytes.utf8ToString()); "\"fields\":{\"foo\":[\"bar\"],\"baz\":[\"baz_0\",\"baz_1\"]}}", originalBytes.utf8ToString());
} }
public void testToXContentEmbeddedNotFound() throws IOException { public void testToXContentEmbeddedNotFound() throws IOException {
GetResult getResult = new GetResult("index", "type", "id", 1, false, null, null); GetResult getResult = new GetResult("index", "type", "id", UNASSIGNED_SEQ_NO, 0, 1, false, null, null);
BytesReference originalBytes = toXContentEmbedded(getResult, XContentType.JSON, false); BytesReference originalBytes = toXContentEmbedded(getResult, XContentType.JSON, false);
assertEquals("{\"found\":false}", originalBytes.utf8ToString()); assertEquals("{\"found\":false}", originalBytes.utf8ToString());
@ -149,25 +151,34 @@ public class GetResultTests extends ESTestCase {
} }
public static GetResult copyGetResult(GetResult getResult) { public static GetResult copyGetResult(GetResult getResult) {
return new GetResult(getResult.getIndex(), getResult.getType(), getResult.getId(), getResult.getVersion(), return new GetResult(getResult.getIndex(), getResult.getType(), getResult.getId(),
getResult.isExists(), getResult.internalSourceRef(), getResult.getFields()); getResult.getSeqNo(), getResult.getPrimaryTerm(), getResult.getVersion(),
getResult.isExists(), getResult.internalSourceRef(), getResult.getFields());
} }
public static GetResult mutateGetResult(GetResult getResult) { public static GetResult mutateGetResult(GetResult getResult) {
List<Supplier<GetResult>> mutations = new ArrayList<>(); List<Supplier<GetResult>> mutations = new ArrayList<>();
mutations.add(() -> new GetResult(randomUnicodeOfLength(15), getResult.getType(), getResult.getId(), getResult.getVersion(), mutations.add(() -> new GetResult(randomUnicodeOfLength(15), getResult.getType(), getResult.getId(),
getResult.getSeqNo(), getResult.getPrimaryTerm(), getResult.getVersion(),
getResult.isExists(), getResult.internalSourceRef(), getResult.getFields())); getResult.isExists(), getResult.internalSourceRef(), getResult.getFields()));
mutations.add(() -> new GetResult(getResult.getIndex(), randomUnicodeOfLength(15), getResult.getId(), getResult.getVersion(), mutations.add(() -> new GetResult(getResult.getIndex(), randomUnicodeOfLength(15), getResult.getId(),
getResult.isExists(), getResult.internalSourceRef(), getResult.getFields())); getResult.getSeqNo(), getResult.getPrimaryTerm(), getResult.getVersion(),
mutations.add(() -> new GetResult(getResult.getIndex(), getResult.getType(), randomUnicodeOfLength(15), getResult.getVersion(), getResult.isExists(), getResult.internalSourceRef(), getResult.getFields()));
getResult.isExists(), getResult.internalSourceRef(), getResult.getFields())); mutations.add(() -> new GetResult(getResult.getIndex(), getResult.getType(), randomUnicodeOfLength(15),
mutations.add(() -> new GetResult(getResult.getIndex(), getResult.getType(), getResult.getId(), randomNonNegativeLong(), getResult.getSeqNo(), getResult.getPrimaryTerm(), getResult.getVersion(),
getResult.isExists(), getResult.internalSourceRef(), getResult.getFields())); getResult.isExists(), getResult.internalSourceRef(), getResult.getFields()));
mutations.add(() -> new GetResult(getResult.getIndex(), getResult.getType(), getResult.getId(), getResult.getVersion(), mutations.add(() -> new GetResult(getResult.getIndex(), getResult.getType(), getResult.getId(),
getResult.isExists() == false, getResult.internalSourceRef(), getResult.getFields())); getResult.getSeqNo(), getResult.getPrimaryTerm(), randomNonNegativeLong(),
mutations.add(() -> new GetResult(getResult.getIndex(), getResult.getType(), getResult.getId(), getResult.getVersion(), getResult.isExists(), getResult.internalSourceRef(), getResult.getFields()));
getResult.isExists(), RandomObjects.randomSource(random()), getResult.getFields())); mutations.add(() -> new GetResult(getResult.getIndex(), getResult.getType(), getResult.getId(),
mutations.add(() -> new GetResult(getResult.getIndex(), getResult.getType(), getResult.getId(), getResult.getVersion(), getResult.isExists() ? UNASSIGNED_SEQ_NO : getResult.getSeqNo(),
getResult.isExists() ? 0 : getResult.getPrimaryTerm(),
getResult.getVersion(), getResult.isExists() == false, getResult.internalSourceRef(), getResult.getFields()));
mutations.add(() -> new GetResult(getResult.getIndex(), getResult.getType(), getResult.getId(),
getResult.getSeqNo(), getResult.getPrimaryTerm(), getResult.getVersion(), getResult.isExists(),
RandomObjects.randomSource(random()), getResult.getFields()));
mutations.add(() -> new GetResult(getResult.getIndex(), getResult.getType(), getResult.getId(),
getResult.getSeqNo(), getResult.getPrimaryTerm(), getResult.getVersion(),
getResult.isExists(), getResult.internalSourceRef(), randomDocumentFields(XContentType.JSON).v1())); getResult.isExists(), getResult.internalSourceRef(), randomDocumentFields(XContentType.JSON).v1()));
return randomFrom(mutations).get(); return randomFrom(mutations).get();
} }
@ -177,12 +188,16 @@ public class GetResultTests extends ESTestCase {
final String type = randomAlphaOfLengthBetween(3, 10); final String type = randomAlphaOfLengthBetween(3, 10);
final String id = randomAlphaOfLengthBetween(3, 10); final String id = randomAlphaOfLengthBetween(3, 10);
final long version; final long version;
final long seqNo;
final long primaryTerm;
final boolean exists; final boolean exists;
BytesReference source = null; BytesReference source = null;
Map<String, DocumentField> fields = null; Map<String, DocumentField> fields = null;
Map<String, DocumentField> expectedFields = null; Map<String, DocumentField> expectedFields = null;
if (frequently()) { if (frequently()) {
version = randomNonNegativeLong(); version = randomNonNegativeLong();
seqNo = randomNonNegativeLong();
primaryTerm = randomLongBetween(1, 100);
exists = true; exists = true;
if (frequently()) { if (frequently()) {
source = RandomObjects.randomSource(random()); source = RandomObjects.randomSource(random());
@ -193,11 +208,13 @@ public class GetResultTests extends ESTestCase {
expectedFields = tuple.v2(); expectedFields = tuple.v2();
} }
} else { } else {
seqNo = UNASSIGNED_SEQ_NO;
primaryTerm = 0;
version = -1; version = -1;
exists = false; exists = false;
} }
GetResult getResult = new GetResult(index, type, id, version, exists, source, fields); GetResult getResult = new GetResult(index, type, id, seqNo, primaryTerm, version, exists, source, fields);
GetResult expectedGetResult = new GetResult(index, type, id, version, exists, source, expectedFields); GetResult expectedGetResult = new GetResult(index, type, id, seqNo, primaryTerm, version, exists, source, expectedFields);
return Tuple.tuple(getResult, expectedGetResult); return Tuple.tuple(getResult, expectedGetResult);
} }

View File

@ -131,7 +131,8 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
} catch (IOException ex) { } catch (IOException ex) {
throw new ElasticsearchException("boom", ex); throw new ElasticsearchException("boom", ex);
} }
return new GetResponse(new GetResult(indexedShapeIndex, indexedShapeType, indexedShapeId, 0, true, new BytesArray(json), null)); return new GetResponse(new GetResult(indexedShapeIndex, indexedShapeType, indexedShapeId, 0, 1, 0, true, new BytesArray(json),
null));
} }
@After @After

View File

@ -201,7 +201,8 @@ public class TermsQueryBuilderTests extends AbstractQueryTestCase<TermsQueryBuil
} catch (IOException ex) { } catch (IOException ex) {
throw new ElasticsearchException("boom", ex); throw new ElasticsearchException("boom", ex);
} }
return new GetResponse(new GetResult(getRequest.index(), getRequest.type(), getRequest.id(), 0, true, new BytesArray(json), null)); return new GetResponse(new GetResult(getRequest.index(), getRequest.type(), getRequest.id(), 0, 1, 0, true,
new BytesArray(json), null));
} }
public void testNumeric() throws IOException { public void testNumeric() throws IOException {

View File

@ -32,6 +32,7 @@ import org.elasticsearch.test.rest.FakeRestRequest;
import org.junit.AfterClass; import org.junit.AfterClass;
import static java.util.Collections.emptyMap; import static java.util.Collections.emptyMap;
import static org.elasticsearch.index.seqno.SequenceNumbers.UNASSIGNED_SEQ_NO;
import static org.elasticsearch.rest.RestStatus.OK; import static org.elasticsearch.rest.RestStatus.OK;
import static org.elasticsearch.rest.action.document.RestGetSourceAction.RestGetSourceResponseListener; import static org.elasticsearch.rest.action.document.RestGetSourceAction.RestGetSourceResponseListener;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
@ -51,7 +52,8 @@ public class RestGetSourceActionTests extends ESTestCase {
public void testRestGetSourceAction() throws Exception { public void testRestGetSourceAction() throws Exception {
final BytesReference source = new BytesArray("{\"foo\": \"bar\"}"); final BytesReference source = new BytesArray("{\"foo\": \"bar\"}");
final GetResponse response = new GetResponse(new GetResult("index1", "_doc", "1", -1, true, source, emptyMap())); final GetResponse response =
new GetResponse(new GetResult("index1", "_doc", "1", UNASSIGNED_SEQ_NO, 0, -1, true, source, emptyMap()));
final RestResponse restResponse = listener.buildResponse(response); final RestResponse restResponse = listener.buildResponse(response);
@ -61,7 +63,8 @@ public class RestGetSourceActionTests extends ESTestCase {
} }
public void testRestGetSourceActionWithMissingDocument() { public void testRestGetSourceActionWithMissingDocument() {
final GetResponse response = new GetResponse(new GetResult("index1", "_doc", "1", -1, false, null, emptyMap())); final GetResponse response =
new GetResponse(new GetResult("index1", "_doc", "1", UNASSIGNED_SEQ_NO, 0, -1, false, null, emptyMap()));
final ResourceNotFoundException exception = expectThrows(ResourceNotFoundException.class, () -> listener.buildResponse(response)); final ResourceNotFoundException exception = expectThrows(ResourceNotFoundException.class, () -> listener.buildResponse(response));
@ -69,7 +72,8 @@ public class RestGetSourceActionTests extends ESTestCase {
} }
public void testRestGetSourceActionWithMissingDocumentSource() { public void testRestGetSourceActionWithMissingDocumentSource() {
final GetResponse response = new GetResponse(new GetResult("index1", "_doc", "1", -1, true, null, emptyMap())); final GetResponse response =
new GetResponse(new GetResult("index1", "_doc", "1", UNASSIGNED_SEQ_NO, 0, -1, true, null, emptyMap()));
final ResourceNotFoundException exception = expectThrows(ResourceNotFoundException.class, () -> listener.buildResponse(response)); final ResourceNotFoundException exception = expectThrows(ResourceNotFoundException.class, () -> listener.buildResponse(response));

View File

@ -24,6 +24,7 @@ import org.elasticsearch.action.DocWriteRequest;
import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteResponse; import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.metadata.IndexMetaData;
@ -311,12 +312,11 @@ public class SimpleVersioningIT extends ESIntegTestCase {
assertThrows(client().prepareDelete("test", "type", "1").setIfMatch(1, 2).execute(), VersionConflictEngineException.class); assertThrows(client().prepareDelete("test", "type", "1").setIfMatch(1, 2).execute(), VersionConflictEngineException.class);
client().admin().indices().prepareRefresh().execute().actionGet(); client().admin().indices().prepareRefresh().execute().actionGet();
// TODO: Enable once get response returns seqNo for (int i = 0; i < 10; i++) {
// for (int i = 0; i < 10; i++) { final GetResponse response = client().prepareGet("test", "type", "1").get();
// final GetResponse response = client().prepareGet("test", "type", "1").get(); assertThat(response.getSeqNo(), equalTo(1L));
// assertThat(response.getSeqNo(), equalTo(1L)); assertThat(response.getPrimaryTerm(), equalTo(1L));
// assertThat(response.getPrimaryTerm(), equalTo(1L)); }
// }
// search with versioning // search with versioning
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {

View File

@ -45,6 +45,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer; import java.util.function.Consumer;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.seqno.SequenceNumbers.UNASSIGNED_SEQ_NO;
import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.notNullValue;
@ -112,7 +113,7 @@ public class NativeUsersStoreTests extends ESTestCase {
SecurityIndexManager.SECURITY_INDEX_NAME, SecurityIndexManager.SECURITY_INDEX_NAME,
NativeUsersStore.INDEX_TYPE, NativeUsersStore.INDEX_TYPE,
NativeUsersStore.getIdForUser(NativeUsersStore.RESERVED_USER_TYPE, randomAlphaOfLength(12)), NativeUsersStore.getIdForUser(NativeUsersStore.RESERVED_USER_TYPE, randomAlphaOfLength(12)),
1L, 0, 1, 1L,
true, true,
BytesReference.bytes(jsonBuilder().map(values)), BytesReference.bytes(jsonBuilder().map(values)),
Collections.emptyMap()); Collections.emptyMap());
@ -181,7 +182,7 @@ public class NativeUsersStoreTests extends ESTestCase {
SecurityIndexManager.SECURITY_INDEX_NAME, SecurityIndexManager.SECURITY_INDEX_NAME,
NativeUsersStore.INDEX_TYPE, NativeUsersStore.INDEX_TYPE,
NativeUsersStore.getIdForUser(NativeUsersStore.USER_DOC_TYPE, username), NativeUsersStore.getIdForUser(NativeUsersStore.USER_DOC_TYPE, username),
1L, UNASSIGNED_SEQ_NO, 0, 1L,
false, false,
null, null,
Collections.emptyMap()); Collections.emptyMap());
@ -223,7 +224,7 @@ public class NativeUsersStoreTests extends ESTestCase {
SecurityIndexManager.SECURITY_INDEX_NAME, SecurityIndexManager.SECURITY_INDEX_NAME,
NativeUsersStore.INDEX_TYPE, NativeUsersStore.INDEX_TYPE,
NativeUsersStore.getIdForUser(NativeUsersStore.USER_DOC_TYPE, username), NativeUsersStore.getIdForUser(NativeUsersStore.USER_DOC_TYPE, username),
1L, 0, 1, 1L,
true, true,
source, source,
Collections.emptyMap()); Collections.emptyMap());

View File

@ -56,6 +56,7 @@ import java.util.function.Consumer;
import static java.util.Collections.emptyMap; import static java.util.Collections.emptyMap;
import static org.elasticsearch.common.util.set.Sets.newHashSet; import static org.elasticsearch.common.util.set.Sets.newHashSet;
import static org.elasticsearch.index.seqno.SequenceNumbers.UNASSIGNED_SEQ_NO;
import static org.hamcrest.Matchers.arrayContaining; import static org.hamcrest.Matchers.arrayContaining;
import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsInAnyOrder;
@ -129,7 +130,7 @@ public class NativePrivilegeStoreTests extends ESTestCase {
final String docSource = Strings.toString(sourcePrivilege); final String docSource = Strings.toString(sourcePrivilege);
listener.get().onResponse(new GetResponse( listener.get().onResponse(new GetResponse(
new GetResult(request.index(), request.type(), request.id(), 1L, true, new BytesArray(docSource), emptyMap()) new GetResult(request.index(), request.type(), request.id(), 0, 1, 1L, true, new BytesArray(docSource), emptyMap())
)); ));
final ApplicationPrivilegeDescriptor getPrivilege = future.get(1, TimeUnit.SECONDS); final ApplicationPrivilegeDescriptor getPrivilege = future.get(1, TimeUnit.SECONDS);
assertThat(getPrivilege, equalTo(sourcePrivilege)); assertThat(getPrivilege, equalTo(sourcePrivilege));
@ -146,7 +147,7 @@ public class NativePrivilegeStoreTests extends ESTestCase {
assertThat(request.id(), equalTo("application-privilege_myapp:admin")); assertThat(request.id(), equalTo("application-privilege_myapp:admin"));
listener.get().onResponse(new GetResponse( listener.get().onResponse(new GetResponse(
new GetResult(request.index(), request.type(), request.id(), -1, false, null, emptyMap()) new GetResult(request.index(), request.type(), request.id(), UNASSIGNED_SEQ_NO, 0, -1, false, null, emptyMap())
)); ));
final ApplicationPrivilegeDescriptor getPrivilege = future.get(1, TimeUnit.SECONDS); final ApplicationPrivilegeDescriptor getPrivilege = future.get(1, TimeUnit.SECONDS);
assertThat(getPrivilege, Matchers.nullValue()); assertThat(getPrivilege, Matchers.nullValue());

View File

@ -24,6 +24,7 @@ import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException;
import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.common.xcontent.DeprecationHandler; import org.elasticsearch.common.xcontent.DeprecationHandler;
import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.ObjectPath;
import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.common.xcontent.XContentType;
@ -53,7 +54,6 @@ import org.elasticsearch.xpack.core.watcher.execution.Wid;
import org.elasticsearch.xpack.core.watcher.history.WatchRecord; import org.elasticsearch.xpack.core.watcher.history.WatchRecord;
import org.elasticsearch.xpack.core.watcher.input.ExecutableInput; import org.elasticsearch.xpack.core.watcher.input.ExecutableInput;
import org.elasticsearch.xpack.core.watcher.input.Input; import org.elasticsearch.xpack.core.watcher.input.Input;
import org.elasticsearch.common.xcontent.ObjectPath;
import org.elasticsearch.xpack.core.watcher.transform.ExecutableTransform; import org.elasticsearch.xpack.core.watcher.transform.ExecutableTransform;
import org.elasticsearch.xpack.core.watcher.transform.Transform; import org.elasticsearch.xpack.core.watcher.transform.Transform;
import org.elasticsearch.xpack.core.watcher.trigger.TriggerEvent; import org.elasticsearch.xpack.core.watcher.trigger.TriggerEvent;
@ -88,6 +88,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static java.util.Collections.singletonMap; import static java.util.Collections.singletonMap;
import static org.elasticsearch.common.unit.TimeValue.timeValueSeconds; import static org.elasticsearch.common.unit.TimeValue.timeValueSeconds;
import static org.elasticsearch.index.seqno.SequenceNumbers.UNASSIGNED_SEQ_NO;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.hasSize;
@ -1148,7 +1149,8 @@ public class ExecutionServiceTests extends ESTestCase {
if (request.id().equals(id)) { if (request.id().equals(id)) {
listener.onResponse(response); listener.onResponse(response);
} else { } else {
GetResult notFoundResult = new GetResult(request.index(), request.type(), request.id(), -1, false, null, null); GetResult notFoundResult =
new GetResult(request.index(), request.type(), request.id(), UNASSIGNED_SEQ_NO, 0, -1, false, null, null);
listener.onResponse(new GetResponse(notFoundResult)); listener.onResponse(new GetResponse(notFoundResult));
} }
return null; return null;
@ -1162,7 +1164,8 @@ public class ExecutionServiceTests extends ESTestCase {
if (request.id().equals(id)) { if (request.id().equals(id)) {
listener.onFailure(e); listener.onFailure(e);
} else { } else {
GetResult notFoundResult = new GetResult(request.index(), request.type(), request.id(), -1, false, null, null); GetResult notFoundResult =
new GetResult(request.index(), request.type(), request.id(), UNASSIGNED_SEQ_NO, 0, -1, false, null, null);
listener.onResponse(new GetResponse(notFoundResult)); listener.onResponse(new GetResponse(notFoundResult));
} }
return null; return null;

View File

@ -38,6 +38,7 @@ import java.time.Clock;
import java.util.Collections; import java.util.Collections;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import static org.elasticsearch.index.seqno.SequenceNumbers.UNASSIGNED_SEQ_NO;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.mockito.Matchers.anyObject; import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.eq; import static org.mockito.Matchers.eq;
@ -67,7 +68,7 @@ public class TransportAckWatchActionTests extends ESTestCase {
String watchId = "my_watch_id"; String watchId = "my_watch_id";
doAnswer(invocation -> { doAnswer(invocation -> {
ActionListener<GetResponse> listener = (ActionListener<GetResponse>) invocation.getArguments()[1]; ActionListener<GetResponse> listener = (ActionListener<GetResponse>) invocation.getArguments()[1];
listener.onResponse(new GetResponse(new GetResult(Watch.INDEX, Watch.DOC_TYPE, watchId, -1, false, listener.onResponse(new GetResponse(new GetResult(Watch.INDEX, Watch.DOC_TYPE, watchId, UNASSIGNED_SEQ_NO, 0, -1, false,
BytesArray.EMPTY, Collections.emptyMap()))); BytesArray.EMPTY, Collections.emptyMap())));
return null; return null;
}).when(client).get(anyObject(), anyObject()); }).when(client).get(anyObject(), anyObject());