mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-17 02:14:54 +00:00
Scripting: Simplify ScriptContext (#24818)
As we work towards contexts implying the return type of compilation, we first need ScriptContext to not be an enum. This commit removes the Standard enum and Plugin subclass of ScriptContext.
This commit is contained in:
parent
5ae48f7dd5
commit
52d504bb5f
@ -301,7 +301,7 @@ public class UpdateHelper extends AbstractComponent {
|
||||
private Map<String, Object> executeScript(Script script, Map<String, Object> ctx) {
|
||||
try {
|
||||
if (scriptService != null) {
|
||||
CompiledScript compiledScript = scriptService.compile(script, ScriptContext.Standard.UPDATE);
|
||||
CompiledScript compiledScript = scriptService.compile(script, ScriptContext.UPDATE);
|
||||
ExecutableScript executableScript = scriptService.executable(compiledScript, script.getParams());
|
||||
executableScript.setNextVar(ContextFields.CTX, ctx);
|
||||
executableScript.run();
|
||||
|
@ -620,7 +620,7 @@ public final class InnerHitBuilder extends ToXContentToBytes implements Writeabl
|
||||
if (scriptFields != null) {
|
||||
for (ScriptField field : scriptFields) {
|
||||
SearchScript searchScript = innerHitsContext.getQueryShardContext().getSearchScript(field.script(),
|
||||
ScriptContext.Standard.SEARCH);
|
||||
ScriptContext.SEARCH);
|
||||
innerHitsContext.scriptFields().add(new org.elasticsearch.search.fetch.subphase.ScriptFieldsContext.ScriptField(
|
||||
field.fieldName(), searchScript, field.ignoreFailure()));
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ public class QueryRewriteContext {
|
||||
}
|
||||
|
||||
public String getTemplateBytes(Script template) {
|
||||
CompiledTemplate compiledTemplate = scriptService.compileTemplate(template, ScriptContext.Standard.SEARCH);
|
||||
CompiledTemplate compiledTemplate = scriptService.compileTemplate(template, ScriptContext.SEARCH);
|
||||
return compiledTemplate.run(template.getParams());
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ public class ScriptQueryBuilder extends AbstractQueryBuilder<ScriptQueryBuilder>
|
||||
|
||||
@Override
|
||||
protected Query doToQuery(QueryShardContext context) throws IOException {
|
||||
return new ScriptQuery(script, context.getSearchScript(script, ScriptContext.Standard.SEARCH));
|
||||
return new ScriptQuery(script, context.getSearchScript(script, ScriptContext.SEARCH));
|
||||
}
|
||||
|
||||
static class ScriptQuery extends Query {
|
||||
|
@ -94,7 +94,7 @@ public class ScriptScoreFunctionBuilder extends ScoreFunctionBuilder<ScriptScore
|
||||
@Override
|
||||
protected ScoreFunction doToFunction(QueryShardContext context) {
|
||||
try {
|
||||
SearchScript searchScript = context.getSearchScript(script, ScriptContext.Standard.SEARCH);
|
||||
SearchScript searchScript = context.getSearchScript(script, ScriptContext.SEARCH);
|
||||
return new ScriptScoreFunction(script, searchScript);
|
||||
} catch (Exception e) {
|
||||
throw new QueryShardException(context, "script_score: the script could not be loaded", e);
|
||||
|
@ -44,7 +44,7 @@ public class InternalTemplateService implements TemplateService {
|
||||
int mustacheEnd = template.indexOf("}}");
|
||||
if (mustacheStart != -1 && mustacheEnd != -1 && mustacheStart < mustacheEnd) {
|
||||
Script script = new Script(ScriptType.INLINE, "mustache", template, Collections.emptyMap());
|
||||
CompiledTemplate compiledTemplate = scriptService.compileTemplate(script, ScriptContext.Standard.INGEST);
|
||||
CompiledTemplate compiledTemplate = scriptService.compileTemplate(script, ScriptContext.INGEST);
|
||||
return new Template() {
|
||||
@Override
|
||||
public String execute(Map<String, Object> model) {
|
||||
|
@ -325,7 +325,7 @@ public class Node implements Closeable {
|
||||
}
|
||||
client = new NodeClient(settings, threadPool);
|
||||
final ResourceWatcherService resourceWatcherService = new ResourceWatcherService(settings, threadPool);
|
||||
final ScriptModule scriptModule = ScriptModule.create(settings, pluginsService.filterPlugins(ScriptPlugin.class));
|
||||
final ScriptModule scriptModule = new ScriptModule(settings, pluginsService.filterPlugins(ScriptPlugin.class));
|
||||
AnalysisModule analysisModule = new AnalysisModule(this.environment, pluginsService.filterPlugins(AnalysisPlugin.class));
|
||||
// this is as early as we can validate settings at this point. we already pass them to ScriptModule as well as ThreadPool
|
||||
// so we might be late here already
|
||||
|
@ -18,6 +18,10 @@
|
||||
*/
|
||||
package org.elasticsearch.plugins;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.script.ScriptContext;
|
||||
import org.elasticsearch.script.ScriptEngine;
|
||||
@ -35,9 +39,9 @@ public interface ScriptPlugin {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link ScriptContext.Plugin} instance or <code>null</code> if this plugin doesn't add a new script context plugin
|
||||
* Return script contexts this plugin wants to allow using.
|
||||
*/
|
||||
default ScriptContext.Plugin getCustomScriptContexts() {
|
||||
return null;
|
||||
default List<ScriptContext> getContexts() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
@ -19,87 +19,35 @@
|
||||
|
||||
package org.elasticsearch.script;
|
||||
|
||||
import org.elasticsearch.common.Strings;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Context of an operation that uses scripts as part of its execution.
|
||||
* A holder for information about a context in which a script is compiled and run.
|
||||
*/
|
||||
public interface ScriptContext {
|
||||
public final class ScriptContext {
|
||||
|
||||
/**
|
||||
* @return the name of the operation
|
||||
*/
|
||||
String getKey();
|
||||
public static final ScriptContext AGGS = new ScriptContext("aggs");
|
||||
public static final ScriptContext SEARCH = new ScriptContext("search");
|
||||
public static final ScriptContext UPDATE = new ScriptContext("update");
|
||||
public static final ScriptContext INGEST = new ScriptContext("ingest");
|
||||
|
||||
/**
|
||||
* Standard operations that make use of scripts as part of their execution.
|
||||
* Note that the suggest api is considered part of search for simplicity, as well as the percolate api.
|
||||
*/
|
||||
enum Standard implements ScriptContext {
|
||||
|
||||
AGGS("aggs"), SEARCH("search"), UPDATE("update"), INGEST("ingest");
|
||||
|
||||
private final String key;
|
||||
|
||||
Standard(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getKey();
|
||||
}
|
||||
public static final Map<String, ScriptContext> BUILTINS;
|
||||
static {
|
||||
Map<String, ScriptContext> builtins = new HashMap<>();
|
||||
builtins.put(AGGS.name, AGGS);
|
||||
builtins.put(SEARCH.name, SEARCH);
|
||||
builtins.put(UPDATE.name, UPDATE);
|
||||
builtins.put(INGEST.name, INGEST);
|
||||
BUILTINS = Collections.unmodifiableMap(builtins);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom operation exposed via plugin, which makes use of scripts as part of its execution
|
||||
*/
|
||||
final class Plugin implements ScriptContext {
|
||||
/** A unique identifier for this context. */
|
||||
public final String name;
|
||||
|
||||
private final String pluginName;
|
||||
private final String operation;
|
||||
private final String key;
|
||||
|
||||
/**
|
||||
* Creates a new custom scripts based operation exposed via plugin.
|
||||
* The name of the plugin combined with the operation name can be used to enable/disable scripts via fine-grained settings.
|
||||
*
|
||||
* @param pluginName the name of the plugin
|
||||
* @param operation the name of the operation
|
||||
*/
|
||||
public Plugin(String pluginName, String operation) {
|
||||
if (Strings.hasLength(pluginName) == false) {
|
||||
throw new IllegalArgumentException("plugin name cannot be empty when registering a custom script context");
|
||||
}
|
||||
if (Strings.hasLength(operation) == false) {
|
||||
throw new IllegalArgumentException("operation name cannot be empty when registering a custom script context");
|
||||
}
|
||||
this.pluginName = pluginName;
|
||||
this.operation = operation;
|
||||
this.key = pluginName + "_" + operation;
|
||||
}
|
||||
|
||||
public String getPluginName() {
|
||||
return pluginName;
|
||||
}
|
||||
|
||||
public String getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getKey();
|
||||
}
|
||||
// pkg private ctor, only created by script module
|
||||
public ScriptContext(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.script;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Collections.unmodifiableMap;
|
||||
import static java.util.Collections.unmodifiableSet;
|
||||
|
||||
/**
|
||||
* Registry for operations that use scripts as part of their execution. Can be standard operations of custom defined ones (via plugin).
|
||||
* Allows plugins to register custom operations that they use scripts for,
|
||||
* via {@link org.elasticsearch.plugins.ScriptPlugin}
|
||||
* Scripts can be enabled/disabled via fine-grained settings for each single registered operation.
|
||||
*/
|
||||
public final class ScriptContextRegistry {
|
||||
static final Set<String> RESERVED_SCRIPT_CONTEXTS = reservedScriptContexts();
|
||||
|
||||
private final Map<String, ScriptContext> scriptContexts;
|
||||
|
||||
public ScriptContextRegistry(Collection<ScriptContext.Plugin> customScriptContexts) {
|
||||
Map<String, ScriptContext> scriptContexts = new HashMap<>();
|
||||
for (ScriptContext.Standard scriptContext : ScriptContext.Standard.values()) {
|
||||
scriptContexts.put(scriptContext.getKey(), scriptContext);
|
||||
}
|
||||
for (ScriptContext.Plugin customScriptContext : customScriptContexts) {
|
||||
validateScriptContext(customScriptContext);
|
||||
ScriptContext previousContext = scriptContexts.put(customScriptContext.getKey(), customScriptContext);
|
||||
if (previousContext != null) {
|
||||
throw new IllegalArgumentException("script context [" + customScriptContext.getKey() + "] cannot be registered twice");
|
||||
}
|
||||
}
|
||||
this.scriptContexts = unmodifiableMap(scriptContexts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a list that contains all the supported {@link ScriptContext}s, both standard ones and registered via plugins
|
||||
*/
|
||||
Collection<ScriptContext> scriptContexts() {
|
||||
return scriptContexts.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <tt>true</tt> if the provided {@link ScriptContext} is supported, <tt>false</tt> otherwise
|
||||
*/
|
||||
boolean isSupportedContext(String scriptContext) {
|
||||
return scriptContexts.containsKey(scriptContext);
|
||||
}
|
||||
|
||||
//script contexts can be used in fine-grained settings, we need to be careful with what we allow here
|
||||
private void validateScriptContext(ScriptContext.Plugin scriptContext) {
|
||||
if (RESERVED_SCRIPT_CONTEXTS.contains(scriptContext.getPluginName())) {
|
||||
throw new IllegalArgumentException("[" + scriptContext.getPluginName() + "] is a reserved name, it cannot be registered as a custom script context");
|
||||
}
|
||||
if (RESERVED_SCRIPT_CONTEXTS.contains(scriptContext.getOperation())) {
|
||||
throw new IllegalArgumentException("[" + scriptContext.getOperation() + "] is a reserved name, it cannot be registered as a custom script context");
|
||||
}
|
||||
}
|
||||
|
||||
private static Set<String> reservedScriptContexts() {
|
||||
Set<String> reserved = new HashSet<>(ScriptType.values().length + ScriptContext.Standard.values().length);
|
||||
for (ScriptType scriptType : ScriptType.values()) {
|
||||
reserved.add(scriptType.toString());
|
||||
}
|
||||
for (ScriptContext.Standard scriptContext : ScriptContext.Standard.values()) {
|
||||
reserved.add(scriptContext.getKey());
|
||||
}
|
||||
reserved.add("script");
|
||||
reserved.add("engine");
|
||||
return unmodifiableSet(reserved);
|
||||
}
|
||||
}
|
@ -37,13 +37,12 @@ public interface ScriptEngine extends Closeable {
|
||||
|
||||
/**
|
||||
* Compiles a script.
|
||||
* @param scriptName name of the script. {@code null} if it is anonymous (inline).
|
||||
* For a file script, its the file name (with extension).
|
||||
* For a stored script, its the identifier.
|
||||
* @param scriptSource actual source of the script
|
||||
* @param name the name of the script. {@code null} if it is anonymous (inline). For a stored script, its the identifier.
|
||||
* @param code actual source of the script
|
||||
* @param params compile-time parameters (such as flags to the compiler)
|
||||
* @return an opaque compiled script which may be cached and later passed to
|
||||
*/
|
||||
Object compile(String scriptName, String scriptSource, Map<String, String> params);
|
||||
Object compile(String name, String code, Map<String, String> params);
|
||||
|
||||
ExecutableScript executable(CompiledScript compiledScript, @Nullable Map<String, Object> vars);
|
||||
|
||||
|
@ -19,17 +19,14 @@
|
||||
|
||||
package org.elasticsearch.script;
|
||||
|
||||
import org.elasticsearch.common.settings.ClusterSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.plugins.ScriptPlugin;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.elasticsearch.common.settings.ClusterSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.plugins.ScriptPlugin;
|
||||
|
||||
/**
|
||||
* Manages building {@link ScriptService}.
|
||||
@ -37,42 +34,26 @@ import java.util.stream.Collectors;
|
||||
public class ScriptModule {
|
||||
private final ScriptService scriptService;
|
||||
|
||||
/**
|
||||
* Build from {@linkplain ScriptPlugin}s. Convenient for normal use but not great for tests. See
|
||||
* {@link ScriptModule#ScriptModule(Settings, List, List)} for easier use in tests.
|
||||
*/
|
||||
public static ScriptModule create(Settings settings, List<ScriptPlugin> scriptPlugins) {
|
||||
List<ScriptEngine> scriptEngines = scriptPlugins.stream().map(x -> x.getScriptEngine(settings))
|
||||
.filter(Objects::nonNull).collect(Collectors.toList());
|
||||
List<ScriptContext.Plugin> plugins = scriptPlugins.stream().map(x -> x.getCustomScriptContexts()).filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
return new ScriptModule(settings, scriptEngines, plugins);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build {@linkplain ScriptEngine} and {@linkplain ScriptContext.Plugin}.
|
||||
*/
|
||||
public ScriptModule(Settings settings, List<ScriptEngine> scriptEngines,
|
||||
List<ScriptContext.Plugin> customScriptContexts) {
|
||||
ScriptContextRegistry scriptContextRegistry = new ScriptContextRegistry(customScriptContexts);
|
||||
Map<String, ScriptEngine> enginesByName = getEnginesByName(scriptEngines);
|
||||
try {
|
||||
scriptService = new ScriptService(settings, enginesByName, scriptContextRegistry);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Couldn't setup ScriptService", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, ScriptEngine> getEnginesByName(List<ScriptEngine> engines) {
|
||||
Map<String, ScriptEngine> enginesByName = new HashMap<>();
|
||||
for (ScriptEngine engine : engines) {
|
||||
ScriptEngine existing = enginesByName.put(engine.getType(), engine);
|
||||
if (existing != null) {
|
||||
throw new IllegalArgumentException("scripting language [" + engine.getType() + "] defined for engine [" +
|
||||
existing.getClass().getName() + "] and [" + engine.getClass().getName());
|
||||
public ScriptModule(Settings settings, List<ScriptPlugin> scriptPlugins) {
|
||||
Map<String, ScriptEngine> engines = new HashMap<>();
|
||||
Map<String, ScriptContext> contexts = new HashMap<>(ScriptContext.BUILTINS);
|
||||
for (ScriptPlugin plugin : scriptPlugins) {
|
||||
for (ScriptContext context : plugin.getContexts()) {
|
||||
ScriptContext oldContext = contexts.put(context.name, context);
|
||||
if (oldContext != null) {
|
||||
throw new IllegalArgumentException("Context name [" + context.name + "] defined twice");
|
||||
}
|
||||
}
|
||||
ScriptEngine engine = plugin.getScriptEngine(settings);
|
||||
if (engine != null) {
|
||||
ScriptEngine existing = engines.put(engine.getType(), engine);
|
||||
if (existing != null) {
|
||||
throw new IllegalArgumentException("scripting language [" + engine.getType() + "] defined for engine [" +
|
||||
existing.getClass().getName() + "] and [" + engine.getClass().getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableMap(enginesByName);
|
||||
scriptService = new ScriptService(settings, Collections.unmodifiableMap(engines), Collections.unmodifiableMap(contexts));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -82,11 +82,10 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
|
||||
private final Set<String> contextsAllowed;
|
||||
|
||||
private final Map<String, ScriptEngine> engines;
|
||||
private final Map<String, ScriptContext> contexts;
|
||||
|
||||
private final Cache<CacheKey, CompiledScript> cache;
|
||||
|
||||
private final ScriptContextRegistry scriptContextRegistry;
|
||||
|
||||
private final ScriptMetrics scriptMetrics = new ScriptMetrics();
|
||||
|
||||
private ClusterState clusterState;
|
||||
@ -96,12 +95,12 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
|
||||
private double scriptsPerMinCounter;
|
||||
private double compilesAllowedPerNano;
|
||||
|
||||
public ScriptService(Settings settings, Map<String, ScriptEngine> engines, ScriptContextRegistry scriptContextRegistry) throws IOException {
|
||||
public ScriptService(Settings settings, Map<String, ScriptEngine> engines, Map<String, ScriptContext> contexts) {
|
||||
super(settings);
|
||||
|
||||
Objects.requireNonNull(settings);
|
||||
this.engines = Objects.requireNonNull(engines);
|
||||
Objects.requireNonNull(scriptContextRegistry);
|
||||
this.contexts = Objects.requireNonNull(contexts);
|
||||
|
||||
if (Strings.hasLength(settings.get(DISABLE_DYNAMIC_SCRIPTING_SETTING))) {
|
||||
throw new IllegalArgumentException(DISABLE_DYNAMIC_SCRIPTING_SETTING + " is not a supported setting, replace with fine-grained script settings. \n" +
|
||||
@ -166,7 +165,7 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
|
||||
}
|
||||
}
|
||||
|
||||
if (scriptContextRegistry.isSupportedContext(settingContext)) {
|
||||
if (contexts.containsKey(settingContext)) {
|
||||
this.contextsAllowed.add(settingContext);
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
@ -175,8 +174,6 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
|
||||
}
|
||||
}
|
||||
|
||||
this.scriptContextRegistry = scriptContextRegistry;
|
||||
|
||||
int cacheMaxSize = SCRIPT_CACHE_SIZE_SETTING.get(settings);
|
||||
|
||||
CacheBuilder<CacheKey, CompiledScript> cacheBuilder = CacheBuilder.builder();
|
||||
@ -223,9 +220,9 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
|
||||
/**
|
||||
* Checks if a script can be executed and compiles it if needed, or returns the previously compiled and cached script.
|
||||
*/
|
||||
public CompiledScript compile(Script script, ScriptContext scriptContext) {
|
||||
public CompiledScript compile(Script script, ScriptContext context) {
|
||||
Objects.requireNonNull(script);
|
||||
Objects.requireNonNull(scriptContext);
|
||||
Objects.requireNonNull(context);
|
||||
|
||||
ScriptType type = script.getType();
|
||||
String lang = script.getLang();
|
||||
@ -266,10 +263,10 @@ 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 notSupported = scriptContext.getKey().equals(ScriptContext.Standard.UPDATE.getKey());
|
||||
boolean notSupported = context.name.equals(ScriptContext.UPDATE.name);
|
||||
if (expression && notSupported) {
|
||||
throw new UnsupportedOperationException("scripts of type [" + script.getType() + "]," +
|
||||
" operation [" + scriptContext.getKey() + "] and lang [" + lang + "] are not supported");
|
||||
" operation [" + context.name + "] and lang [" + lang + "] are not supported");
|
||||
}
|
||||
|
||||
ScriptEngine scriptEngine = getEngine(lang);
|
||||
@ -278,12 +275,12 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
|
||||
throw new IllegalArgumentException("cannot execute [" + type + "] scripts");
|
||||
}
|
||||
|
||||
if (scriptContextRegistry.isSupportedContext(scriptContext.getKey()) == false) {
|
||||
throw new IllegalArgumentException("script context [" + scriptContext.getKey() + "] not supported");
|
||||
if (contexts.containsKey(context.name) == false) {
|
||||
throw new IllegalArgumentException("script context [" + context.name + "] not supported");
|
||||
}
|
||||
|
||||
if (isContextEnabled(scriptContext) == false) {
|
||||
throw new IllegalArgumentException("cannot execute scripts using [" + scriptContext.getKey() + "] context");
|
||||
if (isContextEnabled(context) == false) {
|
||||
throw new IllegalArgumentException("cannot execute scripts using [" + context.name + "] context");
|
||||
}
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
@ -380,7 +377,7 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
|
||||
}
|
||||
|
||||
public boolean isContextEnabled(ScriptContext scriptContext) {
|
||||
return contextsAllowed == null || contextsAllowed.contains(scriptContext.getKey());
|
||||
return contextsAllowed == null || contextsAllowed.contains(scriptContext.name);
|
||||
}
|
||||
|
||||
public boolean isAnyContextEnabled() {
|
||||
|
@ -686,7 +686,7 @@ public class SearchService extends AbstractLifecycleComponent implements IndexEv
|
||||
}
|
||||
if (source.scriptFields() != null) {
|
||||
for (org.elasticsearch.search.builder.SearchSourceBuilder.ScriptField field : source.scriptFields()) {
|
||||
CompiledScript compile = scriptService.compile(field.script(), ScriptContext.Standard.SEARCH);
|
||||
CompiledScript compile = scriptService.compile(field.script(), ScriptContext.SEARCH);
|
||||
SearchScript searchScript = scriptService.search(context.lookup(), compile, field.script().getParams());
|
||||
context.scriptFields().add(new ScriptField(field.fieldName(), searchScript, field.ignoreFailure()));
|
||||
}
|
||||
|
@ -93,13 +93,13 @@ public class ScriptHeuristic extends SignificanceHeuristic {
|
||||
|
||||
@Override
|
||||
public SignificanceHeuristic rewrite(InternalAggregation.ReduceContext context) {
|
||||
CompiledScript compiledScript = context.scriptService().compile(script, ScriptContext.Standard.AGGS);
|
||||
CompiledScript compiledScript = context.scriptService().compile(script, ScriptContext.AGGS);
|
||||
return new ExecutableScriptHeuristic(script, context.scriptService().executable(compiledScript, script.getParams()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SignificanceHeuristic rewrite(SearchContext context) {
|
||||
return new ExecutableScriptHeuristic(script, context.getQueryShardContext().getExecutableScript(script, ScriptContext.Standard.AGGS));
|
||||
return new ExecutableScriptHeuristic(script, context.getQueryShardContext().getExecutableScript(script, ScriptContext.AGGS));
|
||||
}
|
||||
|
||||
|
||||
|
@ -97,7 +97,7 @@ public class InternalScriptedMetric extends InternalAggregation implements Scrip
|
||||
vars.putAll(firstAggregation.reduceScript.getParams());
|
||||
}
|
||||
CompiledScript compiledScript = reduceContext.scriptService().compile(
|
||||
firstAggregation.reduceScript, ScriptContext.Standard.AGGS);
|
||||
firstAggregation.reduceScript, ScriptContext.AGGS);
|
||||
ExecutableScript script = reduceContext.scriptService().executable(compiledScript, vars);
|
||||
aggregation = Collections.singletonList(script.run());
|
||||
} else if (reduceContext.isFinalReduce()) {
|
||||
|
@ -186,15 +186,15 @@ public class ScriptedMetricAggregationBuilder extends AbstractAggregationBuilder
|
||||
QueryShardContext queryShardContext = context.getQueryShardContext();
|
||||
Function<Map<String, Object>, ExecutableScript> executableInitScript;
|
||||
if (initScript != null) {
|
||||
executableInitScript = queryShardContext.getLazyExecutableScript(initScript, ScriptContext.Standard.AGGS);
|
||||
executableInitScript = queryShardContext.getLazyExecutableScript(initScript, ScriptContext.AGGS);
|
||||
} else {
|
||||
executableInitScript = (p) -> null;
|
||||
}
|
||||
Function<Map<String, Object>, SearchScript> searchMapScript = queryShardContext.getLazySearchScript(mapScript,
|
||||
ScriptContext.Standard.AGGS);
|
||||
ScriptContext.AGGS);
|
||||
Function<Map<String, Object>, ExecutableScript> executableCombineScript;
|
||||
if (combineScript != null) {
|
||||
executableCombineScript = queryShardContext.getLazyExecutableScript(combineScript, ScriptContext.Standard.AGGS);
|
||||
executableCombineScript = queryShardContext.getLazyExecutableScript(combineScript, ScriptContext.AGGS);
|
||||
} else {
|
||||
executableCombineScript = (p) -> null;
|
||||
}
|
||||
|
@ -534,7 +534,7 @@ public class TopHitsAggregationBuilder extends AbstractAggregationBuilder<TopHit
|
||||
if (scriptFields != null) {
|
||||
for (ScriptField field : scriptFields) {
|
||||
SearchScript searchScript = context.getQueryShardContext().getSearchScript(field.script(),
|
||||
ScriptContext.Standard.SEARCH);
|
||||
ScriptContext.SEARCH);
|
||||
fields.add(new org.elasticsearch.search.fetch.subphase.ScriptFieldsContext.ScriptField(
|
||||
field.fieldName(), searchScript, field.ignoreFailure()));
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ public class BucketScriptPipelineAggregator extends PipelineAggregator {
|
||||
(InternalMultiBucketAggregation<InternalMultiBucketAggregation, InternalMultiBucketAggregation.InternalBucket>) aggregation;
|
||||
List<? extends InternalMultiBucketAggregation.InternalBucket> buckets = originalAgg.getBuckets();
|
||||
|
||||
CompiledScript compiledScript = reduceContext.scriptService().compile(script, ScriptContext.Standard.AGGS);
|
||||
CompiledScript compiledScript = reduceContext.scriptService().compile(script, ScriptContext.AGGS);
|
||||
List<InternalMultiBucketAggregation.InternalBucket> newBuckets = new ArrayList<>();
|
||||
for (InternalMultiBucketAggregation.InternalBucket bucket : buckets) {
|
||||
Map<String, Object> vars = new HashMap<>();
|
||||
|
@ -84,7 +84,7 @@ public class BucketSelectorPipelineAggregator extends PipelineAggregator {
|
||||
(InternalMultiBucketAggregation<InternalMultiBucketAggregation, InternalMultiBucketAggregation.InternalBucket>) aggregation;
|
||||
List<? extends InternalMultiBucketAggregation.InternalBucket> buckets = originalAgg.getBuckets();
|
||||
|
||||
CompiledScript compiledScript = reduceContext.scriptService().compile(script, ScriptContext.Standard.AGGS);
|
||||
CompiledScript compiledScript = reduceContext.scriptService().compile(script, ScriptContext.AGGS);
|
||||
List<InternalMultiBucketAggregation.InternalBucket> newBuckets = new ArrayList<>();
|
||||
for (InternalMultiBucketAggregation.InternalBucket bucket : buckets) {
|
||||
Map<String, Object> vars = new HashMap<>();
|
||||
|
@ -120,7 +120,7 @@ public class ValuesSourceConfig<VS extends ValuesSource> {
|
||||
if (script == null) {
|
||||
return null;
|
||||
} else {
|
||||
return context.getSearchScript(script, ScriptContext.Standard.AGGS);
|
||||
return context.getSearchScript(script, ScriptContext.AGGS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,7 +242,7 @@ public class ScriptSortBuilder extends SortBuilder<ScriptSortBuilder> {
|
||||
|
||||
@Override
|
||||
public SortFieldAndFormat build(QueryShardContext context) throws IOException {
|
||||
final SearchScript searchScript = context.getSearchScript(script, ScriptContext.Standard.SEARCH);
|
||||
final SearchScript searchScript = context.getSearchScript(script, ScriptContext.SEARCH);
|
||||
|
||||
MultiValueMode valueMode = null;
|
||||
if (sortMode != null) {
|
||||
|
@ -631,7 +631,7 @@ public class PhraseSuggestionBuilder extends SuggestionBuilder<PhraseSuggestionB
|
||||
|
||||
if (this.collateQuery != null) {
|
||||
Function<Map<String, Object>, ExecutableScript> compiledScript = context.getLazyExecutableScript(this.collateQuery,
|
||||
ScriptContext.Standard.SEARCH);
|
||||
ScriptContext.SEARCH);
|
||||
suggestionContext.setCollateQueryScript(compiledScript);
|
||||
if (this.collateParams != null) {
|
||||
suggestionContext.setCollateScriptParams(this.collateParams);
|
||||
|
@ -42,7 +42,8 @@ import org.elasticsearch.index.get.GetResult;
|
||||
import org.elasticsearch.index.shard.ShardId;
|
||||
import org.elasticsearch.script.MockScriptEngine;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptContextRegistry;
|
||||
import org.elasticsearch.script.ScriptContext;
|
||||
import org.elasticsearch.script.ScriptEngine;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.script.ScriptType;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
@ -56,7 +57,6 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.elasticsearch.common.xcontent.XContentHelper.toXContent;
|
||||
@ -80,7 +80,6 @@ public class UpdateRequestTests extends ESTestCase {
|
||||
.put(Environment.PATH_HOME_SETTING.getKey(), createTempDir().toString())
|
||||
.put(Environment.PATH_CONF_SETTING.getKey(), genericConfigFolder)
|
||||
.build();
|
||||
final Environment environment = new Environment(baseSettings);
|
||||
final Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
|
||||
scripts.put(
|
||||
"ctx._source.update_timestamp = ctx._now",
|
||||
@ -135,13 +134,9 @@ public class UpdateRequestTests extends ESTestCase {
|
||||
return null;
|
||||
});
|
||||
scripts.put("return", vars -> null);
|
||||
final ScriptContextRegistry scriptContextRegistry = new ScriptContextRegistry(emptyList());
|
||||
final MockScriptEngine engine = new MockScriptEngine("mock", scripts);
|
||||
|
||||
ScriptService scriptService = new ScriptService(
|
||||
baseSettings,
|
||||
Collections.singletonMap(engine.getType(), engine),
|
||||
scriptContextRegistry);
|
||||
Map<String, ScriptEngine> engines = Collections.singletonMap(engine.getType(), engine);
|
||||
ScriptService scriptService = new ScriptService(baseSettings, engines, ScriptContext.BUILTINS);
|
||||
final Settings settings = settings(Version.CURRENT).build();
|
||||
|
||||
updateHelper = new UpdateHelper(settings, scriptService);
|
||||
|
@ -67,7 +67,6 @@ import org.elasticsearch.indices.breaker.NoneCircuitBreakerService;
|
||||
import org.elasticsearch.indices.cluster.IndicesClusterStateService.AllocatedIndices.IndexRemovalReason;
|
||||
import org.elasticsearch.indices.fielddata.cache.IndicesFieldDataCache;
|
||||
import org.elasticsearch.indices.mapper.MapperRegistry;
|
||||
import org.elasticsearch.script.ScriptContextRegistry;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.search.internal.SearchContext;
|
||||
import org.elasticsearch.test.ClusterServiceUtils;
|
||||
@ -125,8 +124,7 @@ public class IndexModuleTests extends ESTestCase {
|
||||
threadPool = new TestThreadPool("test");
|
||||
circuitBreakerService = new NoneCircuitBreakerService();
|
||||
bigArrays = new BigArrays(settings, circuitBreakerService);
|
||||
ScriptContextRegistry scriptContextRegistry = new ScriptContextRegistry(Collections.emptyList());
|
||||
scriptService = new ScriptService(settings, Collections.emptyMap(), scriptContextRegistry);
|
||||
scriptService = new ScriptService(settings, Collections.emptyMap(), Collections.emptyMap());
|
||||
clusterService = ClusterServiceUtils.createClusterService(threadPool);
|
||||
nodeEnvironment = new NodeEnvironment(settings, environment);
|
||||
mapperRegistry = new IndicesModule(Collections.emptyList()).getMapperRegistry();
|
||||
|
@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.script;
|
||||
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.hamcrest.Matchers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
public class ScriptContextRegistryTests extends ESTestCase {
|
||||
public void testValidateCustomScriptContextsOperation() throws IOException {
|
||||
for (final String rejectedContext : ScriptContextRegistry.RESERVED_SCRIPT_CONTEXTS) {
|
||||
try {
|
||||
//try to register a prohibited script context
|
||||
new ScriptContextRegistry(Arrays.asList(new ScriptContext.Plugin("test", rejectedContext)));
|
||||
fail("ScriptContextRegistry initialization should have failed");
|
||||
} catch(IllegalArgumentException e) {
|
||||
assertThat(e.getMessage(), Matchers.containsString("[" + rejectedContext + "] is a reserved name, it cannot be registered as a custom script context"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testValidateCustomScriptContextsPluginName() throws IOException {
|
||||
for (final String rejectedContext : ScriptContextRegistry.RESERVED_SCRIPT_CONTEXTS) {
|
||||
try {
|
||||
//try to register a prohibited script context
|
||||
new ScriptContextRegistry(Collections.singleton(new ScriptContext.Plugin(rejectedContext, "test")));
|
||||
fail("ScriptContextRegistry initialization should have failed");
|
||||
} catch(IllegalArgumentException e) {
|
||||
assertThat(e.getMessage(), Matchers.containsString("[" + rejectedContext + "] is a reserved name, it cannot be registered as a custom script context"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testValidateCustomScriptContextsEmptyPluginName() throws IOException {
|
||||
try {
|
||||
new ScriptContext.Plugin(randomBoolean() ? null : "", "test");
|
||||
fail("Expected exception");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage(), containsString("plugin name cannot be empty"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testValidateCustomScriptContextsEmptyOperation() throws IOException {
|
||||
try {
|
||||
new ScriptContext.Plugin("test", randomBoolean() ? null : "");
|
||||
fail("Expected exception");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage(), containsString("operation name cannot be empty"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testDuplicatedPluginScriptContexts() throws IOException {
|
||||
try {
|
||||
//try to register a prohibited script context
|
||||
new ScriptContextRegistry(Arrays.asList(new ScriptContext.Plugin("testplugin", "test"), new ScriptContext.Plugin("testplugin", "test")));
|
||||
fail("ScriptContextRegistry initialization should have failed");
|
||||
} catch(IllegalArgumentException e) {
|
||||
assertThat(e.getMessage(), containsString("script context [testplugin_test] cannot be registered twice"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testNonDuplicatedPluginScriptContexts() throws IOException {
|
||||
new ScriptContextRegistry(Arrays.asList(new ScriptContext.Plugin("testplugin1", "test"), new ScriptContext.Plugin("testplugin2", "test")));
|
||||
}
|
||||
}
|
@ -1,124 +0,0 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.script;
|
||||
|
||||
import org.elasticsearch.cluster.ClusterChangedEvent;
|
||||
import org.elasticsearch.cluster.ClusterName;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ScriptContextTests extends ESTestCase {
|
||||
|
||||
private static final String PLUGIN_NAME = "testplugin";
|
||||
|
||||
ScriptService makeScriptService() throws Exception {
|
||||
Settings settings = Settings.builder()
|
||||
.put(Environment.PATH_HOME_SETTING.getKey(), createTempDir())
|
||||
.put("script.contexts_allowed", "search, aggs, testplugin_custom_op")
|
||||
.build();
|
||||
|
||||
MockScriptEngine scriptEngine = new MockScriptEngine(MockScriptEngine.NAME, Collections.singletonMap("1", script -> "1"));
|
||||
Map<String, ScriptEngine> engines = Collections.singletonMap(scriptEngine.getType(), scriptEngine);
|
||||
List<ScriptContext.Plugin> customContexts = Arrays.asList(
|
||||
new ScriptContext.Plugin(PLUGIN_NAME, "custom_op"),
|
||||
new ScriptContext.Plugin(PLUGIN_NAME, "custom_exp_disabled_op"),
|
||||
new ScriptContext.Plugin(PLUGIN_NAME, "custom_globally_disabled_op"));
|
||||
ScriptContextRegistry scriptContextRegistry = new ScriptContextRegistry(customContexts);
|
||||
ScriptService scriptService = new ScriptService(settings, engines, scriptContextRegistry);
|
||||
|
||||
ClusterState empty = ClusterState.builder(new ClusterName("_name")).build();
|
||||
ScriptMetaData smd = empty.metaData().custom(ScriptMetaData.TYPE);
|
||||
smd = ScriptMetaData.putStoredScript(smd, "1", new StoredScriptSource(MockScriptEngine.NAME, "1", Collections.emptyMap()));
|
||||
MetaData.Builder mdb = MetaData.builder(empty.getMetaData()).putCustom(ScriptMetaData.TYPE, smd);
|
||||
ClusterState stored = ClusterState.builder(empty).metaData(mdb).build();
|
||||
scriptService.clusterChanged(new ClusterChangedEvent("test", stored, empty));
|
||||
|
||||
return scriptService;
|
||||
}
|
||||
|
||||
public void testCustomGlobalScriptContextSettings() throws Exception {
|
||||
ScriptService scriptService = makeScriptService();
|
||||
for (ScriptType scriptType : ScriptType.values()) {
|
||||
try {
|
||||
Script script = new Script(scriptType, MockScriptEngine.NAME, "1", Collections.emptyMap());
|
||||
scriptService.compile(script, new ScriptContext.Plugin(PLUGIN_NAME, "custom_globally_disabled_op"));
|
||||
fail("script compilation should have been rejected");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertTrue(e.getMessage(), e.getMessage().contains("cannot execute scripts using [" + PLUGIN_NAME + "_custom_globally_disabled_op] context"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testCustomScriptContextSettings() throws Exception {
|
||||
ScriptService scriptService = makeScriptService();
|
||||
Script script = new Script(ScriptType.INLINE, MockScriptEngine.NAME, "1", Collections.emptyMap());
|
||||
try {
|
||||
scriptService.compile(script, new ScriptContext.Plugin(PLUGIN_NAME, "custom_exp_disabled_op"));
|
||||
fail("script compilation should have been rejected");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertTrue(e.getMessage(), e.getMessage().contains("cannot execute scripts using [" + PLUGIN_NAME + "_custom_exp_disabled_op] context"));
|
||||
}
|
||||
|
||||
// still works for other script contexts
|
||||
assertNotNull(scriptService.compile(script, ScriptContext.Standard.AGGS));
|
||||
assertNotNull(scriptService.compile(script, ScriptContext.Standard.SEARCH));
|
||||
assertNotNull(scriptService.compile(script, new ScriptContext.Plugin(PLUGIN_NAME, "custom_op")));
|
||||
}
|
||||
|
||||
public void testUnknownPluginScriptContext() throws Exception {
|
||||
ScriptService scriptService = makeScriptService();
|
||||
for (ScriptType scriptType : ScriptType.values()) {
|
||||
try {
|
||||
Script script = new Script(scriptType, MockScriptEngine.NAME, "1", Collections.emptyMap());
|
||||
scriptService.compile(script, new ScriptContext.Plugin(PLUGIN_NAME, "unknown"));
|
||||
fail("script compilation should have been rejected");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertTrue(e.getMessage(), e.getMessage().contains("script context [" + PLUGIN_NAME + "_unknown] not supported"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testUnknownCustomScriptContext() throws Exception {
|
||||
ScriptContext context = new ScriptContext() {
|
||||
@Override
|
||||
public String getKey() {
|
||||
return "test";
|
||||
}
|
||||
};
|
||||
ScriptService scriptService = makeScriptService();
|
||||
for (ScriptType scriptType : ScriptType.values()) {
|
||||
try {
|
||||
Script script = new Script(scriptType, MockScriptEngine.NAME, "1", Collections.emptyMap());
|
||||
scriptService.compile(script, context);
|
||||
fail("script compilation should have been rejected");
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertTrue(e.getMessage(), e.getMessage().contains("script context [test] not supported"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -20,12 +20,8 @@ package org.elasticsearch.script;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.elasticsearch.ResourceNotFoundException;
|
||||
@ -41,6 +37,7 @@ import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.search.aggregations.support.ValuesSource;
|
||||
import org.elasticsearch.search.lookup.SearchLookup;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.junit.Before;
|
||||
@ -53,20 +50,11 @@ import static org.hamcrest.Matchers.sameInstance;
|
||||
public class ScriptServiceTests extends ESTestCase {
|
||||
|
||||
private ScriptEngine scriptEngine;
|
||||
private ScriptEngine dangerousScriptEngine;
|
||||
private Map<String, ScriptEngine> engines;
|
||||
private ScriptContextRegistry scriptContextRegistry;
|
||||
private ScriptContext[] scriptContexts;
|
||||
private Map<String, ScriptContext> contexts;
|
||||
private ScriptService scriptService;
|
||||
private Settings baseSettings;
|
||||
|
||||
private static final Map<ScriptType, Boolean> DEFAULT_SCRIPT_ENABLED = new HashMap<>();
|
||||
|
||||
static {
|
||||
DEFAULT_SCRIPT_ENABLED.put(ScriptType.STORED, false);
|
||||
DEFAULT_SCRIPT_ENABLED.put(ScriptType.INLINE, false);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() throws IOException {
|
||||
Path genericConfigFolder = createTempDir();
|
||||
@ -80,30 +68,16 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
//randomly register custom script contexts
|
||||
int randomInt = randomIntBetween(0, 3);
|
||||
//prevent duplicates using map
|
||||
Map<String, ScriptContext.Plugin> contexts = new HashMap<>();
|
||||
for (int i = 0; i < randomInt; i++) {
|
||||
String plugin;
|
||||
do {
|
||||
plugin = randomAlphaOfLength(randomIntBetween(1, 10));
|
||||
} while (ScriptContextRegistry.RESERVED_SCRIPT_CONTEXTS.contains(plugin));
|
||||
String operation;
|
||||
do {
|
||||
operation = randomAlphaOfLength(randomIntBetween(1, 30));
|
||||
} while (ScriptContextRegistry.RESERVED_SCRIPT_CONTEXTS.contains(operation));
|
||||
String context = plugin + "_" + operation;
|
||||
contexts.put(context, new ScriptContext.Plugin(plugin, operation));
|
||||
}
|
||||
contexts = new HashMap<>(ScriptContext.BUILTINS);
|
||||
engines = new HashMap<>();
|
||||
engines.put(scriptEngine.getType(), scriptEngine);
|
||||
engines.put(defaultScriptServiceEngine.getType(), defaultScriptServiceEngine);
|
||||
scriptContextRegistry = new ScriptContextRegistry(contexts.values());
|
||||
scriptContexts = scriptContextRegistry.scriptContexts().toArray(new ScriptContext[scriptContextRegistry.scriptContexts().size()]);
|
||||
logger.info("--> setup script service");
|
||||
}
|
||||
|
||||
private void buildScriptService(Settings additionalSettings) throws IOException {
|
||||
Settings finalSettings = Settings.builder().put(baseSettings).put(additionalSettings).build();
|
||||
scriptService = new ScriptService(finalSettings, engines, scriptContextRegistry) {
|
||||
scriptService = new ScriptService(finalSettings, engines, contexts) {
|
||||
@Override
|
||||
StoredScriptSource getScriptFromClusterState(String id, String lang) {
|
||||
//mock the script that gets retrieved from an index
|
||||
@ -148,26 +122,26 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
public void testInlineScriptCompiledOnceCache() throws IOException {
|
||||
buildScriptService(Settings.EMPTY);
|
||||
CompiledScript compiledScript1 = scriptService.compile(new Script(ScriptType.INLINE, "test", "1+1", Collections.emptyMap()),
|
||||
randomFrom(scriptContexts));
|
||||
randomFrom(contexts.values()));
|
||||
CompiledScript compiledScript2 = scriptService.compile(new Script(ScriptType.INLINE, "test", "1+1", Collections.emptyMap()),
|
||||
randomFrom(scriptContexts));
|
||||
randomFrom(contexts.values()));
|
||||
assertThat(compiledScript1.compiled(), sameInstance(compiledScript2.compiled()));
|
||||
}
|
||||
|
||||
public void testAllowAllScriptTypeSettings() throws IOException {
|
||||
buildScriptService(Settings.EMPTY);
|
||||
|
||||
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.Standard.SEARCH);
|
||||
assertCompileAccepted("painless", "script", ScriptType.STORED, ScriptContext.Standard.SEARCH);
|
||||
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.SEARCH);
|
||||
assertCompileAccepted("painless", "script", ScriptType.STORED, ScriptContext.SEARCH);
|
||||
}
|
||||
|
||||
public void testAllowAllScriptContextSettings() throws IOException {
|
||||
buildScriptService(Settings.EMPTY);
|
||||
|
||||
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.Standard.SEARCH);
|
||||
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.Standard.AGGS);
|
||||
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.Standard.UPDATE);
|
||||
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.Standard.INGEST);
|
||||
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.SEARCH);
|
||||
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.AGGS);
|
||||
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.UPDATE);
|
||||
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.INGEST);
|
||||
}
|
||||
|
||||
public void testAllowSomeScriptTypeSettings() throws IOException {
|
||||
@ -175,8 +149,8 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
builder.put("script.types_allowed", "inline");
|
||||
buildScriptService(builder.build());
|
||||
|
||||
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.Standard.SEARCH);
|
||||
assertCompileRejected("painless", "script", ScriptType.STORED, ScriptContext.Standard.SEARCH);
|
||||
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.SEARCH);
|
||||
assertCompileRejected("painless", "script", ScriptType.STORED, ScriptContext.SEARCH);
|
||||
}
|
||||
|
||||
public void testAllowSomeScriptContextSettings() throws IOException {
|
||||
@ -184,9 +158,9 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
builder.put("script.contexts_allowed", "search, aggs");
|
||||
buildScriptService(builder.build());
|
||||
|
||||
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.Standard.SEARCH);
|
||||
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.Standard.AGGS);
|
||||
assertCompileRejected("painless", "script", ScriptType.INLINE, ScriptContext.Standard.UPDATE);
|
||||
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.SEARCH);
|
||||
assertCompileAccepted("painless", "script", ScriptType.INLINE, ScriptContext.AGGS);
|
||||
assertCompileRejected("painless", "script", ScriptType.INLINE, ScriptContext.UPDATE);
|
||||
}
|
||||
|
||||
public void testAllowNoScriptTypeSettings() throws IOException {
|
||||
@ -194,8 +168,8 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
builder.put("script.types_allowed", "none");
|
||||
buildScriptService(builder.build());
|
||||
|
||||
assertCompileRejected("painless", "script", ScriptType.INLINE, ScriptContext.Standard.SEARCH);
|
||||
assertCompileRejected("painless", "script", ScriptType.STORED, ScriptContext.Standard.SEARCH);
|
||||
assertCompileRejected("painless", "script", ScriptType.INLINE, ScriptContext.SEARCH);
|
||||
assertCompileRejected("painless", "script", ScriptType.STORED, ScriptContext.SEARCH);
|
||||
}
|
||||
|
||||
public void testAllowNoScriptContextSettings() throws IOException {
|
||||
@ -203,41 +177,30 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
builder.put("script.contexts_allowed", "none");
|
||||
buildScriptService(builder.build());
|
||||
|
||||
assertCompileRejected("painless", "script", ScriptType.INLINE, ScriptContext.Standard.SEARCH);
|
||||
assertCompileRejected("painless", "script", ScriptType.INLINE, ScriptContext.Standard.AGGS);
|
||||
assertCompileRejected("painless", "script", ScriptType.INLINE, ScriptContext.Standard.UPDATE);
|
||||
assertCompileRejected("painless", "script", ScriptType.INLINE, ScriptContext.Standard.INGEST);
|
||||
assertCompileRejected("painless", "script", ScriptType.INLINE, ScriptContext.SEARCH);
|
||||
assertCompileRejected("painless", "script", ScriptType.INLINE, ScriptContext.AGGS);
|
||||
}
|
||||
|
||||
public void testCompileNonRegisteredContext() throws IOException {
|
||||
contexts.remove(ScriptContext.INGEST.name);
|
||||
buildScriptService(Settings.EMPTY);
|
||||
String pluginName;
|
||||
String unknownContext;
|
||||
do {
|
||||
pluginName = randomAlphaOfLength(randomIntBetween(1, 10));
|
||||
unknownContext = randomAlphaOfLength(randomIntBetween(1, 30));
|
||||
} while(scriptContextRegistry.isSupportedContext(new ScriptContext.Plugin(pluginName, unknownContext).getKey()));
|
||||
|
||||
String type = scriptEngine.getType();
|
||||
try {
|
||||
scriptService.compile(new Script(randomFrom(ScriptType.values()), type, "test", Collections.emptyMap()),
|
||||
new ScriptContext.Plugin(pluginName, unknownContext));
|
||||
fail("script compilation should have been rejected");
|
||||
} catch(IllegalArgumentException e) {
|
||||
assertThat(e.getMessage(), containsString("script context [" + pluginName + "_" + unknownContext + "] not supported"));
|
||||
}
|
||||
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () ->
|
||||
scriptService.compile(new Script(randomFrom(ScriptType.values()), type, "test", Collections.emptyMap()), ScriptContext.INGEST));
|
||||
assertThat(e.getMessage(), containsString("script context [" + ScriptContext.INGEST.name + "] not supported"));
|
||||
}
|
||||
|
||||
public void testCompileCountedInCompilationStats() throws IOException {
|
||||
buildScriptService(Settings.EMPTY);
|
||||
scriptService.compile(new Script(ScriptType.INLINE, "test", "1+1", Collections.emptyMap()), randomFrom(scriptContexts));
|
||||
scriptService.compile(new Script(ScriptType.INLINE, "test", "1+1", Collections.emptyMap()), randomFrom(contexts.values()));
|
||||
assertEquals(1L, scriptService.stats().getCompilations());
|
||||
}
|
||||
|
||||
public void testExecutableCountedInCompilationStats() throws IOException {
|
||||
buildScriptService(Settings.EMPTY);
|
||||
Script script = new Script(ScriptType.INLINE, "test", "1+1", Collections.emptyMap());
|
||||
CompiledScript compiledScript = scriptService.compile(script, randomFrom(scriptContexts));
|
||||
CompiledScript compiledScript = scriptService.compile(script, randomFrom(contexts.values()));
|
||||
scriptService.executable(compiledScript, script.getParams());
|
||||
assertEquals(1L, scriptService.stats().getCompilations());
|
||||
}
|
||||
@ -245,7 +208,7 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
public void testSearchCountedInCompilationStats() throws IOException {
|
||||
buildScriptService(Settings.EMPTY);
|
||||
Script script = new Script(ScriptType.INLINE, "test", "1+1", Collections.emptyMap());
|
||||
CompiledScript compile = scriptService.compile(script, randomFrom(scriptContexts));
|
||||
CompiledScript compile = scriptService.compile(script, randomFrom(contexts.values()));
|
||||
scriptService.search(null, compile, script.getParams());
|
||||
assertEquals(1L, scriptService.stats().getCompilations());
|
||||
}
|
||||
@ -255,7 +218,7 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
int numberOfCompilations = randomIntBetween(1, 1024);
|
||||
for (int i = 0; i < numberOfCompilations; i++) {
|
||||
scriptService
|
||||
.compile(new Script(ScriptType.INLINE, "test", i + " + " + i, Collections.emptyMap()), randomFrom(scriptContexts));
|
||||
.compile(new Script(ScriptType.INLINE, "test", i + " + " + i, Collections.emptyMap()), randomFrom(contexts.values()));
|
||||
}
|
||||
assertEquals(numberOfCompilations, scriptService.stats().getCompilations());
|
||||
}
|
||||
@ -265,14 +228,14 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
builder.put(ScriptService.SCRIPT_CACHE_SIZE_SETTING.getKey(), 1);
|
||||
buildScriptService(builder.build());
|
||||
Script script = new Script(ScriptType.INLINE, "test", "1+1", Collections.emptyMap());
|
||||
scriptService.compile(script, randomFrom(scriptContexts));
|
||||
scriptService.compile(script, randomFrom(scriptContexts));
|
||||
scriptService.compile(script, randomFrom(contexts.values()));
|
||||
scriptService.compile(script, randomFrom(contexts.values()));
|
||||
assertEquals(1L, scriptService.stats().getCompilations());
|
||||
}
|
||||
|
||||
public void testIndexedScriptCountedInCompilationStats() throws IOException {
|
||||
buildScriptService(Settings.EMPTY);
|
||||
scriptService.compile(new Script(ScriptType.STORED, "test", "script", Collections.emptyMap()), randomFrom(scriptContexts));
|
||||
scriptService.compile(new Script(ScriptType.STORED, "test", "script", Collections.emptyMap()), randomFrom(contexts.values()));
|
||||
assertEquals(1L, scriptService.stats().getCompilations());
|
||||
}
|
||||
|
||||
@ -280,8 +243,8 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
Settings.Builder builder = Settings.builder();
|
||||
builder.put(ScriptService.SCRIPT_CACHE_SIZE_SETTING.getKey(), 1);
|
||||
buildScriptService(builder.build());
|
||||
scriptService.compile(new Script(ScriptType.INLINE, "test", "1+1", Collections.emptyMap()), randomFrom(scriptContexts));
|
||||
scriptService.compile(new Script(ScriptType.INLINE, "test", "2+2", Collections.emptyMap()), randomFrom(scriptContexts));
|
||||
scriptService.compile(new Script(ScriptType.INLINE, "test", "1+1", Collections.emptyMap()), randomFrom(contexts.values()));
|
||||
scriptService.compile(new Script(ScriptType.INLINE, "test", "2+2", Collections.emptyMap()), randomFrom(contexts.values()));
|
||||
assertEquals(2L, scriptService.stats().getCompilations());
|
||||
assertEquals(1L, scriptService.stats().getCacheEvictions());
|
||||
}
|
||||
@ -290,7 +253,7 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
Settings.Builder builder = Settings.builder();
|
||||
buildScriptService(builder.build());
|
||||
CompiledScript script = scriptService.compile(
|
||||
new Script(ScriptType.INLINE, Script.DEFAULT_SCRIPT_LANG, "1 + 1", Collections.emptyMap()), randomFrom(scriptContexts));
|
||||
new Script(ScriptType.INLINE, Script.DEFAULT_SCRIPT_LANG, "1 + 1", Collections.emptyMap()), randomFrom(contexts.values()));
|
||||
assertEquals(script.lang(), Script.DEFAULT_SCRIPT_LANG);
|
||||
}
|
||||
|
||||
|
@ -19,20 +19,18 @@
|
||||
|
||||
package org.elasticsearch.search.aggregations.metrics.scripted;
|
||||
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.common.io.stream.Writeable.Reader;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.script.MockScriptEngine;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptContextRegistry;
|
||||
import org.elasticsearch.script.ScriptContext;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.script.ScriptType;
|
||||
import org.elasticsearch.search.aggregations.ParsedAggregation;
|
||||
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
||||
import org.elasticsearch.test.InternalAggregationTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@ -114,15 +112,8 @@ public class InternalScriptedMetricTests extends InternalAggregationTestCase<Int
|
||||
// mock script always retuns the size of the input aggs list as result
|
||||
@SuppressWarnings("unchecked")
|
||||
MockScriptEngine scriptEngine = new MockScriptEngine(MockScriptEngine.NAME,
|
||||
Collections.singletonMap(REDUCE_SCRIPT_NAME, script -> {
|
||||
return ((List<Object>) script.get("_aggs")).size();
|
||||
}));
|
||||
ScriptContextRegistry scriptContextRegistry = new ScriptContextRegistry(Collections.emptyList());
|
||||
try {
|
||||
return new ScriptService(Settings.EMPTY, Collections.singletonMap(scriptEngine.getType(), scriptEngine), scriptContextRegistry);
|
||||
} catch (IOException e) {
|
||||
throw new ElasticsearchException(e);
|
||||
}
|
||||
Collections.singletonMap(REDUCE_SCRIPT_NAME, script -> ((List<Object>) script.get("_aggs")).size()));
|
||||
return new ScriptService(Settings.EMPTY, Collections.singletonMap(scriptEngine.getType(), scriptEngine), ScriptContext.BUILTINS);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -25,7 +25,6 @@ import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.RandomIndexWriter;
|
||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
@ -34,7 +33,7 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
||||
import org.elasticsearch.script.MockScriptEngine;
|
||||
import org.elasticsearch.script.ScoreAccessor;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptContextRegistry;
|
||||
import org.elasticsearch.script.ScriptContext;
|
||||
import org.elasticsearch.script.ScriptEngine;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.script.ScriptType;
|
||||
@ -198,13 +197,7 @@ public class ScriptedMetricAggregatorTests extends AggregatorTestCase {
|
||||
CircuitBreakerService circuitBreakerService) {
|
||||
MockScriptEngine scriptEngine = new MockScriptEngine(MockScriptEngine.NAME, SCRIPTS);
|
||||
Map<String, ScriptEngine> engines = Collections.singletonMap(scriptEngine.getType(), scriptEngine);
|
||||
ScriptContextRegistry scriptContextRegistry = new ScriptContextRegistry(Collections.emptyList());
|
||||
ScriptService scriptService;
|
||||
try {
|
||||
scriptService = new ScriptService(Settings.EMPTY, engines, scriptContextRegistry);
|
||||
} catch (IOException e) {
|
||||
throw new ElasticsearchException(e);
|
||||
}
|
||||
ScriptService scriptService = new ScriptService(Settings.EMPTY, engines, ScriptContext.BUILTINS);
|
||||
return new QueryShardContext(0, mapperService.getIndexSettings(), null, null, mapperService, null, scriptService,
|
||||
xContentRegistry(), null, null, System::currentTimeMillis);
|
||||
}
|
||||
|
@ -53,7 +53,6 @@ import org.elasticsearch.indices.fielddata.cache.IndicesFieldDataCache;
|
||||
import org.elasticsearch.script.CompiledScript;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptContext;
|
||||
import org.elasticsearch.script.ScriptContextRegistry;
|
||||
import org.elasticsearch.script.ScriptEngine;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.script.ScriptServiceTests.TestEngine;
|
||||
@ -87,9 +86,8 @@ public abstract class AbstractSortTestCase<T extends SortBuilder<T>> extends EST
|
||||
.put(Environment.PATH_HOME_SETTING.getKey(), createTempDir().toString())
|
||||
.put(Environment.PATH_CONF_SETTING.getKey(), genericConfigFolder)
|
||||
.build();
|
||||
ScriptContextRegistry scriptContextRegistry = new ScriptContextRegistry(Collections.emptyList());
|
||||
ScriptEngine engine = new TestEngine();
|
||||
scriptService = new ScriptService(baseSettings, Collections.singletonMap(engine.getType(), engine), scriptContextRegistry) {
|
||||
scriptService = new ScriptService(baseSettings, Collections.singletonMap(engine.getType(), engine), ScriptContext.BUILTINS) {
|
||||
@Override
|
||||
public CompiledScript compile(Script script, ScriptContext scriptContext) {
|
||||
return new CompiledScript(ScriptType.INLINE, "mockName", "test", script);
|
||||
|
@ -70,7 +70,7 @@ public final class ScriptProcessor extends AbstractProcessor {
|
||||
*/
|
||||
@Override
|
||||
public void execute(IngestDocument document) {
|
||||
CompiledScript compiledScript = scriptService.compile(script, ScriptContext.Standard.INGEST);
|
||||
CompiledScript compiledScript = scriptService.compile(script, ScriptContext.INGEST);
|
||||
ExecutableScript executableScript = scriptService.executable(compiledScript, script.getParams());
|
||||
executableScript.setNextVar("ctx", document.getSourceAndMetadata());
|
||||
executableScript.run();
|
||||
@ -134,7 +134,7 @@ public final class ScriptProcessor extends AbstractProcessor {
|
||||
|
||||
// verify script is able to be compiled before successfully creating processor.
|
||||
try {
|
||||
scriptService.compile(script, ScriptContext.Standard.INGEST);
|
||||
scriptService.compile(script, ScriptContext.INGEST);
|
||||
} catch (ScriptException e) {
|
||||
throw newConfigurationException(TYPE, processorTag, scriptPropertyUsed, e);
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ import org.elasticsearch.transport.TransportService;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.elasticsearch.script.ScriptContext.Standard.SEARCH;
|
||||
import static org.elasticsearch.script.ScriptContext.SEARCH;
|
||||
|
||||
public class TransportSearchTemplateAction extends HandledTransportAction<SearchTemplateRequest, SearchTemplateResponse> {
|
||||
|
||||
|
@ -27,6 +27,7 @@ import org.elasticsearch.painless.Compiler.Loader;
|
||||
import org.elasticsearch.script.CompiledScript;
|
||||
import org.elasticsearch.script.ExecutableScript;
|
||||
import org.elasticsearch.script.LeafSearchScript;
|
||||
import org.elasticsearch.script.ScriptContext;
|
||||
import org.elasticsearch.script.ScriptEngine;
|
||||
import org.elasticsearch.script.ScriptException;
|
||||
import org.elasticsearch.script.SearchScript;
|
||||
|
@ -773,7 +773,7 @@ public abstract class AbstractAsyncBulkByScrollAction<Request extends AbstractBu
|
||||
return request;
|
||||
}
|
||||
if (executable == null) {
|
||||
CompiledScript compiled = scriptService.compile(script, ScriptContext.Standard.UPDATE);
|
||||
CompiledScript compiled = scriptService.compile(script, ScriptContext.UPDATE);
|
||||
executable = scriptService.executable(compiled, params);
|
||||
}
|
||||
if (context == null) {
|
||||
|
@ -20,7 +20,7 @@
|
||||
package org.elasticsearch.ingest;
|
||||
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.script.ScriptContextRegistry;
|
||||
import org.elasticsearch.script.ScriptContext;
|
||||
import org.elasticsearch.script.ScriptEngine;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.script.mustache.MustacheScriptEngine;
|
||||
@ -38,8 +38,7 @@ public abstract class AbstractScriptTestCase extends ESTestCase {
|
||||
public void init() throws Exception {
|
||||
MustacheScriptEngine engine = new MustacheScriptEngine();
|
||||
Map<String, ScriptEngine> engines = Collections.singletonMap(engine.getType(), engine);
|
||||
ScriptContextRegistry scriptContextRegistry = new ScriptContextRegistry(Collections.emptyList());
|
||||
ScriptService scriptService = new ScriptService(Settings.EMPTY, engines, scriptContextRegistry);
|
||||
ScriptService scriptService = new ScriptService(Settings.EMPTY, engines, ScriptContext.BUILTINS);
|
||||
templateService = new InternalTemplateService(scriptService);
|
||||
}
|
||||
|
||||
|
@ -1086,7 +1086,7 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
|
||||
if (scriptPlugins == null || scriptPlugins.isEmpty()) {
|
||||
return newTestScriptModule();
|
||||
}
|
||||
return ScriptModule.create(Settings.EMPTY, scriptPlugins);
|
||||
return new ScriptModule(Settings.EMPTY, scriptPlugins);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -91,8 +91,10 @@ import org.elasticsearch.indices.IndicesService;
|
||||
import org.elasticsearch.indices.analysis.AnalysisModule;
|
||||
import org.elasticsearch.plugins.AnalysisPlugin;
|
||||
import org.elasticsearch.plugins.MapperPlugin;
|
||||
import org.elasticsearch.plugins.ScriptPlugin;
|
||||
import org.elasticsearch.script.MockScriptEngine;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptEngine;
|
||||
import org.elasticsearch.script.ScriptModule;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.script.ScriptType;
|
||||
@ -1200,8 +1202,12 @@ public abstract class ESTestCase extends LuceneTestCase {
|
||||
}
|
||||
|
||||
public static ScriptModule newTestScriptModule() {
|
||||
MockScriptEngine scriptEngine = new MockScriptEngine(MockScriptEngine.NAME, Collections.singletonMap("1", script -> "1"));
|
||||
return new ScriptModule(Settings.EMPTY, singletonList(scriptEngine), emptyList());
|
||||
return new ScriptModule(Settings.EMPTY, singletonList(new ScriptPlugin() {
|
||||
@Override
|
||||
public ScriptEngine getScriptEngine(Settings settings) {
|
||||
return new MockScriptEngine(MockScriptEngine.NAME, Collections.singletonMap("1", script -> "1"));
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
/** Creates an IndicesModule for testing with the given mappers and metadata mappers. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user