mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-08 22:14:59 +00:00
Scripting: allow plugins to define custom operations that they use scripts for
Plugins can now define multiple operations/contexts that they use scripts for. Fine-grained settings can then be used to enable/disable scripts based on each single registered context. Also added a new generic category called `plugin`, which will be used as a default when the context is not specified. This allows us to restore backwards compatibility for plugins on `ScriptService` by restoring the old methods that don't require the script context and making them internally use the `plugin` context, as they can only be called from plugins. Closes #10347 Closes #10419
This commit is contained in:
parent
5d4a4fc3ff
commit
7bd7ea8f13
@ -300,12 +300,17 @@ supported operations are:
|
|||||||
| `mapping` |Mappings (script transform feature)
|
| `mapping` |Mappings (script transform feature)
|
||||||
| `search` |Search api, Percolator api and Suggester api (e.g filters, script_fields)
|
| `search` |Search api, Percolator api and Suggester api (e.g filters, script_fields)
|
||||||
| `update` |Update api
|
| `update` |Update api
|
||||||
|
| `plugin` |Any plugin that makes use of scripts under the generic `plugin` category
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|
|
||||||
|
Plugins can also define custom operations that they use scripts for instead
|
||||||
|
of using the generic `plugin` category. Those operations can be referred to
|
||||||
|
in the following form: `${pluginName}_${operation}`.
|
||||||
|
|
||||||
The following example disables scripting for `update` and `mapping` operations,
|
The following example disables scripting for `update` and `mapping` operations,
|
||||||
regardless of the script source, for any engine. Scripts can still be
|
regardless of the script source, for any engine. Scripts can still be
|
||||||
executed from sandboxed languages as part of `aggregations` and `search`
|
executed from sandboxed languages as part of `aggregations`, `search`
|
||||||
operations though, as the above defaults still get applied.
|
and plugins execution though, as the above defaults still get applied.
|
||||||
|
|
||||||
[source,yaml]
|
[source,yaml]
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
@ -325,14 +330,17 @@ script.engine.groovy.file.aggs: on
|
|||||||
script.engine.groovy.file.mapping: on
|
script.engine.groovy.file.mapping: on
|
||||||
script.engine.groovy.file.search: on
|
script.engine.groovy.file.search: on
|
||||||
script.engine.groovy.file.update: on
|
script.engine.groovy.file.update: on
|
||||||
|
script.engine.groovy.file.plugin: on
|
||||||
script.engine.groovy.indexed.aggs: on
|
script.engine.groovy.indexed.aggs: on
|
||||||
script.engine.groovy.indexed.mapping: off
|
script.engine.groovy.indexed.mapping: off
|
||||||
script.engine.groovy.indexed.search: on
|
script.engine.groovy.indexed.search: on
|
||||||
script.engine.groovy.indexed.update: off
|
script.engine.groovy.indexed.update: off
|
||||||
|
script.engine.groovy.indexed.plugin: off
|
||||||
script.engine.groovy.inline.aggs: on
|
script.engine.groovy.inline.aggs: on
|
||||||
script.engine.groovy.inline.mapping: off
|
script.engine.groovy.inline.mapping: off
|
||||||
script.engine.groovy.inline.search: off
|
script.engine.groovy.inline.search: off
|
||||||
script.engine.groovy.inline.update: off
|
script.engine.groovy.inline.update: off
|
||||||
|
script.engine.groovy.inline.plugin: off
|
||||||
|
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ public class UpdateHelper extends AbstractComponent {
|
|||||||
ctx.put("op", "create");
|
ctx.put("op", "create");
|
||||||
ctx.put("_source", upsertDoc);
|
ctx.put("_source", upsertDoc);
|
||||||
try {
|
try {
|
||||||
ExecutableScript script = scriptService.executable(request.scriptLang, request.script, request.scriptType, ScriptContext.UPDATE, request.scriptParams);
|
ExecutableScript script = scriptService.executable(request.scriptLang, request.script, request.scriptType, ScriptContext.Standard.UPDATE, request.scriptParams);
|
||||||
script.setNextVar("ctx", ctx);
|
script.setNextVar("ctx", ctx);
|
||||||
script.run();
|
script.run();
|
||||||
// we need to unwrap the ctx...
|
// we need to unwrap the ctx...
|
||||||
@ -193,7 +193,7 @@ public class UpdateHelper extends AbstractComponent {
|
|||||||
ctx.put("_source", sourceAndContent.v2());
|
ctx.put("_source", sourceAndContent.v2());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ExecutableScript script = scriptService.executable(request.scriptLang, request.script, request.scriptType, ScriptContext.UPDATE, request.scriptParams);
|
ExecutableScript script = scriptService.executable(request.scriptLang, request.script, request.scriptType, ScriptContext.Standard.UPDATE, request.scriptParams);
|
||||||
script.setNextVar("ctx", ctx);
|
script.setNextVar("ctx", ctx);
|
||||||
script.run();
|
script.run();
|
||||||
// we need to unwrap the ctx...
|
// we need to unwrap the ctx...
|
||||||
|
@ -64,8 +64,9 @@ import org.elasticsearch.index.mapper.internal.VersionFieldMapper;
|
|||||||
import org.elasticsearch.index.mapper.object.ObjectMapper;
|
import org.elasticsearch.index.mapper.object.ObjectMapper;
|
||||||
import org.elasticsearch.index.mapper.object.RootObjectMapper;
|
import org.elasticsearch.index.mapper.object.RootObjectMapper;
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
import org.elasticsearch.script.ExecutableScript;
|
||||||
import org.elasticsearch.script.ScriptService;
|
|
||||||
import org.elasticsearch.script.ScriptContext;
|
import org.elasticsearch.script.ScriptContext;
|
||||||
|
import org.elasticsearch.script.ScriptService;
|
||||||
|
import org.elasticsearch.script.ScriptService.ScriptType;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -79,7 +80,6 @@ import java.util.Set;
|
|||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import static com.google.common.collect.Lists.newArrayList;
|
import static com.google.common.collect.Lists.newArrayList;
|
||||||
import static org.elasticsearch.script.ScriptService.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -760,7 +760,7 @@ public class DocumentMapper implements ToXContent {
|
|||||||
public Map<String, Object> transformSourceAsMap(Map<String, Object> sourceAsMap) {
|
public Map<String, Object> transformSourceAsMap(Map<String, Object> sourceAsMap) {
|
||||||
try {
|
try {
|
||||||
// We use the ctx variable and the _source name to be consistent with the update api.
|
// We use the ctx variable and the _source name to be consistent with the update api.
|
||||||
ExecutableScript executable = scriptService.executable(language, script, scriptType, ScriptContext.MAPPING, parameters);
|
ExecutableScript executable = scriptService.executable(language, script, scriptType, ScriptContext.Standard.MAPPING, parameters);
|
||||||
Map<String, Object> ctx = new HashMap<>(1);
|
Map<String, Object> ctx = new HashMap<>(1);
|
||||||
ctx.put("_source", sourceAsMap);
|
ctx.put("_source", sourceAsMap);
|
||||||
executable.setNextVar("ctx", ctx);
|
executable.setNextVar("ctx", ctx);
|
||||||
|
@ -134,7 +134,7 @@ public class ScriptFilterParser implements FilterParser {
|
|||||||
public ScriptFilter(String scriptLang, String script, ScriptService.ScriptType scriptType, Map<String, Object> params, ScriptService scriptService, SearchLookup searchLookup) {
|
public ScriptFilter(String scriptLang, String script, ScriptService.ScriptType scriptType, Map<String, Object> params, ScriptService scriptService, SearchLookup searchLookup) {
|
||||||
this.script = script;
|
this.script = script;
|
||||||
this.params = params;
|
this.params = params;
|
||||||
this.searchScript = scriptService.search(searchLookup, scriptLang, script, scriptType, ScriptContext.SEARCH, newHashMap(params));
|
this.searchScript = scriptService.search(searchLookup, scriptLang, script, scriptType, ScriptContext.Standard.SEARCH, newHashMap(params));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,8 +26,8 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
|
|||||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
import org.elasticsearch.script.ExecutableScript;
|
||||||
import org.elasticsearch.script.ScriptService;
|
|
||||||
import org.elasticsearch.script.ScriptContext;
|
import org.elasticsearch.script.ScriptContext;
|
||||||
|
import org.elasticsearch.script.ScriptService;
|
||||||
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
|
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -77,7 +77,7 @@ public class TemplateQueryParser implements QueryParser {
|
|||||||
public Query parse(QueryParseContext parseContext) throws IOException {
|
public Query parse(QueryParseContext parseContext) throws IOException {
|
||||||
XContentParser parser = parseContext.parser();
|
XContentParser parser = parseContext.parser();
|
||||||
TemplateContext templateContext = parse(parser, PARAMS, parametersToTypes);
|
TemplateContext templateContext = parse(parser, PARAMS, parametersToTypes);
|
||||||
ExecutableScript executable = this.scriptService.executable(MustacheScriptEngineService.NAME, templateContext.template(), templateContext.scriptType(), ScriptContext.SEARCH, templateContext.params());
|
ExecutableScript executable = this.scriptService.executable(MustacheScriptEngineService.NAME, templateContext.template(), templateContext.scriptType(), ScriptContext.Standard.SEARCH, templateContext.params());
|
||||||
|
|
||||||
BytesReference querySource = (BytesReference) executable.run();
|
BytesReference querySource = (BytesReference) executable.run();
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ public class ScriptScoreFunctionParser implements ScoreFunctionParser {
|
|||||||
|
|
||||||
SearchScript searchScript;
|
SearchScript searchScript;
|
||||||
try {
|
try {
|
||||||
searchScript = parseContext.scriptService().search(parseContext.lookup(), scriptParameterParser.lang(), script, scriptType, ScriptContext.SEARCH, vars);
|
searchScript = parseContext.scriptService().search(parseContext.lookup(), scriptParameterParser.lang(), script, scriptType, ScriptContext.Standard.SEARCH, vars);
|
||||||
return new ScriptScoreFunction(script, vars, searchScript);
|
return new ScriptScoreFunction(script, vars, searchScript);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new QueryParsingException(parseContext.index(), NAMES[0] + " the script could not be loaded", e);
|
throw new QueryParsingException(parseContext.index(), NAMES[0] + " the script could not be loaded", e);
|
||||||
|
@ -19,20 +19,95 @@
|
|||||||
|
|
||||||
package org.elasticsearch.script;
|
package org.elasticsearch.script;
|
||||||
|
|
||||||
import java.util.Locale;
|
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||||
|
import org.elasticsearch.common.Strings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Operation/api that uses a script as part of its execution.
|
* Context of an operation that uses scripts as part of its execution.
|
||||||
* Note that the suggest api is considered part of search for simplicity, as well as the percolate api.
|
|
||||||
*/
|
*/
|
||||||
public enum ScriptContext {
|
public interface ScriptContext {
|
||||||
MAPPING,
|
|
||||||
UPDATE,
|
|
||||||
SEARCH,
|
|
||||||
AGGS;
|
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public String toString() {
|
* @return the name of the operation
|
||||||
return name().toLowerCase(Locale.ROOT);
|
*/
|
||||||
|
String getKey();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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"), MAPPING("mapping"), SEARCH("search"), UPDATE("update"),
|
||||||
|
/**
|
||||||
|
* Generic custom operation exposed via plugin
|
||||||
|
*
|
||||||
|
* @deprecated create a new {@link org.elasticsearch.script.ScriptContext.Plugin} instance instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
GENERIC_PLUGIN("plugin");
|
||||||
|
|
||||||
|
private final String key;
|
||||||
|
|
||||||
|
Standard(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom operation exposed via plugin, which makes use of scripts as part of its execution
|
||||||
|
*/
|
||||||
|
final class Plugin implements ScriptContext {
|
||||||
|
|
||||||
|
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 ElasticsearchIllegalArgumentException("plugin name cannot be empty when registering a custom script context");
|
||||||
|
}
|
||||||
|
if (Strings.hasLength(operation) == false) {
|
||||||
|
throw new ElasticsearchIllegalArgumentException("operation name cannot be empty when registering a custom script context");
|
||||||
|
}
|
||||||
|
this.pluginName = pluginName;
|
||||||
|
this.operation = operation;
|
||||||
|
this.key = pluginName + "_" + operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String getPluginName() {
|
||||||
|
return pluginName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String getOperation() {
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final String toString() {
|
||||||
|
return getKey();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.google.common.collect.ImmutableCollection;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 ScriptModule#registerScriptContext(org.elasticsearch.script.ScriptContext.Plugin)}.
|
||||||
|
* Scripts can be enabled/disabled via fine-grained settings for each single registered operation.
|
||||||
|
*/
|
||||||
|
public final class ScriptContextRegistry {
|
||||||
|
static final ImmutableSet<String> RESERVED_SCRIPT_CONTEXTS = reservedScriptContexts();
|
||||||
|
|
||||||
|
private final ImmutableMap<String, ScriptContext> scriptContexts;
|
||||||
|
|
||||||
|
ScriptContextRegistry(Iterable<ScriptContext.Plugin> customScriptContexts) {
|
||||||
|
Map<String, ScriptContext> scriptContexts = Maps.newHashMap();
|
||||||
|
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 ElasticsearchIllegalArgumentException("script context [" + customScriptContext.getKey() + "] cannot be registered twice");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.scriptContexts = ImmutableMap.copyOf(scriptContexts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a list that contains all the supported {@link ScriptContext}s, both standard ones and registered via plugins
|
||||||
|
*/
|
||||||
|
ImmutableCollection<ScriptContext> scriptContexts() {
|
||||||
|
return scriptContexts.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return <tt>true</tt> if the provided {@link ScriptContext} is supported, <tt>false</tt> otherwise
|
||||||
|
*/
|
||||||
|
boolean isSupportedContext(ScriptContext scriptContext) {
|
||||||
|
return scriptContexts.containsKey(scriptContext.getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
//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 ElasticsearchIllegalArgumentException("[" + scriptContext.getPluginName() + "] is a reserved name, it cannot be registered as a custom script context");
|
||||||
|
}
|
||||||
|
if (RESERVED_SCRIPT_CONTEXTS.contains(scriptContext.getOperation())) {
|
||||||
|
throw new ElasticsearchIllegalArgumentException("[" + scriptContext.getOperation() + "] is a reserved name, it cannot be registered as a custom script context");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ImmutableSet<String> reservedScriptContexts() {
|
||||||
|
ImmutableSet.Builder<String> builder = ImmutableSet.builder();
|
||||||
|
for (ScriptService.ScriptType scriptType : ScriptService.ScriptType.values()) {
|
||||||
|
builder.add(scriptType.toString());
|
||||||
|
}
|
||||||
|
for (ScriptContext.Standard scriptContext : ScriptContext.Standard.values()) {
|
||||||
|
builder.add(scriptContext.getKey());
|
||||||
|
}
|
||||||
|
builder.add("script").add("engine");
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
}
|
@ -42,45 +42,45 @@ public class ScriptModes {
|
|||||||
|
|
||||||
final ImmutableMap<String, ScriptMode> scriptModes;
|
final ImmutableMap<String, ScriptMode> scriptModes;
|
||||||
|
|
||||||
ScriptModes(Map<String, ScriptEngineService> scriptEngines, Settings settings) {
|
ScriptModes(Map<String, ScriptEngineService> scriptEngines, ScriptContextRegistry scriptContextRegistry, Settings settings) {
|
||||||
//filter out the native engine as we don't want to apply fine grained settings to it.
|
//filter out the native engine as we don't want to apply fine grained settings to it.
|
||||||
//native scripts are always on as they are static by definition.
|
//native scripts are always on as they are static by definition.
|
||||||
Map<String, ScriptEngineService> filteredEngines = Maps.newHashMap(scriptEngines);
|
Map<String, ScriptEngineService> filteredEngines = Maps.newHashMap(scriptEngines);
|
||||||
filteredEngines.remove(NativeScriptEngineService.NAME);
|
filteredEngines.remove(NativeScriptEngineService.NAME);
|
||||||
this.scriptModes = buildScriptModeSettingsMap(settings, filteredEngines);
|
this.scriptModes = buildScriptModeSettingsMap(settings, filteredEngines, scriptContextRegistry);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ImmutableMap<String, ScriptMode> buildScriptModeSettingsMap(Settings settings, Map<String, ScriptEngineService> scriptEngines) {
|
private static ImmutableMap<String, ScriptMode> buildScriptModeSettingsMap(Settings settings, Map<String, ScriptEngineService> scriptEngines, ScriptContextRegistry scriptContextRegistry) {
|
||||||
HashMap<String, ScriptMode> scriptModesMap = Maps.newHashMap();
|
HashMap<String, ScriptMode> scriptModesMap = Maps.newHashMap();
|
||||||
|
|
||||||
//file scripts are enabled by default, for any language
|
//file scripts are enabled by default, for any language
|
||||||
addGlobalScriptTypeModes(scriptEngines.keySet(), ScriptType.FILE, ScriptMode.ON, scriptModesMap);
|
addGlobalScriptTypeModes(scriptEngines.keySet(), scriptContextRegistry, ScriptType.FILE, ScriptMode.ON, scriptModesMap);
|
||||||
//indexed scripts are enabled by default only for sandboxed languages
|
//indexed scripts are enabled by default only for sandboxed languages
|
||||||
addGlobalScriptTypeModes(scriptEngines.keySet(), ScriptType.INDEXED, ScriptMode.SANDBOX, scriptModesMap);
|
addGlobalScriptTypeModes(scriptEngines.keySet(), scriptContextRegistry, ScriptType.INDEXED, ScriptMode.SANDBOX, scriptModesMap);
|
||||||
//dynamic scripts are enabled by default only for sandboxed languages
|
//dynamic scripts are enabled by default only for sandboxed languages
|
||||||
addGlobalScriptTypeModes(scriptEngines.keySet(), ScriptType.INLINE, ScriptMode.SANDBOX, scriptModesMap);
|
addGlobalScriptTypeModes(scriptEngines.keySet(), scriptContextRegistry, ScriptType.INLINE, ScriptMode.SANDBOX, scriptModesMap);
|
||||||
|
|
||||||
processSourceBasedGlobalSettings(settings, scriptEngines, scriptModesMap);
|
processSourceBasedGlobalSettings(settings, scriptEngines, scriptContextRegistry, scriptModesMap);
|
||||||
processOperationBasedGlobalSettings(settings, scriptEngines, scriptModesMap);
|
processOperationBasedGlobalSettings(settings, scriptEngines, scriptContextRegistry, scriptModesMap);
|
||||||
processEngineSpecificSettings(settings, scriptEngines, scriptModesMap);
|
processEngineSpecificSettings(settings, scriptEngines, scriptContextRegistry, scriptModesMap);
|
||||||
return ImmutableMap.copyOf(scriptModesMap);
|
return ImmutableMap.copyOf(scriptModesMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void processSourceBasedGlobalSettings(Settings settings, Map<String, ScriptEngineService> scriptEngines, Map<String, ScriptMode> scriptModes) {
|
private static void processSourceBasedGlobalSettings(Settings settings, Map<String, ScriptEngineService> scriptEngines, ScriptContextRegistry scriptContextRegistry, Map<String, ScriptMode> scriptModes) {
|
||||||
//read custom source based settings for all operations (e.g. script.indexed: on)
|
//read custom source based settings for all operations (e.g. script.indexed: on)
|
||||||
for (ScriptType scriptType : ScriptType.values()) {
|
for (ScriptType scriptType : ScriptType.values()) {
|
||||||
String scriptTypeSetting = settings.get(SCRIPT_SETTINGS_PREFIX + scriptType);
|
String scriptTypeSetting = settings.get(SCRIPT_SETTINGS_PREFIX + scriptType);
|
||||||
if (Strings.hasLength(scriptTypeSetting)) {
|
if (Strings.hasLength(scriptTypeSetting)) {
|
||||||
ScriptMode scriptTypeMode = ScriptMode.parse(scriptTypeSetting);
|
ScriptMode scriptTypeMode = ScriptMode.parse(scriptTypeSetting);
|
||||||
addGlobalScriptTypeModes(scriptEngines.keySet(), scriptType, scriptTypeMode, scriptModes);
|
addGlobalScriptTypeModes(scriptEngines.keySet(), scriptContextRegistry, scriptType, scriptTypeMode, scriptModes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void processOperationBasedGlobalSettings(Settings settings, Map<String, ScriptEngineService> scriptEngines, Map<String, ScriptMode> scriptModes) {
|
private static void processOperationBasedGlobalSettings(Settings settings, Map<String, ScriptEngineService> scriptEngines, ScriptContextRegistry scriptContextRegistry, Map<String, ScriptMode> scriptModes) {
|
||||||
//read custom op based settings for all sources (e.g. script.aggs: off)
|
//read custom op based settings for all sources (e.g. script.aggs: off)
|
||||||
//op based settings take precedence over source based settings, hence they get expanded later
|
//op based settings take precedence over source based settings, hence they get expanded later
|
||||||
for (ScriptContext scriptContext : ScriptContext.values()) {
|
for (ScriptContext scriptContext : scriptContextRegistry.scriptContexts()) {
|
||||||
ScriptMode scriptMode = getScriptContextMode(settings, SCRIPT_SETTINGS_PREFIX, scriptContext);
|
ScriptMode scriptMode = getScriptContextMode(settings, SCRIPT_SETTINGS_PREFIX, scriptContext);
|
||||||
if (scriptMode != null) {
|
if (scriptMode != null) {
|
||||||
addGlobalScriptContextModes(scriptEngines.keySet(), scriptContext, scriptMode, scriptModes);
|
addGlobalScriptContextModes(scriptEngines.keySet(), scriptContext, scriptMode, scriptModes);
|
||||||
@ -88,16 +88,15 @@ public class ScriptModes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void processEngineSpecificSettings(Settings settings, Map<String, ScriptEngineService> scriptEngines, Map<String, ScriptMode> scriptModes) {
|
private static void processEngineSpecificSettings(Settings settings, Map<String, ScriptEngineService> scriptEngines, ScriptContextRegistry scriptContextRegistry, Map<String, ScriptMode> scriptModes) {
|
||||||
Map<String, Settings> langGroupedSettings = settings.getGroups(ENGINE_SETTINGS_PREFIX, true);
|
Map<String, Settings> langGroupedSettings = settings.getGroups(ENGINE_SETTINGS_PREFIX, true);
|
||||||
for (Map.Entry<String, Settings> langSettings : langGroupedSettings.entrySet()) {
|
for (Map.Entry<String, Settings> langSettings : langGroupedSettings.entrySet()) {
|
||||||
//read engine specific settings that refer to a non existing script lang will be ignored
|
//read engine specific settings that refer to a non existing script lang will be ignored
|
||||||
ScriptEngineService scriptEngineService = scriptEngines.get(langSettings.getKey());
|
ScriptEngineService scriptEngineService = scriptEngines.get(langSettings.getKey());
|
||||||
if (scriptEngineService != null) {
|
if (scriptEngineService != null) {
|
||||||
String enginePrefix = ScriptModes.ENGINE_SETTINGS_PREFIX + "." + langSettings.getKey() + ".";
|
|
||||||
for (ScriptType scriptType : ScriptType.values()) {
|
for (ScriptType scriptType : ScriptType.values()) {
|
||||||
String scriptTypePrefix = scriptType + ".";
|
String scriptTypePrefix = scriptType + ".";
|
||||||
for (ScriptContext scriptContext : ScriptContext.values()) {
|
for (ScriptContext scriptContext : scriptContextRegistry.scriptContexts()) {
|
||||||
ScriptMode scriptMode = getScriptContextMode(langSettings.getValue(), scriptTypePrefix, scriptContext);
|
ScriptMode scriptMode = getScriptContextMode(langSettings.getValue(), scriptTypePrefix, scriptContext);
|
||||||
if (scriptMode != null) {
|
if (scriptMode != null) {
|
||||||
addScriptMode(scriptEngineService, scriptType, scriptContext, scriptMode, scriptModes);
|
addScriptMode(scriptEngineService, scriptType, scriptContext, scriptMode, scriptModes);
|
||||||
@ -109,16 +108,16 @@ public class ScriptModes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static ScriptMode getScriptContextMode(Settings settings, String prefix, ScriptContext scriptContext) {
|
private static ScriptMode getScriptContextMode(Settings settings, String prefix, ScriptContext scriptContext) {
|
||||||
String settingValue = settings.get(prefix + scriptContext);
|
String settingValue = settings.get(prefix + scriptContext.getKey());
|
||||||
if (Strings.hasLength(settingValue)) {
|
if (Strings.hasLength(settingValue)) {
|
||||||
return ScriptMode.parse(settingValue);
|
return ScriptMode.parse(settingValue);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void addGlobalScriptTypeModes(Set<String> langs, ScriptType scriptType, ScriptMode scriptMode, Map<String, ScriptMode> scriptModes) {
|
private static void addGlobalScriptTypeModes(Set<String> langs, ScriptContextRegistry scriptContextRegistry, ScriptType scriptType, ScriptMode scriptMode, Map<String, ScriptMode> scriptModes) {
|
||||||
for (String lang : langs) {
|
for (String lang : langs) {
|
||||||
for (ScriptContext scriptContext : ScriptContext.values()) {
|
for (ScriptContext scriptContext : scriptContextRegistry.scriptContexts()) {
|
||||||
addScriptMode(lang, scriptType, scriptContext, scriptMode, scriptModes);
|
addScriptMode(lang, scriptType, scriptContext, scriptMode, scriptModes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,7 +140,7 @@ public class ScriptModes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void addScriptMode(String lang, ScriptType scriptType, ScriptContext scriptContext, ScriptMode scriptMode, Map<String, ScriptMode> scriptModes) {
|
private static void addScriptMode(String lang, ScriptType scriptType, ScriptContext scriptContext, ScriptMode scriptMode, Map<String, ScriptMode> scriptModes) {
|
||||||
scriptModes.put(ENGINE_SETTINGS_PREFIX + "." + lang + "." + scriptType + "." + scriptContext, scriptMode);
|
scriptModes.put(ENGINE_SETTINGS_PREFIX + "." + lang + "." + scriptType + "." + scriptContext.getKey(), scriptMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -150,7 +149,7 @@ public class ScriptModes {
|
|||||||
*
|
*
|
||||||
* @param lang the language that the script is written in
|
* @param lang the language that the script is written in
|
||||||
* @param scriptType the type of the script
|
* @param scriptType the type of the script
|
||||||
* @param scriptContext the api that requires the execution of the script
|
* @param scriptContext the operation that requires the execution of the script
|
||||||
* @return whether scripts are on, off, or enabled only for sandboxed languages
|
* @return whether scripts are on, off, or enabled only for sandboxed languages
|
||||||
*/
|
*/
|
||||||
public ScriptMode getScriptMode(String lang, ScriptType scriptType, ScriptContext scriptContext) {
|
public ScriptMode getScriptMode(String lang, ScriptType scriptType, ScriptContext scriptContext) {
|
||||||
@ -158,9 +157,9 @@ public class ScriptModes {
|
|||||||
if (NativeScriptEngineService.NAME.equals(lang)) {
|
if (NativeScriptEngineService.NAME.equals(lang)) {
|
||||||
return ScriptMode.ON;
|
return ScriptMode.ON;
|
||||||
}
|
}
|
||||||
ScriptMode scriptMode = scriptModes.get(ENGINE_SETTINGS_PREFIX + "." + lang + "." + scriptType + "." + scriptContext);
|
ScriptMode scriptMode = scriptModes.get(ENGINE_SETTINGS_PREFIX + "." + lang + "." + scriptType + "." + scriptContext.getKey());
|
||||||
if (scriptMode == null) {
|
if (scriptMode == null) {
|
||||||
throw new ElasticsearchIllegalArgumentException("script mode not found for lang [" + lang + "], script_type [" + scriptType + "], operation [" + scriptContext + "]");
|
throw new ElasticsearchIllegalArgumentException("script mode not found for lang [" + lang + "], script_type [" + scriptType + "], operation [" + scriptContext.getKey() + "]");
|
||||||
}
|
}
|
||||||
return scriptMode;
|
return scriptMode;
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,8 @@ public class ScriptModule extends AbstractModule {
|
|||||||
|
|
||||||
private final Map<String, Class<? extends NativeScriptFactory>> scripts = Maps.newHashMap();
|
private final Map<String, Class<? extends NativeScriptFactory>> scripts = Maps.newHashMap();
|
||||||
|
|
||||||
|
private final List<ScriptContext.Plugin> customScriptContexts = Lists.newArrayList();
|
||||||
|
|
||||||
public ScriptModule(Settings settings) {
|
public ScriptModule(Settings settings) {
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
}
|
}
|
||||||
@ -58,6 +60,14 @@ public class ScriptModule extends AbstractModule {
|
|||||||
scripts.put(name, script);
|
scripts.put(name, script);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a custom script context that can be used by plugins to categorize the different operations that they use scripts for.
|
||||||
|
* Fine-grained settings allow to enable/disable scripts per context.
|
||||||
|
*/
|
||||||
|
public void registerScriptContext(ScriptContext.Plugin scriptContext) {
|
||||||
|
customScriptContexts.add(scriptContext);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
MapBinder<String, NativeScriptFactory> scriptsBinder
|
MapBinder<String, NativeScriptFactory> scriptsBinder
|
||||||
@ -105,6 +115,7 @@ public class ScriptModule extends AbstractModule {
|
|||||||
multibinder.addBinding().to(scriptEngine).asEagerSingleton();
|
multibinder.addBinding().to(scriptEngine).asEagerSingleton();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bind(ScriptContextRegistry.class).toInstance(new ScriptContextRegistry(customScriptContexts));
|
||||||
bind(ScriptService.class).asEagerSingleton();
|
bind(ScriptService.class).asEagerSingleton();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,6 +103,7 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
|||||||
private final FileWatcher fileWatcher;
|
private final FileWatcher fileWatcher;
|
||||||
|
|
||||||
private final ScriptModes scriptModes;
|
private final ScriptModes scriptModes;
|
||||||
|
private final ScriptContextRegistry scriptContextRegistry;
|
||||||
|
|
||||||
private Client client = null;
|
private Client client = null;
|
||||||
|
|
||||||
@ -113,7 +114,7 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ScriptService(Settings settings, Environment env, Set<ScriptEngineService> scriptEngines,
|
public ScriptService(Settings settings, Environment env, Set<ScriptEngineService> scriptEngines,
|
||||||
ResourceWatcherService resourceWatcherService, NodeSettingsService nodeSettingsService) throws IOException {
|
ResourceWatcherService resourceWatcherService, NodeSettingsService nodeSettingsService, ScriptContextRegistry scriptContextRegistry) throws IOException {
|
||||||
super(settings);
|
super(settings);
|
||||||
|
|
||||||
if (Strings.hasLength(settings.get(DISABLE_DYNAMIC_SCRIPTING_SETTING))) {
|
if (Strings.hasLength(settings.get(DISABLE_DYNAMIC_SCRIPTING_SETTING))) {
|
||||||
@ -122,6 +123,7 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.scriptEngines = scriptEngines;
|
this.scriptEngines = scriptEngines;
|
||||||
|
this.scriptContextRegistry = scriptContextRegistry;
|
||||||
int cacheMaxSize = settings.getAsInt(SCRIPT_CACHE_SIZE_SETTING, 100);
|
int cacheMaxSize = settings.getAsInt(SCRIPT_CACHE_SIZE_SETTING, 100);
|
||||||
TimeValue cacheExpire = settings.getAsTime(SCRIPT_CACHE_EXPIRE_SETTING, null);
|
TimeValue cacheExpire = settings.getAsTime(SCRIPT_CACHE_EXPIRE_SETTING, null);
|
||||||
logger.debug("using script cache with max_size [{}], expire [{}]", cacheMaxSize, cacheExpire);
|
logger.debug("using script cache with max_size [{}], expire [{}]", cacheMaxSize, cacheExpire);
|
||||||
@ -150,7 +152,7 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
|||||||
this.scriptEnginesByLang = enginesByLangBuilder.build();
|
this.scriptEnginesByLang = enginesByLangBuilder.build();
|
||||||
this.scriptEnginesByExt = enginesByExtBuilder.build();
|
this.scriptEnginesByExt = enginesByExtBuilder.build();
|
||||||
|
|
||||||
this.scriptModes = new ScriptModes(this.scriptEnginesByLang, settings);
|
this.scriptModes = new ScriptModes(this.scriptEnginesByLang, scriptContextRegistry, settings);
|
||||||
|
|
||||||
// add file watcher for static scripts
|
// add file watcher for static scripts
|
||||||
scriptsDirectory = env.configFile().resolve("scripts");
|
scriptsDirectory = env.configFile().resolve("scripts");
|
||||||
@ -212,6 +214,18 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
|||||||
return scriptEngineService;
|
return scriptEngineService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a script can be executed and compiles it if needed, or returns the previously compiled and cached script.
|
||||||
|
* Doesn't require to specify a script context in order to maintain backwards compatibility, internally uses
|
||||||
|
* the {@link org.elasticsearch.script.ScriptContext.Standard#GENERIC_PLUGIN} default context, assuming that it can only be called from plugins.
|
||||||
|
*
|
||||||
|
* @deprecated use the method variant that accepts the {@link ScriptContext} argument too: {@link #compile(String, String, ScriptType, ScriptContext)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public CompiledScript compile(String lang, String script, ScriptType scriptType) {
|
||||||
|
return compile(lang, script, scriptType, ScriptContext.Standard.GENERIC_PLUGIN);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a script can be executed and compiles it if needed, or returns the previously compiled and cached script.
|
* Checks if a script can be executed and compiles it if needed, or returns the previously compiled and cached script.
|
||||||
*/
|
*/
|
||||||
@ -226,7 +240,7 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
|||||||
|
|
||||||
ScriptEngineService scriptEngineService = getScriptEngineServiceForLang(lang);
|
ScriptEngineService scriptEngineService = getScriptEngineServiceForLang(lang);
|
||||||
if (canExecuteScript(lang, scriptEngineService, scriptType, scriptContext) == false) {
|
if (canExecuteScript(lang, scriptEngineService, scriptType, scriptContext) == false) {
|
||||||
throw new ScriptException("scripts of type [" + scriptType + "], operation [" + scriptContext + "] and lang [" + lang + "] are disabled");
|
throw new ScriptException("scripts of type [" + scriptType + "], operation [" + scriptContext.getKey() + "] and lang [" + lang + "] are disabled");
|
||||||
}
|
}
|
||||||
return compileInternal(lang, script, scriptType);
|
return compileInternal(lang, script, scriptType);
|
||||||
}
|
}
|
||||||
@ -380,6 +394,18 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compiles (or retrieves from cache) and executes the provided script.
|
||||||
|
* Doesn't require to specify a script context in order to maintain backwards compatibility, internally uses
|
||||||
|
* the {@link org.elasticsearch.script.ScriptContext.Standard#GENERIC_PLUGIN} default context, assuming that it can only be called from plugins.
|
||||||
|
*
|
||||||
|
* @deprecated use the method variant that accepts the {@link ScriptContext} argument too: {@link #executable(String, String, ScriptType, ScriptContext, Map)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public ExecutableScript executable(String lang, String script, ScriptType scriptType, Map<String, Object> vars) {
|
||||||
|
return executable(lang, script, scriptType, ScriptContext.Standard.GENERIC_PLUGIN, vars);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compiles (or retrieves from cache) and executes the provided script
|
* Compiles (or retrieves from cache) and executes the provided script
|
||||||
*/
|
*/
|
||||||
@ -394,6 +420,18 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
|||||||
return getScriptEngineServiceForLang(compiledScript.lang()).executable(compiledScript.compiled(), vars);
|
return getScriptEngineServiceForLang(compiledScript.lang()).executable(compiledScript.compiled(), vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compiles (or retrieves from cache) and executes the provided search script
|
||||||
|
* Doesn't require to specify a script context in order to maintain backwards compatibility, internally uses
|
||||||
|
* the {@link org.elasticsearch.script.ScriptContext.Standard#GENERIC_PLUGIN} default context, assuming that it can only be called from plugins.
|
||||||
|
*
|
||||||
|
* @deprecated use the method variant that accepts the {@link ScriptContext} argument too: {@link #search(SearchLookup, String, String, ScriptType, ScriptContext, Map)}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public SearchScript search(SearchLookup lookup, String lang, String script, ScriptType scriptType, @Nullable Map<String, Object> vars) {
|
||||||
|
return search(lookup, lang, script, scriptType, ScriptContext.Standard.GENERIC_PLUGIN, vars);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compiles (or retrieves from cache) and executes the provided search script
|
* Compiles (or retrieves from cache) and executes the provided search script
|
||||||
*/
|
*/
|
||||||
@ -403,7 +441,7 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAnyScriptContextEnabled(String lang, ScriptEngineService scriptEngineService, ScriptType scriptType) {
|
private boolean isAnyScriptContextEnabled(String lang, ScriptEngineService scriptEngineService, ScriptType scriptType) {
|
||||||
for (ScriptContext scriptContext : ScriptContext.values()) {
|
for (ScriptContext scriptContext : scriptContextRegistry.scriptContexts()) {
|
||||||
if (canExecuteScript(lang, scriptEngineService, scriptType, scriptContext)) {
|
if (canExecuteScript(lang, scriptEngineService, scriptType, scriptContext)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -413,6 +451,9 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
|||||||
|
|
||||||
private boolean canExecuteScript(String lang, ScriptEngineService scriptEngineService, ScriptType scriptType, ScriptContext scriptContext) {
|
private boolean canExecuteScript(String lang, ScriptEngineService scriptEngineService, ScriptType scriptType, ScriptContext scriptContext) {
|
||||||
assert lang != null;
|
assert lang != null;
|
||||||
|
if (scriptContextRegistry.isSupportedContext(scriptContext) == false) {
|
||||||
|
throw new ElasticsearchIllegalArgumentException("script context [" + scriptContext.getKey() + "] not supported");
|
||||||
|
}
|
||||||
ScriptMode mode = scriptModes.getScriptMode(lang, scriptType, scriptContext);
|
ScriptMode mode = scriptModes.getScriptMode(lang, scriptType, scriptContext);
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case ON:
|
case ON:
|
||||||
|
@ -71,8 +71,9 @@ import org.elasticsearch.indices.IndicesWarmer.TerminationHandle;
|
|||||||
import org.elasticsearch.indices.IndicesWarmer.WarmerContext;
|
import org.elasticsearch.indices.IndicesWarmer.WarmerContext;
|
||||||
import org.elasticsearch.indices.cache.query.IndicesQueryCache;
|
import org.elasticsearch.indices.cache.query.IndicesQueryCache;
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
import org.elasticsearch.script.ExecutableScript;
|
||||||
import org.elasticsearch.script.ScriptService;
|
|
||||||
import org.elasticsearch.script.ScriptContext;
|
import org.elasticsearch.script.ScriptContext;
|
||||||
|
import org.elasticsearch.script.ScriptService;
|
||||||
|
import org.elasticsearch.script.ScriptContextRegistry;
|
||||||
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
|
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
|
||||||
import org.elasticsearch.search.dfs.CachedDfSource;
|
import org.elasticsearch.search.dfs.CachedDfSource;
|
||||||
import org.elasticsearch.search.dfs.DfsPhase;
|
import org.elasticsearch.search.dfs.DfsPhase;
|
||||||
@ -652,7 +653,7 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
|||||||
|
|
||||||
final ExecutableScript executable;
|
final ExecutableScript executable;
|
||||||
if (hasLength(request.templateName())) {
|
if (hasLength(request.templateName())) {
|
||||||
executable = this.scriptService.executable(MustacheScriptEngineService.NAME, request.templateName(), request.templateType(), ScriptContext.SEARCH, request.templateParams());
|
executable = this.scriptService.executable(MustacheScriptEngineService.NAME, request.templateName(), request.templateType(), ScriptContext.Standard.SEARCH, request.templateParams());
|
||||||
} else {
|
} else {
|
||||||
if (!hasLength(request.templateSource())) {
|
if (!hasLength(request.templateSource())) {
|
||||||
return;
|
return;
|
||||||
@ -692,7 +693,7 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
|||||||
if (!hasLength(templateContext.template())) {
|
if (!hasLength(templateContext.template())) {
|
||||||
throw new ElasticsearchParseException("Template must have [template] field configured");
|
throw new ElasticsearchParseException("Template must have [template] field configured");
|
||||||
}
|
}
|
||||||
executable = this.scriptService.executable(MustacheScriptEngineService.NAME, templateContext.template(), templateContext.scriptType(), ScriptContext.SEARCH, templateContext.params());
|
executable = this.scriptService.executable(MustacheScriptEngineService.NAME, templateContext.template(), templateContext.scriptType(), ScriptContext.Standard.SEARCH, templateContext.params());
|
||||||
}
|
}
|
||||||
|
|
||||||
BytesReference processedQuery = (BytesReference) executable.run();
|
BytesReference processedQuery = (BytesReference) executable.run();
|
||||||
|
@ -30,10 +30,7 @@ import org.elasticsearch.common.logging.ESLoggerFactory;
|
|||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.index.query.QueryParsingException;
|
import org.elasticsearch.index.query.QueryParsingException;
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
import org.elasticsearch.script.*;
|
||||||
import org.elasticsearch.script.ScriptParameterParser;
|
|
||||||
import org.elasticsearch.script.ScriptService;
|
|
||||||
import org.elasticsearch.script.ScriptContext;
|
|
||||||
import org.elasticsearch.search.aggregations.InternalAggregation;
|
import org.elasticsearch.search.aggregations.InternalAggregation;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -86,7 +83,7 @@ public class ScriptHeuristic extends SignificanceHeuristic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void initialize(InternalAggregation.ReduceContext context) {
|
public void initialize(InternalAggregation.ReduceContext context) {
|
||||||
script = context.scriptService().executable(scriptLang, scriptString, scriptType, ScriptContext.AGGS, params);
|
script = context.scriptService().executable(scriptLang, scriptString, scriptType, ScriptContext.Standard.AGGS, params);
|
||||||
script.setNextVar("_subset_freq", subsetDfHolder);
|
script.setNextVar("_subset_freq", subsetDfHolder);
|
||||||
script.setNextVar("_subset_size", subsetSizeHolder);
|
script.setNextVar("_subset_size", subsetSizeHolder);
|
||||||
script.setNextVar("_superset_freq", supersetDfHolder);
|
script.setNextVar("_superset_freq", supersetDfHolder);
|
||||||
@ -171,7 +168,7 @@ public class ScriptHeuristic extends SignificanceHeuristic {
|
|||||||
}
|
}
|
||||||
ExecutableScript searchScript;
|
ExecutableScript searchScript;
|
||||||
try {
|
try {
|
||||||
searchScript = scriptService.executable(scriptLang, script, scriptType, ScriptContext.AGGS, params);
|
searchScript = scriptService.executable(scriptLang, script, scriptType, ScriptContext.Standard.AGGS, params);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ElasticsearchParseException("The script [" + script + "] could not be loaded", e);
|
throw new ElasticsearchParseException("The script [" + script + "] could not be loaded", e);
|
||||||
}
|
}
|
||||||
|
@ -24,8 +24,8 @@ import org.elasticsearch.common.io.stream.StreamInput;
|
|||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
import org.elasticsearch.script.ExecutableScript;
|
||||||
import org.elasticsearch.script.ScriptService.ScriptType;
|
|
||||||
import org.elasticsearch.script.ScriptContext;
|
import org.elasticsearch.script.ScriptContext;
|
||||||
|
import org.elasticsearch.script.ScriptService.ScriptType;
|
||||||
import org.elasticsearch.search.aggregations.AggregationStreams;
|
import org.elasticsearch.search.aggregations.AggregationStreams;
|
||||||
import org.elasticsearch.search.aggregations.InternalAggregation;
|
import org.elasticsearch.search.aggregations.InternalAggregation;
|
||||||
import org.elasticsearch.search.aggregations.metrics.InternalMetricsAggregation;
|
import org.elasticsearch.search.aggregations.metrics.InternalMetricsAggregation;
|
||||||
@ -99,7 +99,7 @@ public class InternalScriptedMetric extends InternalMetricsAggregation implement
|
|||||||
}
|
}
|
||||||
params.put("_aggs", aggregationObjects);
|
params.put("_aggs", aggregationObjects);
|
||||||
ExecutableScript script = reduceContext.scriptService().executable(firstAggregation.scriptLang, firstAggregation.reduceScript,
|
ExecutableScript script = reduceContext.scriptService().executable(firstAggregation.scriptLang, firstAggregation.reduceScript,
|
||||||
firstAggregation.scriptType, ScriptContext.AGGS, params);
|
firstAggregation.scriptType, ScriptContext.Standard.AGGS, params);
|
||||||
aggregation = script.run();
|
aggregation = script.run();
|
||||||
} else {
|
} else {
|
||||||
aggregation = aggregationObjects;
|
aggregation = aggregationObjects;
|
||||||
|
@ -23,9 +23,8 @@ import org.apache.lucene.index.LeafReaderContext;
|
|||||||
import org.elasticsearch.script.ExecutableScript;
|
import org.elasticsearch.script.ExecutableScript;
|
||||||
import org.elasticsearch.script.LeafSearchScript;
|
import org.elasticsearch.script.LeafSearchScript;
|
||||||
import org.elasticsearch.script.ScriptService;
|
import org.elasticsearch.script.ScriptService;
|
||||||
|
import org.elasticsearch.script.*;
|
||||||
import org.elasticsearch.script.ScriptService.ScriptType;
|
import org.elasticsearch.script.ScriptService.ScriptType;
|
||||||
import org.elasticsearch.script.ScriptContext;
|
|
||||||
import org.elasticsearch.script.SearchScript;
|
|
||||||
import org.elasticsearch.search.SearchParseException;
|
import org.elasticsearch.search.SearchParseException;
|
||||||
import org.elasticsearch.search.aggregations.Aggregator;
|
import org.elasticsearch.search.aggregations.Aggregator;
|
||||||
import org.elasticsearch.search.aggregations.AggregatorFactory;
|
import org.elasticsearch.search.aggregations.AggregatorFactory;
|
||||||
@ -75,11 +74,11 @@ public class ScriptedMetricAggregator extends MetricsAggregator {
|
|||||||
}
|
}
|
||||||
ScriptService scriptService = context.searchContext().scriptService();
|
ScriptService scriptService = context.searchContext().scriptService();
|
||||||
if (initScript != null) {
|
if (initScript != null) {
|
||||||
scriptService.executable(scriptLang, initScript, initScriptType, ScriptContext.AGGS, this.params).run();
|
scriptService.executable(scriptLang, initScript, initScriptType, ScriptContext.Standard.AGGS, this.params).run();
|
||||||
}
|
}
|
||||||
this.mapScript = scriptService.search(context.searchContext().lookup(), scriptLang, mapScript, mapScriptType, ScriptContext.AGGS, this.params);
|
this.mapScript = scriptService.search(context.searchContext().lookup(), scriptLang, mapScript, mapScriptType, ScriptContext.Standard.AGGS, this.params);
|
||||||
if (combineScript != null) {
|
if (combineScript != null) {
|
||||||
this.combineScript = scriptService.executable(scriptLang, combineScript, combineScriptType, ScriptContext.AGGS, this.params);
|
this.combineScript = scriptService.executable(scriptLang, combineScript, combineScriptType, ScriptContext.Standard.AGGS, this.params);
|
||||||
} else {
|
} else {
|
||||||
this.combineScript = null;
|
this.combineScript = null;
|
||||||
}
|
}
|
||||||
|
@ -29,11 +29,8 @@ import org.elasticsearch.index.mapper.core.BooleanFieldMapper;
|
|||||||
import org.elasticsearch.index.mapper.core.DateFieldMapper;
|
import org.elasticsearch.index.mapper.core.DateFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.core.NumberFieldMapper;
|
import org.elasticsearch.index.mapper.core.NumberFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.ip.IpFieldMapper;
|
import org.elasticsearch.index.mapper.ip.IpFieldMapper;
|
||||||
import org.elasticsearch.script.ScriptParameterParser;
|
import org.elasticsearch.script.*;
|
||||||
import org.elasticsearch.script.ScriptParameterParser.ScriptParameterValue;
|
import org.elasticsearch.script.ScriptParameterParser.ScriptParameterValue;
|
||||||
import org.elasticsearch.script.ScriptService;
|
|
||||||
import org.elasticsearch.script.ScriptContext;
|
|
||||||
import org.elasticsearch.script.SearchScript;
|
|
||||||
import org.elasticsearch.search.SearchParseException;
|
import org.elasticsearch.search.SearchParseException;
|
||||||
import org.elasticsearch.search.aggregations.InternalAggregation;
|
import org.elasticsearch.search.aggregations.InternalAggregation;
|
||||||
import org.elasticsearch.search.aggregations.support.format.ValueFormat;
|
import org.elasticsearch.search.aggregations.support.format.ValueFormat;
|
||||||
@ -189,7 +186,7 @@ public class ValuesSourceParser<VS extends ValuesSource> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private SearchScript createScript() {
|
private SearchScript createScript() {
|
||||||
return input.script == null ? null : context.scriptService().search(context.lookup(), input.lang, input.script, input.scriptType, ScriptContext.AGGS, input.params);
|
return input.script == null ? null : context.scriptService().search(context.lookup(), input.lang, input.script, input.scriptType, ScriptContext.Standard.AGGS, input.params);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ValueFormat resolveFormat(@Nullable String format, @Nullable ValueType valueType) {
|
private static ValueFormat resolveFormat(@Nullable String format, @Nullable ValueType valueType) {
|
||||||
|
@ -20,11 +20,8 @@
|
|||||||
package org.elasticsearch.search.fetch.script;
|
package org.elasticsearch.search.fetch.script;
|
||||||
|
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.script.ScriptParameterParser;
|
import org.elasticsearch.script.*;
|
||||||
import org.elasticsearch.script.ScriptParameterParser.ScriptParameterValue;
|
import org.elasticsearch.script.ScriptParameterParser.ScriptParameterValue;
|
||||||
import org.elasticsearch.script.ScriptService;
|
|
||||||
import org.elasticsearch.script.ScriptContext;
|
|
||||||
import org.elasticsearch.script.SearchScript;
|
|
||||||
import org.elasticsearch.search.SearchParseElement;
|
import org.elasticsearch.search.SearchParseElement;
|
||||||
import org.elasticsearch.search.internal.SearchContext;
|
import org.elasticsearch.search.internal.SearchContext;
|
||||||
|
|
||||||
@ -79,7 +76,7 @@ public class ScriptFieldsParseElement implements SearchParseElement {
|
|||||||
script = scriptValue.script();
|
script = scriptValue.script();
|
||||||
scriptType = scriptValue.scriptType();
|
scriptType = scriptValue.scriptType();
|
||||||
}
|
}
|
||||||
SearchScript searchScript = context.scriptService().search(context.lookup(), scriptParameterParser.lang(), script, scriptType, ScriptContext.SEARCH, params);
|
SearchScript searchScript = context.scriptService().search(context.lookup(), scriptParameterParser.lang(), script, scriptType, ScriptContext.Standard.SEARCH, params);
|
||||||
context.scriptFields().add(new ScriptFieldsContext.ScriptField(fieldName, searchScript, ignoreException));
|
context.scriptFields().add(new ScriptFieldsContext.ScriptField(fieldName, searchScript, ignoreException));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ public class ScriptSortParser implements SortParser {
|
|||||||
if (type == null) {
|
if (type == null) {
|
||||||
throw new SearchParseException(context, "_script sorting requires setting the type of the script");
|
throw new SearchParseException(context, "_script sorting requires setting the type of the script");
|
||||||
}
|
}
|
||||||
final SearchScript searchScript = context.scriptService().search(context.lookup(), scriptLang, script, scriptType, ScriptContext.SEARCH, params);
|
final SearchScript searchScript = context.scriptService().search(context.lookup(), scriptLang, script, scriptType, ScriptContext.Standard.SEARCH, params);
|
||||||
|
|
||||||
if (STRING_SORT_TYPE.equals(type) && (sortMode == MultiValueMode.SUM || sortMode == MultiValueMode.AVG)) {
|
if (STRING_SORT_TYPE.equals(type) && (sortMode == MultiValueMode.SUM || sortMode == MultiValueMode.AVG)) {
|
||||||
throw new SearchParseException(context, "type [string] doesn't support mode [" + sortMode + "]");
|
throw new SearchParseException(context, "type [string] doesn't support mode [" + sortMode + "]");
|
||||||
|
@ -30,8 +30,8 @@ import org.elasticsearch.index.analysis.ShingleTokenFilterFactory;
|
|||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.script.CompiledScript;
|
import org.elasticsearch.script.CompiledScript;
|
||||||
import org.elasticsearch.script.ScriptService.ScriptType;
|
|
||||||
import org.elasticsearch.script.ScriptContext;
|
import org.elasticsearch.script.ScriptContext;
|
||||||
|
import org.elasticsearch.script.ScriptService.ScriptType;
|
||||||
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
|
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
|
||||||
import org.elasticsearch.search.suggest.SuggestContextParser;
|
import org.elasticsearch.search.suggest.SuggestContextParser;
|
||||||
import org.elasticsearch.search.suggest.SuggestUtils;
|
import org.elasticsearch.search.suggest.SuggestUtils;
|
||||||
@ -153,7 +153,7 @@ public final class PhraseSuggestParser implements SuggestContextParser {
|
|||||||
if (suggestion.getCollateQueryScript() != null) {
|
if (suggestion.getCollateQueryScript() != null) {
|
||||||
throw new ElasticsearchIllegalArgumentException("suggester[phrase][collate] query already set, doesn't support additional [" + fieldName + "]");
|
throw new ElasticsearchIllegalArgumentException("suggester[phrase][collate] query already set, doesn't support additional [" + fieldName + "]");
|
||||||
}
|
}
|
||||||
CompiledScript compiledScript = suggester.scriptService().compile(MustacheScriptEngineService.NAME, templateNameOrTemplateContent, ScriptType.INLINE, ScriptContext.SEARCH);
|
CompiledScript compiledScript = suggester.scriptService().compile(MustacheScriptEngineService.NAME, templateNameOrTemplateContent, ScriptType.INLINE, ScriptContext.Standard.SEARCH);
|
||||||
if ("query".equals(fieldName)) {
|
if ("query".equals(fieldName)) {
|
||||||
suggestion.setCollateQueryScript(compiledScript);
|
suggestion.setCollateQueryScript(compiledScript);
|
||||||
} else {
|
} else {
|
||||||
|
@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.google.common.collect.ImmutableSet;
|
||||||
|
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||||
|
import org.elasticsearch.common.inject.Module;
|
||||||
|
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.plugins.AbstractPlugin;
|
||||||
|
import org.elasticsearch.script.expression.ExpressionScriptEngineService;
|
||||||
|
import org.elasticsearch.script.groovy.GroovyScriptEngineService;
|
||||||
|
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
|
||||||
|
import org.elasticsearch.test.ElasticsearchIntegrationTest;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
|
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||||
|
|
||||||
|
public class CustomScriptContextTests extends ElasticsearchIntegrationTest {
|
||||||
|
|
||||||
|
private static final ImmutableSet<String> LANG_SET = ImmutableSet.of(GroovyScriptEngineService.NAME, MustacheScriptEngineService.NAME, ExpressionScriptEngineService.NAME);
|
||||||
|
|
||||||
|
private static final String PLUGIN_NAME = "testplugin";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Settings nodeSettings(int nodeOrdinal) {
|
||||||
|
return ImmutableSettings.builder().put(super.nodeSettings(nodeOrdinal))
|
||||||
|
.put("plugin.types", CustomScriptContextPlugin.class.getName())
|
||||||
|
.put("script." + PLUGIN_NAME + "_custom_globally_disabled_op", "off")
|
||||||
|
.put("script.engine.expression.inline." + PLUGIN_NAME + "_custom_exp_disabled_op", "off")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCustomScriptContextsSettings() {
|
||||||
|
ScriptService scriptService = internalCluster().getInstance(ScriptService.class);
|
||||||
|
for (String lang : LANG_SET) {
|
||||||
|
for (ScriptService.ScriptType scriptType : ScriptService.ScriptType.values()) {
|
||||||
|
try {
|
||||||
|
scriptService.compile(lang, "test", scriptType, new ScriptContext.Plugin(PLUGIN_NAME, "custom_globally_disabled_op"));
|
||||||
|
fail("script compilation should have been rejected");
|
||||||
|
} catch(ScriptException e) {
|
||||||
|
assertThat(e.getMessage(), containsString("scripts of type [" + scriptType + "], operation [" + PLUGIN_NAME + "_custom_globally_disabled_op] and lang [" + lang + "] are disabled"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
scriptService.compile("expression", "1", ScriptService.ScriptType.INLINE, new ScriptContext.Plugin(PLUGIN_NAME, "custom_exp_disabled_op"));
|
||||||
|
fail("script compilation should have been rejected");
|
||||||
|
} catch(ScriptException e) {
|
||||||
|
assertThat(e.getMessage(), containsString("scripts of type [inline], operation [" + PLUGIN_NAME + "_custom_exp_disabled_op] and lang [expression] are disabled"));
|
||||||
|
}
|
||||||
|
|
||||||
|
CompiledScript compiledScript = scriptService.compile("expression", "1", ScriptService.ScriptType.INLINE, randomFrom(ScriptContext.Standard.values()));
|
||||||
|
assertThat(compiledScript, notNullValue());
|
||||||
|
|
||||||
|
compiledScript = scriptService.compile("mustache", "1", ScriptService.ScriptType.INLINE, new ScriptContext.Plugin(PLUGIN_NAME, "custom_exp_disabled_op"));
|
||||||
|
assertThat(compiledScript, notNullValue());
|
||||||
|
|
||||||
|
for (String lang : LANG_SET) {
|
||||||
|
compiledScript = scriptService.compile(lang, "1", ScriptService.ScriptType.INLINE, new ScriptContext.Plugin(PLUGIN_NAME, "custom_op"));
|
||||||
|
assertThat(compiledScript, notNullValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCompileNonRegisteredPluginContext() {
|
||||||
|
ScriptService scriptService = internalCluster().getInstance(ScriptService.class);
|
||||||
|
try {
|
||||||
|
scriptService.compile(randomFrom(LANG_SET.toArray(new String[LANG_SET.size()])), "test", randomFrom(ScriptService.ScriptType.values()), new ScriptContext.Plugin("test", "unknown"));
|
||||||
|
fail("script compilation should have been rejected");
|
||||||
|
} catch(ElasticsearchIllegalArgumentException e) {
|
||||||
|
assertThat(e.getMessage(), containsString("script context [test_unknown] not supported"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCompileNonRegisteredScriptContext() {
|
||||||
|
ScriptService scriptService = internalCluster().getInstance(ScriptService.class);
|
||||||
|
try {
|
||||||
|
scriptService.compile(randomFrom(LANG_SET.toArray(new String[LANG_SET.size()])), "test", randomFrom(ScriptService.ScriptType.values()), new ScriptContext() {
|
||||||
|
@Override
|
||||||
|
public String getKey() {
|
||||||
|
return "test";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fail("script compilation should have been rejected");
|
||||||
|
} catch(ElasticsearchIllegalArgumentException e) {
|
||||||
|
assertThat(e.getMessage(), containsString("script context [test] not supported"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CustomScriptContextPlugin extends AbstractPlugin {
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return "custom_script_context_plugin";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String description() {
|
||||||
|
return "Custom script context plugin";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processModule(Module module) {
|
||||||
|
if (module instanceof ScriptModule) {
|
||||||
|
ScriptModule scriptModule = (ScriptModule) module;
|
||||||
|
scriptModule.registerScriptContext(new ScriptContext.Plugin(PLUGIN_NAME, "custom_op"));
|
||||||
|
scriptModule.registerScriptContext(new ScriptContext.Plugin(PLUGIN_NAME, "custom_exp_disabled_op"));
|
||||||
|
scriptModule.registerScriptContext(new ScriptContext.Plugin(PLUGIN_NAME, "custom_globally_disabled_op"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -20,6 +20,7 @@
|
|||||||
package org.elasticsearch.script;
|
package org.elasticsearch.script;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.inject.Injector;
|
import org.elasticsearch.common.inject.Injector;
|
||||||
import org.elasticsearch.common.inject.ModulesBuilder;
|
import org.elasticsearch.common.inject.ModulesBuilder;
|
||||||
@ -58,7 +59,7 @@ public class NativeScriptTests extends ElasticsearchTestCase {
|
|||||||
|
|
||||||
ScriptService scriptService = injector.getInstance(ScriptService.class);
|
ScriptService scriptService = injector.getInstance(ScriptService.class);
|
||||||
|
|
||||||
ExecutableScript executable = scriptService.executable(NativeScriptEngineService.NAME, "my", ScriptType.INLINE, ScriptContext.SEARCH, null);
|
ExecutableScript executable = scriptService.executable(NativeScriptEngineService.NAME, "my", ScriptType.INLINE, ScriptContext.Standard.SEARCH, null);
|
||||||
assertThat(executable.run().toString(), equalTo("test"));
|
assertThat(executable.run().toString(), equalTo("test"));
|
||||||
terminate(injector.getInstance(ThreadPool.class));
|
terminate(injector.getInstance(ThreadPool.class));
|
||||||
}
|
}
|
||||||
@ -70,7 +71,7 @@ public class NativeScriptTests extends ElasticsearchTestCase {
|
|||||||
ScriptType scriptType = randomFrom(ScriptType.values());
|
ScriptType scriptType = randomFrom(ScriptType.values());
|
||||||
builder.put(ScriptModes.SCRIPT_SETTINGS_PREFIX + scriptType, randomFrom(ScriptMode.values()));
|
builder.put(ScriptModes.SCRIPT_SETTINGS_PREFIX + scriptType, randomFrom(ScriptMode.values()));
|
||||||
} else {
|
} else {
|
||||||
ScriptContext scriptContext = randomFrom(ScriptContext.values());
|
String scriptContext = randomFrom(ScriptContext.Standard.values()).getKey();
|
||||||
builder.put(ScriptModes.SCRIPT_SETTINGS_PREFIX + scriptContext, randomFrom(ScriptMode.values()));
|
builder.put(ScriptModes.SCRIPT_SETTINGS_PREFIX + scriptContext, randomFrom(ScriptMode.values()));
|
||||||
}
|
}
|
||||||
Settings settings = builder.build();
|
Settings settings = builder.build();
|
||||||
@ -79,9 +80,10 @@ public class NativeScriptTests extends ElasticsearchTestCase {
|
|||||||
Map<String, NativeScriptFactory> nativeScriptFactoryMap = new HashMap<>();
|
Map<String, NativeScriptFactory> nativeScriptFactoryMap = new HashMap<>();
|
||||||
nativeScriptFactoryMap.put("my", new MyNativeScriptFactory());
|
nativeScriptFactoryMap.put("my", new MyNativeScriptFactory());
|
||||||
Set<ScriptEngineService> scriptEngineServices = ImmutableSet.<ScriptEngineService>of(new NativeScriptEngineService(settings, nativeScriptFactoryMap));
|
Set<ScriptEngineService> scriptEngineServices = ImmutableSet.<ScriptEngineService>of(new NativeScriptEngineService(settings, nativeScriptFactoryMap));
|
||||||
ScriptService scriptService = new ScriptService(settings, environment, scriptEngineServices, resourceWatcherService, new NodeSettingsService(settings));
|
ScriptContextRegistry scriptContextRegistry = new ScriptContextRegistry(Lists.<ScriptContext.Plugin>newArrayList());
|
||||||
|
ScriptService scriptService = new ScriptService(settings, environment, scriptEngineServices, resourceWatcherService, new NodeSettingsService(settings), scriptContextRegistry);
|
||||||
|
|
||||||
for (ScriptContext scriptContext : ScriptContext.values()) {
|
for (ScriptContext scriptContext : scriptContextRegistry.scriptContexts()) {
|
||||||
assertThat(scriptService.compile(NativeScriptEngineService.NAME, "my", ScriptType.INLINE, scriptContext), notNullValue());
|
assertThat(scriptService.compile(NativeScriptEngineService.NAME, "my", ScriptType.INLINE, scriptContext), notNullValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* 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 com.google.common.collect.Lists;
|
||||||
|
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||||
|
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class ScriptContextRegistryTests extends ElasticsearchTestCase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateCustomScriptContextsOperation() throws IOException {
|
||||||
|
for (final String rejectedContext : ScriptContextRegistry.RESERVED_SCRIPT_CONTEXTS) {
|
||||||
|
try {
|
||||||
|
//try to register a prohibited script context
|
||||||
|
new ScriptContextRegistry(Lists.newArrayList(new ScriptContext.Plugin("test", rejectedContext)));
|
||||||
|
fail("ScriptContextRegistry initialization should have failed");
|
||||||
|
} catch(ElasticsearchIllegalArgumentException e) {
|
||||||
|
assertThat(e.getMessage(), Matchers.containsString("[" + rejectedContext + "] is a reserved name, it cannot be registered as a custom script context"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateCustomScriptContextsPluginName() throws IOException {
|
||||||
|
for (final String rejectedContext : ScriptContextRegistry.RESERVED_SCRIPT_CONTEXTS) {
|
||||||
|
try {
|
||||||
|
//try to register a prohibited script context
|
||||||
|
new ScriptContextRegistry(Lists.newArrayList(new ScriptContext.Plugin(rejectedContext, "test")));
|
||||||
|
fail("ScriptContextRegistry initialization should have failed");
|
||||||
|
} catch(ElasticsearchIllegalArgumentException e) {
|
||||||
|
assertThat(e.getMessage(), Matchers.containsString("[" + rejectedContext + "] is a reserved name, it cannot be registered as a custom script context"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ElasticsearchIllegalArgumentException.class)
|
||||||
|
public void testValidateCustomScriptContextsEmptyPluginName() throws IOException {
|
||||||
|
new ScriptContext.Plugin(randomBoolean() ? null : "", "test");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ElasticsearchIllegalArgumentException.class)
|
||||||
|
public void testValidateCustomScriptContextsEmptyOperation() throws IOException {
|
||||||
|
new ScriptContext.Plugin("test", randomBoolean() ? null : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicatedPluginScriptContexts() throws IOException {
|
||||||
|
try {
|
||||||
|
//try to register a prohibited script context
|
||||||
|
new ScriptContextRegistry(Lists.newArrayList(new ScriptContext.Plugin("testplugin", "test"), new ScriptContext.Plugin("testplugin", "test")));
|
||||||
|
fail("ScriptContextRegistry initialization should have failed");
|
||||||
|
} catch(ElasticsearchIllegalArgumentException e) {
|
||||||
|
assertThat(e.getMessage(), Matchers.containsString("script context [testplugin_test] cannot be registered twice"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNonDuplicatedPluginScriptContexts() throws IOException {
|
||||||
|
new ScriptContextRegistry(Lists.newArrayList(new ScriptContext.Plugin("testplugin1", "test"), new ScriptContext.Plugin("testplugin2", "test")));
|
||||||
|
}
|
||||||
|
}
|
@ -19,8 +19,7 @@
|
|||||||
|
|
||||||
package org.elasticsearch.script;
|
package org.elasticsearch.script;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.*;
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||||
@ -34,10 +33,7 @@ import org.junit.After;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||||
@ -49,6 +45,8 @@ public class ScriptModesTests extends ElasticsearchTestCase {
|
|||||||
static final String[] ENABLE_VALUES = new String[]{"on", "true", "yes", "1"};
|
static final String[] ENABLE_VALUES = new String[]{"on", "true", "yes", "1"};
|
||||||
static final String[] DISABLE_VALUES = new String[]{"off", "false", "no", "0"};
|
static final String[] DISABLE_VALUES = new String[]{"off", "false", "no", "0"};
|
||||||
|
|
||||||
|
ScriptContextRegistry scriptContextRegistry;
|
||||||
|
private ScriptContext[] scriptContexts;
|
||||||
private Map<String, ScriptEngineService> scriptEngines;
|
private Map<String, ScriptEngineService> scriptEngines;
|
||||||
private ScriptModes scriptModes;
|
private ScriptModes scriptModes;
|
||||||
private Set<String> checkedSettings;
|
private Set<String> checkedSettings;
|
||||||
@ -57,6 +55,18 @@ public class ScriptModesTests extends ElasticsearchTestCase {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setupScriptEngines() {
|
public void setupScriptEngines() {
|
||||||
|
//randomly register custom script contexts
|
||||||
|
int randomInt = randomIntBetween(0, 3);
|
||||||
|
//prevent duplicates using map
|
||||||
|
Map<String, ScriptContext.Plugin> contexts = Maps.newHashMap();
|
||||||
|
for (int i = 0; i < randomInt; i++) {
|
||||||
|
String plugin = randomAsciiOfLength(randomIntBetween(1, 10));
|
||||||
|
String operation = randomAsciiOfLength(randomIntBetween(1, 30));
|
||||||
|
String context = plugin + "-" + operation;
|
||||||
|
contexts.put(context, new ScriptContext.Plugin(plugin, operation));
|
||||||
|
}
|
||||||
|
scriptContextRegistry = new ScriptContextRegistry(contexts.values());
|
||||||
|
scriptContexts = scriptContextRegistry.scriptContexts().toArray(new ScriptContext[scriptContextRegistry.scriptContexts().size()]);
|
||||||
scriptEngines = buildScriptEnginesByLangMap(ImmutableSet.of(
|
scriptEngines = buildScriptEnginesByLangMap(ImmutableSet.of(
|
||||||
new GroovyScriptEngineService(ImmutableSettings.EMPTY),
|
new GroovyScriptEngineService(ImmutableSettings.EMPTY),
|
||||||
new MustacheScriptEngineService(ImmutableSettings.EMPTY),
|
new MustacheScriptEngineService(ImmutableSettings.EMPTY),
|
||||||
@ -72,7 +82,7 @@ public class ScriptModesTests extends ElasticsearchTestCase {
|
|||||||
@After
|
@After
|
||||||
public void assertNativeScriptsAreAlwaysAllowed() {
|
public void assertNativeScriptsAreAlwaysAllowed() {
|
||||||
if (assertScriptModesNonNull) {
|
if (assertScriptModesNonNull) {
|
||||||
assertThat(scriptModes.getScriptMode(NativeScriptEngineService.NAME, randomFrom(ScriptType.values()), randomFrom(ScriptContext.values())), equalTo(ScriptMode.ON));
|
assertThat(scriptModes.getScriptMode(NativeScriptEngineService.NAME, randomFrom(ScriptType.values()), randomFrom(scriptContexts)), equalTo(ScriptMode.ON));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +91,7 @@ public class ScriptModesTests extends ElasticsearchTestCase {
|
|||||||
if (assertScriptModesNonNull) {
|
if (assertScriptModesNonNull) {
|
||||||
assertThat(scriptModes, notNullValue());
|
assertThat(scriptModes, notNullValue());
|
||||||
//4 is the number of engines (native excluded), custom is counted twice though as it's associated with two different names
|
//4 is the number of engines (native excluded), custom is counted twice though as it's associated with two different names
|
||||||
int numberOfSettings = 5 * ScriptType.values().length * ScriptContext.values().length;
|
int numberOfSettings = 5 * ScriptType.values().length * scriptContextRegistry.scriptContexts().size();
|
||||||
assertThat(scriptModes.scriptModes.size(), equalTo(numberOfSettings));
|
assertThat(scriptModes.scriptModes.size(), equalTo(numberOfSettings));
|
||||||
if (assertAllSettingsWereChecked) {
|
if (assertAllSettingsWereChecked) {
|
||||||
assertThat(checkedSettings.size(), equalTo(numberOfSettings));
|
assertThat(checkedSettings.size(), equalTo(numberOfSettings));
|
||||||
@ -91,7 +101,7 @@ public class ScriptModesTests extends ElasticsearchTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefaultSettings() {
|
public void testDefaultSettings() {
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, ImmutableSettings.EMPTY);
|
this.scriptModes = new ScriptModes(scriptEngines, scriptContextRegistry, ImmutableSettings.EMPTY);
|
||||||
assertScriptModesAllOps(ScriptMode.ON, ALL_LANGS, ScriptType.FILE);
|
assertScriptModesAllOps(ScriptMode.ON, ALL_LANGS, ScriptType.FILE);
|
||||||
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.INDEXED, ScriptType.INLINE);
|
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.INDEXED, ScriptType.INLINE);
|
||||||
}
|
}
|
||||||
@ -99,239 +109,95 @@ public class ScriptModesTests extends ElasticsearchTestCase {
|
|||||||
@Test(expected = ElasticsearchIllegalArgumentException.class)
|
@Test(expected = ElasticsearchIllegalArgumentException.class)
|
||||||
public void testMissingSetting() {
|
public void testMissingSetting() {
|
||||||
assertAllSettingsWereChecked = false;
|
assertAllSettingsWereChecked = false;
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, ImmutableSettings.EMPTY);
|
this.scriptModes = new ScriptModes(scriptEngines, scriptContextRegistry, ImmutableSettings.EMPTY);
|
||||||
scriptModes.getScriptMode("non_existing", randomFrom(ScriptType.values()), randomFrom(ScriptContext.values()));
|
scriptModes.getScriptMode("non_existing", randomFrom(ScriptType.values()), randomFrom(scriptContexts));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEnableInlineGenericSettings() {
|
public void testScriptTypeGenericSettings() {
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.inline", randomFrom(ENABLE_VALUES));
|
int randomInt = randomIntBetween(1, ScriptType.values().length - 1);
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
Set<ScriptType> randomScriptTypesSet = Sets.newHashSet();
|
||||||
assertScriptModesAllOps(ScriptMode.ON, ALL_LANGS, ScriptType.FILE, ScriptType.INLINE);
|
ScriptMode[] randomScriptModes = new ScriptMode[randomInt];
|
||||||
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.INDEXED);
|
for (int i = 0; i < randomInt; i++) {
|
||||||
|
boolean added = false;
|
||||||
|
while (added == false) {
|
||||||
|
added = randomScriptTypesSet.add(randomFrom(ScriptType.values()));
|
||||||
|
}
|
||||||
|
randomScriptModes[i] = randomFrom(ScriptMode.values());
|
||||||
|
}
|
||||||
|
ScriptType[] randomScriptTypes = randomScriptTypesSet.toArray(new ScriptType[randomScriptTypesSet.size()]);
|
||||||
|
ImmutableSettings.Builder builder = ImmutableSettings.builder();
|
||||||
|
for (int i = 0; i < randomInt; i++) {
|
||||||
|
builder.put(ScriptModes.SCRIPT_SETTINGS_PREFIX + randomScriptTypes[i], randomScriptModes[i]);
|
||||||
|
}
|
||||||
|
this.scriptModes = new ScriptModes(scriptEngines, scriptContextRegistry, builder.build());
|
||||||
|
|
||||||
|
for (int i = 0; i < randomInt; i++) {
|
||||||
|
assertScriptModesAllOps(randomScriptModes[i], ALL_LANGS, randomScriptTypes[i]);
|
||||||
|
}
|
||||||
|
if (randomScriptTypesSet.contains(ScriptType.FILE) == false) {
|
||||||
|
assertScriptModesAllOps(ScriptMode.ON, ALL_LANGS, ScriptType.FILE);
|
||||||
|
}
|
||||||
|
if (randomScriptTypesSet.contains(ScriptType.INDEXED) == false) {
|
||||||
|
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.INDEXED);
|
||||||
|
}
|
||||||
|
if (randomScriptTypesSet.contains(ScriptType.INLINE) == false) {
|
||||||
|
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.INLINE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDisableInlineGenericSettings() {
|
public void testScriptContextGenericSettings() {
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.inline", randomFrom(DISABLE_VALUES));
|
int randomInt = randomIntBetween(1, scriptContexts.length - 1);
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
Set<ScriptContext> randomScriptContextsSet = Sets.newHashSet();
|
||||||
assertScriptModesAllOps(ScriptMode.ON, ALL_LANGS, ScriptType.FILE);
|
ScriptMode[] randomScriptModes = new ScriptMode[randomInt];
|
||||||
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.INDEXED);
|
for (int i = 0; i < randomInt; i++) {
|
||||||
assertScriptModesAllOps(ScriptMode.OFF, ALL_LANGS, ScriptType.INLINE);
|
boolean added = false;
|
||||||
}
|
while (added == false) {
|
||||||
|
added = randomScriptContextsSet.add(randomFrom(scriptContexts));
|
||||||
|
}
|
||||||
|
randomScriptModes[i] = randomFrom(ScriptMode.values());
|
||||||
|
}
|
||||||
|
ScriptContext[] randomScriptContexts = randomScriptContextsSet.toArray(new ScriptContext[randomScriptContextsSet.size()]);
|
||||||
|
ImmutableSettings.Builder builder = ImmutableSettings.builder();
|
||||||
|
for (int i = 0; i < randomInt; i++) {
|
||||||
|
builder.put(ScriptModes.SCRIPT_SETTINGS_PREFIX + randomScriptContexts[i].getKey(), randomScriptModes[i]);
|
||||||
|
}
|
||||||
|
this.scriptModes = new ScriptModes(scriptEngines, scriptContextRegistry, builder.build());
|
||||||
|
|
||||||
@Test
|
for (int i = 0; i < randomInt; i++) {
|
||||||
public void testSandboxInlineGenericSettings() {
|
assertScriptModesAllTypes(randomScriptModes[i], ALL_LANGS, randomScriptContexts[i]);
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.inline", randomFrom(ScriptMode.SANDBOX));
|
}
|
||||||
//nothing changes if setting set is same as default
|
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
|
||||||
assertScriptModesAllOps(ScriptMode.ON, ALL_LANGS, ScriptType.FILE);
|
|
||||||
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.INDEXED, ScriptType.INLINE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
ScriptContext[] complementOf = complementOf(randomScriptContexts);
|
||||||
public void testEnableIndexedGenericSettings() {
|
assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.FILE}, complementOf);
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.indexed", randomFrom(ENABLE_VALUES));
|
assertScriptModes(ScriptMode.SANDBOX, ALL_LANGS, new ScriptType[]{ScriptType.INDEXED, ScriptType.INLINE}, complementOf);
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
|
||||||
assertScriptModesAllOps(ScriptMode.ON, ALL_LANGS, ScriptType.FILE, ScriptType.INDEXED);
|
|
||||||
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.INLINE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDisableIndexedGenericSettings() {
|
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.indexed", randomFrom(DISABLE_VALUES));
|
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
|
||||||
assertScriptModesAllOps(ScriptMode.ON, ALL_LANGS, ScriptType.FILE);
|
|
||||||
assertScriptModesAllOps(ScriptMode.OFF, ALL_LANGS, ScriptType.INDEXED);
|
|
||||||
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.INLINE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSandboxIndexedGenericSettings() {
|
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.indexed", ScriptMode.SANDBOX);
|
|
||||||
//nothing changes if setting set is same as default
|
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
|
||||||
assertScriptModesAllOps(ScriptMode.ON, ALL_LANGS, ScriptType.FILE);
|
|
||||||
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.INDEXED, ScriptType.INLINE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testEnableFileGenericSettings() {
|
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.file", randomFrom(ENABLE_VALUES));
|
|
||||||
//nothing changes if setting set is same as default
|
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
|
||||||
assertScriptModesAllOps(ScriptMode.ON, ALL_LANGS, ScriptType.FILE);
|
|
||||||
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.INDEXED, ScriptType.INLINE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDisableFileGenericSettings() {
|
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.file", randomFrom(DISABLE_VALUES));
|
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
|
||||||
assertScriptModesAllOps(ScriptMode.OFF, ALL_LANGS, ScriptType.FILE);
|
|
||||||
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.INDEXED, ScriptType.INLINE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSandboxFileGenericSettings() {
|
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.file", ScriptMode.SANDBOX);
|
|
||||||
//nothing changes if setting set is same as default
|
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
|
||||||
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.FILE, ScriptType.INDEXED, ScriptType.INLINE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMultipleScriptTypeGenericSettings() {
|
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.file", ScriptMode.SANDBOX).put("script.inline", randomFrom(DISABLE_VALUES));
|
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
|
||||||
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.FILE);
|
|
||||||
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.INDEXED);
|
|
||||||
assertScriptModesAllOps(ScriptMode.OFF, ALL_LANGS, ScriptType.INLINE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testEnableMappingGenericSettings() {
|
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.mapping", randomFrom(ENABLE_VALUES));
|
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
|
||||||
assertScriptModesAllTypes(ScriptMode.ON, ALL_LANGS, ScriptContext.MAPPING);
|
|
||||||
assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.FILE}, ScriptContext.AGGS, ScriptContext.SEARCH, ScriptContext.UPDATE);
|
|
||||||
assertScriptModes(ScriptMode.SANDBOX, ALL_LANGS, new ScriptType[]{ScriptType.INDEXED, ScriptType.INLINE}, ScriptContext.AGGS, ScriptContext.SEARCH, ScriptContext.UPDATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDisableMappingGenericSettings() {
|
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.mapping", randomFrom(DISABLE_VALUES));
|
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
|
||||||
assertScriptModesAllTypes(ScriptMode.OFF, ALL_LANGS, ScriptContext.MAPPING);
|
|
||||||
assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.FILE}, ScriptContext.AGGS, ScriptContext.SEARCH, ScriptContext.UPDATE);
|
|
||||||
assertScriptModes(ScriptMode.SANDBOX, ALL_LANGS, new ScriptType[]{ScriptType.INDEXED, ScriptType.INLINE}, ScriptContext.AGGS, ScriptContext.SEARCH, ScriptContext.UPDATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSandboxMappingGenericSettings() {
|
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.mapping", ScriptMode.SANDBOX);
|
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
|
||||||
assertScriptModesAllTypes(ScriptMode.SANDBOX, ALL_LANGS, ScriptContext.MAPPING);
|
|
||||||
assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.FILE}, ScriptContext.AGGS, ScriptContext.SEARCH, ScriptContext.UPDATE);
|
|
||||||
assertScriptModes(ScriptMode.SANDBOX, ALL_LANGS, new ScriptType[]{ScriptType.INDEXED, ScriptType.INLINE}, ScriptContext.AGGS, ScriptContext.SEARCH, ScriptContext.UPDATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testEnableSearchGenericSettings() {
|
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.search", randomFrom(ENABLE_VALUES));
|
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
|
||||||
assertScriptModesAllTypes(ScriptMode.ON, ALL_LANGS, ScriptContext.SEARCH);
|
|
||||||
assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.FILE}, ScriptContext.AGGS, ScriptContext.MAPPING, ScriptContext.UPDATE);
|
|
||||||
assertScriptModes(ScriptMode.SANDBOX, ALL_LANGS, new ScriptType[]{ScriptType.INDEXED, ScriptType.INLINE}, ScriptContext.AGGS, ScriptContext.MAPPING, ScriptContext.UPDATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDisableSearchGenericSettings() {
|
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.search", randomFrom(DISABLE_VALUES));
|
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
|
||||||
assertScriptModesAllTypes(ScriptMode.OFF, ALL_LANGS, ScriptContext.SEARCH);
|
|
||||||
assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.FILE}, ScriptContext.AGGS, ScriptContext.MAPPING, ScriptContext.UPDATE);
|
|
||||||
assertScriptModes(ScriptMode.SANDBOX, ALL_LANGS, new ScriptType[]{ScriptType.INDEXED, ScriptType.INLINE}, ScriptContext.AGGS, ScriptContext.MAPPING, ScriptContext.UPDATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSandboxSearchGenericSettings() {
|
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.search", ScriptMode.SANDBOX);
|
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
|
||||||
assertScriptModesAllTypes(ScriptMode.SANDBOX, ALL_LANGS, ScriptContext.SEARCH);
|
|
||||||
assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.FILE}, ScriptContext.AGGS, ScriptContext.MAPPING, ScriptContext.UPDATE);
|
|
||||||
assertScriptModes(ScriptMode.SANDBOX, ALL_LANGS, new ScriptType[]{ScriptType.INDEXED, ScriptType.INLINE}, ScriptContext.AGGS, ScriptContext.MAPPING, ScriptContext.UPDATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testEnableAggsGenericSettings() {
|
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.aggs", randomFrom(ENABLE_VALUES));
|
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
|
||||||
assertScriptModesAllTypes(ScriptMode.ON, ALL_LANGS, ScriptContext.AGGS);
|
|
||||||
assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.FILE}, ScriptContext.SEARCH, ScriptContext.MAPPING, ScriptContext.UPDATE);
|
|
||||||
assertScriptModes(ScriptMode.SANDBOX, ALL_LANGS, new ScriptType[]{ScriptType.INDEXED, ScriptType.INLINE}, ScriptContext.SEARCH, ScriptContext.MAPPING, ScriptContext.UPDATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDisableAggsGenericSettings() {
|
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.aggs", randomFrom(DISABLE_VALUES));
|
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
|
||||||
assertScriptModesAllTypes(ScriptMode.OFF, ALL_LANGS, ScriptContext.AGGS);
|
|
||||||
assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.FILE}, ScriptContext.SEARCH, ScriptContext.MAPPING, ScriptContext.UPDATE);
|
|
||||||
assertScriptModes(ScriptMode.SANDBOX, ALL_LANGS, new ScriptType[]{ScriptType.INDEXED, ScriptType.INLINE}, ScriptContext.SEARCH, ScriptContext.MAPPING, ScriptContext.UPDATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSandboxAggsGenericSettings() {
|
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.aggs", ScriptMode.SANDBOX);
|
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
|
||||||
assertScriptModesAllTypes(ScriptMode.SANDBOX, ALL_LANGS, ScriptContext.AGGS);
|
|
||||||
assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.FILE}, ScriptContext.SEARCH, ScriptContext.MAPPING, ScriptContext.UPDATE);
|
|
||||||
assertScriptModes(ScriptMode.SANDBOX, ALL_LANGS, new ScriptType[]{ScriptType.INDEXED, ScriptType.INLINE}, ScriptContext.SEARCH, ScriptContext.MAPPING, ScriptContext.UPDATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testEnableUpdateGenericSettings() {
|
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.update", randomFrom(ENABLE_VALUES));
|
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
|
||||||
assertScriptModesAllTypes(ScriptMode.ON, ALL_LANGS, ScriptContext.UPDATE);
|
|
||||||
assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.FILE}, ScriptContext.SEARCH, ScriptContext.MAPPING, ScriptContext.AGGS);
|
|
||||||
assertScriptModes(ScriptMode.SANDBOX, ALL_LANGS, new ScriptType[]{ScriptType.INDEXED, ScriptType.INLINE}, ScriptContext.SEARCH, ScriptContext.MAPPING, ScriptContext.AGGS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDisableUpdateGenericSettings() {
|
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.update", randomFrom(DISABLE_VALUES));
|
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
|
||||||
assertScriptModesAllTypes(ScriptMode.OFF, ALL_LANGS, ScriptContext.UPDATE);
|
|
||||||
assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.FILE}, ScriptContext.SEARCH, ScriptContext.MAPPING, ScriptContext.AGGS);
|
|
||||||
assertScriptModes(ScriptMode.SANDBOX, ALL_LANGS, new ScriptType[]{ScriptType.INDEXED, ScriptType.INLINE}, ScriptContext.SEARCH, ScriptContext.MAPPING, ScriptContext.AGGS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSandboxUpdateGenericSettings() {
|
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.update", ScriptMode.SANDBOX);
|
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
|
||||||
assertScriptModesAllTypes(ScriptMode.SANDBOX, ALL_LANGS, ScriptContext.UPDATE);
|
|
||||||
assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.FILE}, ScriptContext.SEARCH, ScriptContext.MAPPING, ScriptContext.AGGS);
|
|
||||||
assertScriptModes(ScriptMode.SANDBOX, ALL_LANGS, new ScriptType[]{ScriptType.INDEXED, ScriptType.INLINE}, ScriptContext.SEARCH, ScriptContext.MAPPING, ScriptContext.AGGS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMultipleScriptContextGenericSettings() {
|
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.update", ScriptMode.SANDBOX)
|
|
||||||
.put("script.aggs", randomFrom(DISABLE_VALUES))
|
|
||||||
.put("script.search", randomFrom(ENABLE_VALUES));
|
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
|
||||||
assertScriptModesAllTypes(ScriptMode.SANDBOX, ALL_LANGS, ScriptContext.UPDATE);
|
|
||||||
assertScriptModesAllTypes(ScriptMode.OFF, ALL_LANGS, ScriptContext.AGGS);
|
|
||||||
assertScriptModesAllTypes(ScriptMode.ON, ALL_LANGS, ScriptContext.SEARCH);
|
|
||||||
assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.FILE}, ScriptContext.MAPPING);
|
|
||||||
assertScriptModes(ScriptMode.SANDBOX, ALL_LANGS, new ScriptType[]{ScriptType.INDEXED, ScriptType.INLINE}, ScriptContext.MAPPING);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConflictingScriptTypeAndOpGenericSettings() {
|
public void testConflictingScriptTypeAndOpGenericSettings() {
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.update", randomFrom(DISABLE_VALUES))
|
ScriptContext scriptContext = randomFrom(scriptContexts);
|
||||||
|
ImmutableSettings.Builder builder = ImmutableSettings.builder().put(ScriptModes.SCRIPT_SETTINGS_PREFIX + scriptContext.getKey(), randomFrom(DISABLE_VALUES))
|
||||||
.put("script.indexed", randomFrom(ENABLE_VALUES)).put("script.inline", ScriptMode.SANDBOX);
|
.put("script.indexed", randomFrom(ENABLE_VALUES)).put("script.inline", ScriptMode.SANDBOX);
|
||||||
//operations generic settings have precedence over script type generic settings
|
//operations generic settings have precedence over script type generic settings
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
this.scriptModes = new ScriptModes(scriptEngines, scriptContextRegistry, builder.build());
|
||||||
assertScriptModesAllTypes(ScriptMode.OFF, ALL_LANGS, ScriptContext.UPDATE);
|
assertScriptModesAllTypes(ScriptMode.OFF, ALL_LANGS, scriptContext);
|
||||||
assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.FILE, ScriptType.INDEXED}, ScriptContext.MAPPING, ScriptContext.AGGS, ScriptContext.SEARCH);
|
ScriptContext[] complementOf = complementOf(scriptContext);
|
||||||
assertScriptModes(ScriptMode.SANDBOX, ALL_LANGS, new ScriptType[]{ScriptType.INLINE}, ScriptContext.MAPPING, ScriptContext.AGGS, ScriptContext.SEARCH);
|
assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.FILE, ScriptType.INDEXED}, complementOf);
|
||||||
|
assertScriptModes(ScriptMode.SANDBOX, ALL_LANGS, new ScriptType[]{ScriptType.INLINE}, complementOf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEngineSpecificSettings() {
|
public void testEngineSpecificSettings() {
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder()
|
ImmutableSettings.Builder builder = ImmutableSettings.builder()
|
||||||
.put(specificEngineOpSettings(GroovyScriptEngineService.NAME, ScriptType.INLINE, ScriptContext.MAPPING), randomFrom(DISABLE_VALUES))
|
.put(specificEngineOpSettings(GroovyScriptEngineService.NAME, ScriptType.INLINE, ScriptContext.Standard.MAPPING), randomFrom(DISABLE_VALUES))
|
||||||
.put(specificEngineOpSettings(GroovyScriptEngineService.NAME, ScriptType.INLINE, ScriptContext.UPDATE), randomFrom(DISABLE_VALUES));
|
.put(specificEngineOpSettings(GroovyScriptEngineService.NAME, ScriptType.INLINE, ScriptContext.Standard.UPDATE), randomFrom(DISABLE_VALUES));
|
||||||
ImmutableSet<String> groovyLangSet = ImmutableSet.of(GroovyScriptEngineService.NAME);
|
ImmutableSet<String> groovyLangSet = ImmutableSet.of(GroovyScriptEngineService.NAME);
|
||||||
Set<String> allButGroovyLangSet = new HashSet<>(ALL_LANGS);
|
Set<String> allButGroovyLangSet = new HashSet<>(ALL_LANGS);
|
||||||
allButGroovyLangSet.remove(GroovyScriptEngineService.NAME);
|
allButGroovyLangSet.remove(GroovyScriptEngineService.NAME);
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
this.scriptModes = new ScriptModes(scriptEngines, scriptContextRegistry, builder.build());
|
||||||
assertScriptModes(ScriptMode.OFF, groovyLangSet, new ScriptType[]{ScriptType.INLINE}, ScriptContext.MAPPING, ScriptContext.UPDATE);
|
assertScriptModes(ScriptMode.OFF, groovyLangSet, new ScriptType[]{ScriptType.INLINE}, ScriptContext.Standard.MAPPING, ScriptContext.Standard.UPDATE);
|
||||||
assertScriptModes(ScriptMode.SANDBOX, groovyLangSet, new ScriptType[]{ScriptType.INLINE}, ScriptContext.SEARCH, ScriptContext.AGGS);
|
assertScriptModes(ScriptMode.SANDBOX, groovyLangSet, new ScriptType[]{ScriptType.INLINE}, complementOf(ScriptContext.Standard.MAPPING, ScriptContext.Standard.UPDATE));
|
||||||
assertScriptModesAllOps(ScriptMode.SANDBOX, allButGroovyLangSet, ScriptType.INLINE);
|
assertScriptModesAllOps(ScriptMode.SANDBOX, allButGroovyLangSet, ScriptType.INLINE);
|
||||||
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.INDEXED);
|
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.INDEXED);
|
||||||
assertScriptModesAllOps(ScriptMode.ON, ALL_LANGS, ScriptType.FILE);
|
assertScriptModesAllOps(ScriptMode.ON, ALL_LANGS, ScriptType.FILE);
|
||||||
@ -340,88 +206,21 @@ public class ScriptModesTests extends ElasticsearchTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testInteractionBetweenGenericAndEngineSpecificSettings() {
|
public void testInteractionBetweenGenericAndEngineSpecificSettings() {
|
||||||
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.inline", randomFrom(DISABLE_VALUES))
|
ImmutableSettings.Builder builder = ImmutableSettings.builder().put("script.inline", randomFrom(DISABLE_VALUES))
|
||||||
.put(specificEngineOpSettings(MustacheScriptEngineService.NAME, ScriptType.INLINE, ScriptContext.AGGS), randomFrom(ENABLE_VALUES))
|
.put(specificEngineOpSettings(MustacheScriptEngineService.NAME, ScriptType.INLINE, ScriptContext.Standard.AGGS), randomFrom(ENABLE_VALUES))
|
||||||
.put(specificEngineOpSettings(MustacheScriptEngineService.NAME, ScriptType.INLINE, ScriptContext.SEARCH), randomFrom(ENABLE_VALUES));
|
.put(specificEngineOpSettings(MustacheScriptEngineService.NAME, ScriptType.INLINE, ScriptContext.Standard.SEARCH), randomFrom(ENABLE_VALUES));
|
||||||
ImmutableSet<String> mustacheLangSet = ImmutableSet.of(MustacheScriptEngineService.NAME);
|
ImmutableSet<String> mustacheLangSet = ImmutableSet.of(MustacheScriptEngineService.NAME);
|
||||||
Set<String> allButMustacheLangSet = new HashSet<>(ALL_LANGS);
|
Set<String> allButMustacheLangSet = new HashSet<>(ALL_LANGS);
|
||||||
allButMustacheLangSet.remove(MustacheScriptEngineService.NAME);
|
allButMustacheLangSet.remove(MustacheScriptEngineService.NAME);
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, builder.build());
|
this.scriptModes = new ScriptModes(scriptEngines, scriptContextRegistry, builder.build());
|
||||||
assertScriptModes(ScriptMode.ON, mustacheLangSet, new ScriptType[]{ScriptType.INLINE}, ScriptContext.AGGS, ScriptContext.SEARCH);
|
assertScriptModes(ScriptMode.ON, mustacheLangSet, new ScriptType[]{ScriptType.INLINE}, ScriptContext.Standard.AGGS, ScriptContext.Standard.SEARCH);
|
||||||
assertScriptModes(ScriptMode.OFF, mustacheLangSet, new ScriptType[]{ScriptType.INLINE}, ScriptContext.MAPPING, ScriptContext.UPDATE);
|
assertScriptModes(ScriptMode.OFF, mustacheLangSet, new ScriptType[]{ScriptType.INLINE}, complementOf(ScriptContext.Standard.AGGS, ScriptContext.Standard.SEARCH));
|
||||||
assertScriptModesAllOps(ScriptMode.OFF, allButMustacheLangSet, ScriptType.INLINE);
|
assertScriptModesAllOps(ScriptMode.OFF, allButMustacheLangSet, ScriptType.INLINE);
|
||||||
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.INDEXED);
|
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.INDEXED);
|
||||||
assertScriptModesAllOps(ScriptMode.ON, ALL_LANGS, ScriptType.FILE);
|
assertScriptModesAllOps(ScriptMode.ON, ALL_LANGS, ScriptType.FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDefaultSettingsToString() {
|
|
||||||
assertAllSettingsWereChecked = false;
|
|
||||||
this.scriptModes = new ScriptModes(scriptEngines, ImmutableSettings.EMPTY);
|
|
||||||
assertThat(scriptModes.toString(), equalTo(
|
|
||||||
"script.engine.custom.file.aggs: on\n" +
|
|
||||||
"script.engine.custom.file.mapping: on\n" +
|
|
||||||
"script.engine.custom.file.search: on\n" +
|
|
||||||
"script.engine.custom.file.update: on\n" +
|
|
||||||
"script.engine.custom.indexed.aggs: sandbox\n" +
|
|
||||||
"script.engine.custom.indexed.mapping: sandbox\n" +
|
|
||||||
"script.engine.custom.indexed.search: sandbox\n" +
|
|
||||||
"script.engine.custom.indexed.update: sandbox\n" +
|
|
||||||
"script.engine.custom.inline.aggs: sandbox\n" +
|
|
||||||
"script.engine.custom.inline.mapping: sandbox\n" +
|
|
||||||
"script.engine.custom.inline.search: sandbox\n" +
|
|
||||||
"script.engine.custom.inline.update: sandbox\n" +
|
|
||||||
"script.engine.expression.file.aggs: on\n" +
|
|
||||||
"script.engine.expression.file.mapping: on\n" +
|
|
||||||
"script.engine.expression.file.search: on\n" +
|
|
||||||
"script.engine.expression.file.update: on\n" +
|
|
||||||
"script.engine.expression.indexed.aggs: sandbox\n" +
|
|
||||||
"script.engine.expression.indexed.mapping: sandbox\n" +
|
|
||||||
"script.engine.expression.indexed.search: sandbox\n" +
|
|
||||||
"script.engine.expression.indexed.update: sandbox\n" +
|
|
||||||
"script.engine.expression.inline.aggs: sandbox\n" +
|
|
||||||
"script.engine.expression.inline.mapping: sandbox\n" +
|
|
||||||
"script.engine.expression.inline.search: sandbox\n" +
|
|
||||||
"script.engine.expression.inline.update: sandbox\n" +
|
|
||||||
"script.engine.groovy.file.aggs: on\n" +
|
|
||||||
"script.engine.groovy.file.mapping: on\n" +
|
|
||||||
"script.engine.groovy.file.search: on\n" +
|
|
||||||
"script.engine.groovy.file.update: on\n" +
|
|
||||||
"script.engine.groovy.indexed.aggs: sandbox\n" +
|
|
||||||
"script.engine.groovy.indexed.mapping: sandbox\n" +
|
|
||||||
"script.engine.groovy.indexed.search: sandbox\n" +
|
|
||||||
"script.engine.groovy.indexed.update: sandbox\n" +
|
|
||||||
"script.engine.groovy.inline.aggs: sandbox\n" +
|
|
||||||
"script.engine.groovy.inline.mapping: sandbox\n" +
|
|
||||||
"script.engine.groovy.inline.search: sandbox\n" +
|
|
||||||
"script.engine.groovy.inline.update: sandbox\n" +
|
|
||||||
"script.engine.mustache.file.aggs: on\n" +
|
|
||||||
"script.engine.mustache.file.mapping: on\n" +
|
|
||||||
"script.engine.mustache.file.search: on\n" +
|
|
||||||
"script.engine.mustache.file.update: on\n" +
|
|
||||||
"script.engine.mustache.indexed.aggs: sandbox\n" +
|
|
||||||
"script.engine.mustache.indexed.mapping: sandbox\n" +
|
|
||||||
"script.engine.mustache.indexed.search: sandbox\n" +
|
|
||||||
"script.engine.mustache.indexed.update: sandbox\n" +
|
|
||||||
"script.engine.mustache.inline.aggs: sandbox\n" +
|
|
||||||
"script.engine.mustache.inline.mapping: sandbox\n" +
|
|
||||||
"script.engine.mustache.inline.search: sandbox\n" +
|
|
||||||
"script.engine.mustache.inline.update: sandbox\n" +
|
|
||||||
"script.engine.test.file.aggs: on\n" +
|
|
||||||
"script.engine.test.file.mapping: on\n" +
|
|
||||||
"script.engine.test.file.search: on\n" +
|
|
||||||
"script.engine.test.file.update: on\n" +
|
|
||||||
"script.engine.test.indexed.aggs: sandbox\n" +
|
|
||||||
"script.engine.test.indexed.mapping: sandbox\n" +
|
|
||||||
"script.engine.test.indexed.search: sandbox\n" +
|
|
||||||
"script.engine.test.indexed.update: sandbox\n" +
|
|
||||||
"script.engine.test.inline.aggs: sandbox\n" +
|
|
||||||
"script.engine.test.inline.mapping: sandbox\n" +
|
|
||||||
"script.engine.test.inline.search: sandbox\n" +
|
|
||||||
"script.engine.test.inline.update: sandbox\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertScriptModesAllOps(ScriptMode expectedScriptMode, Set<String> langs, ScriptType... scriptTypes) {
|
private void assertScriptModesAllOps(ScriptMode expectedScriptMode, Set<String> langs, ScriptType... scriptTypes) {
|
||||||
assertScriptModes(expectedScriptMode, langs, scriptTypes, ScriptContext.values());
|
assertScriptModes(expectedScriptMode, langs, scriptTypes, scriptContexts);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertScriptModesAllTypes(ScriptMode expectedScriptMode, Set<String> langs, ScriptContext... scriptContexts) {
|
private void assertScriptModesAllTypes(ScriptMode expectedScriptMode, Set<String> langs, ScriptContext... scriptContexts) {
|
||||||
@ -435,15 +234,26 @@ public class ScriptModesTests extends ElasticsearchTestCase {
|
|||||||
for (String lang : langs) {
|
for (String lang : langs) {
|
||||||
for (ScriptType scriptType : scriptTypes) {
|
for (ScriptType scriptType : scriptTypes) {
|
||||||
for (ScriptContext scriptContext : scriptContexts) {
|
for (ScriptContext scriptContext : scriptContexts) {
|
||||||
assertThat(lang + "." + scriptType + "." + scriptContext + " doesn't have the expected value", scriptModes.getScriptMode(lang, scriptType, scriptContext), equalTo(expectedScriptMode));
|
assertThat(lang + "." + scriptType + "." + scriptContext.getKey() + " doesn't have the expected value", scriptModes.getScriptMode(lang, scriptType, scriptContext), equalTo(expectedScriptMode));
|
||||||
checkedSettings.add(lang + "." + scriptType + "." + scriptContext);
|
checkedSettings.add(lang + "." + scriptType + "." + scriptContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ScriptContext[] complementOf(ScriptContext... scriptContexts) {
|
||||||
|
Map<String, ScriptContext> copy = Maps.newHashMap();
|
||||||
|
for (ScriptContext scriptContext : scriptContextRegistry.scriptContexts()) {
|
||||||
|
copy.put(scriptContext.getKey(), scriptContext);
|
||||||
|
}
|
||||||
|
for (ScriptContext scriptContext : scriptContexts) {
|
||||||
|
copy.remove(scriptContext.getKey());
|
||||||
|
}
|
||||||
|
return copy.values().toArray(new ScriptContext[copy.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
private static String specificEngineOpSettings(String lang, ScriptType scriptType, ScriptContext scriptContext) {
|
private static String specificEngineOpSettings(String lang, ScriptType scriptType, ScriptContext scriptContext) {
|
||||||
return ScriptModes.ENGINE_SETTINGS_PREFIX + "." + lang + "." + scriptType + "." + scriptContext;
|
return ScriptModes.ENGINE_SETTINGS_PREFIX + "." + lang + "." + scriptType + "." + scriptContext.getKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
static ImmutableMap<String, ScriptEngineService> buildScriptEnginesByLangMap(Set<ScriptEngineService> scriptEngines) {
|
static ImmutableMap<String, ScriptEngineService> buildScriptEnginesByLangMap(Set<ScriptEngineService> scriptEngines) {
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
package org.elasticsearch.script;
|
package org.elasticsearch.script;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.io.Streams;
|
import org.elasticsearch.common.io.Streams;
|
||||||
@ -44,16 +45,16 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
|
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
|
||||||
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class ScriptServiceTests extends ElasticsearchTestCase {
|
public class ScriptServiceTests extends ElasticsearchTestCase {
|
||||||
|
|
||||||
private ResourceWatcherService resourceWatcherService;
|
private ResourceWatcherService resourceWatcherService;
|
||||||
private Set<ScriptEngineService> scriptEngineServices;
|
private Set<ScriptEngineService> scriptEngineServices;
|
||||||
private Map<String, ScriptEngineService> scriptEnginesByLangMap;
|
private Map<String, ScriptEngineService> scriptEnginesByLangMap;
|
||||||
|
private ScriptContextRegistry scriptContextRegistry;
|
||||||
|
private ScriptContext[] scriptContexts;
|
||||||
private ScriptService scriptService;
|
private ScriptService scriptService;
|
||||||
private Path scriptsFilePath;
|
private Path scriptsFilePath;
|
||||||
private Settings baseSettings;
|
private Settings baseSettings;
|
||||||
@ -76,6 +77,24 @@ public class ScriptServiceTests extends ElasticsearchTestCase {
|
|||||||
scriptEngineServices = ImmutableSet.of(new TestEngineService(), new GroovyScriptEngineService(baseSettings),
|
scriptEngineServices = ImmutableSet.of(new TestEngineService(), new GroovyScriptEngineService(baseSettings),
|
||||||
new ExpressionScriptEngineService(baseSettings), new MustacheScriptEngineService(baseSettings));
|
new ExpressionScriptEngineService(baseSettings), new MustacheScriptEngineService(baseSettings));
|
||||||
scriptEnginesByLangMap = ScriptModesTests.buildScriptEnginesByLangMap(scriptEngineServices);
|
scriptEnginesByLangMap = ScriptModesTests.buildScriptEnginesByLangMap(scriptEngineServices);
|
||||||
|
//randomly register custom script contexts
|
||||||
|
int randomInt = randomIntBetween(0, 3);
|
||||||
|
//prevent duplicates using map
|
||||||
|
Map<String, ScriptContext.Plugin> contexts = Maps.newHashMap();
|
||||||
|
for (int i = 0; i < randomInt; i++) {
|
||||||
|
String plugin;
|
||||||
|
do {
|
||||||
|
plugin = randomAsciiOfLength(randomIntBetween(1, 10));
|
||||||
|
} while (ScriptContextRegistry.RESERVED_SCRIPT_CONTEXTS.contains(plugin));
|
||||||
|
String operation;
|
||||||
|
do {
|
||||||
|
operation = randomAsciiOfLength(randomIntBetween(1, 30));
|
||||||
|
} while (ScriptContextRegistry.RESERVED_SCRIPT_CONTEXTS.contains(operation));
|
||||||
|
String context = plugin + "_" + operation;
|
||||||
|
contexts.put(context, new ScriptContext.Plugin(plugin, operation));
|
||||||
|
}
|
||||||
|
scriptContextRegistry = new ScriptContextRegistry(contexts.values());
|
||||||
|
scriptContexts = scriptContextRegistry.scriptContexts().toArray(new ScriptContext[scriptContextRegistry.scriptContexts().size()]);
|
||||||
logger.info("--> setup script service");
|
logger.info("--> setup script service");
|
||||||
scriptsFilePath = genericConfigFolder.resolve("scripts");
|
scriptsFilePath = genericConfigFolder.resolve("scripts");
|
||||||
Files.createDirectories(scriptsFilePath);
|
Files.createDirectories(scriptsFilePath);
|
||||||
@ -84,7 +103,7 @@ public class ScriptServiceTests extends ElasticsearchTestCase {
|
|||||||
private void buildScriptService(Settings additionalSettings) throws IOException {
|
private void buildScriptService(Settings additionalSettings) throws IOException {
|
||||||
Settings finalSettings = ImmutableSettings.builder().put(baseSettings).put(additionalSettings).build();
|
Settings finalSettings = ImmutableSettings.builder().put(baseSettings).put(additionalSettings).build();
|
||||||
Environment environment = new Environment(finalSettings);
|
Environment environment = new Environment(finalSettings);
|
||||||
scriptService = new ScriptService(finalSettings, environment, scriptEngineServices, resourceWatcherService, new NodeSettingsService(finalSettings)) {
|
scriptService = new ScriptService(finalSettings, environment, scriptEngineServices, resourceWatcherService, new NodeSettingsService(finalSettings), scriptContextRegistry) {
|
||||||
@Override
|
@Override
|
||||||
String getScriptFromIndex(String scriptLang, String id) {
|
String getScriptFromIndex(String scriptLang, String id) {
|
||||||
//mock the script that gets retrieved from an index
|
//mock the script that gets retrieved from an index
|
||||||
@ -114,7 +133,7 @@ public class ScriptServiceTests extends ElasticsearchTestCase {
|
|||||||
resourceWatcherService.notifyNow();
|
resourceWatcherService.notifyNow();
|
||||||
|
|
||||||
logger.info("--> verify that file with extension was correctly processed");
|
logger.info("--> verify that file with extension was correctly processed");
|
||||||
CompiledScript compiledScript = scriptService.compile("test", "test_script", ScriptType.FILE, ScriptContext.SEARCH);
|
CompiledScript compiledScript = scriptService.compile("test", "test_script", ScriptType.FILE, ScriptContext.Standard.SEARCH);
|
||||||
assertThat(compiledScript.compiled(), equalTo((Object) "compiled_test_file"));
|
assertThat(compiledScript.compiled(), equalTo((Object) "compiled_test_file"));
|
||||||
|
|
||||||
logger.info("--> delete both files");
|
logger.info("--> delete both files");
|
||||||
@ -124,7 +143,7 @@ public class ScriptServiceTests extends ElasticsearchTestCase {
|
|||||||
|
|
||||||
logger.info("--> verify that file with extension was correctly removed");
|
logger.info("--> verify that file with extension was correctly removed");
|
||||||
try {
|
try {
|
||||||
scriptService.compile("test", "test_script", ScriptType.FILE, ScriptContext.SEARCH);
|
scriptService.compile("test", "test_script", ScriptType.FILE, ScriptContext.Standard.SEARCH);
|
||||||
fail("the script test_script should no longer exist");
|
fail("the script test_script should no longer exist");
|
||||||
} catch (ElasticsearchIllegalArgumentException ex) {
|
} catch (ElasticsearchIllegalArgumentException ex) {
|
||||||
assertThat(ex.getMessage(), containsString("Unable to find on disk script test_script"));
|
assertThat(ex.getMessage(), containsString("Unable to find on disk script test_script"));
|
||||||
@ -135,17 +154,17 @@ public class ScriptServiceTests extends ElasticsearchTestCase {
|
|||||||
public void testScriptsSameNameDifferentLanguage() throws IOException {
|
public void testScriptsSameNameDifferentLanguage() throws IOException {
|
||||||
buildScriptService(ImmutableSettings.EMPTY);
|
buildScriptService(ImmutableSettings.EMPTY);
|
||||||
createFileScripts("groovy", "expression");
|
createFileScripts("groovy", "expression");
|
||||||
CompiledScript groovyScript = scriptService.compile(GroovyScriptEngineService.NAME, "file_script", ScriptType.FILE, randomFrom(ScriptContext.values()));
|
CompiledScript groovyScript = scriptService.compile(GroovyScriptEngineService.NAME, "file_script", ScriptType.FILE, randomFrom(scriptContexts));
|
||||||
assertThat(groovyScript.lang(), equalTo(GroovyScriptEngineService.NAME));
|
assertThat(groovyScript.lang(), equalTo(GroovyScriptEngineService.NAME));
|
||||||
CompiledScript expressionScript = scriptService.compile(ExpressionScriptEngineService.NAME, "file_script", ScriptType.FILE, randomFrom(ScriptContext.values()));
|
CompiledScript expressionScript = scriptService.compile(ExpressionScriptEngineService.NAME, "file_script", ScriptType.FILE, randomFrom(scriptContexts));
|
||||||
assertThat(expressionScript.lang(), equalTo(ExpressionScriptEngineService.NAME));
|
assertThat(expressionScript.lang(), equalTo(ExpressionScriptEngineService.NAME));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInlineScriptCompiledOnceMultipleLangAcronyms() throws IOException {
|
public void testInlineScriptCompiledOnceMultipleLangAcronyms() throws IOException {
|
||||||
buildScriptService(ImmutableSettings.EMPTY);
|
buildScriptService(ImmutableSettings.EMPTY);
|
||||||
CompiledScript compiledScript1 = scriptService.compile("test", "script", ScriptType.INLINE, randomFrom(ScriptContext.values()));
|
CompiledScript compiledScript1 = scriptService.compile("test", "script", ScriptType.INLINE, randomFrom(scriptContexts));
|
||||||
CompiledScript compiledScript2 = scriptService.compile("test2", "script", ScriptType.INLINE, randomFrom(ScriptContext.values()));
|
CompiledScript compiledScript2 = scriptService.compile("test2", "script", ScriptType.INLINE, randomFrom(scriptContexts));
|
||||||
assertThat(compiledScript1, sameInstance(compiledScript2));
|
assertThat(compiledScript1, sameInstance(compiledScript2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,8 +172,8 @@ public class ScriptServiceTests extends ElasticsearchTestCase {
|
|||||||
public void testFileScriptCompiledOnceMultipleLangAcronyms() throws IOException {
|
public void testFileScriptCompiledOnceMultipleLangAcronyms() throws IOException {
|
||||||
buildScriptService(ImmutableSettings.EMPTY);
|
buildScriptService(ImmutableSettings.EMPTY);
|
||||||
createFileScripts("test");
|
createFileScripts("test");
|
||||||
CompiledScript compiledScript1 = scriptService.compile("test", "file_script", ScriptType.FILE, randomFrom(ScriptContext.values()));
|
CompiledScript compiledScript1 = scriptService.compile("test", "file_script", ScriptType.FILE, randomFrom(scriptContexts));
|
||||||
CompiledScript compiledScript2 = scriptService.compile("test2", "file_script", ScriptType.FILE, randomFrom(ScriptContext.values()));
|
CompiledScript compiledScript2 = scriptService.compile("test2", "file_script", ScriptType.FILE, randomFrom(scriptContexts));
|
||||||
assertThat(compiledScript1, sameInstance(compiledScript2));
|
assertThat(compiledScript1, sameInstance(compiledScript2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,7 +193,7 @@ public class ScriptServiceTests extends ElasticsearchTestCase {
|
|||||||
buildScriptService(builder.build());
|
buildScriptService(builder.build());
|
||||||
createFileScripts("groovy", "expression", "mustache", "test");
|
createFileScripts("groovy", "expression", "mustache", "test");
|
||||||
|
|
||||||
for (ScriptContext scriptContext : ScriptContext.values()) {
|
for (ScriptContext scriptContext : scriptContexts) {
|
||||||
//groovy is not sandboxed, only file scripts are enabled by default
|
//groovy is not sandboxed, only file scripts are enabled by default
|
||||||
assertCompileRejected(GroovyScriptEngineService.NAME, "script", ScriptType.INLINE, scriptContext);
|
assertCompileRejected(GroovyScriptEngineService.NAME, "script", ScriptType.INLINE, scriptContext);
|
||||||
assertCompileRejected(GroovyScriptEngineService.NAME, "script", ScriptType.INDEXED, scriptContext);
|
assertCompileRejected(GroovyScriptEngineService.NAME, "script", ScriptType.INDEXED, scriptContext);
|
||||||
@ -206,12 +225,12 @@ public class ScriptServiceTests extends ElasticsearchTestCase {
|
|||||||
} while (scriptSourceSettings.containsKey(scriptType));
|
} while (scriptSourceSettings.containsKey(scriptType));
|
||||||
scriptSourceSettings.put(scriptType, randomFrom(ScriptMode.values()));
|
scriptSourceSettings.put(scriptType, randomFrom(ScriptMode.values()));
|
||||||
}
|
}
|
||||||
int numScriptContextSettings = randomIntBetween(0, ScriptContext.values().length);
|
int numScriptContextSettings = randomIntBetween(0, this.scriptContextRegistry.scriptContexts().size());
|
||||||
Map<ScriptContext, ScriptMode> scriptContextSettings = new HashMap<>();
|
Map<String, ScriptMode> scriptContextSettings = new HashMap<>();
|
||||||
for (int i = 0; i < numScriptContextSettings; i++) {
|
for (int i = 0; i < numScriptContextSettings; i++) {
|
||||||
ScriptContext scriptContext;
|
String scriptContext;
|
||||||
do {
|
do {
|
||||||
scriptContext = randomFrom(ScriptContext.values());
|
scriptContext = randomFrom(this.scriptContexts).getKey();
|
||||||
} while (scriptContextSettings.containsKey(scriptContext));
|
} while (scriptContextSettings.containsKey(scriptContext));
|
||||||
scriptContextSettings.put(scriptContext, randomFrom(ScriptMode.values()));
|
scriptContextSettings.put(scriptContext, randomFrom(ScriptMode.values()));
|
||||||
}
|
}
|
||||||
@ -223,9 +242,9 @@ public class ScriptServiceTests extends ElasticsearchTestCase {
|
|||||||
ScriptEngineService[] scriptEngineServices = this.scriptEngineServices.toArray(new ScriptEngineService[this.scriptEngineServices.size()]);
|
ScriptEngineService[] scriptEngineServices = this.scriptEngineServices.toArray(new ScriptEngineService[this.scriptEngineServices.size()]);
|
||||||
ScriptEngineService scriptEngineService = randomFrom(scriptEngineServices);
|
ScriptEngineService scriptEngineService = randomFrom(scriptEngineServices);
|
||||||
ScriptType scriptType = randomFrom(ScriptType.values());
|
ScriptType scriptType = randomFrom(ScriptType.values());
|
||||||
ScriptContext scriptContext = randomFrom(ScriptContext.values());
|
ScriptContext scriptContext = randomFrom(this.scriptContexts);
|
||||||
settingKey = scriptEngineService.types()[0] + "." + scriptType + "." + scriptContext;
|
settingKey = scriptEngineService.types()[0] + "." + scriptType + "." + scriptContext.getKey();
|
||||||
} while(engineSettings.containsKey(settingKey));
|
} while (engineSettings.containsKey(settingKey));
|
||||||
engineSettings.put(settingKey, randomFrom(ScriptMode.values()));
|
engineSettings.put(settingKey, randomFrom(ScriptMode.values()));
|
||||||
}
|
}
|
||||||
//set the selected fine-grained settings
|
//set the selected fine-grained settings
|
||||||
@ -243,7 +262,7 @@ public class ScriptServiceTests extends ElasticsearchTestCase {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Map.Entry<ScriptContext, ScriptMode> entry : scriptContextSettings.entrySet()) {
|
for (Map.Entry<String, ScriptMode> entry : scriptContextSettings.entrySet()) {
|
||||||
switch (entry.getValue()) {
|
switch (entry.getValue()) {
|
||||||
case ON:
|
case ON:
|
||||||
builder.put(ScriptModes.SCRIPT_SETTINGS_PREFIX + entry.getKey(), randomFrom(ScriptModesTests.ENABLE_VALUES));
|
builder.put(ScriptModes.SCRIPT_SETTINGS_PREFIX + entry.getKey(), randomFrom(ScriptModesTests.ENABLE_VALUES));
|
||||||
@ -283,11 +302,11 @@ public class ScriptServiceTests extends ElasticsearchTestCase {
|
|||||||
//make sure file scripts have a different name than inline ones.
|
//make sure file scripts have a different name than inline ones.
|
||||||
//Otherwise they are always considered file ones as they can be found in the static cache.
|
//Otherwise they are always considered file ones as they can be found in the static cache.
|
||||||
String script = scriptType == ScriptType.FILE ? "file_script" : "script";
|
String script = scriptType == ScriptType.FILE ? "file_script" : "script";
|
||||||
for (ScriptContext scriptContext : ScriptContext.values()) {
|
for (ScriptContext scriptContext : this.scriptContexts) {
|
||||||
//fallback mechanism: 1) engine specific settings 2) op based settings 3) source based settings
|
//fallback mechanism: 1) engine specific settings 2) op based settings 3) source based settings
|
||||||
ScriptMode scriptMode = engineSettings.get(scriptEngineService.types()[0] + "." + scriptType + "." + scriptContext);
|
ScriptMode scriptMode = engineSettings.get(scriptEngineService.types()[0] + "." + scriptType + "." + scriptContext.getKey());
|
||||||
if (scriptMode == null) {
|
if (scriptMode == null) {
|
||||||
scriptMode = scriptContextSettings.get(scriptContext);
|
scriptMode = scriptContextSettings.get(scriptContext.getKey());
|
||||||
}
|
}
|
||||||
if (scriptMode == null) {
|
if (scriptMode == null) {
|
||||||
scriptMode = scriptSourceSettings.get(scriptType);
|
scriptMode = scriptSourceSettings.get(scriptType);
|
||||||
@ -318,6 +337,28 @@ public class ScriptServiceTests extends ElasticsearchTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCompileNonRegisteredContext() throws IOException {
|
||||||
|
buildScriptService(ImmutableSettings.EMPTY);
|
||||||
|
String pluginName;
|
||||||
|
String unknownContext;
|
||||||
|
do {
|
||||||
|
pluginName = randomAsciiOfLength(randomIntBetween(1, 10));
|
||||||
|
unknownContext = randomAsciiOfLength(randomIntBetween(1, 30));
|
||||||
|
} while(scriptContextRegistry.isSupportedContext(new ScriptContext.Plugin(pluginName, unknownContext)));
|
||||||
|
|
||||||
|
for (ScriptEngineService scriptEngineService : scriptEngineServices) {
|
||||||
|
for (String type : scriptEngineService.types()) {
|
||||||
|
try {
|
||||||
|
scriptService.compile(type, "test", randomFrom(ScriptType.values()), new ScriptContext.Plugin(pluginName, unknownContext));
|
||||||
|
fail("script compilation should have been rejected");
|
||||||
|
} catch(ElasticsearchIllegalArgumentException e) {
|
||||||
|
assertThat(e.getMessage(), containsString("script context [" + pluginName + "_" + unknownContext + "] not supported"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void createFileScripts(String... langs) throws IOException {
|
private void createFileScripts(String... langs) throws IOException {
|
||||||
for (String lang : langs) {
|
for (String lang : langs) {
|
||||||
Path scriptPath = scriptsFilePath.resolve("file_script." + lang);
|
Path scriptPath = scriptsFilePath.resolve("file_script." + lang);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user