Skip to content

Commit 70c14a5

Browse files
author
Vladimir Dolzhenko
committed
Add get stored script and delete stored script to high level REST API
Relates to #27205 (cherry picked from commit 04e4e44)
1 parent e2e59a8 commit 70c14a5

File tree

16 files changed

+789
-46
lines changed

16 files changed

+789
-46
lines changed

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryRequest;
3838
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryRequest;
3939
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
40+
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
41+
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
4042
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
4143
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
4244
import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheRequest;
@@ -903,6 +905,23 @@ static Request getAlias(GetAliasesRequest getAliasesRequest) {
903905
return request;
904906
}
905907

908+
static Request getScript(GetStoredScriptRequest getStoredScriptRequest) {
909+
String endpoint = new EndpointBuilder().addPathPartAsIs("_scripts").addPathPart(getStoredScriptRequest.id()).build();
910+
Request request = new Request(HttpGet.METHOD_NAME, endpoint);
911+
Params params = new Params(request);
912+
params.withMasterTimeout(getStoredScriptRequest.masterNodeTimeout());
913+
return request;
914+
}
915+
916+
static Request deleteScript(DeleteStoredScriptRequest deleteStoredScriptRequest) {
917+
String endpoint = new EndpointBuilder().addPathPartAsIs("_scripts").addPathPart(deleteStoredScriptRequest.id()).build();
918+
Request request = new Request(HttpDelete.METHOD_NAME, endpoint);
919+
Params params = new Params(request);
920+
params.withTimeout(deleteStoredScriptRequest.timeout());
921+
params.withMasterTimeout(deleteStoredScriptRequest.masterNodeTimeout());
922+
return request;
923+
}
924+
906925
private static HttpEntity createEntity(ToXContent toXContent, XContentType xContentType) throws IOException {
907926
BytesRef source = XContentHelper.toXContent(toXContent, xContentType, false).toBytesRef();
908927
return new ByteArrayEntity(source.bytes, source.offset, source.length, createContentType(xContentType));

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

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
import org.elasticsearch.action.ActionListener;
2727
import org.elasticsearch.action.ActionRequest;
2828
import org.elasticsearch.action.ActionRequestValidationException;
29+
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
30+
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptResponse;
31+
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
32+
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptResponse;
2933
import org.elasticsearch.action.bulk.BulkRequest;
3034
import org.elasticsearch.action.bulk.BulkResponse;
3135
import org.elasticsearch.action.delete.DeleteRequest;
@@ -963,6 +967,62 @@ public final FieldCapabilitiesResponse fieldCaps(FieldCapabilitiesRequest fieldC
963967
FieldCapabilitiesResponse::fromXContent, emptySet());
964968
}
965969

970+
/**
971+
* Get stored script by id.
972+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting-using.html">
973+
* How to use scripts on elastic.co</a>
974+
* @param request the request
975+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
976+
* @return the response
977+
* @throws IOException in case there is a problem sending the request or parsing back the response
978+
*/
979+
public GetStoredScriptResponse getScript(GetStoredScriptRequest request, RequestOptions options) throws IOException {
980+
return performRequestAndParseEntity(request, RequestConverters::getScript, options,
981+
GetStoredScriptResponse::fromXContent, emptySet());
982+
}
983+
984+
/**
985+
* Asynchronously get stored script by id.
986+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting-using.html">
987+
* How to use scripts on elastic.co</a>
988+
* @param request the request
989+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
990+
* @param listener the listener to be notified upon request completion
991+
*/
992+
public void getScriptAsync(GetStoredScriptRequest request, RequestOptions options,
993+
ActionListener<GetStoredScriptResponse> listener) {
994+
performRequestAsyncAndParseEntity(request, RequestConverters::getScript, options,
995+
GetStoredScriptResponse::fromXContent, listener, emptySet());
996+
}
997+
998+
/**
999+
* Delete stored script by id.
1000+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting-using.html">
1001+
* How to use scripts on elastic.co</a>
1002+
* @param request the request
1003+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
1004+
* @return the response
1005+
* @throws IOException in case there is a problem sending the request or parsing back the response
1006+
*/
1007+
public DeleteStoredScriptResponse deleteScript(DeleteStoredScriptRequest request, RequestOptions options) throws IOException {
1008+
return performRequestAndParseEntity(request, RequestConverters::deleteScript, options,
1009+
DeleteStoredScriptResponse::fromXContent, emptySet());
1010+
}
1011+
1012+
/**
1013+
* Asynchronously delete stored script by id.
1014+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting-using.html">
1015+
* How to use scripts on elastic.co</a>
1016+
* @param request the request
1017+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
1018+
* @param listener the listener to be notified upon request completion
1019+
*/
1020+
public void deleteScriptAsync(DeleteStoredScriptRequest request, RequestOptions options,
1021+
ActionListener<DeleteStoredScriptResponse> listener) {
1022+
performRequestAsyncAndParseEntity(request, RequestConverters::deleteScript, options,
1023+
DeleteStoredScriptResponse::fromXContent, listener, emptySet());
1024+
}
1025+
9661026
/**
9671027
* Asynchronously executes a request using the Field Capabilities API.
9681028
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/search-field-caps.html">Field Capabilities API

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryRequest;
3838
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryRequest;
3939
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
40+
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
41+
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
4042
import org.elasticsearch.action.admin.indices.alias.Alias;
4143
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
4244
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions;
@@ -1981,6 +1983,32 @@ public void testGetTemplateRequest() throws Exception {
19811983
assertThat(request.getEntity(), nullValue());
19821984
}
19831985

1986+
public void testGetScriptRequest() {
1987+
GetStoredScriptRequest getStoredScriptRequest = new GetStoredScriptRequest("x-script");
1988+
Map<String, String> expectedParams = new HashMap<>();
1989+
setRandomMasterTimeout(getStoredScriptRequest, expectedParams);
1990+
1991+
Request request = RequestConverters.getScript(getStoredScriptRequest);
1992+
assertThat(request.getEndpoint(), equalTo("/_scripts/" + getStoredScriptRequest.id()));
1993+
assertThat(request.getMethod(), equalTo(HttpGet.METHOD_NAME));
1994+
assertThat(request.getParameters(), equalTo(expectedParams));
1995+
assertThat(request.getEntity(), nullValue());
1996+
}
1997+
1998+
public void testDeleteScriptRequest() {
1999+
DeleteStoredScriptRequest deleteStoredScriptRequest = new DeleteStoredScriptRequest("x-script");
2000+
2001+
Map<String, String> expectedParams = new HashMap<>();
2002+
setRandomTimeout(deleteStoredScriptRequest::timeout, AcknowledgedRequest.DEFAULT_ACK_TIMEOUT, expectedParams);
2003+
setRandomMasterTimeout(deleteStoredScriptRequest, expectedParams);
2004+
2005+
Request request = RequestConverters.deleteScript(deleteStoredScriptRequest);
2006+
assertThat(request.getEndpoint(), equalTo("/_scripts/" + deleteStoredScriptRequest.id()));
2007+
assertThat(request.getMethod(), equalTo(HttpDelete.METHOD_NAME));
2008+
assertThat(request.getParameters(), equalTo(expectedParams));
2009+
assertThat(request.getEntity(), nullValue());
2010+
}
2011+
19842012
private static void assertToXContentBody(ToXContent expectedBody, HttpEntity actualEntity) throws IOException {
19852013
BytesReference expectedBytes = XContentHelper.toXContent(expectedBody, REQUEST_BODY_CONTENT_TYPE, false);
19862014
assertEquals(XContentType.JSON.mediaTypeWithoutParameters(), actualEntity.getContentType().getValue());
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package org.elasticsearch.client;/*
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+
21+
import org.apache.http.entity.ContentType;
22+
import org.apache.http.entity.StringEntity;
23+
import org.apache.http.util.EntityUtils;
24+
import org.elasticsearch.ElasticsearchStatusException;
25+
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
26+
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptResponse;
27+
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
28+
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptResponse;
29+
import org.elasticsearch.common.Strings;
30+
import org.elasticsearch.common.xcontent.ToXContent;
31+
import org.elasticsearch.common.xcontent.XContentType;
32+
import org.elasticsearch.rest.RestStatus;
33+
import org.elasticsearch.script.Script;
34+
import org.elasticsearch.script.StoredScriptSource;
35+
36+
import java.util.Collections;
37+
38+
import static java.util.Collections.emptyMap;
39+
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
40+
import static org.hamcrest.Matchers.equalTo;
41+
42+
public class StoredScriptsIT extends ESRestHighLevelClientTestCase {
43+
44+
final String id = "calculate-score";
45+
46+
public void testGetStoredScript() throws Exception {
47+
final StoredScriptSource scriptSource =
48+
new StoredScriptSource("painless",
49+
"Math.log(_score * 2) + params.my_modifier",
50+
Collections.singletonMap(Script.CONTENT_TYPE_OPTION, XContentType.JSON.mediaType()));
51+
52+
final String script = Strings.toString(scriptSource.toXContent(jsonBuilder(), ToXContent.EMPTY_PARAMS));
53+
// TODO: change to HighLevel PutStoredScriptRequest when it will be ready
54+
// so far - using low-level REST API
55+
Response putResponse =
56+
adminClient()
57+
.performRequest("PUT", "/_scripts/calculate-score", emptyMap(),
58+
new StringEntity("{\"script\":" + script + "}",
59+
ContentType.APPLICATION_JSON));
60+
assertEquals(putResponse.getStatusLine().getReasonPhrase(), 200, putResponse.getStatusLine().getStatusCode());
61+
assertEquals("{\"acknowledged\":true}", EntityUtils.toString(putResponse.getEntity()));
62+
63+
GetStoredScriptRequest getRequest = new GetStoredScriptRequest("calculate-score");
64+
getRequest.masterNodeTimeout("50s");
65+
66+
GetStoredScriptResponse getResponse = execute(getRequest, highLevelClient()::getScript,
67+
highLevelClient()::getScriptAsync);
68+
69+
assertThat(getResponse.getSource(), equalTo(scriptSource));
70+
}
71+
72+
public void testDeleteStoredScript() throws Exception {
73+
final StoredScriptSource scriptSource =
74+
new StoredScriptSource("painless",
75+
"Math.log(_score * 2) + params.my_modifier",
76+
Collections.singletonMap(Script.CONTENT_TYPE_OPTION, XContentType.JSON.mediaType()));
77+
78+
final String script = Strings.toString(scriptSource.toXContent(jsonBuilder(), ToXContent.EMPTY_PARAMS));
79+
// TODO: change to HighLevel PutStoredScriptRequest when it will be ready
80+
// so far - using low-level REST API
81+
Response putResponse =
82+
adminClient()
83+
.performRequest("PUT", "/_scripts/" + id, emptyMap(),
84+
new StringEntity("{\"script\":" + script + "}",
85+
ContentType.APPLICATION_JSON));
86+
assertEquals(putResponse.getStatusLine().getReasonPhrase(), 200, putResponse.getStatusLine().getStatusCode());
87+
assertEquals("{\"acknowledged\":true}", EntityUtils.toString(putResponse.getEntity()));
88+
89+
DeleteStoredScriptRequest deleteRequest = new DeleteStoredScriptRequest(id);
90+
deleteRequest.masterNodeTimeout("50s");
91+
deleteRequest.timeout("50s");
92+
93+
DeleteStoredScriptResponse deleteResponse = execute(deleteRequest, highLevelClient()::deleteScript,
94+
highLevelClient()::deleteScriptAsync);
95+
96+
assertThat(deleteResponse.isAcknowledged(), equalTo(true));
97+
98+
GetStoredScriptRequest getRequest = new GetStoredScriptRequest(id);
99+
100+
final ElasticsearchStatusException statusException = expectThrows(ElasticsearchStatusException.class,
101+
() -> execute(getRequest, highLevelClient()::getScript,
102+
highLevelClient()::getScriptAsync));
103+
assertThat(statusException.status(), equalTo(RestStatus.NOT_FOUND));
104+
}
105+
}

0 commit comments

Comments
 (0)