diff --git a/modules/reindex/src/main/java/org/elasticsearch/index/reindex/ReindexRequest.java b/modules/reindex/src/main/java/org/elasticsearch/index/reindex/ReindexRequest.java index 618db3dfa48..2f684fe96ea 100644 --- a/modules/reindex/src/main/java/org/elasticsearch/index/reindex/ReindexRequest.java +++ b/modules/reindex/src/main/java/org/elasticsearch/index/reindex/ReindexRequest.java @@ -71,6 +71,9 @@ public class ReindexRequest extends AbstractBulkIndexByScrollRequest { remoteVersion = version; execute("POST", initialSearchPath(searchRequest), initialSearchParams(searchRequest, version), - initialSearchEntity(query), RESPONSE_PARSER, r -> onStartResponse(onResponse, r)); + initialSearchEntity(searchRequest, query), RESPONSE_PARSER, r -> onStartResponse(onResponse, r)); }); } diff --git a/modules/reindex/src/test/java/org/elasticsearch/index/reindex/remote/RemoteRequestBuildersTests.java b/modules/reindex/src/test/java/org/elasticsearch/index/reindex/remote/RemoteRequestBuildersTests.java index dec5263352a..3de7e09debe 100644 --- a/modules/reindex/src/test/java/org/elasticsearch/index/reindex/remote/RemoteRequestBuildersTests.java +++ b/modules/reindex/src/test/java/org/elasticsearch/index/reindex/remote/RemoteRequestBuildersTests.java @@ -152,20 +152,29 @@ public class RemoteRequestBuildersTests extends ESTestCase { assertThat(params, scroll == null ? not(hasKey("scroll")) : hasEntry("scroll", scroll.toString())); assertThat(params, hasEntry("size", Integer.toString(size))); assertThat(params, fetchVersion == null || fetchVersion == true ? hasEntry("version", null) : not(hasEntry("version", null))); - assertThat(params, hasEntry("_source", "true")); } public void testInitialSearchEntity() throws IOException { + SearchRequest searchRequest = new SearchRequest(); + searchRequest.source(new SearchSourceBuilder()); String query = "{\"match_all\":{}}"; - HttpEntity entity = initialSearchEntity(new BytesArray(query)); + HttpEntity entity = initialSearchEntity(searchRequest, new BytesArray(query)); assertEquals(ContentType.APPLICATION_JSON.toString(), entity.getContentType().getValue()); assertEquals("{\"query\":" + query + "}", Streams.copyToString(new InputStreamReader(entity.getContent(), StandardCharsets.UTF_8))); + // Source filtering is included if set up + searchRequest.source().fetchSource(new String[] {"in1", "in2"}, new String[] {"out"}); + entity = initialSearchEntity(searchRequest, new BytesArray(query)); + assertEquals(ContentType.APPLICATION_JSON.toString(), entity.getContentType().getValue()); + assertEquals("{\"query\":" + query + ",\"_source\":{\"includes\":[\"in1\",\"in2\"],\"excludes\":[\"out\"]}}", + Streams.copyToString(new InputStreamReader(entity.getContent(), StandardCharsets.UTF_8))); + // Invalid XContent fails - RuntimeException e = expectThrows(RuntimeException.class, () -> initialSearchEntity(new BytesArray("{}, \"trailing\": {}"))); + RuntimeException e = expectThrows(RuntimeException.class, + () -> initialSearchEntity(searchRequest, new BytesArray("{}, \"trailing\": {}"))); assertThat(e.getCause().getMessage(), containsString("Unexpected character (',' (code 44))")); - e = expectThrows(RuntimeException.class, () -> initialSearchEntity(new BytesArray("{"))); + e = expectThrows(RuntimeException.class, () -> initialSearchEntity(searchRequest, new BytesArray("{"))); assertThat(e.getCause().getMessage(), containsString("Unexpected end-of-input")); } diff --git a/modules/reindex/src/test/resources/rest-api-spec/test/reindex/10_basic.yaml b/modules/reindex/src/test/resources/rest-api-spec/test/reindex/10_basic.yaml index a567ca67bfa..403382622f1 100644 --- a/modules/reindex/src/test/resources/rest-api-spec/test/reindex/10_basic.yaml +++ b/modules/reindex/src/test/resources/rest-api-spec/test/reindex/10_basic.yaml @@ -416,3 +416,42 @@ type: foo id: 1 - match: { _source: {} } + +--- +"Reindex with source filtering": + - do: + index: + index: source + type: foo + id: 1 + body: { "text": "test", "filtered": "removed" } + refresh: true + + - do: + reindex: + refresh: true + body: + source: + index: source + _source: + excludes: + - filtered + dest: + index: dest + - match: {created: 1} + - match: {updated: 0} + - match: {version_conflicts: 0} + - match: {batches: 1} + - match: {failures: []} + - match: {throttled_millis: 0} + - gte: { took: 0 } + - is_false: task + - is_false: deleted + + - do: + get: + index: dest + type: foo + id: 1 + - match: { _source.text: "test" } + - is_false: _source.filtered diff --git a/modules/reindex/src/test/resources/rest-api-spec/test/reindex/20_validation.yaml b/modules/reindex/src/test/resources/rest-api-spec/test/reindex/20_validation.yaml index 50f12192960..c9f441c9cd3 100644 --- a/modules/reindex/src/test/resources/rest-api-spec/test/reindex/20_validation.yaml +++ b/modules/reindex/src/test/resources/rest-api-spec/test/reindex/20_validation.yaml @@ -295,3 +295,21 @@ index: test dest: index: dest + +--- +"_source:false is rejected": + - do: + index: + index: source + type: foo + id: 1 + body: { "text": "test" } + - do: + catch: /_source:false is not supported in this context/ + reindex: + body: + source: + index: source + _source: false + dest: + index: dest diff --git a/modules/reindex/src/test/resources/rest-api-spec/test/reindex/90_remote.yaml b/modules/reindex/src/test/resources/rest-api-spec/test/reindex/90_remote.yaml index ab47a306f57..7b10a4612e6 100644 --- a/modules/reindex/src/test/resources/rest-api-spec/test/reindex/90_remote.yaml +++ b/modules/reindex/src/test/resources/rest-api-spec/test/reindex/90_remote.yaml @@ -311,3 +311,53 @@ index: source dest: index: dest + +--- +"Reindex from remote with source filtering": + - do: + index: + index: source + type: foo + id: 1 + body: { "text": "test", "filtered": "removed" } + refresh: true + + # Fetch the http host. We use the host of the master because we know there will always be a master. + - do: + cluster.state: {} + - set: { master_node: master } + - do: + nodes.info: + metric: [ http ] + - is_true: nodes.$master.http.publish_address + - set: {nodes.$master.http.publish_address: host} + - do: + reindex: + refresh: true + body: + source: + remote: + host: http://${host} + index: source + _source: + excludes: + - filtered + dest: + index: dest + - match: {created: 1} + - match: {updated: 0} + - match: {version_conflicts: 0} + - match: {batches: 1} + - match: {failures: []} + - match: {throttled_millis: 0} + - gte: { took: 0 } + - is_false: task + - is_false: deleted + + - do: + get: + index: dest + type: foo + id: 1 + - match: { _source.text: "test" } + - is_false: _source.filtered