HLRC: Add put stored script support to high-level rest client (#31323)
Relates to #27205
This commit is contained in:
parent
c67b0ba33e
commit
9073dbefd6
|
@ -32,6 +32,7 @@ import org.elasticsearch.action.DocWriteRequest;
|
|||
import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptRequest;
|
||||
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
|
||||
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
|
||||
import org.elasticsearch.action.admin.indices.analyze.AnalyzeRequest;
|
||||
|
@ -887,6 +888,19 @@ final class RequestConverters {
|
|||
return request;
|
||||
}
|
||||
|
||||
static Request putScript(PutStoredScriptRequest putStoredScriptRequest) throws IOException {
|
||||
String endpoint = new EndpointBuilder().addPathPartAsIs("_scripts").addPathPart(putStoredScriptRequest.id()).build();
|
||||
Request request = new Request(HttpPost.METHOD_NAME, endpoint);
|
||||
Params params = new Params(request);
|
||||
params.withTimeout(putStoredScriptRequest.timeout());
|
||||
params.withMasterTimeout(putStoredScriptRequest.masterNodeTimeout());
|
||||
if (Strings.hasText(putStoredScriptRequest.context())) {
|
||||
params.putParam("context", putStoredScriptRequest.context());
|
||||
}
|
||||
request.setEntity(createEntity(putStoredScriptRequest, REQUEST_BODY_CONTENT_TYPE));
|
||||
return request;
|
||||
}
|
||||
|
||||
static Request analyze(AnalyzeRequest request) throws IOException {
|
||||
EndpointBuilder builder = new EndpointBuilder();
|
||||
String index = request.index();
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.elasticsearch.action.ActionRequestValidationException;
|
|||
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptResponse;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptRequest;
|
||||
import org.elasticsearch.action.bulk.BulkRequest;
|
||||
import org.elasticsearch.action.bulk.BulkResponse;
|
||||
import org.elasticsearch.action.delete.DeleteRequest;
|
||||
|
@ -121,36 +122,36 @@ import org.elasticsearch.search.aggregations.bucket.terms.ParsedLongTerms;
|
|||
import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms;
|
||||
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
|
||||
import org.elasticsearch.search.aggregations.metrics.AvgAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedAvg;
|
||||
import org.elasticsearch.search.aggregations.metrics.CardinalityAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedCardinality;
|
||||
import org.elasticsearch.search.aggregations.metrics.ExtendedStatsAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.metrics.GeoBoundsAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedGeoBounds;
|
||||
import org.elasticsearch.search.aggregations.metrics.GeoCentroidAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedGeoCentroid;
|
||||
import org.elasticsearch.search.aggregations.metrics.MaxAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedMax;
|
||||
import org.elasticsearch.search.aggregations.metrics.MinAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedMin;
|
||||
import org.elasticsearch.search.aggregations.metrics.InternalHDRPercentileRanks;
|
||||
import org.elasticsearch.search.aggregations.metrics.InternalHDRPercentiles;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedHDRPercentileRanks;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedHDRPercentiles;
|
||||
import org.elasticsearch.search.aggregations.metrics.InternalTDigestPercentileRanks;
|
||||
import org.elasticsearch.search.aggregations.metrics.InternalTDigestPercentiles;
|
||||
import org.elasticsearch.search.aggregations.metrics.MaxAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.metrics.MinAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedAvg;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedCardinality;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedExtendedStats;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedGeoBounds;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedGeoCentroid;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedHDRPercentileRanks;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedHDRPercentiles;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedMax;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedMin;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedScriptedMetric;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedStats;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedSum;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedTDigestPercentileRanks;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedTDigestPercentiles;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedScriptedMetric;
|
||||
import org.elasticsearch.search.aggregations.metrics.ScriptedMetricAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedStats;
|
||||
import org.elasticsearch.search.aggregations.metrics.StatsAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.metrics.ExtendedStatsAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedExtendedStats;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedSum;
|
||||
import org.elasticsearch.search.aggregations.metrics.SumAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedTopHits;
|
||||
import org.elasticsearch.search.aggregations.metrics.TopHitsAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedValueCount;
|
||||
import org.elasticsearch.search.aggregations.metrics.ScriptedMetricAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.metrics.StatsAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.metrics.SumAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.metrics.TopHitsAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.metrics.ValueCountAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.pipeline.InternalSimpleValue;
|
||||
import org.elasticsearch.search.aggregations.pipeline.ParsedSimpleValue;
|
||||
|
@ -1050,6 +1051,35 @@ public class RestHighLevelClient implements Closeable {
|
|||
AcknowledgedResponse::fromXContent, listener, emptySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts an stored script using the Scripting API.
|
||||
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting-using.html"> Scripting API
|
||||
* on elastic.co</a>
|
||||
* @param putStoredScriptRequest the request
|
||||
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
|
||||
* @return the response
|
||||
* @throws IOException in case there is a problem sending the request or parsing back the response
|
||||
*/
|
||||
public AcknowledgedResponse putScript(PutStoredScriptRequest putStoredScriptRequest,
|
||||
RequestOptions options) throws IOException {
|
||||
return performRequestAndParseEntity(putStoredScriptRequest, RequestConverters::putScript, options,
|
||||
AcknowledgedResponse::fromXContent, emptySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously puts an stored script using the Scripting API.
|
||||
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting-using.html"> Scripting API
|
||||
* on elastic.co</a>
|
||||
* @param putStoredScriptRequest the request
|
||||
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
|
||||
* @param listener the listener to be notified upon request completion
|
||||
*/
|
||||
public void putScriptAsync(PutStoredScriptRequest putStoredScriptRequest, RequestOptions options,
|
||||
ActionListener<AcknowledgedResponse> listener) {
|
||||
performRequestAsyncAndParseEntity(putStoredScriptRequest, RequestConverters::putScript, options,
|
||||
AcknowledgedResponse::fromXContent, listener, emptySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously executes a request using the Field Capabilities API.
|
||||
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/search-field-caps.html">Field Capabilities API
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.elasticsearch.action.ActionRequestValidationException;
|
|||
import org.elasticsearch.action.DocWriteRequest;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptRequest;
|
||||
import org.elasticsearch.action.admin.indices.alias.Alias;
|
||||
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
|
||||
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions;
|
||||
|
@ -1991,6 +1992,42 @@ public class RequestConvertersTests extends ESTestCase {
|
|||
assertThat(request.getEntity(), nullValue());
|
||||
}
|
||||
|
||||
public void testPutScript() throws Exception {
|
||||
PutStoredScriptRequest putStoredScriptRequest = new PutStoredScriptRequest();
|
||||
|
||||
String id = randomAlphaOfLengthBetween(5, 10);
|
||||
putStoredScriptRequest.id(id);
|
||||
|
||||
XContentType xContentType = randomFrom(XContentType.values());
|
||||
try (XContentBuilder builder = XContentBuilder.builder(xContentType.xContent())) {
|
||||
builder.startObject();
|
||||
builder.startObject("script")
|
||||
.field("lang", "painless")
|
||||
.field("source", "Math.log(_score * 2) + params.multiplier")
|
||||
.endObject();
|
||||
builder.endObject();
|
||||
|
||||
putStoredScriptRequest.content(BytesReference.bytes(builder), xContentType);
|
||||
}
|
||||
|
||||
Map<String, String> expectedParams = new HashMap<>();
|
||||
setRandomMasterTimeout(putStoredScriptRequest, expectedParams);
|
||||
setRandomTimeout(putStoredScriptRequest::timeout, AcknowledgedRequest.DEFAULT_ACK_TIMEOUT, expectedParams);
|
||||
|
||||
if (randomBoolean()) {
|
||||
String context = randomAlphaOfLengthBetween(5, 10);
|
||||
putStoredScriptRequest.context(context);
|
||||
expectedParams.put("context", context);
|
||||
}
|
||||
|
||||
Request request = RequestConverters.putScript(putStoredScriptRequest);
|
||||
|
||||
assertThat(request.getEndpoint(), equalTo("/_scripts/" + id));
|
||||
assertThat(request.getParameters(), equalTo(expectedParams));
|
||||
assertNotNull(request.getEntity());
|
||||
assertToXContentBody(putStoredScriptRequest, request.getEntity());
|
||||
}
|
||||
|
||||
public void testAnalyzeRequest() throws Exception {
|
||||
AnalyzeRequest indexAnalyzeRequest = new AnalyzeRequest()
|
||||
.text("Here is some text")
|
||||
|
|
|
@ -658,7 +658,6 @@ public class RestHighLevelClientTests extends ESTestCase {
|
|||
"indices.get_upgrade",
|
||||
"indices.put_alias",
|
||||
"mtermvectors",
|
||||
"put_script",
|
||||
"reindex_rethrottle",
|
||||
"render_search_template",
|
||||
"scripts_painless_execute",
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
package org.elasticsearch.client;/*
|
||||
package org.elasticsearch.client;
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
|
@ -17,27 +18,27 @@ package org.elasticsearch.client;/*
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.elasticsearch.ElasticsearchStatusException;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptResponse;
|
||||
import org.elasticsearch.action.support.master.AcknowledgedResponse;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptRequest;
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.StoredScriptSource;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.elasticsearch.common.xcontent.support.XContentMapValues.extractValue;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
public class StoredScriptsIT extends ESRestHighLevelClientTestCase {
|
||||
|
||||
final String id = "calculate-score";
|
||||
private static final String id = "calculate-score";
|
||||
|
||||
public void testGetStoredScript() throws Exception {
|
||||
final StoredScriptSource scriptSource =
|
||||
|
@ -45,13 +46,9 @@ public class StoredScriptsIT extends ESRestHighLevelClientTestCase {
|
|||
"Math.log(_score * 2) + params.my_modifier",
|
||||
Collections.singletonMap(Script.CONTENT_TYPE_OPTION, XContentType.JSON.mediaType()));
|
||||
|
||||
final String script = Strings.toString(scriptSource.toXContent(jsonBuilder(), ToXContent.EMPTY_PARAMS));
|
||||
// TODO: change to HighLevel PutStoredScriptRequest when it will be ready
|
||||
// so far - using low-level REST API
|
||||
Request putRequest = new Request("PUT", "/_scripts/calculate-score");
|
||||
putRequest.setJsonEntity("{\"script\":" + script + "}");
|
||||
Response putResponse = adminClient().performRequest(putRequest);
|
||||
assertEquals("{\"acknowledged\":true}", EntityUtils.toString(putResponse.getEntity()));
|
||||
PutStoredScriptRequest request =
|
||||
new PutStoredScriptRequest(id, "search", new BytesArray("{}"), XContentType.JSON, scriptSource);
|
||||
assertAcked(execute(request, highLevelClient()::putScript, highLevelClient()::putScriptAsync));
|
||||
|
||||
GetStoredScriptRequest getRequest = new GetStoredScriptRequest("calculate-score");
|
||||
getRequest.masterNodeTimeout("50s");
|
||||
|
@ -68,22 +65,14 @@ public class StoredScriptsIT extends ESRestHighLevelClientTestCase {
|
|||
"Math.log(_score * 2) + params.my_modifier",
|
||||
Collections.singletonMap(Script.CONTENT_TYPE_OPTION, XContentType.JSON.mediaType()));
|
||||
|
||||
final String script = Strings.toString(scriptSource.toXContent(jsonBuilder(), ToXContent.EMPTY_PARAMS));
|
||||
// TODO: change to HighLevel PutStoredScriptRequest when it will be ready
|
||||
// so far - using low-level REST API
|
||||
Request putRequest = new Request("PUT", "/_scripts/" + id);
|
||||
putRequest.setJsonEntity("{\"script\":" + script + "}");
|
||||
Response putResponse = adminClient().performRequest(putRequest);
|
||||
assertEquals("{\"acknowledged\":true}", EntityUtils.toString(putResponse.getEntity()));
|
||||
PutStoredScriptRequest request =
|
||||
new PutStoredScriptRequest(id, "search", new BytesArray("{}"), XContentType.JSON, scriptSource);
|
||||
assertAcked(execute(request, highLevelClient()::putScript, highLevelClient()::putScriptAsync));
|
||||
|
||||
DeleteStoredScriptRequest deleteRequest = new DeleteStoredScriptRequest(id);
|
||||
deleteRequest.masterNodeTimeout("50s");
|
||||
deleteRequest.timeout("50s");
|
||||
|
||||
AcknowledgedResponse deleteResponse = execute(deleteRequest, highLevelClient()::deleteScript,
|
||||
highLevelClient()::deleteScriptAsync);
|
||||
|
||||
assertThat(deleteResponse.isAcknowledged(), equalTo(true));
|
||||
assertAcked(execute(deleteRequest, highLevelClient()::deleteScript, highLevelClient()::deleteScriptAsync));
|
||||
|
||||
GetStoredScriptRequest getRequest = new GetStoredScriptRequest(id);
|
||||
|
||||
|
@ -92,4 +81,21 @@ public class StoredScriptsIT extends ESRestHighLevelClientTestCase {
|
|||
highLevelClient()::getScriptAsync));
|
||||
assertThat(statusException.status(), equalTo(RestStatus.NOT_FOUND));
|
||||
}
|
||||
|
||||
public void testPutScript() throws Exception {
|
||||
final StoredScriptSource scriptSource =
|
||||
new StoredScriptSource("painless",
|
||||
"Math.log(_score * 2) + params.my_modifier",
|
||||
Collections.singletonMap(Script.CONTENT_TYPE_OPTION, XContentType.JSON.mediaType()));
|
||||
|
||||
PutStoredScriptRequest request =
|
||||
new PutStoredScriptRequest(id, "search", new BytesArray("{}"), XContentType.JSON, scriptSource);
|
||||
assertAcked(execute(request, highLevelClient()::putScript, highLevelClient()::putScriptAsync));
|
||||
|
||||
Map<String, Object> script = getAsMap("/_scripts/" + id);
|
||||
assertThat(extractValue("_id", script), equalTo(id));
|
||||
assertThat(extractValue("found", script), equalTo(true));
|
||||
assertThat(extractValue("script.lang", script), equalTo("painless"));
|
||||
assertThat(extractValue("script.source", script), equalTo("Math.log(_score * 2) + params.my_modifier"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,21 +17,21 @@ package org.elasticsearch.client.documentation;/*
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.LatchedActionListener;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptResponse;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptRequest;
|
||||
import org.elasticsearch.action.support.master.AcknowledgedResponse;
|
||||
import org.elasticsearch.client.ESRestHighLevelClientTestCase;
|
||||
import org.elasticsearch.client.Request;
|
||||
import org.elasticsearch.client.RequestOptions;
|
||||
import org.elasticsearch.client.Response;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.StoredScriptSource;
|
||||
|
@ -42,7 +42,8 @@ import java.util.Map;
|
|||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.elasticsearch.common.xcontent.support.XContentMapValues.extractValue;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
/**
|
||||
|
@ -187,14 +188,124 @@ public class StoredScriptsDocumentationIT extends ESRestHighLevelClientTestCase
|
|||
assertTrue(latch.await(30L, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
public void testPutScript() throws Exception {
|
||||
RestHighLevelClient client = highLevelClient();
|
||||
|
||||
{
|
||||
// tag::put-stored-script-request
|
||||
PutStoredScriptRequest request = new PutStoredScriptRequest();
|
||||
request.id("id"); // <1>
|
||||
request.content(new BytesArray(
|
||||
"{\n" +
|
||||
"\"script\": {\n" +
|
||||
"\"lang\": \"painless\",\n" +
|
||||
"\"source\": \"Math.log(_score * 2) + params.multiplier\"" +
|
||||
"}\n" +
|
||||
"}\n"
|
||||
), XContentType.JSON); // <2>
|
||||
// end::put-stored-script-request
|
||||
|
||||
// tag::put-stored-script-context
|
||||
request.context("context"); // <1>
|
||||
// end::put-stored-script-context
|
||||
|
||||
// tag::put-stored-script-timeout
|
||||
request.timeout(TimeValue.timeValueMinutes(2)); // <1>
|
||||
request.timeout("2m"); // <2>
|
||||
// end::put-stored-script-timeout
|
||||
|
||||
// tag::put-stored-script-masterTimeout
|
||||
request.masterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1>
|
||||
request.masterNodeTimeout("1m"); // <2>
|
||||
// end::put-stored-script-masterTimeout
|
||||
}
|
||||
|
||||
{
|
||||
PutStoredScriptRequest request = new PutStoredScriptRequest();
|
||||
request.id("id");
|
||||
|
||||
// tag::put-stored-script-content-painless
|
||||
XContentBuilder builder = XContentFactory.jsonBuilder();
|
||||
builder.startObject();
|
||||
{
|
||||
builder.startObject("script");
|
||||
{
|
||||
builder.field("lang", "painless");
|
||||
builder.field("source", "Math.log(_score * 2) + params.multiplier");
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
request.content(BytesReference.bytes(builder), XContentType.JSON); // <1>
|
||||
// end::put-stored-script-content-painless
|
||||
|
||||
|
||||
// tag::put-stored-script-execute
|
||||
AcknowledgedResponse putStoredScriptResponse = client.putScript(request, RequestOptions.DEFAULT);
|
||||
// end::put-stored-script-execute
|
||||
|
||||
// tag::put-stored-script-response
|
||||
boolean acknowledged = putStoredScriptResponse.isAcknowledged(); // <1>
|
||||
// end::put-stored-script-response
|
||||
|
||||
assertTrue(acknowledged);
|
||||
|
||||
// tag::put-stored-script-execute-listener
|
||||
ActionListener<AcknowledgedResponse> listener =
|
||||
new ActionListener<AcknowledgedResponse>() {
|
||||
@Override
|
||||
public void onResponse(AcknowledgedResponse response) {
|
||||
// <1>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Exception e) {
|
||||
// <2>
|
||||
}
|
||||
};
|
||||
// end::put-stored-script-execute-listener
|
||||
|
||||
// Replace the empty listener by a blocking listener in test
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
listener = new LatchedActionListener<>(listener, latch);
|
||||
|
||||
// tag::put-stored-script-execute-async
|
||||
client.putScriptAsync(request, RequestOptions.DEFAULT, listener); // <1>
|
||||
// end::put-stored-script-execute-async
|
||||
|
||||
assertTrue(latch.await(30L, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
{
|
||||
PutStoredScriptRequest request = new PutStoredScriptRequest();
|
||||
request.id("id");
|
||||
|
||||
// tag::put-stored-script-content-mustache
|
||||
XContentBuilder builder = XContentFactory.jsonBuilder();
|
||||
builder.startObject();
|
||||
{
|
||||
builder.startObject("script");
|
||||
{
|
||||
builder.field("lang", "mustache");
|
||||
builder.field("source", "{\"query\":{\"match\":{\"title\":\"{{query_string}}\"}}}");
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
request.content(BytesReference.bytes(builder), XContentType.JSON); // <1>
|
||||
// end::put-stored-script-content-mustache
|
||||
|
||||
client.putScript(request, RequestOptions.DEFAULT);
|
||||
|
||||
Map<String, Object> script = getAsMap("/_scripts/id");
|
||||
assertThat(extractValue("script.lang", script), equalTo("mustache"));
|
||||
assertThat(extractValue("script.source", script), equalTo("{\"query\":{\"match\":{\"title\":\"{{query_string}}\"}}}"));
|
||||
}
|
||||
}
|
||||
|
||||
private void putStoredScript(String id, StoredScriptSource scriptSource) throws IOException {
|
||||
final String script = Strings.toString(scriptSource.toXContent(jsonBuilder(), ToXContent.EMPTY_PARAMS));
|
||||
// TODO: change to HighLevel PutStoredScriptRequest when it will be ready
|
||||
// so far - using low-level REST API
|
||||
Request request = new Request("PUT", "/_scripts/" + id);
|
||||
request.setJsonEntity("{\"script\":" + script + "}");
|
||||
Response putResponse = adminClient().performRequest(request);
|
||||
assertEquals(putResponse.getStatusLine().getReasonPhrase(), 200, putResponse.getStatusLine().getStatusCode());
|
||||
assertEquals("{\"acknowledged\":true}", EntityUtils.toString(putResponse.getEntity()));
|
||||
PutStoredScriptRequest request =
|
||||
new PutStoredScriptRequest(id, "search", new BytesArray("{}"), XContentType.JSON, scriptSource);
|
||||
assertAcked(execute(request, highLevelClient()::putScript, highLevelClient()::putScriptAsync));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
[[java-rest-high-put-stored-script]]
|
||||
=== Put Stored Script API
|
||||
|
||||
[[java-rest-high-put-stored-script-request]]
|
||||
==== Put Stored Script Request
|
||||
|
||||
A `PutStoredScriptRequest` requires an `id` and `content`:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/StoredScriptsDocumentationIT.java[put-stored-script-request]
|
||||
--------------------------------------------------
|
||||
<1> The id of the script
|
||||
<2> The content of the script
|
||||
|
||||
[[java-rest-high-put-stored-script-content]]
|
||||
==== Content
|
||||
The content of a script can be written in different languages and provided in
|
||||
different ways:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/StoredScriptsDocumentationIT.java[put-stored-script-content-painless]
|
||||
--------------------------------------------------
|
||||
<1> Specify a painless script and provided as `XContentBuilder` object.
|
||||
Note that the builder needs to be passed as a `BytesReference` object
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/StoredScriptsDocumentationIT.java[put-stored-script-content-mustache]
|
||||
--------------------------------------------------
|
||||
<1> Specify a mustache script and provided as `XContentBuilder` object.
|
||||
Note that value of source can be directly provided as a JSON string
|
||||
|
||||
==== Optional arguments
|
||||
The following arguments can optionally be provided:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/StoredScriptsDocumentationIT.java[put-stored-script-context]
|
||||
--------------------------------------------------
|
||||
<1> The context the script should be executed in.
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/StoredScriptsDocumentationIT.java[put-stored-script-timeout]
|
||||
--------------------------------------------------
|
||||
<1> Timeout to wait for the all the nodes to acknowledge the script creation as a `TimeValue`
|
||||
<2> Timeout to wait for the all the nodes to acknowledge the script creation as a `String`
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/StoredScriptsDocumentationIT.java[put-stored-script-masterTimeout]
|
||||
--------------------------------------------------
|
||||
<1> Timeout to connect to the master node as a `TimeValue`
|
||||
<2> Timeout to connect to the master node as a `String`
|
||||
|
||||
[[java-rest-high-put-stored-script-sync]]
|
||||
==== Synchronous Execution
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/StoredScriptsDocumentationIT.java[put-stored-script-execute]
|
||||
--------------------------------------------------
|
||||
|
||||
[[java-rest-high-put-stored-script-async]]
|
||||
==== Asynchronous Execution
|
||||
|
||||
The asynchronous execution of a put stored script request requires both the `PutStoredScriptRequest`
|
||||
instance and an `ActionListener` instance to be passed to the asynchronous method:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/StoredScriptsDocumentationIT.java[put-stored-script-execute-async]
|
||||
--------------------------------------------------
|
||||
<1> The `PutStoredScriptRequest` to execute and the `ActionListener` to use when
|
||||
the execution completes
|
||||
|
||||
[[java-rest-high-put-stored-script-listener]]
|
||||
===== Action Listener
|
||||
|
||||
The asynchronous method does not block and returns immediately. Once it is
|
||||
completed the `ActionListener` is called back using the `onResponse` method
|
||||
if the execution successfully completed or using the `onFailure` method if
|
||||
it failed.
|
||||
|
||||
A typical listener for `AcknowledgedResponse` looks like:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/StoredScriptsDocumentationIT.java[put-stored-script-execute-listener]
|
||||
--------------------------------------------------
|
||||
<1> Called when the execution is successfully completed. The response is
|
||||
provided as an argument
|
||||
<2> Called in case of failure. The raised exception is provided as an argument
|
||||
|
||||
[[java-rest-high-put-stored-script-response]]
|
||||
==== Put Stored Script Response
|
||||
|
||||
The returned `AcknowledgedResponse` allows to retrieve information about the
|
||||
executed operation as follows:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/StoredScriptsDocumentationIT.java[put-stored-script-response]
|
||||
--------------------------------------------------
|
||||
<1> Indicates whether all of the nodes have acknowledged the request
|
|
@ -189,9 +189,11 @@ include::tasks/cancel_tasks.asciidoc[]
|
|||
The Java High Level REST Client supports the following Scripts APIs:
|
||||
|
||||
* <<java-rest-high-get-stored-script>>
|
||||
* <<java-rest-high-put-stored-script>>
|
||||
* <<java-rest-high-delete-stored-script>>
|
||||
|
||||
include::script/get_script.asciidoc[]
|
||||
include::script/put_script.asciidoc[]
|
||||
include::script/delete_script.asciidoc[]
|
||||
|
||||
== Licensing APIs
|
||||
|
|
|
@ -25,6 +25,8 @@ import org.elasticsearch.action.support.master.AcknowledgedRequest;
|
|||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.script.StoredScriptSource;
|
||||
|
@ -34,7 +36,7 @@ import java.util.Objects;
|
|||
|
||||
import static org.elasticsearch.action.ValidateActions.addValidationError;
|
||||
|
||||
public class PutStoredScriptRequest extends AcknowledgedRequest<PutStoredScriptRequest> {
|
||||
public class PutStoredScriptRequest extends AcknowledgedRequest<PutStoredScriptRequest> implements ToXContent {
|
||||
|
||||
private String id;
|
||||
private String context;
|
||||
|
@ -160,4 +162,12 @@ public class PutStoredScriptRequest extends AcknowledgedRequest<PutStoredScriptR
|
|||
(context != null ? ", context [" + context + "]" : "") +
|
||||
", content [" + source + "]}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.field("script");
|
||||
source.toXContent(builder, params);
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,8 +20,11 @@
|
|||
package org.elasticsearch.action.admin.cluster.storedscripts;
|
||||
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.io.stream.BytesStreamOutput;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.script.StoredScriptSource;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
@ -48,4 +51,30 @@ public class PutStoredScriptRequestTests extends ESTestCase {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testToXContent() throws IOException {
|
||||
XContentType xContentType = randomFrom(XContentType.values());
|
||||
XContentBuilder builder = XContentBuilder.builder(xContentType.xContent());
|
||||
builder.startObject();
|
||||
builder.startObject("script")
|
||||
.field("lang", "painless")
|
||||
.field("source", "Math.log(_score * 2) + params.multiplier")
|
||||
.endObject();
|
||||
builder.endObject();
|
||||
|
||||
BytesReference expectedRequestBody = BytesReference.bytes(builder);
|
||||
|
||||
PutStoredScriptRequest request = new PutStoredScriptRequest();
|
||||
request.id("test1");
|
||||
request.content(expectedRequestBody, xContentType);
|
||||
|
||||
XContentBuilder requestBuilder = XContentBuilder.builder(xContentType.xContent());
|
||||
requestBuilder.startObject();
|
||||
request.toXContent(requestBuilder, ToXContent.EMPTY_PARAMS);
|
||||
requestBuilder.endObject();
|
||||
|
||||
BytesReference actualRequestBody = BytesReference.bytes(requestBuilder);
|
||||
|
||||
assertEquals(expectedRequestBody, actualRequestBody);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue