Disallow lang to be used with Stored Scripts (#25610)
Requests that execute a stored script will no longer be allowed to specify the lang of the script. This information is stored in the cluster state making only an id necessary to execute against. Putting a stored script will still require a lang.
This commit is contained in:
parent
8d7cbc43b5
commit
d2b4f7ac5a
|
@ -283,7 +283,7 @@ public class CRUDDocumentationIT extends ESRestHighLevelClientTestCase {
|
|||
request = new UpdateRequest("posts", "doc", "1").fetchSource(true);
|
||||
//tag::update-request-with-stored-script
|
||||
Script stored =
|
||||
new Script(ScriptType.STORED, "painless", "increment-field", parameters); // <1>
|
||||
new Script(ScriptType.STORED, null, "increment-field", parameters); // <1>
|
||||
request.script(stored); // <2>
|
||||
//end::update-request-with-stored-script
|
||||
updateResponse = client.update(request);
|
||||
|
|
|
@ -339,7 +339,7 @@ public class QueryDSLDocumentationTests extends ESTestCase {
|
|||
parameters.put("param1", 5);
|
||||
scriptQuery(new Script(
|
||||
ScriptType.STORED, // <1>
|
||||
"painless", // <2>
|
||||
null, // <2>
|
||||
"myscript", // <3>
|
||||
singletonMap("param1", 5))); // <4>
|
||||
// end::script_file
|
||||
|
|
|
@ -19,15 +19,12 @@
|
|||
|
||||
package org.elasticsearch.script;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.io.stream.Writeable;
|
||||
import org.elasticsearch.common.logging.DeprecationLogger;
|
||||
import org.elasticsearch.common.logging.ESLoggerFactory;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser.ValueType;
|
||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||
|
@ -66,8 +63,7 @@ import java.util.Objects;
|
|||
* <li> {@link ScriptType#STORED}
|
||||
* <ul>
|
||||
* <li> {@link Script#lang} - the language will be specified when storing the script, so this should
|
||||
* be {@code null}; however, this can be specified to look up a stored
|
||||
* script as part of the deprecated API
|
||||
* be {@code null}
|
||||
* <li> {@link Script#idOrCode} - specifies the id of the stored script to be looked up, must not be {@code null}
|
||||
* <li> {@link Script#options} - compiler options will be specified when a stored script is stored,
|
||||
* so they have no meaning here and must be {@code null}
|
||||
|
@ -78,16 +74,6 @@ import java.util.Objects;
|
|||
*/
|
||||
public final class Script implements ToXContentObject, Writeable {
|
||||
|
||||
/**
|
||||
* Standard logger necessary for allocation of the deprecation logger.
|
||||
*/
|
||||
private static final Logger LOGGER = ESLoggerFactory.getLogger(ScriptMetaData.class);
|
||||
|
||||
/**
|
||||
* Deprecation logger necessary for namespace changes related to stored scripts.
|
||||
*/
|
||||
private static final DeprecationLogger DEPRECATION_LOGGER = new DeprecationLogger(LOGGER);
|
||||
|
||||
/**
|
||||
* The name of the of the default scripting language.
|
||||
*/
|
||||
|
@ -233,7 +219,7 @@ public final class Script implements ToXContentObject, Writeable {
|
|||
|
||||
if (idOrCode == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"must specify <id> for an [" + ScriptType.INLINE.getParseField().getPreferredName() + "] script");
|
||||
"must specify <id> for an inline script");
|
||||
}
|
||||
|
||||
if (options.size() > 1 || options.size() == 1 && options.get(CONTENT_TYPE_OPTION) == null) {
|
||||
|
@ -242,26 +228,21 @@ public final class Script implements ToXContentObject, Writeable {
|
|||
throw new IllegalArgumentException("illegal compiler options [" + options + "] specified");
|
||||
}
|
||||
} else if (type == ScriptType.STORED) {
|
||||
// Only issue this deprecation warning if we aren't using a template. Templates during
|
||||
// this deprecation phase must always specify the default template language or they would
|
||||
// possibly pick up a script in a different language as defined by the user under the new
|
||||
// namespace unintentionally.
|
||||
if (lang != null && lang.equals(DEFAULT_TEMPLATE_LANG) == false) {
|
||||
DEPRECATION_LOGGER.deprecated("specifying the field [" + LANG_PARSE_FIELD.getPreferredName() + "] " +
|
||||
"for executing " + ScriptType.STORED + " scripts is deprecated; use only the field " +
|
||||
"[" + ScriptType.STORED.getParseField().getPreferredName() + "] to specify an <id>");
|
||||
if (lang != null) {
|
||||
throw new IllegalArgumentException(
|
||||
"illegally specified <lang> for a stored script");
|
||||
}
|
||||
|
||||
if (idOrCode == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"must specify <code> for an [" + ScriptType.STORED.getParseField().getPreferredName() + "] script");
|
||||
"must specify <code> for a stored script");
|
||||
}
|
||||
|
||||
if (options.isEmpty()) {
|
||||
options = null;
|
||||
} else {
|
||||
throw new IllegalArgumentException("field [" + OPTIONS_PARSE_FIELD.getPreferredName() + "] " +
|
||||
"cannot be specified using a [" + ScriptType.STORED.getParseField().getPreferredName() + "] script");
|
||||
"cannot be specified using a stored script");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -423,11 +404,14 @@ public final class Script implements ToXContentObject, Writeable {
|
|||
this.lang = Objects.requireNonNull(lang);
|
||||
this.options = Collections.unmodifiableMap(Objects.requireNonNull(options));
|
||||
} else if (type == ScriptType.STORED) {
|
||||
this.lang = lang;
|
||||
if (lang != null) {
|
||||
throw new IllegalArgumentException("lang cannot be specified for stored scripts");
|
||||
}
|
||||
|
||||
this.lang = null;
|
||||
|
||||
if (options != null) {
|
||||
throw new IllegalStateException(
|
||||
"options must be null for [" + ScriptType.STORED.getParseField().getPreferredName() + "] scripts");
|
||||
throw new IllegalStateException("options cannot be specified for stored scripts");
|
||||
}
|
||||
|
||||
this.options = null;
|
||||
|
@ -455,7 +439,8 @@ public final class Script implements ToXContentObject, Writeable {
|
|||
// same order as the constructor.
|
||||
} else if (in.getVersion().onOrAfter(Version.V_5_1_1)) {
|
||||
this.type = ScriptType.readFrom(in);
|
||||
this.lang = in.readString();
|
||||
String lang = in.readString();
|
||||
this.lang = this.type == ScriptType.STORED ? null : lang;
|
||||
|
||||
this.idOrCode = in.readString();
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -482,7 +467,7 @@ public final class Script implements ToXContentObject, Writeable {
|
|||
String lang = in.readOptionalString();
|
||||
|
||||
if (lang == null) {
|
||||
this.lang = DEFAULT_SCRIPT_LANG;
|
||||
this.lang = this.type == ScriptType.STORED ? null : DEFAULT_SCRIPT_LANG;
|
||||
} else {
|
||||
this.lang = lang;
|
||||
}
|
||||
|
|
|
@ -231,28 +231,11 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
|
|||
|
||||
String id = idOrCode;
|
||||
|
||||
// lang may be null when looking up a stored script, so we must get the
|
||||
// source to retrieve the lang before checking if the context is supported
|
||||
if (type == ScriptType.STORED) {
|
||||
// search template requests can possibly pass in the entire path instead
|
||||
// of just an id for looking up a stored script, so we parse the path and
|
||||
// check for appropriate errors
|
||||
String[] path = id.split("/");
|
||||
|
||||
if (path.length == 3) {
|
||||
if (lang != null && lang.equals(path[1]) == false) {
|
||||
throw new IllegalStateException("conflicting script languages, found [" + path[1] + "] but expected [" + lang + "]");
|
||||
}
|
||||
|
||||
id = path[2];
|
||||
|
||||
deprecationLogger.deprecated("use of </lang/id> [" + idOrCode + "] for looking up" +
|
||||
" stored scripts/templates has been deprecated, use only <id> [" + id + "] instead");
|
||||
} else if (path.length != 1) {
|
||||
throw new IllegalArgumentException("illegal stored script format [" + id + "] use only <id>");
|
||||
}
|
||||
|
||||
// a stored script must be pulled from the cluster state every time in case
|
||||
// * lang and options will both be null when looking up a stored script,
|
||||
// so we must get the source to retrieve the them before checking if the
|
||||
// context is supported
|
||||
// * a stored script must be pulled from the cluster state every time in case
|
||||
// the script has been updated since the last compilation
|
||||
StoredScriptSource source = getScriptFromClusterState(id, lang);
|
||||
lang = source.getLang();
|
||||
|
@ -262,7 +245,7 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
|
|||
|
||||
// TODO: fix this through some API or something, that's wrong
|
||||
// special exception to prevent expressions from compiling as update or mapping scripts
|
||||
boolean expression = "expression".equals(script.getLang());
|
||||
boolean expression = "expression".equals(lang);
|
||||
boolean notSupported = context.name.equals(ExecutableScript.UPDATE_CONTEXT.name);
|
||||
if (expression && notSupported) {
|
||||
throw new UnsupportedOperationException("scripts of type [" + script.getType() + "]," +
|
||||
|
@ -303,7 +286,6 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
|
|||
try {
|
||||
// Either an un-cached inline script or indexed script
|
||||
// If the script type is inline the name will be the same as the code for identification in exceptions
|
||||
|
||||
// but give the script engine the chance to be better, give it separate name + source code
|
||||
// for the inline case, then its anonymous: null.
|
||||
if (logger.isTraceEnabled()) {
|
||||
|
@ -379,22 +361,16 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
|
|||
}
|
||||
|
||||
StoredScriptSource getScriptFromClusterState(String id, String lang) {
|
||||
if (lang != null && isLangSupported(lang) == false) {
|
||||
throw new IllegalArgumentException("unable to get stored script with unsupported lang [" + lang + "]");
|
||||
}
|
||||
|
||||
ScriptMetaData scriptMetadata = clusterState.metaData().custom(ScriptMetaData.TYPE);
|
||||
|
||||
if (scriptMetadata == null) {
|
||||
throw new ResourceNotFoundException("unable to find script [" + id + "]" +
|
||||
(lang == null ? "" : " using lang [" + lang + "]") + " in cluster state");
|
||||
throw new ResourceNotFoundException("unable to find script [" + id + "] in cluster state");
|
||||
}
|
||||
|
||||
StoredScriptSource source = scriptMetadata.getStoredScript(id, lang);
|
||||
|
||||
if (source == null) {
|
||||
throw new ResourceNotFoundException("unable to find script [" + id + "]" +
|
||||
(lang == null ? "" : " using lang [" + lang + "]") + " in cluster state");
|
||||
throw new ResourceNotFoundException("unable to find script [" + id + "] in cluster state");
|
||||
}
|
||||
|
||||
return source;
|
||||
|
|
|
@ -18,13 +18,6 @@
|
|||
*/
|
||||
package org.elasticsearch.script;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.elasticsearch.ResourceNotFoundException;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
|
||||
import org.elasticsearch.cluster.ClusterName;
|
||||
|
@ -40,6 +33,12 @@ import org.elasticsearch.env.Environment;
|
|||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.sameInstance;
|
||||
|
@ -77,8 +76,11 @@ public class ScriptServiceTests extends ESTestCase {
|
|||
scriptService = new ScriptService(finalSettings, engines, contexts) {
|
||||
@Override
|
||||
StoredScriptSource getScriptFromClusterState(String id, String lang) {
|
||||
if (lang != null) {
|
||||
throw new IllegalArgumentException("expected null lang in test");
|
||||
}
|
||||
//mock the script that gets retrieved from an index
|
||||
return new StoredScriptSource(lang, "1+1", Collections.emptyMap());
|
||||
return new StoredScriptSource("test", "1+1", Collections.emptyMap());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -128,7 +130,7 @@ public class ScriptServiceTests extends ESTestCase {
|
|||
buildScriptService(Settings.EMPTY);
|
||||
|
||||
assertCompileAccepted("painless", "script", ScriptType.INLINE, SearchScript.CONTEXT);
|
||||
assertCompileAccepted("painless", "script", ScriptType.STORED, SearchScript.CONTEXT);
|
||||
assertCompileAccepted(null, "script", ScriptType.STORED, SearchScript.CONTEXT);
|
||||
}
|
||||
|
||||
public void testAllowAllScriptContextSettings() throws IOException {
|
||||
|
@ -146,7 +148,7 @@ public class ScriptServiceTests extends ESTestCase {
|
|||
buildScriptService(builder.build());
|
||||
|
||||
assertCompileAccepted("painless", "script", ScriptType.INLINE, SearchScript.CONTEXT);
|
||||
assertCompileRejected("painless", "script", ScriptType.STORED, SearchScript.CONTEXT);
|
||||
assertCompileRejected(null, "script", ScriptType.STORED, SearchScript.CONTEXT);
|
||||
}
|
||||
|
||||
public void testAllowSomeScriptContextSettings() throws IOException {
|
||||
|
@ -165,7 +167,7 @@ public class ScriptServiceTests extends ESTestCase {
|
|||
buildScriptService(builder.build());
|
||||
|
||||
assertCompileRejected("painless", "script", ScriptType.INLINE, SearchScript.CONTEXT);
|
||||
assertCompileRejected("painless", "script", ScriptType.STORED, SearchScript.CONTEXT);
|
||||
assertCompileRejected(null, "script", ScriptType.STORED, SearchScript.CONTEXT);
|
||||
}
|
||||
|
||||
public void testAllowNoScriptContextSettings() throws IOException {
|
||||
|
@ -183,7 +185,7 @@ public class ScriptServiceTests extends ESTestCase {
|
|||
|
||||
String type = scriptEngine.getType();
|
||||
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () ->
|
||||
scriptService.compile(new Script(randomFrom(ScriptType.values()), type, "test", Collections.emptyMap()), ExecutableScript.INGEST_CONTEXT));
|
||||
scriptService.compile(new Script(ScriptType.INLINE, type, "test", Collections.emptyMap()), ExecutableScript.INGEST_CONTEXT));
|
||||
assertThat(e.getMessage(), containsString("script context [" + ExecutableScript.INGEST_CONTEXT.name + "] not supported"));
|
||||
}
|
||||
|
||||
|
@ -216,7 +218,7 @@ public class ScriptServiceTests extends ESTestCase {
|
|||
|
||||
public void testIndexedScriptCountedInCompilationStats() throws IOException {
|
||||
buildScriptService(Settings.EMPTY);
|
||||
scriptService.compile(new Script(ScriptType.STORED, "test", "script", Collections.emptyMap()), randomFrom(contexts.values()));
|
||||
scriptService.compile(new Script(ScriptType.STORED, null, "script", Collections.emptyMap()), randomFrom(contexts.values()));
|
||||
assertEquals(1L, scriptService.stats().getCompilations());
|
||||
}
|
||||
|
||||
|
|
|
@ -791,13 +791,13 @@ public class ScriptedMetricIT extends ESIntegTestCase {
|
|||
scriptedMetric("scripted")
|
||||
.params(params)
|
||||
.initScript(
|
||||
new Script(ScriptType.STORED, CustomScriptPlugin.NAME, "initScript_stored", Collections.emptyMap()))
|
||||
new Script(ScriptType.STORED, null, "initScript_stored", Collections.emptyMap()))
|
||||
.mapScript(
|
||||
new Script(ScriptType.STORED, CustomScriptPlugin.NAME, "mapScript_stored", Collections.emptyMap()))
|
||||
new Script(ScriptType.STORED, null, "mapScript_stored", Collections.emptyMap()))
|
||||
.combineScript(
|
||||
new Script(ScriptType.STORED, CustomScriptPlugin.NAME, "combineScript_stored", Collections.emptyMap()))
|
||||
new Script(ScriptType.STORED, null, "combineScript_stored", Collections.emptyMap()))
|
||||
.reduceScript(
|
||||
new Script(ScriptType.STORED, CustomScriptPlugin.NAME, "reduceScript_stored", Collections.emptyMap())))
|
||||
new Script(ScriptType.STORED, null, "reduceScript_stored", Collections.emptyMap())))
|
||||
.get();
|
||||
assertSearchResponse(response);
|
||||
assertThat(response.getHits().getTotalHits(), equalTo(numDocs));
|
||||
|
|
|
@ -496,7 +496,7 @@ public class BucketScriptIT extends ESIntegTestCase {
|
|||
.subAggregation(sum("field4Sum").field(FIELD_4_NAME))
|
||||
.subAggregation(
|
||||
bucketScript("seriesArithmetic",
|
||||
new Script(ScriptType.STORED, CustomScriptPlugin.NAME, "my_script", Collections.emptyMap()),
|
||||
new Script(ScriptType.STORED, null, "my_script", Collections.emptyMap()),
|
||||
"field2Sum", "field3Sum", "field4Sum"))).execute().actionGet();
|
||||
|
||||
assertSearchResponse(response);
|
||||
|
|
|
@ -438,7 +438,7 @@ public class BucketSelectorIT extends ESIntegTestCase {
|
|||
.setContent(new BytesArray("{ \"script\": \"Double.isNaN(_value0) ? false : (_value0 + _value1 > 100)\" }"),
|
||||
XContentType.JSON));
|
||||
|
||||
Script script = new Script(ScriptType.STORED, CustomScriptPlugin.NAME, "my_script", Collections.emptyMap());
|
||||
Script script = new Script(ScriptType.STORED, null, "my_script", Collections.emptyMap());
|
||||
|
||||
SearchResponse response = client()
|
||||
.prepareSearch("idx")
|
||||
|
|
|
@ -26,3 +26,11 @@ The `_index` variable has been removed. If you used it for advanced scoring, con
|
|||
|
||||
All of the existing scripting security settings have been removed. Instead
|
||||
they are replaced with `script.allowed_types` and `script.allowed_contexts`.
|
||||
|
||||
==== `lang` can no longer be specified when using a stored script as part of a request
|
||||
|
||||
The `lang` variable can no longer be specified as part of a request that uses a stored
|
||||
script otherwise an error will occur. Note that a request using a stored script is
|
||||
different from a request that puts a stored script. The language of the script has
|
||||
already been stored as part of the cluster state and an `id` is sufficient to access
|
||||
all of the information necessary to execute a stored script.
|
|
@ -115,28 +115,6 @@ minute will be compiled. You can change this setting dynamically by setting
|
|||
Scripts may be stored in and retrieved from the cluster state using the
|
||||
`_scripts` end-point.
|
||||
|
||||
==== Deprecated Namespace
|
||||
|
||||
The namespace for stored scripts using both `lang` and `id` as a unique
|
||||
identifier has been deprecated. The new namespace for stored scripts will
|
||||
only use `id`. Stored scripts with the same `id`, but different `lang`'s
|
||||
will no longer be allowed in 6.0. To comply with the new namespace for
|
||||
stored scripts, existing stored scripts should be deleted and put again.
|
||||
Any scripts that share an `id` but have different `lang`s will need to
|
||||
be re-named. For example, take the following:
|
||||
|
||||
"id": "example", "lang": "painless"
|
||||
"id": "example", "lang": "expressions"
|
||||
|
||||
The above scripts will conflict under the new namespace since the id's are
|
||||
the same. At least one will have to be re-named to comply with the new
|
||||
namespace of only `id`.
|
||||
|
||||
As a final caveat, stored search templates and stored scripts share
|
||||
the same namespace, so if a search template has the same `id` as a
|
||||
stored script, one of the two will have to be re-named as well using
|
||||
delete and put requests.
|
||||
|
||||
==== Request Examples
|
||||
|
||||
The following are examples of using a stored script that lives at
|
||||
|
|
|
@ -136,7 +136,7 @@ public final class ScriptProcessor extends AbstractProcessor {
|
|||
script = new Script(INLINE, lang, source, (Map<String, Object>)params);
|
||||
scriptPropertyUsed = "source";
|
||||
} else if (Strings.hasLength(id)) {
|
||||
script = new Script(STORED, lang, id, (Map<String, Object>)params);
|
||||
script = new Script(STORED, null, id, (Map<String, Object>)params);
|
||||
scriptPropertyUsed = "id";
|
||||
} else {
|
||||
throw newConfigurationException(TYPE, processorTag, null, "Could not initialize script");
|
||||
|
|
|
@ -57,7 +57,7 @@ public class ScriptProcessorFactoryTests extends ESTestCase {
|
|||
String randomType = randomFrom("id", "source");
|
||||
configMap.put(randomType, "foo");
|
||||
ScriptProcessor processor = factory.create(null, randomAlphaOfLength(10), configMap);
|
||||
assertThat(processor.getScript().getLang(), equalTo(Script.DEFAULT_SCRIPT_LANG));
|
||||
assertThat(processor.getScript().getLang(), equalTo(randomType.equals("id") ? null : Script.DEFAULT_SCRIPT_LANG));
|
||||
assertThat(processor.getScript().getType().toString(), equalTo(ingestScriptParamToType.get(randomType)));
|
||||
assertThat(processor.getScript().getParams(), equalTo(Collections.emptyMap()));
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ public class ScriptProcessorFactoryTests extends ESTestCase {
|
|||
configMap.put(randomType, "foo");
|
||||
configMap.put("params", randomParams);
|
||||
ScriptProcessor processor = factory.create(null, randomAlphaOfLength(10), configMap);
|
||||
assertThat(processor.getScript().getLang(), equalTo(Script.DEFAULT_SCRIPT_LANG));
|
||||
assertThat(processor.getScript().getLang(), equalTo(randomType.equals("id") ? null : Script.DEFAULT_SCRIPT_LANG));
|
||||
assertThat(processor.getScript().getType().toString(), equalTo(ingestScriptParamToType.get(randomType)));
|
||||
assertThat(processor.getScript().getParams(), equalTo(randomParams));
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ public class StoredExpressionTests extends ESIntegTestCase {
|
|||
client().prepareIndex("test", "scriptTest", "1").setSource("{\"theField\":\"foo\"}", XContentType.JSON).get();
|
||||
try {
|
||||
client().prepareUpdate("test", "scriptTest", "1")
|
||||
.setScript(new Script(ScriptType.STORED, ExpressionScriptEngine.NAME, "script1", Collections.emptyMap())).get();
|
||||
.setScript(new Script(ScriptType.STORED, null, "script1", Collections.emptyMap())).get();
|
||||
fail("update script should have been rejected");
|
||||
} catch(Exception e) {
|
||||
assertThat(e.getMessage(), containsString("failed to execute script"));
|
||||
|
@ -67,7 +67,7 @@ public class StoredExpressionTests extends ESIntegTestCase {
|
|||
try {
|
||||
client().prepareSearch()
|
||||
.setSource(
|
||||
new SearchSourceBuilder().scriptField("test1", new Script(ScriptType.STORED, "expression", "script1", Collections.emptyMap())))
|
||||
new SearchSourceBuilder().scriptField("test1", new Script(ScriptType.STORED, null, "script1", Collections.emptyMap())))
|
||||
.setIndices("test").setTypes("scriptTest").get();
|
||||
fail("search script should have been rejected");
|
||||
} catch(Exception e) {
|
||||
|
@ -77,7 +77,7 @@ public class StoredExpressionTests extends ESIntegTestCase {
|
|||
client().prepareSearch("test")
|
||||
.setSource(
|
||||
new SearchSourceBuilder().aggregation(AggregationBuilders.terms("test").script(
|
||||
new Script(ScriptType.STORED, "expression", "script1", Collections.emptyMap())))).get();
|
||||
new Script(ScriptType.STORED, null, "script1", Collections.emptyMap())))).get();
|
||||
} catch (Exception e) {
|
||||
assertThat(e.toString(), containsString("cannot execute scripts using [aggs] context"));
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
|
|||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.script.ScriptType;
|
||||
import org.elasticsearch.script.TemplateScript;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
|
@ -95,7 +96,8 @@ public class TransportSearchTemplateAction extends HandledTransportAction<Search
|
|||
|
||||
static SearchRequest convert(SearchTemplateRequest searchTemplateRequest, SearchTemplateResponse response, ScriptService scriptService,
|
||||
NamedXContentRegistry xContentRegistry) throws IOException {
|
||||
Script script = new Script(searchTemplateRequest.getScriptType(), TEMPLATE_LANG, searchTemplateRequest.getScript(),
|
||||
Script script = new Script(searchTemplateRequest.getScriptType(),
|
||||
searchTemplateRequest.getScriptType() == ScriptType.STORED ? null : TEMPLATE_LANG, searchTemplateRequest.getScript(),
|
||||
searchTemplateRequest.getScriptParams() == null ? Collections.emptyMap() : searchTemplateRequest.getScriptParams());
|
||||
TemplateScript compiledScript = scriptService.compile(script, TemplateScript.CONTEXT).newInstance(script.getParams());
|
||||
String source = compiledScript.execute();
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.elasticsearch.script.mustache;
|
||||
|
||||
import org.elasticsearch.ResourceNotFoundException;
|
||||
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptResponse;
|
||||
import org.elasticsearch.action.bulk.BulkRequestBuilder;
|
||||
import org.elasticsearch.action.search.SearchRequest;
|
||||
|
@ -201,12 +202,6 @@ public class SearchTemplateIT extends ESSingleNodeTestCase {
|
|||
getResponse = client().admin().cluster()
|
||||
.prepareGetStoredScript(MustacheScriptEngine.NAME, "testTemplate").get();
|
||||
assertNull(getResponse.getSource());
|
||||
|
||||
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> new SearchTemplateRequestBuilder(client())
|
||||
.setRequest(new SearchRequest("test").types("type"))
|
||||
.setScript("/template_index/mustache/1000").setScriptType(ScriptType.STORED).setScriptParams(templateParams)
|
||||
.get());
|
||||
assertThat(e.getMessage(), containsString("illegal stored script format [/template_index/mustache/1000] use only <id>"));
|
||||
}
|
||||
|
||||
public void testIndexedTemplate() throws Exception {
|
||||
|
@ -266,16 +261,9 @@ public class SearchTemplateIT extends ESSingleNodeTestCase {
|
|||
.get();
|
||||
assertHitCount(searchResponse.getResponse(), 4);
|
||||
|
||||
expectThrows(IllegalArgumentException.class, () -> new SearchTemplateRequestBuilder(client())
|
||||
expectThrows(ResourceNotFoundException.class, () -> new SearchTemplateRequestBuilder(client())
|
||||
.setRequest(new SearchRequest().indices("test").types("type"))
|
||||
.setScript("/template_index/mustache/1000")
|
||||
.setScriptType(ScriptType.STORED)
|
||||
.setScriptParams(templateParams)
|
||||
.get());
|
||||
|
||||
expectThrows(IllegalArgumentException.class, () -> new SearchTemplateRequestBuilder(client())
|
||||
.setRequest(new SearchRequest().indices("test").types("type"))
|
||||
.setScript("/myindex/mustache/1")
|
||||
.setScript("1000")
|
||||
.setScriptType(ScriptType.STORED)
|
||||
.setScriptParams(templateParams)
|
||||
.get());
|
||||
|
@ -283,11 +271,9 @@ public class SearchTemplateIT extends ESSingleNodeTestCase {
|
|||
templateParams.put("fieldParam", "bar");
|
||||
searchResponse = new SearchTemplateRequestBuilder(client())
|
||||
.setRequest(new SearchRequest("test").types("type"))
|
||||
.setScript("/mustache/2").setScriptType(ScriptType.STORED).setScriptParams(templateParams)
|
||||
.setScript("2").setScriptType(ScriptType.STORED).setScriptParams(templateParams)
|
||||
.get();
|
||||
assertHitCount(searchResponse.getResponse(), 1);
|
||||
assertWarnings("use of </lang/id> [/mustache/2] for looking up" +
|
||||
" stored scripts/templates has been deprecated, use only <id> [2] instead");
|
||||
}
|
||||
|
||||
// Relates to #10397
|
||||
|
|
|
@ -223,6 +223,8 @@ public class RoundTripTests extends ESTestCase {
|
|||
String idOrCode = randomSimpleString(random());
|
||||
Map<String, Object> params = Collections.emptyMap();
|
||||
|
||||
return new Script(type, lang, idOrCode, params);
|
||||
type = ScriptType.STORED;
|
||||
|
||||
return new Script(type, type == ScriptType.STORED ? null : lang, idOrCode, params);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue