Skip to content

Commit b4c75d9

Browse files
committed
Merge branch 'master' into feature/eql
2 parents ba605f4 + 6d4de1f commit b4c75d9

File tree

55 files changed

+1610
-1086
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1610
-1086
lines changed

.ci/matrix-runtime-javas.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ ES_RUNTIME_JAVA:
99
- java11
1010
- openjdk13
1111
- openjdk14
12+
- openjdk15
1213
- zulu11
1314
- corretto11
1415
- adoptopenjdk11

buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import org.elasticsearch.gradle.precommit.PrecommitTasks
3232
import org.elasticsearch.gradle.test.ErrorReportingTestListener
3333
import org.elasticsearch.gradle.testclusters.ElasticsearchCluster
3434
import org.elasticsearch.gradle.testclusters.TestClustersPlugin
35+
import org.elasticsearch.gradle.testclusters.TestDistribution
3536
import org.elasticsearch.gradle.tool.Boilerplate
3637
import org.gradle.api.Action
3738
import org.gradle.api.GradleException
@@ -159,6 +160,7 @@ class BuildPlugin implements Plugin<Project> {
159160
for (File dep : project.getConfigurations().getByName("extraJars").getFiles()){
160161
cluster.extraJarFile(dep)
161162
}
163+
cluster.setTestDistribution(TestDistribution.DEFAULT)
162164
cluster.extraConfigFile("fips_java.security", securityProperties)
163165
cluster.extraConfigFile("fips_java.policy", securityPolicy)
164166
cluster.extraConfigFile("cacerts.bcfks", bcfksKeystore)

client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import org.elasticsearch.action.support.WriteRequest;
5050
import org.elasticsearch.action.update.UpdateRequest;
5151
import org.elasticsearch.client.core.CountRequest;
52+
import org.elasticsearch.client.core.GetSourceRequest;
5253
import org.elasticsearch.client.core.MultiTermVectorsRequest;
5354
import org.elasticsearch.client.core.TermVectorsRequest;
5455
import org.elasticsearch.client.indices.AnalyzeRequest;
@@ -275,14 +276,30 @@ private static Request getStyleRequest(String method, GetRequest getRequest) {
275276
}
276277

277278
static Request sourceExists(GetRequest getRequest) {
278-
String endpoint = endpoint(getRequest.index(), "_source", getRequest.id());
279-
Request request = new Request(HttpHead.METHOD_NAME, endpoint);
280279
Params parameters = new Params();
281280
parameters.withPreference(getRequest.preference());
282281
parameters.withRouting(getRequest.routing());
283282
parameters.withRefresh(getRequest.refresh());
284283
parameters.withRealtime(getRequest.realtime());
285-
// Version params are not currently supported by the source exists API so are not passed
284+
parameters.withFetchSourceContext(getRequest.fetchSourceContext());
285+
// Version params are not currently supported by the _source API so are not passed
286+
287+
String endpoint = endpoint(getRequest.index(), "_source", getRequest.id());
288+
Request request = new Request(HttpHead.METHOD_NAME, endpoint);
289+
request.addParameters(parameters.asMap());
290+
return request;
291+
}
292+
293+
static Request getSource(GetSourceRequest getSourceRequest) {
294+
Params parameters = new Params();
295+
parameters.withPreference(getSourceRequest.preference());
296+
parameters.withRouting(getSourceRequest.routing());
297+
parameters.withRefresh(getSourceRequest.refresh());
298+
parameters.withRealtime(getSourceRequest.realtime());
299+
parameters.withFetchSourceContext(getSourceRequest.fetchSourceContext());
300+
301+
String endpoint = endpoint(getSourceRequest.index(), "_source", getSourceRequest.id());
302+
Request request = new Request(HttpGet.METHOD_NAME, endpoint);
286303
request.addParameters(parameters.asMap());
287304
return request;
288305
}

client/rest-high-level/src/main/java/org/elasticsearch/client/RestHighLevelClient.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@
5656
import org.elasticsearch.action.update.UpdateResponse;
5757
import org.elasticsearch.client.core.CountRequest;
5858
import org.elasticsearch.client.core.CountResponse;
59+
import org.elasticsearch.client.core.GetSourceRequest;
60+
import org.elasticsearch.client.core.GetSourceResponse;
5961
import org.elasticsearch.client.core.MainRequest;
6062
import org.elasticsearch.client.core.MainResponse;
6163
import org.elasticsearch.client.core.MultiTermVectorsRequest;
@@ -860,6 +862,34 @@ public final Cancellable existsSourceAsync(GetRequest getRequest, RequestOptions
860862
RestHighLevelClient::convertExistsResponse, listener, emptySet());
861863
}
862864

865+
/**
866+
* Retrieves the source field only of a document using GetSource API.
867+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-get.html#_source">Get Source API
868+
* on elastic.co</a>
869+
* @param getRequest the request
870+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
871+
* @return the response
872+
*/
873+
public GetSourceResponse getSource(GetSourceRequest getRequest, RequestOptions options) throws IOException {
874+
return performRequestAndParseEntity(getRequest, RequestConverters::getSource, options,
875+
GetSourceResponse::fromXContent, emptySet());
876+
}
877+
878+
/**
879+
* Asynchronously retrieves the source field only of a document using GetSource API.
880+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-get.html#_source">Get Source API
881+
* on elastic.co</a>
882+
* @param getRequest the request
883+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
884+
* @param listener the listener to be notified upon request completion
885+
* @return cancellable that may be used to cancel the request
886+
*/
887+
public final Cancellable getSourceAsync(GetSourceRequest getRequest, RequestOptions options,
888+
ActionListener<GetSourceResponse> listener) {
889+
return performRequestAsyncAndParseEntity(getRequest, RequestConverters::getSource, options,
890+
GetSourceResponse::fromXContent, listener, emptySet());
891+
}
892+
863893
/**
864894
* Index a document using the Index API.
865895
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-index_.html">Index API on elastic.co</a>
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.client.core;
21+
22+
import org.elasticsearch.client.Validatable;
23+
import org.elasticsearch.common.xcontent.ToXContentObject;
24+
import org.elasticsearch.common.xcontent.XContentBuilder;
25+
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
26+
27+
import java.io.IOException;
28+
29+
public final class GetSourceRequest implements Validatable, ToXContentObject {
30+
private String routing;
31+
private String preference;
32+
33+
private boolean refresh = false;
34+
private boolean realtime = true;
35+
36+
private FetchSourceContext fetchSourceContext;
37+
38+
private String index;
39+
private String id;
40+
41+
public GetSourceRequest(String index, String id) {
42+
this.index = index;
43+
this.id = id;
44+
}
45+
46+
/**
47+
* Controls the shard routing of the request. Using this value to hash the shard
48+
* and not the id.
49+
*/
50+
public GetSourceRequest routing(String routing) {
51+
if (routing != null && routing.length() == 0) {
52+
this.routing = null;
53+
} else {
54+
this.routing = routing;
55+
}
56+
return this;
57+
}
58+
59+
/**
60+
* Sets the preference to execute the search. Defaults to randomize across shards. Can be set to
61+
* {@code _local} to prefer local shards or a custom value, which guarantees that the same order
62+
* will be used across different requests.
63+
*/
64+
public GetSourceRequest preference(String preference) {
65+
this.preference = preference;
66+
return this;
67+
}
68+
69+
/**
70+
* Should a refresh be executed before this get operation causing the operation to
71+
* return the latest value. Note, heavy get should not set this to {@code true}. Defaults
72+
* to {@code false}.
73+
*/
74+
public GetSourceRequest refresh(boolean refresh) {
75+
this.refresh = refresh;
76+
return this;
77+
}
78+
79+
public GetSourceRequest realtime(boolean realtime) {
80+
this.realtime = realtime;
81+
return this;
82+
}
83+
84+
/**
85+
* Allows setting the {@link FetchSourceContext} for this request, controlling if and how _source should be returned.
86+
* Note, the {@code fetchSource} field of the context must be set to {@code true}.
87+
*/
88+
89+
public GetSourceRequest fetchSourceContext(FetchSourceContext context) {
90+
this.fetchSourceContext = context;
91+
return this;
92+
}
93+
94+
@Override
95+
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
96+
return null;
97+
}
98+
99+
public String index() {
100+
return index;
101+
}
102+
103+
public String id() {
104+
return id;
105+
}
106+
107+
public String routing() {
108+
return routing;
109+
}
110+
111+
public String preference() {
112+
return preference;
113+
}
114+
115+
public boolean refresh() {
116+
return refresh;
117+
}
118+
119+
public boolean realtime() {
120+
return realtime;
121+
}
122+
123+
public FetchSourceContext fetchSourceContext() {
124+
return fetchSourceContext;
125+
}
126+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.client.core;
21+
22+
import org.elasticsearch.common.xcontent.XContentParser;
23+
24+
import java.io.IOException;
25+
import java.util.Map;
26+
27+
public final class GetSourceResponse {
28+
29+
private final Map<String, Object> source;
30+
31+
public GetSourceResponse(Map<String, Object> source) {
32+
this.source = source;
33+
}
34+
35+
public static GetSourceResponse fromXContent(XContentParser parser) throws IOException {
36+
return new GetSourceResponse(parser.map());
37+
}
38+
39+
public Map<String, Object> getSource() {
40+
return this.source;
41+
}
42+
43+
@Override
44+
public String toString() {
45+
return source.toString();
46+
}
47+
}

client/rest-high-level/src/test/java/org/elasticsearch/client/CrudIT.java

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
import org.elasticsearch.action.support.WriteRequest.RefreshPolicy;
3939
import org.elasticsearch.action.update.UpdateRequest;
4040
import org.elasticsearch.action.update.UpdateResponse;
41+
import org.elasticsearch.client.core.GetSourceRequest;
42+
import org.elasticsearch.client.core.GetSourceResponse;
4143
import org.elasticsearch.client.core.MultiTermVectorsRequest;
4244
import org.elasticsearch.client.core.MultiTermVectorsResponse;
4345
import org.elasticsearch.client.core.TermVectorsRequest;
@@ -64,6 +66,7 @@
6466
import java.io.IOException;
6567
import java.util.ArrayList;
6668
import java.util.Collections;
69+
import java.util.HashMap;
6770
import java.util.List;
6871
import java.util.Map;
6972
import java.util.concurrent.atomic.AtomicReference;
@@ -359,6 +362,71 @@ public void testMultiGet() throws IOException {
359362
}
360363
}
361364

365+
public void testGetSource() throws IOException {
366+
{
367+
GetSourceRequest getRequest = new GetSourceRequest("index", "id");
368+
ElasticsearchException exception = expectThrows(ElasticsearchException.class,
369+
() -> execute(getRequest, highLevelClient()::getSource, highLevelClient()::getSourceAsync));
370+
assertEquals(RestStatus.NOT_FOUND, exception.status());
371+
assertEquals("Elasticsearch exception [type=index_not_found_exception, reason=no such index [index]]", exception.getMessage());
372+
assertEquals("index", exception.getMetadata("es.index").get(0));
373+
}
374+
IndexRequest index = new IndexRequest("index").id("id");
375+
String document = "{\"field1\":\"value1\",\"field2\":\"value2\"}";
376+
index.source(document, XContentType.JSON);
377+
index.setRefreshPolicy(RefreshPolicy.IMMEDIATE);
378+
highLevelClient().index(index, RequestOptions.DEFAULT);
379+
{
380+
GetSourceRequest getRequest = new GetSourceRequest("index", "id");
381+
GetSourceResponse response = execute(getRequest, highLevelClient()::getSource, highLevelClient()::getSourceAsync);
382+
Map<String, Object> expectedResponse = new HashMap<>();
383+
expectedResponse.put("field1", "value1");
384+
expectedResponse.put("field2", "value2");
385+
assertEquals(expectedResponse, response.getSource());
386+
}
387+
{
388+
GetSourceRequest getRequest = new GetSourceRequest("index", "does_not_exist");
389+
ElasticsearchException exception = expectThrows(ElasticsearchException.class,
390+
() -> execute(getRequest, highLevelClient()::getSource, highLevelClient()::getSourceAsync));
391+
assertEquals(RestStatus.NOT_FOUND, exception.status());
392+
assertEquals("Elasticsearch exception [type=resource_not_found_exception, " +
393+
"reason=Document not found [index]/[does_not_exist]]", exception.getMessage());
394+
}
395+
{
396+
GetSourceRequest getRequest = new GetSourceRequest("index", "id");
397+
getRequest.fetchSourceContext(new FetchSourceContext(true, Strings.EMPTY_ARRAY, Strings.EMPTY_ARRAY));
398+
GetSourceResponse response = execute(getRequest, highLevelClient()::getSource, highLevelClient()::getSourceAsync);
399+
Map<String, Object> expectedResponse = new HashMap<>();
400+
expectedResponse.put("field1", "value1");
401+
expectedResponse.put("field2", "value2");
402+
assertEquals(expectedResponse, response.getSource());
403+
}
404+
{
405+
GetSourceRequest getRequest = new GetSourceRequest("index", "id");
406+
getRequest.fetchSourceContext(new FetchSourceContext(true, new String[]{"field1"}, Strings.EMPTY_ARRAY));
407+
GetSourceResponse response = execute(getRequest, highLevelClient()::getSource, highLevelClient()::getSourceAsync);
408+
Map<String, Object> expectedResponse = new HashMap<>();
409+
expectedResponse.put("field1", "value1");
410+
assertEquals(expectedResponse, response.getSource());
411+
}
412+
{
413+
GetSourceRequest getRequest = new GetSourceRequest("index", "id");
414+
getRequest.fetchSourceContext(new FetchSourceContext(true, Strings.EMPTY_ARRAY, new String[]{"field1"}));
415+
GetSourceResponse response = execute(getRequest, highLevelClient()::getSource, highLevelClient()::getSourceAsync);
416+
Map<String, Object> expectedResponse = new HashMap<>();
417+
expectedResponse.put("field2", "value2");
418+
assertEquals(expectedResponse, response.getSource());
419+
}
420+
{
421+
GetSourceRequest getRequest = new GetSourceRequest("index", "id");
422+
getRequest.fetchSourceContext(new FetchSourceContext(false));
423+
ElasticsearchException exception = expectThrows(ElasticsearchException.class,
424+
() -> execute(getRequest, highLevelClient()::getSource, highLevelClient()::getSourceAsync));
425+
assertEquals("Elasticsearch exception [type=action_request_validation_exception, " +
426+
"reason=Validation Failed: 1: fetching source can not be disabled;]", exception.getMessage());
427+
}
428+
}
429+
362430
public void testIndex() throws IOException {
363431
final XContentType xContentType = randomFrom(XContentType.values());
364432
{

0 commit comments

Comments
 (0)