Scripting: cleanup ScriptService & friends in preparation for #6418
- Added NAME constants for each script language, avoiding to repeat the same strings all over the place. - Simplified `compile` method signatures by removing a couple of variants. Note that all of these signatures are going to change again with #6418 as in order to compile/execute a script the caller will need to specify which operation is attempting to execute the script, info that will be provided as an additional mandatory argument. - Removed double call to ScriptService#verifyDynamicScripting for every indexed or dynamic script. - Decreased ScriptService inner classes visibility to private (CacheKey, IndexedScript, ApplySettings) - Moved ScriptService inner classes to the bottom of the class, I think it makes it more readable. - Resolved some compiler warnings Closes #9992
This commit is contained in:
parent
2d2ba48c0b
commit
521ac7f35a
|
@ -69,7 +69,7 @@ public class ScriptFilterParser implements FilterParser {
|
|||
HashedBytesRef cacheKey = null;
|
||||
// also, when caching, since its isCacheable is false, will result in loading all bit set...
|
||||
String script = null;
|
||||
String scriptLang = null;
|
||||
String scriptLang;
|
||||
Map<String, Object> params = null;
|
||||
|
||||
String filterName = null;
|
||||
|
@ -130,12 +130,9 @@ public class ScriptFilterParser implements FilterParser {
|
|||
|
||||
private final SearchScript searchScript;
|
||||
|
||||
private final ScriptService.ScriptType scriptType;
|
||||
|
||||
public ScriptFilter(String scriptLang, String script, ScriptService.ScriptType scriptType, Map<String, Object> params, ScriptService scriptService, SearchLookup searchLookup) {
|
||||
this.script = script;
|
||||
this.params = params;
|
||||
this.scriptType = scriptType;
|
||||
this.searchScript = scriptService.search(searchLookup, scriptLang, script, scriptType, newHashMap(params));
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ package org.elasticsearch.index.query;
|
|||
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.search.aggregations.support.ValuesSource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
|
|
@ -19,17 +19,15 @@
|
|||
package org.elasticsearch.index.query;
|
||||
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.logging.ESLogger;
|
||||
import org.elasticsearch.common.logging.Loggers;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.script.ExecutableScript;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
@ -52,9 +50,9 @@ public class TemplateQueryParser implements QueryParser {
|
|||
|
||||
private final static Map<String,ScriptService.ScriptType> parametersToTypes = new HashMap<>();
|
||||
static {
|
||||
parametersToTypes.put("query",ScriptService.ScriptType.INLINE);
|
||||
parametersToTypes.put("file",ScriptService.ScriptType.FILE);
|
||||
parametersToTypes.put("id",ScriptService.ScriptType.INDEXED);
|
||||
parametersToTypes.put("query", ScriptService.ScriptType.INLINE);
|
||||
parametersToTypes.put("file", ScriptService.ScriptType.FILE);
|
||||
parametersToTypes.put("id", ScriptService.ScriptType.INDEXED);
|
||||
}
|
||||
|
||||
@Inject
|
||||
|
@ -78,15 +76,14 @@ public class TemplateQueryParser implements QueryParser {
|
|||
public Query parse(QueryParseContext parseContext) throws IOException {
|
||||
XContentParser parser = parseContext.parser();
|
||||
TemplateContext templateContext = parse(parser, PARAMS, parametersToTypes);
|
||||
ExecutableScript executable = this.scriptService.executable("mustache", templateContext.template(), templateContext.scriptType(), templateContext.params());
|
||||
ExecutableScript executable = this.scriptService.executable(MustacheScriptEngineService.NAME, templateContext.template(), templateContext.scriptType(), templateContext.params());
|
||||
|
||||
BytesReference querySource = (BytesReference) executable.run();
|
||||
|
||||
try (XContentParser qSourceParser = XContentFactory.xContent(querySource).createParser(querySource)) {
|
||||
final QueryParseContext context = new QueryParseContext(parseContext.index(), parseContext.indexQueryParserService());
|
||||
context.reset(qSourceParser);
|
||||
Query result = context.parseInnerQuery();
|
||||
return result;
|
||||
return context.parseInnerQuery();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,6 @@ public class ScriptScoreFunctionParser implements ScoreFunctionParser {
|
|||
public ScoreFunction parse(QueryParseContext parseContext, XContentParser parser) throws IOException, QueryParsingException {
|
||||
ScriptParameterParser scriptParameterParser = new ScriptParameterParser();
|
||||
String script = null;
|
||||
String scriptLang = null;
|
||||
Map<String, Object> vars = null;
|
||||
ScriptService.ScriptType scriptType = null;
|
||||
String currentFieldName = null;
|
||||
|
@ -82,15 +81,13 @@ public class ScriptScoreFunctionParser implements ScoreFunctionParser {
|
|||
script = scriptValue.script();
|
||||
scriptType = scriptValue.scriptType();
|
||||
}
|
||||
scriptLang = scriptParameterParser.lang();
|
||||
|
||||
if (script == null) {
|
||||
throw new QueryParsingException(parseContext.index(), NAMES[0] + " requires 'script' field");
|
||||
}
|
||||
|
||||
SearchScript searchScript;
|
||||
try {
|
||||
searchScript = parseContext.scriptService().search(parseContext.lookup(), scriptLang, script, scriptType, vars);
|
||||
searchScript = parseContext.scriptService().search(parseContext.lookup(), scriptParameterParser.lang(), script, scriptType, vars);
|
||||
return new ScriptScoreFunction(script, vars, searchScript);
|
||||
} catch (Exception e) {
|
||||
throw new QueryParsingException(parseContext.index(), NAMES[0] + " the script could not be loaded", e);
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.elasticsearch.common.settings.Settings;
|
|||
import org.elasticsearch.rest.RestController;
|
||||
import org.elasticsearch.rest.RestRequest;
|
||||
import org.elasticsearch.rest.action.script.RestDeleteIndexedScriptAction;
|
||||
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
|
||||
|
||||
import static org.elasticsearch.rest.RestRequest.Method.DELETE;
|
||||
|
||||
|
@ -37,6 +38,6 @@ public class RestDeleteSearchTemplateAction extends RestDeleteIndexedScriptActio
|
|||
|
||||
@Override
|
||||
protected String getScriptLang(RestRequest request) {
|
||||
return "mustache";
|
||||
return MustacheScriptEngineService.NAME;
|
||||
}
|
||||
}
|
|
@ -24,6 +24,7 @@ import org.elasticsearch.common.settings.Settings;
|
|||
import org.elasticsearch.rest.RestController;
|
||||
import org.elasticsearch.rest.RestRequest;
|
||||
import org.elasticsearch.rest.action.script.RestGetIndexedScriptAction;
|
||||
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
|
||||
|
||||
import static org.elasticsearch.rest.RestRequest.Method.GET;
|
||||
|
||||
|
@ -40,7 +41,7 @@ public class RestGetSearchTemplateAction extends RestGetIndexedScriptAction {
|
|||
|
||||
@Override
|
||||
protected String getScriptLang(RestRequest request) {
|
||||
return "mustache";
|
||||
return MustacheScriptEngineService.NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.elasticsearch.common.inject.Inject;
|
|||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.rest.*;
|
||||
import org.elasticsearch.rest.action.script.RestPutIndexedScriptAction;
|
||||
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
|
||||
|
||||
import static org.elasticsearch.rest.RestRequest.Method.POST;
|
||||
import static org.elasticsearch.rest.RestRequest.Method.PUT;
|
||||
|
@ -58,6 +59,6 @@ public class RestPutSearchTemplateAction extends RestPutIndexedScriptAction {
|
|||
|
||||
@Override
|
||||
protected String getScriptLang(RestRequest request) {
|
||||
return "mustache";
|
||||
return MustacheScriptEngineService.NAME;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ import java.util.Map;
|
|||
*/
|
||||
public class NativeScriptEngineService extends AbstractComponent implements ScriptEngineService {
|
||||
|
||||
public static final String NAME = "native";
|
||||
|
||||
private final ImmutableMap<String, NativeScriptFactory> scripts;
|
||||
|
||||
@Inject
|
||||
|
@ -44,7 +46,7 @@ public class NativeScriptEngineService extends AbstractComponent implements Scri
|
|||
|
||||
@Override
|
||||
public String[] types() {
|
||||
return new String[]{"native"};
|
||||
return new String[]{NAME};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,7 +25,6 @@ import com.google.common.cache.CacheBuilder;
|
|||
import com.google.common.cache.RemovalListener;
|
||||
import com.google.common.cache.RemovalNotification;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||
import org.elasticsearch.ElasticsearchIllegalStateException;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
|
@ -60,6 +59,7 @@ import org.elasticsearch.env.Environment;
|
|||
import org.elasticsearch.index.query.TemplateQueryParser;
|
||||
import org.elasticsearch.node.settings.NodeSettingsService;
|
||||
import org.elasticsearch.script.groovy.GroovyScriptEngineService;
|
||||
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
|
||||
import org.elasticsearch.search.lookup.SearchLookup;
|
||||
import org.elasticsearch.watcher.FileChangesListener;
|
||||
import org.elasticsearch.watcher.FileWatcher;
|
||||
|
@ -139,94 +139,6 @@ public class ScriptService extends AbstractComponent {
|
|||
public static final ParseField SCRIPT_ID = new ParseField("script_id");
|
||||
public static final ParseField SCRIPT_INLINE = new ParseField("script");
|
||||
|
||||
public static enum ScriptType {
|
||||
|
||||
INLINE,
|
||||
INDEXED,
|
||||
FILE;
|
||||
|
||||
private static final int INLINE_VAL = 0;
|
||||
private static final int INDEXED_VAL = 1;
|
||||
private static final int FILE_VAL = 2;
|
||||
|
||||
public static ScriptType readFrom(StreamInput in) throws IOException {
|
||||
int scriptTypeVal = in.readVInt();
|
||||
switch (scriptTypeVal) {
|
||||
case INDEXED_VAL:
|
||||
return INDEXED;
|
||||
case INLINE_VAL:
|
||||
return INLINE;
|
||||
case FILE_VAL:
|
||||
return FILE;
|
||||
default:
|
||||
throw new ElasticsearchIllegalArgumentException("Unexpected value read for ScriptType got [" + scriptTypeVal +
|
||||
"] expected one of ["+INLINE_VAL +"," + INDEXED_VAL + "," + FILE_VAL+"]");
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeTo(ScriptType scriptType, StreamOutput out) throws IOException{
|
||||
if (scriptType != null) {
|
||||
switch (scriptType){
|
||||
case INDEXED:
|
||||
out.writeVInt(INDEXED_VAL);
|
||||
return;
|
||||
case INLINE:
|
||||
out.writeVInt(INLINE_VAL);
|
||||
return;
|
||||
case FILE:
|
||||
out.writeVInt(FILE_VAL);
|
||||
return;
|
||||
default:
|
||||
throw new ElasticsearchIllegalStateException("Unknown ScriptType " + scriptType);
|
||||
}
|
||||
} else {
|
||||
out.writeVInt(INLINE_VAL); //Default to inline
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class IndexedScript {
|
||||
private final String lang;
|
||||
private final String id;
|
||||
|
||||
IndexedScript(String lang, String script) {
|
||||
this.lang = lang;
|
||||
final String[] parts = script.split("/");
|
||||
if (parts.length == 1) {
|
||||
this.id = script;
|
||||
} else {
|
||||
if (parts.length != 3) {
|
||||
throw new ElasticsearchIllegalArgumentException("Illegal index script format [" + script + "]" +
|
||||
" should be /lang/id");
|
||||
} else {
|
||||
if (!parts[1].equals(this.lang)) {
|
||||
throw new ElasticsearchIllegalStateException("Conflicting script language, found [" + parts[1] + "] expected + ["+ this.lang + "]");
|
||||
}
|
||||
this.id = parts[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ApplySettings implements NodeSettingsService.Listener {
|
||||
@Override
|
||||
public void onRefreshSettings(Settings settings) {
|
||||
GroovyScriptEngineService engine = (GroovyScriptEngineService) ScriptService.this.scriptEngines.get("groovy");
|
||||
if (engine != null) {
|
||||
String[] patches = settings.getAsArray(GroovyScriptEngineService.GROOVY_SCRIPT_BLACKLIST_PATCH, Strings.EMPTY_ARRAY);
|
||||
boolean blacklistChanged = engine.addToBlacklist(patches);
|
||||
if (blacklistChanged) {
|
||||
logger.info("adding {} to [{}], new blacklisted methods: {}", patches,
|
||||
GroovyScriptEngineService.GROOVY_SCRIPT_BLACKLIST_PATCH, engine.blacklistAdditions());
|
||||
engine.reloadConfig();
|
||||
// Because the GroovyScriptEngineService knows nothing about the
|
||||
// cache, we need to clear it here if the setting changes
|
||||
ScriptService.this.clearCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
public ScriptService(Settings settings, Environment env, Set<ScriptEngineService> scriptEngines,
|
||||
ResourceWatcherService resourceWatcherService, NodeSettingsService nodeSettingsService) throws IOException {
|
||||
|
@ -287,14 +199,6 @@ public class ScriptService extends AbstractComponent {
|
|||
}
|
||||
}
|
||||
|
||||
public CompiledScript compile(String script) {
|
||||
return compile(defaultLang, script);
|
||||
}
|
||||
|
||||
public CompiledScript compile(String lang, String script) {
|
||||
return compile(lang, script, ScriptType.INLINE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear both the in memory and on disk compiled script caches. Files on
|
||||
* disk will be treated as if they are new and recompiled.
|
||||
|
@ -310,77 +214,59 @@ public class ScriptService extends AbstractComponent {
|
|||
this.fileWatcher.clearState();
|
||||
}
|
||||
|
||||
private ScriptEngineService getScriptEngineService(String lang) {
|
||||
ScriptEngineService scriptEngineService = scriptEngines.get(lang);
|
||||
if (scriptEngineService == null) {
|
||||
throw new ElasticsearchIllegalArgumentException("script_lang not supported [" + lang + "]");
|
||||
}
|
||||
return scriptEngineService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles a script straight-away, or returns the previously compiled and cached script, without checking if it can be executed based on settings.
|
||||
*/
|
||||
public CompiledScript compile(String lang, String script, ScriptType scriptType) {
|
||||
if (lang == null) {
|
||||
lang = defaultLang;
|
||||
}
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Compiling lang: [{}] type: [{}] script: {}", lang, scriptType, script);
|
||||
}
|
||||
|
||||
CacheKey cacheKey;
|
||||
CompiledScript compiled;
|
||||
|
||||
if (lang == null) {
|
||||
lang = defaultLang;
|
||||
}
|
||||
|
||||
if(scriptType == ScriptType.INDEXED) {
|
||||
if (client == null) {
|
||||
throw new ElasticsearchIllegalArgumentException("Got an indexed script with no Client registered.");
|
||||
}
|
||||
|
||||
final IndexedScript indexedScript = new IndexedScript(lang, script);
|
||||
|
||||
verifyDynamicScripting(indexedScript.lang); //Since anyone can index a script, disable indexed scripting
|
||||
// if dynamic scripting is disabled, perhaps its own setting ?
|
||||
|
||||
script = getScriptFromIndex(client, indexedScript.lang, indexedScript.id);
|
||||
} else if (scriptType == ScriptType.FILE) {
|
||||
|
||||
compiled = staticCache.get(script); //On disk scripts will be loaded into the staticCache by the listener
|
||||
|
||||
if (compiled != null) {
|
||||
return compiled;
|
||||
} else {
|
||||
if (scriptType == ScriptType.FILE) {
|
||||
CompiledScript compiled = staticCache.get(script); //On disk scripts will be loaded into the staticCache by the listener
|
||||
if (compiled == null) {
|
||||
throw new ElasticsearchIllegalArgumentException("Unable to find on disk script " + script);
|
||||
}
|
||||
}
|
||||
|
||||
//This is an inline script check to see if we have it in the cache
|
||||
verifyDynamicScripting(lang);
|
||||
|
||||
cacheKey = new CacheKey(lang, script);
|
||||
|
||||
compiled = cache.getIfPresent(cacheKey);
|
||||
if (compiled != null) {
|
||||
return compiled;
|
||||
}
|
||||
|
||||
//Either an un-cached inline script or an indexed script
|
||||
ScriptEngineService scriptEngineService = getScriptEngineService(lang);
|
||||
verifyDynamicScripting(lang, scriptEngineService);
|
||||
|
||||
if (!dynamicScriptEnabled(lang)) {
|
||||
throw new ScriptException("dynamic scripting for [" + lang + "] disabled");
|
||||
if (scriptType == ScriptType.INDEXED) {
|
||||
if (client == null) {
|
||||
throw new ElasticsearchIllegalArgumentException("Got an indexed script with no Client registered.");
|
||||
}
|
||||
final IndexedScript indexedScript = new IndexedScript(lang, script);
|
||||
script = getScriptFromIndex(client, indexedScript.lang, indexedScript.id);
|
||||
}
|
||||
|
||||
// not the end of the world if we compile it twice...
|
||||
compiled = getCompiledScript(lang, script);
|
||||
//Since the cache key is the script content itself we don't need to
|
||||
//invalidate/check the cache if an indexed script changes.
|
||||
cache.put(cacheKey, compiled);
|
||||
|
||||
CacheKey cacheKey = new CacheKey(lang, script);
|
||||
CompiledScript compiled = cache.getIfPresent(cacheKey);
|
||||
if (compiled == null) {
|
||||
//Either an un-cached inline script or an indexed script
|
||||
// not the end of the world if we compile it twice...
|
||||
compiled = new CompiledScript(lang, scriptEngineService.compile(script));
|
||||
//Since the cache key is the script content itself we don't need to
|
||||
//invalidate/check the cache if an indexed script changes.
|
||||
cache.put(cacheKey, compiled);
|
||||
}
|
||||
return compiled;
|
||||
}
|
||||
|
||||
private CompiledScript getCompiledScript(String lang, String script) {
|
||||
CompiledScript compiled;ScriptEngineService service = scriptEngines.get(lang);
|
||||
if (service == null) {
|
||||
throw new ElasticsearchIllegalArgumentException("script_lang not supported [" + lang + "]");
|
||||
}
|
||||
|
||||
compiled = new CompiledScript(lang, service.compile(script));
|
||||
return compiled;
|
||||
}
|
||||
|
||||
private void verifyDynamicScripting(String lang) {
|
||||
if (!dynamicScriptEnabled(lang)) {
|
||||
private void verifyDynamicScripting(String lang, ScriptEngineService scriptEngineService) {
|
||||
if (!dynamicScriptEnabled(lang, scriptEngineService)) {
|
||||
throw new ScriptException("dynamic scripting for [" + lang + "] disabled");
|
||||
}
|
||||
}
|
||||
|
@ -421,7 +307,7 @@ public class ScriptService extends AbstractComponent {
|
|||
//Just try and compile it
|
||||
//This will have the benefit of also adding the script to the cache if it compiles
|
||||
try {
|
||||
CompiledScript compiledScript = compile(scriptLang, context.template(), ScriptService.ScriptType.INLINE);
|
||||
CompiledScript compiledScript = compile(scriptLang, context.template(), ScriptType.INLINE);
|
||||
if (compiledScript == null) {
|
||||
throw new ElasticsearchIllegalArgumentException("Unable to parse [" + context.template() +
|
||||
"] lang [" + scriptLang + "] (ScriptService.compile returned null)");
|
||||
|
@ -456,6 +342,7 @@ public class ScriptService extends AbstractComponent {
|
|||
client.delete(deleteRequest, listener);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static String getScriptFromResponse(GetResponse responseFields) {
|
||||
Map<String, Object> source = responseFields.getSourceAsMap();
|
||||
if (source.containsKey("template")) {
|
||||
|
@ -484,37 +371,39 @@ public class ScriptService extends AbstractComponent {
|
|||
}
|
||||
}
|
||||
|
||||
public ExecutableScript executable(String lang, String script, ScriptType scriptType, Map vars) {
|
||||
/**
|
||||
* Compiles (or retrieves from cache) and executes the provided script
|
||||
*/
|
||||
public ExecutableScript executable(String lang, String script, ScriptType scriptType, Map<String, Object> vars) {
|
||||
return executable(compile(lang, script, scriptType), vars);
|
||||
}
|
||||
|
||||
public ExecutableScript executable(CompiledScript compiledScript, Map vars) {
|
||||
/**
|
||||
* Executes a previously compiled script provided as an argument
|
||||
*/
|
||||
public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> vars) {
|
||||
return scriptEngines.get(compiledScript.lang()).executable(compiledScript.compiled(), vars);
|
||||
}
|
||||
|
||||
public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, @Nullable Map<String, Object> vars) {
|
||||
/**
|
||||
* Compiles (or retrieves from cache) and executes the provided search script
|
||||
*/
|
||||
public SearchScript search(SearchLookup lookup, String lang, String script, ScriptType scriptType, @Nullable Map<String, Object> vars) {
|
||||
CompiledScript compiledScript = compile(lang, script, scriptType);
|
||||
return scriptEngines.get(compiledScript.lang()).search(compiledScript.compiled(), lookup, vars);
|
||||
}
|
||||
|
||||
public SearchScript search(SearchLookup lookup, String lang, String script, ScriptType scriptType, @Nullable Map<String, Object> vars) {
|
||||
return search(compile(lang, script, scriptType), lookup, vars);
|
||||
}
|
||||
|
||||
private boolean dynamicScriptEnabled(String lang) {
|
||||
ScriptEngineService service = scriptEngines.get(lang);
|
||||
if (service == null) {
|
||||
throw new ElasticsearchIllegalArgumentException("script_lang not supported [" + lang + "]");
|
||||
}
|
||||
|
||||
private boolean dynamicScriptEnabled(String lang, ScriptEngineService scriptEngineService) {
|
||||
// Templating languages (mustache) and native scripts are always
|
||||
// allowed, "native" executions are registered through plugins
|
||||
if (this.dynamicScriptingDisabled == DynamicScriptDisabling.EVERYTHING_ALLOWED || "native".equals(lang) || "mustache".equals(lang)) {
|
||||
if (this.dynamicScriptingDisabled == DynamicScriptDisabling.EVERYTHING_ALLOWED ||
|
||||
NativeScriptEngineService.NAME.equals(lang) || MustacheScriptEngineService.NAME.equals(lang)) {
|
||||
return true;
|
||||
} else if (this.dynamicScriptingDisabled == DynamicScriptDisabling.ONLY_DISK_ALLOWED) {
|
||||
return false;
|
||||
} else {
|
||||
return service.sandboxed();
|
||||
}
|
||||
if (this.dynamicScriptingDisabled == DynamicScriptDisabling.ONLY_DISK_ALLOWED) {
|
||||
return false;
|
||||
}
|
||||
return scriptEngineService.sandboxed();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -608,7 +497,59 @@ public class ScriptService extends AbstractComponent {
|
|||
|
||||
}
|
||||
|
||||
public final static class CacheKey {
|
||||
/**
|
||||
* The type of a script, more specifically where it gets loaded from:
|
||||
* - provided dynamically at request time
|
||||
* - loaded from an index
|
||||
* - loaded from file
|
||||
*/
|
||||
public static enum ScriptType {
|
||||
|
||||
INLINE,
|
||||
INDEXED,
|
||||
FILE;
|
||||
|
||||
private static final int INLINE_VAL = 0;
|
||||
private static final int INDEXED_VAL = 1;
|
||||
private static final int FILE_VAL = 2;
|
||||
|
||||
public static ScriptType readFrom(StreamInput in) throws IOException {
|
||||
int scriptTypeVal = in.readVInt();
|
||||
switch (scriptTypeVal) {
|
||||
case INDEXED_VAL:
|
||||
return INDEXED;
|
||||
case INLINE_VAL:
|
||||
return INLINE;
|
||||
case FILE_VAL:
|
||||
return FILE;
|
||||
default:
|
||||
throw new ElasticsearchIllegalArgumentException("Unexpected value read for ScriptType got [" + scriptTypeVal +
|
||||
"] expected one of [" + INLINE_VAL + "," + INDEXED_VAL + "," + FILE_VAL + "]");
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeTo(ScriptType scriptType, StreamOutput out) throws IOException{
|
||||
if (scriptType != null) {
|
||||
switch (scriptType){
|
||||
case INDEXED:
|
||||
out.writeVInt(INDEXED_VAL);
|
||||
return;
|
||||
case INLINE:
|
||||
out.writeVInt(INLINE_VAL);
|
||||
return;
|
||||
case FILE:
|
||||
out.writeVInt(FILE_VAL);
|
||||
return;
|
||||
default:
|
||||
throw new ElasticsearchIllegalStateException("Unknown ScriptType " + scriptType);
|
||||
}
|
||||
} else {
|
||||
out.writeVInt(INLINE_VAL); //Default to inline
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class CacheKey {
|
||||
public final String lang;
|
||||
public final String script;
|
||||
|
||||
|
@ -631,4 +572,46 @@ public class ScriptService extends AbstractComponent {
|
|||
return lang.hashCode() + 31 * script.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
private static class IndexedScript {
|
||||
private final String lang;
|
||||
private final String id;
|
||||
|
||||
IndexedScript(String lang, String script) {
|
||||
this.lang = lang;
|
||||
final String[] parts = script.split("/");
|
||||
if (parts.length == 1) {
|
||||
this.id = script;
|
||||
} else {
|
||||
if (parts.length != 3) {
|
||||
throw new ElasticsearchIllegalArgumentException("Illegal index script format [" + script + "]" +
|
||||
" should be /lang/id");
|
||||
} else {
|
||||
if (!parts[1].equals(this.lang)) {
|
||||
throw new ElasticsearchIllegalStateException("Conflicting script language, found [" + parts[1] + "] expected + ["+ this.lang + "]");
|
||||
}
|
||||
this.id = parts[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ApplySettings implements NodeSettingsService.Listener {
|
||||
@Override
|
||||
public void onRefreshSettings(Settings settings) {
|
||||
GroovyScriptEngineService engine = (GroovyScriptEngineService) ScriptService.this.scriptEngines.get("groovy");
|
||||
if (engine != null) {
|
||||
String[] patches = settings.getAsArray(GroovyScriptEngineService.GROOVY_SCRIPT_BLACKLIST_PATCH, Strings.EMPTY_ARRAY);
|
||||
boolean blacklistChanged = engine.addToBlacklist(patches);
|
||||
if (blacklistChanged) {
|
||||
logger.info("adding {} to [{}], new blacklisted methods: {}", patches,
|
||||
GroovyScriptEngineService.GROOVY_SCRIPT_BLACKLIST_PATCH, engine.blacklistAdditions());
|
||||
engine.reloadConfig();
|
||||
// Because the GroovyScriptEngineService knows nothing about the
|
||||
// cache, we need to clear it here if the setting changes
|
||||
ScriptService.this.clearCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,8 +20,6 @@ package org.elasticsearch.script;
|
|||
|
||||
import org.elasticsearch.common.lucene.ReaderContextAware;
|
||||
import org.elasticsearch.common.lucene.ScorerAware;
|
||||
import org.elasticsearch.search.internal.SearchContext;
|
||||
import org.elasticsearch.search.lookup.SearchLookup;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -39,36 +37,4 @@ public interface SearchScript extends ExecutableScript, ReaderContextAware, Scor
|
|||
long runAsLong();
|
||||
|
||||
double runAsDouble();
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private String script;
|
||||
private ScriptService.ScriptType scriptType;
|
||||
private String lang;
|
||||
private Map<String, Object> params;
|
||||
|
||||
public Builder script(String script, ScriptService.ScriptType scriptType) {
|
||||
this.script = script;
|
||||
this.scriptType = scriptType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder lang(String lang) {
|
||||
this.lang = lang;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder params(Map<String, Object> params) {
|
||||
this.params = params;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SearchScript build(SearchContext context) {
|
||||
return build(context.scriptService(), context.lookup());
|
||||
}
|
||||
|
||||
public SearchScript build(ScriptService service, SearchLookup lookup) {
|
||||
return service.search(lookup, lang, script, scriptType, params);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -48,6 +48,8 @@ import java.util.Map;
|
|||
*/
|
||||
public class ExpressionScriptEngineService extends AbstractComponent implements ScriptEngineService {
|
||||
|
||||
public static final String NAME = "expression";
|
||||
|
||||
@Inject
|
||||
public ExpressionScriptEngineService(Settings settings) {
|
||||
super(settings);
|
||||
|
@ -55,12 +57,12 @@ public class ExpressionScriptEngineService extends AbstractComponent implements
|
|||
|
||||
@Override
|
||||
public String[] types() {
|
||||
return new String[]{"expression"};
|
||||
return new String[]{NAME};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] extensions() {
|
||||
return new String[]{"expression"};
|
||||
return new String[]{NAME};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -48,10 +48,7 @@ import org.elasticsearch.search.lookup.SearchLookup;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
|
@ -59,6 +56,7 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||
*/
|
||||
public class GroovyScriptEngineService extends AbstractComponent implements ScriptEngineService {
|
||||
|
||||
public static final String NAME = "groovy";
|
||||
public static String GROOVY_SCRIPT_SANDBOX_ENABLED = "script.groovy.sandbox.enabled";
|
||||
public static String GROOVY_SCRIPT_BLACKLIST_PATCH = "script.groovy.sandbox.method_blacklist_patch";
|
||||
|
||||
|
@ -85,9 +83,7 @@ public class GroovyScriptEngineService extends AbstractComponent implements Scri
|
|||
*/
|
||||
public boolean addToBlacklist(String... additions) {
|
||||
Set<String> newBlackList = new HashSet<>(blacklistAdditions);
|
||||
for (String addition : additions) {
|
||||
newBlackList.add(addition);
|
||||
}
|
||||
Collections.addAll(newBlackList, additions);
|
||||
boolean changed = this.blacklistAdditions.equals(newBlackList) == false;
|
||||
this.blacklistAdditions = ImmutableSet.copyOf(newBlackList);
|
||||
return changed;
|
||||
|
@ -120,7 +116,7 @@ public class GroovyScriptEngineService extends AbstractComponent implements Scri
|
|||
@Override
|
||||
public void scriptRemoved(@Nullable CompiledScript script) {
|
||||
// script could be null, meaning the script has already been garbage collected
|
||||
if (script == null || "groovy".equals(script.lang())) {
|
||||
if (script == null || NAME.equals(script.lang())) {
|
||||
// Clear the cache, this removes old script versions from the
|
||||
// cache to prevent running out of PermGen space
|
||||
loader.clearCache();
|
||||
|
@ -129,12 +125,12 @@ public class GroovyScriptEngineService extends AbstractComponent implements Scri
|
|||
|
||||
@Override
|
||||
public String[] types() {
|
||||
return new String[]{"groovy"};
|
||||
return new String[]{NAME};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] extensions() {
|
||||
return new String[]{"groovy"};
|
||||
return new String[]{NAME};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -157,6 +153,7 @@ public class GroovyScriptEngineService extends AbstractComponent implements Scri
|
|||
/**
|
||||
* Return a script object with the given vars from the compiled script object
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private Script createScript(Object compiledScript, Map<String, Object> vars) throws InstantiationException, IllegalAccessException {
|
||||
Class scriptClass = (Class) compiledScript;
|
||||
Script scriptObject = (Script) scriptClass.newInstance();
|
||||
|
@ -225,12 +222,12 @@ public class GroovyScriptEngineService extends AbstractComponent implements Scri
|
|||
private final SearchLookup lookup;
|
||||
private final Map<String, Object> variables;
|
||||
private final ESLogger logger;
|
||||
private Scorer scorer;
|
||||
|
||||
public GroovyScript(Script script, ESLogger logger) {
|
||||
this(script, null, logger);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public GroovyScript(Script script, @Nullable SearchLookup lookup, ESLogger logger) {
|
||||
this.script = script;
|
||||
this.lookup = lookup;
|
||||
|
@ -240,7 +237,6 @@ public class GroovyScriptEngineService extends AbstractComponent implements Scri
|
|||
|
||||
@Override
|
||||
public void setScorer(Scorer scorer) {
|
||||
this.scorer = scorer;
|
||||
this.variables.put("_score", new ScoreAccessor(scorer));
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,8 @@ import java.util.Map;
|
|||
*/
|
||||
public class MustacheScriptEngineService extends AbstractComponent implements ScriptEngineService {
|
||||
|
||||
public static final String NAME = "mustache";
|
||||
|
||||
/** Thread local UTF8StreamWriter to store template execution results in, thread local to save object creation.*/
|
||||
private static ThreadLocal<SoftReference<UTF8StreamWriter>> utf8StreamWriter = new ThreadLocal<>();
|
||||
|
||||
|
@ -116,12 +118,12 @@ public class MustacheScriptEngineService extends AbstractComponent implements Sc
|
|||
|
||||
@Override
|
||||
public String[] types() {
|
||||
return new String[] {"mustache"};
|
||||
return new String[] {NAME};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] extensions() {
|
||||
return new String[] {"mustache"};
|
||||
return new String[] {NAME};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -172,7 +174,7 @@ public class MustacheScriptEngineService extends AbstractComponent implements Sc
|
|||
public MustacheExecutableScript(Mustache mustache,
|
||||
Map<String, Object> vars) {
|
||||
this.mustache = mustache;
|
||||
this.vars = vars == null ? Collections.EMPTY_MAP : vars;
|
||||
this.vars = vars == null ? Collections.<String, Object>emptyMap() : vars;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -184,7 +186,7 @@ public class MustacheScriptEngineService extends AbstractComponent implements Sc
|
|||
public Object run() {
|
||||
BytesStreamOutput result = new BytesStreamOutput();
|
||||
UTF8StreamWriter writer = utf8StreamWriter().setOutput(result);
|
||||
((Mustache) mustache).execute(writer, vars);
|
||||
mustache.execute(writer, vars);
|
||||
try {
|
||||
writer.flush();
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -24,7 +24,6 @@ import com.carrotsearch.hppc.ObjectSet;
|
|||
import com.carrotsearch.hppc.cursors.ObjectCursor;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import org.apache.lucene.index.IndexOptions;
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.index.NumericDocValues;
|
||||
|
@ -73,6 +72,7 @@ import org.elasticsearch.indices.IndicesWarmer.WarmerContext;
|
|||
import org.elasticsearch.indices.cache.query.IndicesQueryCache;
|
||||
import org.elasticsearch.script.ExecutableScript;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
|
||||
import org.elasticsearch.search.dfs.CachedDfSource;
|
||||
import org.elasticsearch.search.dfs.DfsPhase;
|
||||
import org.elasticsearch.search.dfs.DfsSearchResult;
|
||||
|
@ -85,7 +85,6 @@ import org.elasticsearch.threadpool.ThreadPool;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
@ -629,7 +628,7 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
|||
|
||||
final ExecutableScript executable;
|
||||
if (hasLength(request.templateName())) {
|
||||
executable = this.scriptService.executable("mustache", request.templateName(), request.templateType(), request.templateParams());
|
||||
executable = this.scriptService.executable(MustacheScriptEngineService.NAME, request.templateName(), request.templateType(), request.templateParams());
|
||||
} else {
|
||||
if (!hasLength(request.templateSource())) {
|
||||
return;
|
||||
|
@ -641,7 +640,7 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
|||
parser = XContentFactory.xContent(request.templateSource()).createParser(request.templateSource());
|
||||
templateContext = TemplateQueryParser.parse(parser, "params", "template");
|
||||
|
||||
if (templateContext.scriptType().equals(ScriptService.ScriptType.INLINE)) {
|
||||
if (templateContext.scriptType() == ScriptService.ScriptType.INLINE) {
|
||||
//Try to double parse for nested template id/file
|
||||
parser = null;
|
||||
try {
|
||||
|
@ -666,10 +665,10 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
|||
Releasables.closeWhileHandlingException(parser);
|
||||
}
|
||||
|
||||
if (templateContext == null || !hasLength(templateContext.template())) {
|
||||
if (!hasLength(templateContext.template())) {
|
||||
throw new ElasticsearchParseException("Template must have [template] field configured");
|
||||
}
|
||||
executable = this.scriptService.executable("mustache", templateContext.template(), templateContext.scriptType(), templateContext.params());
|
||||
executable = this.scriptService.executable(MustacheScriptEngineService.NAME, templateContext.template(), templateContext.scriptType(), templateContext.params());
|
||||
}
|
||||
|
||||
BytesReference processedQuery = (BytesReference) executable.run();
|
||||
|
@ -811,8 +810,8 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
|||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
for (Iterator<ObjectCursor<String>> it = warmUp.iterator(); it.hasNext(); ) {
|
||||
final String indexName = it.next().value;
|
||||
for (ObjectCursor<String> stringObjectCursor : warmUp) {
|
||||
final String indexName = stringObjectCursor.value;
|
||||
final long start = System.nanoTime();
|
||||
for (final LeafReaderContext ctx : context.searcher().reader().leaves()) {
|
||||
final NumericDocValues values = ctx.reader().getNormValues(indexName);
|
||||
|
|
|
@ -92,9 +92,9 @@ public class InternalScriptedMetric extends InternalMetricsAggregation implement
|
|||
if (firstAggregation.reduceScript != null) {
|
||||
Map<String, Object> params;
|
||||
if (firstAggregation.reduceParams != null) {
|
||||
params = new HashMap<String, Object>(firstAggregation.reduceParams);
|
||||
params = new HashMap<>(firstAggregation.reduceParams);
|
||||
} else {
|
||||
params = new HashMap<String, Object>();
|
||||
params = new HashMap<>();
|
||||
}
|
||||
params.put("_aggs", aggregationObjects);
|
||||
ExecutableScript script = reduceContext.scriptService().executable(firstAggregation.scriptLang, firstAggregation.reduceScript,
|
||||
|
|
|
@ -52,14 +52,12 @@ public class ScriptedMetricAggregator extends MetricsAggregator {
|
|||
private final Map<String, Object> params;
|
||||
// initial parameters for {reduce}
|
||||
private final Map<String, Object> reduceParams;
|
||||
private final ScriptService scriptService;
|
||||
private final ScriptType reduceScriptType;
|
||||
|
||||
protected ScriptedMetricAggregator(String name, String scriptLang, ScriptType initScriptType, String initScript,
|
||||
ScriptType mapScriptType, String mapScript, ScriptType combineScriptType, String combineScript, ScriptType reduceScriptType,
|
||||
String reduceScript, Map<String, Object> params, Map<String, Object> reduceParams, AggregationContext context, Aggregator parent, Map<String, Object> metaData) throws IOException {
|
||||
super(name, context, parent, metaData);
|
||||
this.scriptService = context.searchContext().scriptService();
|
||||
this.scriptLang = scriptLang;
|
||||
this.reduceScriptType = reduceScriptType;
|
||||
if (params == null) {
|
||||
|
@ -73,6 +71,7 @@ public class ScriptedMetricAggregator extends MetricsAggregator {
|
|||
} else {
|
||||
this.reduceParams = reduceParams;
|
||||
}
|
||||
ScriptService scriptService = context.searchContext().scriptService();
|
||||
if (initScript != null) {
|
||||
scriptService.executable(scriptLang, initScript, initScriptType, this.params).run();
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ public class ScriptedMetricParser implements Aggregator.Parser {
|
|||
|
||||
@Override
|
||||
public AggregatorFactory parse(String aggregationName, XContentParser parser, SearchContext context) throws IOException {
|
||||
String scriptLang = null;
|
||||
String scriptLang;
|
||||
Map<String, Object> params = null;
|
||||
Map<String, Object> reduceParams = null;
|
||||
XContentParser.Token token;
|
||||
|
|
|
@ -56,7 +56,6 @@ public class ScriptFieldsParseElement implements SearchParseElement {
|
|||
String fieldName = currentFieldName;
|
||||
ScriptParameterParser scriptParameterParser = new ScriptParameterParser();
|
||||
String script = null;
|
||||
String scriptLang = null;
|
||||
ScriptService.ScriptType scriptType = null;
|
||||
Map<String, Object> params = null;
|
||||
boolean ignoreException = false;
|
||||
|
@ -79,9 +78,7 @@ public class ScriptFieldsParseElement implements SearchParseElement {
|
|||
script = scriptValue.script();
|
||||
scriptType = scriptValue.scriptType();
|
||||
}
|
||||
scriptLang = scriptParameterParser.lang();
|
||||
|
||||
SearchScript searchScript = context.scriptService().search(context.lookup(), scriptLang, script, scriptType, params);
|
||||
SearchScript searchScript = context.scriptService().search(context.lookup(), scriptParameterParser.lang(), script, scriptType, params);
|
||||
context.scriptFields().add(new ScriptFieldsContext.ScriptField(fieldName, searchScript, ignoreException));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ import org.elasticsearch.index.fielddata.*;
|
|||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||
import org.elasticsearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource;
|
||||
import org.elasticsearch.index.fielddata.fieldcomparator.DoubleValuesComparatorSource;
|
||||
import org.elasticsearch.index.mapper.object.ObjectMapper;
|
||||
import org.elasticsearch.index.query.support.NestedInnerQueryParseSupport;
|
||||
import org.elasticsearch.index.search.nested.NonNestedDocsFilter;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
|
@ -128,7 +127,6 @@ public class ScriptSortParser implements SortParser {
|
|||
}
|
||||
|
||||
// If nested_path is specified, then wrap the `fieldComparatorSource` in a `NestedFieldComparatorSource`
|
||||
ObjectMapper objectMapper;
|
||||
final Nested nested;
|
||||
if (nestedHelper != null && nestedHelper.getPath() != null) {
|
||||
BitDocIdSetFilter rootDocumentsFilter = context.bitsetFilterCache().getBitDocIdSetFilter(NonNestedDocsFilter.INSTANCE);
|
||||
|
|
|
@ -30,6 +30,8 @@ import org.elasticsearch.index.analysis.ShingleTokenFilterFactory;
|
|||
import org.elasticsearch.index.mapper.FieldMapper;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.script.CompiledScript;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
|
||||
import org.elasticsearch.search.suggest.SuggestContextParser;
|
||||
import org.elasticsearch.search.suggest.SuggestUtils;
|
||||
import org.elasticsearch.search.suggest.SuggestionSearchContext;
|
||||
|
@ -150,7 +152,7 @@ public final class PhraseSuggestParser implements SuggestContextParser {
|
|||
if (suggestion.getCollateQueryScript() != null) {
|
||||
throw new ElasticsearchIllegalArgumentException("suggester[phrase][collate] query already set, doesn't support additional [" + fieldName + "]");
|
||||
}
|
||||
CompiledScript compiledScript = suggester.scriptService().compile("mustache", templateNameOrTemplateContent);
|
||||
CompiledScript compiledScript = suggester.scriptService().compile(MustacheScriptEngineService.NAME, templateNameOrTemplateContent, ScriptService.ScriptType.INLINE);
|
||||
if ("query".equals(fieldName)) {
|
||||
suggestion.setCollateQueryScript(compiledScript);
|
||||
} else {
|
||||
|
|
|
@ -38,7 +38,6 @@ import org.elasticsearch.rest.RestStatus;
|
|||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.test.ElasticsearchIntegrationTest;
|
||||
import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
|
||||
import org.elasticsearch.test.junit.annotations.TestLogging;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.elasticsearch.action.suggest.SuggestResponse;
|
|||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.script.groovy.GroovyScriptEngineService;
|
||||
import org.elasticsearch.search.suggest.SuggestBuilders;
|
||||
import org.elasticsearch.search.suggest.completion.CompletionSuggestion;
|
||||
import org.elasticsearch.test.ElasticsearchIntegrationTest;
|
||||
|
@ -90,7 +91,7 @@ public class TransformOnIndexMapperIntegrationTest extends ElasticsearchIntegrat
|
|||
builder.endObject();
|
||||
builder.startObject("transform");
|
||||
builder.field("script", "ctx._source.suggest = ['input': ctx._source.text];ctx._source.suggest.payload = ['display': ctx._source.text, 'display_detail': 'on the fly']");
|
||||
builder.field("lang", "groovy");
|
||||
builder.field("lang", GroovyScriptEngineService.NAME);
|
||||
builder.endObject();
|
||||
assertAcked(client().admin().indices().prepareCreate("test").addMapping("test", builder));
|
||||
// Payload is stored using original source format (json, smile, yaml, whatever)
|
||||
|
@ -127,7 +128,7 @@ public class TransformOnIndexMapperIntegrationTest extends ElasticsearchIntegrat
|
|||
// Single transform
|
||||
builder.startObject();
|
||||
buildTransformScript(builder);
|
||||
builder.field("lang", "groovy");
|
||||
builder.field("lang", GroovyScriptEngineService.NAME);
|
||||
builder.endObject();
|
||||
} else {
|
||||
// Multiple transforms
|
||||
|
@ -141,7 +142,7 @@ public class TransformOnIndexMapperIntegrationTest extends ElasticsearchIntegrat
|
|||
} else {
|
||||
builder.field("script", "true");
|
||||
}
|
||||
builder.field("lang", "groovy");
|
||||
builder.field("lang", GroovyScriptEngineService.NAME);
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endArray();
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
package org.elasticsearch.index.query;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import org.elasticsearch.action.index.IndexRequestBuilder;
|
||||
import org.elasticsearch.action.indexedscripts.delete.DeleteIndexedScriptResponse;
|
||||
import org.elasticsearch.action.indexedscripts.get.GetIndexedScriptResponse;
|
||||
|
@ -31,6 +30,7 @@ import org.elasticsearch.common.bytes.BytesArray;
|
|||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.script.mustache.MustacheScriptEngineService;
|
||||
import org.elasticsearch.test.ElasticsearchIntegrationTest;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -43,9 +43,7 @@ import java.util.Map;
|
|||
|
||||
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertFailures;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.*;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
|
@ -230,7 +228,7 @@ public class TemplateQueryTest extends ElasticsearchIntegrationTest {
|
|||
createIndex(ScriptService.SCRIPT_INDEX);
|
||||
ensureGreen(ScriptService.SCRIPT_INDEX);
|
||||
|
||||
PutIndexedScriptResponse scriptResponse = client().preparePutIndexedScript("mustache", "testTemplate", "{" +
|
||||
PutIndexedScriptResponse scriptResponse = client().preparePutIndexedScript(MustacheScriptEngineService.NAME, "testTemplate", "{" +
|
||||
"\"template\":{" +
|
||||
" \"query\":{" +
|
||||
" \"match\":{" +
|
||||
|
@ -241,7 +239,7 @@ public class TemplateQueryTest extends ElasticsearchIntegrationTest {
|
|||
|
||||
assertTrue(scriptResponse.isCreated());
|
||||
|
||||
scriptResponse = client().preparePutIndexedScript("mustache", "testTemplate", "{" +
|
||||
scriptResponse = client().preparePutIndexedScript(MustacheScriptEngineService.NAME, "testTemplate", "{" +
|
||||
"\"template\":{" +
|
||||
" \"query\":{" +
|
||||
" \"match\":{" +
|
||||
|
@ -252,7 +250,7 @@ public class TemplateQueryTest extends ElasticsearchIntegrationTest {
|
|||
|
||||
assertEquals(scriptResponse.getVersion(), 2);
|
||||
|
||||
GetIndexedScriptResponse getResponse = client().prepareGetIndexedScript("mustache", "testTemplate").get();
|
||||
GetIndexedScriptResponse getResponse = client().prepareGetIndexedScript(MustacheScriptEngineService.NAME, "testTemplate").get();
|
||||
assertTrue(getResponse.isExists());
|
||||
|
||||
List<IndexRequestBuilder> builders = new ArrayList<>();
|
||||
|
@ -272,10 +270,10 @@ public class TemplateQueryTest extends ElasticsearchIntegrationTest {
|
|||
setTemplateName("testTemplate").setTemplateType(ScriptService.ScriptType.INDEXED).setTemplateParams(templateParams).get();
|
||||
assertHitCount(searchResponse, 4);
|
||||
|
||||
DeleteIndexedScriptResponse deleteResponse = client().prepareDeleteIndexedScript("mustache","testTemplate").get();
|
||||
DeleteIndexedScriptResponse deleteResponse = client().prepareDeleteIndexedScript(MustacheScriptEngineService.NAME,"testTemplate").get();
|
||||
assertTrue(deleteResponse.isFound());
|
||||
|
||||
getResponse = client().prepareGetIndexedScript("mustache", "testTemplate").get();
|
||||
getResponse = client().prepareGetIndexedScript(MustacheScriptEngineService.NAME, "testTemplate").get();
|
||||
assertFalse(getResponse.isExists());
|
||||
|
||||
client().prepareSearch("test").setTypes("type").
|
||||
|
@ -287,7 +285,7 @@ public class TemplateQueryTest extends ElasticsearchIntegrationTest {
|
|||
createIndex(ScriptService.SCRIPT_INDEX);
|
||||
ensureGreen(ScriptService.SCRIPT_INDEX);
|
||||
List<IndexRequestBuilder> builders = new ArrayList<>();
|
||||
builders.add(client().prepareIndex(ScriptService.SCRIPT_INDEX, "mustache", "1a").setSource("{" +
|
||||
builders.add(client().prepareIndex(ScriptService.SCRIPT_INDEX, MustacheScriptEngineService.NAME, "1a").setSource("{" +
|
||||
"\"template\":{"+
|
||||
" \"query\":{" +
|
||||
" \"match\":{" +
|
||||
|
@ -295,7 +293,7 @@ public class TemplateQueryTest extends ElasticsearchIntegrationTest {
|
|||
" }" +
|
||||
"}" +
|
||||
"}"));
|
||||
builders.add(client().prepareIndex(ScriptService.SCRIPT_INDEX, "mustache", "2").setSource("{" +
|
||||
builders.add(client().prepareIndex(ScriptService.SCRIPT_INDEX, MustacheScriptEngineService.NAME, "2").setSource("{" +
|
||||
"\"template\":{"+
|
||||
" \"query\":{" +
|
||||
" \"match\":{" +
|
||||
|
@ -304,7 +302,7 @@ public class TemplateQueryTest extends ElasticsearchIntegrationTest {
|
|||
"}" +
|
||||
"}"));
|
||||
|
||||
builders.add(client().prepareIndex(ScriptService.SCRIPT_INDEX, "mustache", "3").setSource("{" +
|
||||
builders.add(client().prepareIndex(ScriptService.SCRIPT_INDEX, MustacheScriptEngineService.NAME, "3").setSource("{" +
|
||||
"\"template\":{"+
|
||||
" \"match\":{" +
|
||||
" \"theField\" : \"{{fieldParam}}\"}" +
|
||||
|
@ -381,7 +379,7 @@ public class TemplateQueryTest extends ElasticsearchIntegrationTest {
|
|||
|
||||
String multiQuery = "{\"query\":{\"terms\":{\"theField\":[\"{{#fieldParam}}\",\"{{.}}\",\"{{/fieldParam}}\"]}}}";
|
||||
|
||||
builders.add(client().prepareIndex(ScriptService.SCRIPT_INDEX, "mustache", "4").setSource(jsonBuilder().startObject().field("template", multiQuery).endObject()));
|
||||
builders.add(client().prepareIndex(ScriptService.SCRIPT_INDEX, MustacheScriptEngineService.NAME, "4").setSource(jsonBuilder().startObject().field("template", multiQuery).endObject()));
|
||||
|
||||
indexRandom(true,builders);
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.elasticsearch.action.index.IndexRequestBuilder;
|
|||
import org.elasticsearch.action.search.SearchPhaseExecutionException;
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.common.lucene.search.function.CombineFunction;
|
||||
import org.elasticsearch.script.groovy.GroovyScriptEngineService;
|
||||
import org.elasticsearch.test.ElasticsearchIntegrationTest;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -72,7 +73,7 @@ public class GroovyScriptTests extends ElasticsearchIntegrationTest {
|
|||
}
|
||||
indexRandom(true, false, reqs);
|
||||
try {
|
||||
client().prepareSearch("test").setQuery(constantScoreQuery(scriptFilter("1 == not_found").lang("groovy"))).get();
|
||||
client().prepareSearch("test").setQuery(constantScoreQuery(scriptFilter("1 == not_found").lang(GroovyScriptEngineService.NAME))).get();
|
||||
fail("should have thrown an exception");
|
||||
} catch (SearchPhaseExecutionException e) {
|
||||
assertThat(ExceptionsHelper.detailedMessage(e) + "should not contained NotSerializableTransportException",
|
||||
|
|
|
@ -28,11 +28,9 @@ import org.elasticsearch.common.settings.SettingsModule;
|
|||
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.threadpool.ThreadPoolModule;
|
||||
import org.elasticsearch.watcher.ResourceWatcherService;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
|
@ -51,7 +49,7 @@ public class NativeScriptTests extends ElasticsearchTestCase {
|
|||
|
||||
ScriptService scriptService = injector.getInstance(ScriptService.class);
|
||||
|
||||
ExecutableScript executable = scriptService.executable("native", "my", ScriptService.ScriptType.INLINE, null);
|
||||
ExecutableScript executable = scriptService.executable(NativeScriptEngineService.NAME, "my", ScriptService.ScriptType.INLINE, null);
|
||||
assertThat(executable.run().toString(), equalTo("test"));
|
||||
terminate(injector.getInstance(ThreadPool.class));
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ public class ScriptServiceTests extends ElasticsearchTestCase {
|
|||
logger.info("--> verify that file with extension was correctly removed");
|
||||
try {
|
||||
scriptService.compile("test", "test_script", ScriptService.ScriptType.FILE);
|
||||
fail("the script test_script should no longe exist");
|
||||
fail("the script test_script should no longer exist");
|
||||
} catch (ElasticsearchIllegalArgumentException ex) {
|
||||
assertThat(ex.getMessage(), containsString("Unable to find on disk script test_script"));
|
||||
}
|
||||
|
|
|
@ -20,24 +20,21 @@
|
|||
package org.elasticsearch.script.expression;
|
||||
|
||||
import org.elasticsearch.ExceptionsHelper;
|
||||
import org.elasticsearch.action.get.GetRequestBuilder;
|
||||
import org.elasticsearch.action.search.*;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.action.search.SearchPhaseExecutionException;
|
||||
import org.elasticsearch.action.search.SearchRequestBuilder;
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.action.search.SearchType;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilder;
|
||||
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
|
||||
import org.elasticsearch.search.SearchHits;
|
||||
import org.elasticsearch.search.aggregations.AggregationBuilders;
|
||||
import org.elasticsearch.search.aggregations.metrics.stats.Stats;
|
||||
import org.elasticsearch.search.sort.SortBuilder;
|
||||
import org.elasticsearch.search.sort.SortBuilders;
|
||||
import org.elasticsearch.search.sort.SortOrder;
|
||||
import org.elasticsearch.test.ElasticsearchIntegrationTest;
|
||||
import org.elasticsearch.test.hamcrest.ElasticsearchAssertions;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -225,8 +222,8 @@ public class ExpressionScriptTests extends ElasticsearchIntegrationTest {
|
|||
|
||||
SearchRequestBuilder req = new SearchRequestBuilder(client()).setIndices("test");
|
||||
req.setQuery(QueryBuilders.matchAllQuery())
|
||||
.addAggregation(AggregationBuilders.stats("int_agg").field("x").script("_value * 3").lang("expression"))
|
||||
.addAggregation(AggregationBuilders.stats("double_agg").field("y").script("_value - 1.1").lang("expression"));
|
||||
.addAggregation(AggregationBuilders.stats("int_agg").field("x").script("_value * 3").lang(ExpressionScriptEngineService.NAME))
|
||||
.addAggregation(AggregationBuilders.stats("double_agg").field("y").script("_value - 1.1").lang(ExpressionScriptEngineService.NAME));
|
||||
|
||||
SearchResponse rsp = req.get();
|
||||
assertEquals(3, rsp.getHits().getTotalHits());
|
||||
|
@ -251,7 +248,7 @@ public class ExpressionScriptTests extends ElasticsearchIntegrationTest {
|
|||
|
||||
SearchRequestBuilder req = new SearchRequestBuilder(client()).setIndices("test");
|
||||
req.setQuery(QueryBuilders.matchAllQuery())
|
||||
.addAggregation(AggregationBuilders.terms("term_agg").field("text").script("_value").lang("expression"));
|
||||
.addAggregation(AggregationBuilders.terms("term_agg").field("text").script("_value").lang(ExpressionScriptEngineService.NAME));
|
||||
|
||||
String message;
|
||||
try {
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.elasticsearch.action.indexedscripts.put.PutIndexedScriptResponse;
|
|||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.script.groovy.GroovyScriptEngineService;
|
||||
import org.elasticsearch.search.aggregations.Aggregation;
|
||||
import org.elasticsearch.search.aggregations.Aggregations;
|
||||
import org.elasticsearch.search.aggregations.bucket.global.Global;
|
||||
|
@ -91,11 +92,11 @@ public class ScriptedMetricTests extends ElasticsearchIntegrationTest {
|
|||
jsonBuilder().startObject().field("value", i * 2).endObject()));
|
||||
}
|
||||
|
||||
PutIndexedScriptResponse indexScriptResponse = client().preparePutIndexedScript("groovy", "initScript_indexed", "{\"script\":\"vars.multiplier = 3\"}").get();
|
||||
PutIndexedScriptResponse indexScriptResponse = client().preparePutIndexedScript(GroovyScriptEngineService.NAME, "initScript_indexed", "{\"script\":\"vars.multiplier = 3\"}").get();
|
||||
assertThat(indexScriptResponse.isCreated(), equalTo(true));
|
||||
indexScriptResponse = client().preparePutIndexedScript("groovy", "mapScript_indexed", "{\"script\":\"_agg.add(vars.multiplier)\"}").get();
|
||||
indexScriptResponse = client().preparePutIndexedScript(GroovyScriptEngineService.NAME, "mapScript_indexed", "{\"script\":\"_agg.add(vars.multiplier)\"}").get();
|
||||
assertThat(indexScriptResponse.isCreated(), equalTo(true));
|
||||
indexScriptResponse = client().preparePutIndexedScript("groovy", "combineScript_indexed",
|
||||
indexScriptResponse = client().preparePutIndexedScript(GroovyScriptEngineService.NAME, "combineScript_indexed",
|
||||
"{\"script\":\"newaggregation = []; sum = 0;for (a in _agg) { sum += a}; newaggregation.add(sum); return newaggregation\"}")
|
||||
.get();
|
||||
assertThat(indexScriptResponse.isCreated(), equalTo(true));
|
||||
|
|
|
@ -22,10 +22,7 @@ import com.google.common.collect.Maps;
|
|||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.script.AbstractExecutableScript;
|
||||
import org.elasticsearch.script.ExecutableScript;
|
||||
import org.elasticsearch.script.NativeScriptFactory;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.script.*;
|
||||
import org.elasticsearch.test.ElasticsearchIntegrationTest;
|
||||
import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
|
||||
import org.junit.Test;
|
||||
|
@ -61,7 +58,7 @@ public class UpdateByNativeScriptTests extends ElasticsearchIntegrationTest {
|
|||
params.put("foo", "SETVALUE");
|
||||
client().prepareUpdate("test", "type", "1")
|
||||
.setScript("custom", ScriptService.ScriptType.INLINE)
|
||||
.setScriptLang("native").setScriptParams(params).get();
|
||||
.setScriptLang(NativeScriptEngineService.NAME).setScriptParams(params).get();
|
||||
|
||||
Map<String, Object> data = client().prepareGet("test", "type", "1").get().getSource();
|
||||
assertThat(data, hasKey("foo"));
|
||||
|
|
|
@ -19,10 +19,7 @@
|
|||
|
||||
package org.elasticsearch.update;
|
||||
|
||||
import org.apache.lucene.index.MergePolicy;
|
||||
import org.apache.lucene.index.NoMergePolicy;
|
||||
import org.apache.lucene.util.LuceneTestCase.Slow;
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.ElasticsearchTimeoutException;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.ActionRequestValidationException;
|
||||
|
@ -34,16 +31,13 @@ import org.elasticsearch.action.update.UpdateRequest;
|
|||
import org.elasticsearch.action.update.UpdateRequestBuilder;
|
||||
import org.elasticsearch.action.update.UpdateResponse;
|
||||
import org.elasticsearch.client.transport.NoNodeAvailableException;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.index.VersionType;
|
||||
import org.elasticsearch.index.engine.DocumentMissingException;
|
||||
import org.elasticsearch.index.engine.VersionConflictEngineException;
|
||||
import org.elasticsearch.index.merge.policy.AbstractMergePolicyProvider;
|
||||
import org.elasticsearch.index.merge.policy.MergePolicyModule;
|
||||
import org.elasticsearch.index.store.Store;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.test.ElasticsearchIntegrationTest;
|
||||
import org.elasticsearch.test.index.merge.NoMergePolicyProvider;
|
||||
|
|
Loading…
Reference in New Issue