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:
javanna 2015-03-05 00:23:31 +01:00 committed by Luca Cavanna
parent 2d2ba48c0b
commit 521ac7f35a
30 changed files with 237 additions and 312 deletions

View File

@ -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));
}

View File

@ -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;

View File

@ -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();
}
}

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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

View File

@ -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();
}
}
}
}
}

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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));
}

View File

@ -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) {

View File

@ -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);

View File

@ -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,

View File

@ -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();
}

View File

@ -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;

View File

@ -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));
}
}

View File

@ -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);

View File

@ -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 {

View File

@ -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;

View File

@ -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();

View File

@ -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);

View File

@ -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",

View File

@ -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));
}

View File

@ -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"));
}

View File

@ -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 {

View File

@ -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));

View File

@ -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"));

View File

@ -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;