mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-09 22:45:04 +00:00
Add script type and script name to error messages
Modified ScriptEngineService to pass in a CompiledScript object with newly added name and type member variables. This can in turn be used to give better scripting error messages with the type of script used and the name of the script. Required slight modifications to the caching mechanism. Note that this does not enforce good behavior in that plugins will have to write exceptions that also output the name of the script in order to be effective. There was no way to wrap the script methods in a try/catch block properly further up the chain because many have script-like objects passed back that can be run at a later time. closes #6653 closes #11449
This commit is contained in:
parent
8790989a47
commit
c1137b3b78
@ -24,19 +24,41 @@ package org.elasticsearch.script;
|
|||||||
*/
|
*/
|
||||||
public class CompiledScript {
|
public class CompiledScript {
|
||||||
|
|
||||||
|
private final ScriptService.ScriptType type;
|
||||||
|
private final String name;
|
||||||
private final String lang;
|
private final String lang;
|
||||||
private final Object compiled;
|
private final Object compiled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for CompiledScript.
|
* Constructor for CompiledScript.
|
||||||
|
* @param type The type of script to be executed.
|
||||||
|
* @param name The name of the script to be executed.
|
||||||
* @param lang The language of the script to be executed.
|
* @param lang The language of the script to be executed.
|
||||||
* @param compiled The compiled script Object that is executable.
|
* @param compiled The compiled script Object that is executable.
|
||||||
*/
|
*/
|
||||||
public CompiledScript(String lang, Object compiled) {
|
public CompiledScript(ScriptService.ScriptType type, String name, String lang, Object compiled) {
|
||||||
|
this.type = type;
|
||||||
|
this.name = name;
|
||||||
this.lang = lang;
|
this.lang = lang;
|
||||||
this.compiled = compiled;
|
this.compiled = compiled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to get the type of language.
|
||||||
|
* @return The type of language the script was compiled in.
|
||||||
|
*/
|
||||||
|
public ScriptService.ScriptType type() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to get the name of the script.
|
||||||
|
* @return The name of the script to be executed.
|
||||||
|
*/
|
||||||
|
public String name() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to get the language.
|
* Method to get the language.
|
||||||
* @return The language of the script to be executed.
|
* @return The language of the script to be executed.
|
||||||
@ -52,4 +74,12 @@ public class CompiledScript {
|
|||||||
public Object compiled() {
|
public Object compiled() {
|
||||||
return compiled;
|
return compiled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A string composed of type, lang, and name to describe the CompiledScript.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return type + " script [" + name + "] using lang [" + lang + "]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,14 +71,14 @@ public class NativeScriptEngineService extends AbstractComponent implements Scri
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExecutableScript executable(Object compiledScript, @Nullable Map<String, Object> vars) {
|
public ExecutableScript executable(CompiledScript compiledScript, @Nullable Map<String, Object> vars) {
|
||||||
NativeScriptFactory scriptFactory = (NativeScriptFactory) compiledScript;
|
NativeScriptFactory scriptFactory = (NativeScriptFactory) compiledScript.compiled();
|
||||||
return scriptFactory.newScript(vars);
|
return scriptFactory.newScript(vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SearchScript search(Object compiledScript, final SearchLookup lookup, @Nullable final Map<String, Object> vars) {
|
public SearchScript search(CompiledScript compiledScript, final SearchLookup lookup, @Nullable final Map<String, Object> vars) {
|
||||||
final NativeScriptFactory scriptFactory = (NativeScriptFactory) compiledScript;
|
final NativeScriptFactory scriptFactory = (NativeScriptFactory) compiledScript.compiled();
|
||||||
return new SearchScript() {
|
return new SearchScript() {
|
||||||
@Override
|
@Override
|
||||||
public LeafSearchScript getLeafSearchScript(LeafReaderContext context) throws IOException {
|
public LeafSearchScript getLeafSearchScript(LeafReaderContext context) throws IOException {
|
||||||
@ -90,7 +90,7 @@ public class NativeScriptEngineService extends AbstractComponent implements Scri
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object execute(Object compiledScript, Map<String, Object> vars) {
|
public Object execute(CompiledScript compiledScript, Map<String, Object> vars) {
|
||||||
return executable(compiledScript, vars).run();
|
return executable(compiledScript, vars).run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,11 +38,11 @@ public interface ScriptEngineService extends Closeable {
|
|||||||
|
|
||||||
Object compile(String script);
|
Object compile(String script);
|
||||||
|
|
||||||
ExecutableScript executable(Object compiledScript, @Nullable Map<String, Object> vars);
|
ExecutableScript executable(CompiledScript compiledScript, @Nullable Map<String, Object> vars);
|
||||||
|
|
||||||
SearchScript search(Object compiledScript, SearchLookup lookup, @Nullable Map<String, Object> vars);
|
SearchScript search(CompiledScript compiledScript, SearchLookup lookup, @Nullable Map<String, Object> vars);
|
||||||
|
|
||||||
Object execute(Object compiledScript, Map<String, Object> vars);
|
Object execute(CompiledScript compiledScript, Map<String, Object> vars);
|
||||||
|
|
||||||
Object unwrap(Object value);
|
Object unwrap(Object value);
|
||||||
|
|
||||||
|
@ -249,50 +249,67 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compiles a script straight-away, or returns the previously compiled and cached script, without checking if it can be executed based on settings.
|
* 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 compileInternal(Script script) {
|
public CompiledScript compileInternal(Script script) {
|
||||||
if (script == null) {
|
if (script == null) {
|
||||||
throw new IllegalArgumentException("The parameter script (Script) must not be null.");
|
throw new IllegalArgumentException("The parameter script (Script) must not be null.");
|
||||||
}
|
}
|
||||||
|
|
||||||
String lang = script.getLang();
|
String lang = script.getLang() == null ? defaultLang : script.getLang();
|
||||||
|
ScriptType type = script.getType();
|
||||||
|
//script.getScript() could return either a name or code for a script,
|
||||||
|
//but we check for a file script name first and an indexed script name second
|
||||||
|
String name = script.getScript();
|
||||||
|
|
||||||
if (lang == null) {
|
|
||||||
lang = defaultLang;
|
|
||||||
}
|
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("Compiling lang: [{}] type: [{}] script: {}", lang, script.getType(), script.getScript());
|
logger.trace("Compiling lang: [{}] type: [{}] script: {}", lang, type, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptEngineService scriptEngineService = getScriptEngineServiceForLang(lang);
|
ScriptEngineService scriptEngineService = getScriptEngineServiceForLang(lang);
|
||||||
String cacheKey = getCacheKey(scriptEngineService, script.getScript());
|
|
||||||
|
|
||||||
if (script.getType() == ScriptType.FILE) {
|
if (type == ScriptType.FILE) {
|
||||||
CompiledScript compiled = staticCache.get(cacheKey); //On disk scripts will be loaded into the staticCache by the listener
|
String cacheKey = getCacheKey(scriptEngineService, name, null);
|
||||||
if (compiled == null) {
|
//On disk scripts will be loaded into the staticCache by the listener
|
||||||
throw new IllegalArgumentException("Unable to find on disk script " + script.getScript());
|
CompiledScript compiledScript = staticCache.get(cacheKey);
|
||||||
}
|
|
||||||
return compiled;
|
if (compiledScript == null) {
|
||||||
|
throw new IllegalArgumentException("Unable to find on disk file script [" + name + "] using lang [" + lang + "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return compiledScript;
|
||||||
|
}
|
||||||
|
|
||||||
|
//script.getScript() will be code if the script type is inline
|
||||||
String code = script.getScript();
|
String code = script.getScript();
|
||||||
|
|
||||||
if (script.getType() == ScriptType.INDEXED) {
|
if (type == ScriptType.INDEXED) {
|
||||||
final IndexedScript indexedScript = new IndexedScript(lang, script.getScript());
|
//The look up for an indexed script must be done every time in case
|
||||||
|
//the script has been updated in the index since the last look up.
|
||||||
|
final IndexedScript indexedScript = new IndexedScript(lang, name);
|
||||||
|
name = indexedScript.id;
|
||||||
code = getScriptFromIndex(indexedScript.lang, indexedScript.id);
|
code = getScriptFromIndex(indexedScript.lang, indexedScript.id);
|
||||||
cacheKey = getCacheKey(scriptEngineService, code);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CompiledScript compiled = cache.getIfPresent(cacheKey);
|
String cacheKey = getCacheKey(scriptEngineService, type == ScriptType.INLINE ? null : name, code);
|
||||||
if (compiled == null) {
|
CompiledScript compiledScript = cache.getIfPresent(cacheKey);
|
||||||
//Either an un-cached inline script or an indexed script
|
|
||||||
compiled = new CompiledScript(lang, scriptEngineService.compile(code));
|
if (compiledScript == null) {
|
||||||
|
//Either an un-cached inline script or indexed script
|
||||||
|
//If the script type is inline the name will be the same as the code for identification in exceptions
|
||||||
|
try {
|
||||||
|
compiledScript = new CompiledScript(type, name, lang, scriptEngineService.compile(code));
|
||||||
|
} catch (Exception exception) {
|
||||||
|
throw new ScriptException("Failed to compile " + type + " script [" + name + "] using lang [" + lang + "]", exception);
|
||||||
|
}
|
||||||
|
|
||||||
//Since the cache key is the script content itself we don't need to
|
//Since the cache key is the script content itself we don't need to
|
||||||
//invalidate/check the cache if an indexed script changes.
|
//invalidate/check the cache if an indexed script changes.
|
||||||
cache.put(cacheKey, compiled);
|
cache.put(cacheKey, compiledScript);
|
||||||
}
|
}
|
||||||
return compiled;
|
|
||||||
|
return compiledScript;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void queryScriptIndex(GetIndexedScriptRequest request, final ActionListener<GetResponse> listener) {
|
public void queryScriptIndex(GetIndexedScriptRequest request, final ActionListener<GetResponse> listener) {
|
||||||
@ -334,13 +351,13 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
|||||||
Template template = TemplateQueryParser.parse(scriptLang, parser, parseFieldMatcher, "params", "script", "template");
|
Template template = TemplateQueryParser.parse(scriptLang, parser, parseFieldMatcher, "params", "script", "template");
|
||||||
if (Strings.hasLength(template.getScript())) {
|
if (Strings.hasLength(template.getScript())) {
|
||||||
//Just try and compile it
|
//Just try and compile it
|
||||||
//This will have the benefit of also adding the script to the cache if it compiles
|
|
||||||
try {
|
try {
|
||||||
|
ScriptEngineService scriptEngineService = getScriptEngineServiceForLang(scriptLang);
|
||||||
//we don't know yet what the script will be used for, but if all of the operations for this lang with
|
//we don't know yet what the script will be used for, but if all of the operations for this lang with
|
||||||
//indexed scripts are disabled, it makes no sense to even compile it and cache it.
|
//indexed scripts are disabled, it makes no sense to even compile it.
|
||||||
if (isAnyScriptContextEnabled(scriptLang, getScriptEngineServiceForLang(scriptLang), ScriptType.INDEXED)) {
|
if (isAnyScriptContextEnabled(scriptLang, scriptEngineService, ScriptType.INDEXED)) {
|
||||||
CompiledScript compiledScript = compileInternal(template);
|
Object compiled = scriptEngineService.compile(template.getScript());
|
||||||
if (compiledScript == null) {
|
if (compiled == null) {
|
||||||
throw new IllegalArgumentException("Unable to parse [" + template.getScript() +
|
throw new IllegalArgumentException("Unable to parse [" + template.getScript() +
|
||||||
"] lang [" + scriptLang + "] (ScriptService.compile returned null)");
|
"] lang [" + scriptLang + "] (ScriptService.compile returned null)");
|
||||||
}
|
}
|
||||||
@ -419,7 +436,7 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
|||||||
* Executes a previously compiled script provided as an argument
|
* Executes a previously compiled script provided as an argument
|
||||||
*/
|
*/
|
||||||
public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> vars) {
|
public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> vars) {
|
||||||
return getScriptEngineServiceForLang(compiledScript.lang()).executable(compiledScript.compiled(), vars);
|
return getScriptEngineServiceForLang(compiledScript.lang()).executable(compiledScript, vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -427,7 +444,7 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
|||||||
*/
|
*/
|
||||||
public SearchScript search(SearchLookup lookup, Script script, ScriptContext scriptContext) {
|
public SearchScript search(SearchLookup lookup, Script script, ScriptContext scriptContext) {
|
||||||
CompiledScript compiledScript = compile(script, scriptContext);
|
CompiledScript compiledScript = compile(script, scriptContext);
|
||||||
return getScriptEngineServiceForLang(compiledScript.lang()).search(compiledScript.compiled(), lookup, script.getParams());
|
return getScriptEngineServiceForLang(compiledScript.lang()).search(compiledScript, lookup, script.getParams());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAnyScriptContextEnabled(String lang, ScriptEngineService scriptEngineService, ScriptType scriptType) {
|
private boolean isAnyScriptContextEnabled(String lang, ScriptEngineService scriptEngineService, ScriptType scriptType) {
|
||||||
@ -513,8 +530,8 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
|||||||
logger.info("compiling script file [{}]", file.toAbsolutePath());
|
logger.info("compiling script file [{}]", file.toAbsolutePath());
|
||||||
try(InputStreamReader reader = new InputStreamReader(Files.newInputStream(file), Charsets.UTF_8)) {
|
try(InputStreamReader reader = new InputStreamReader(Files.newInputStream(file), Charsets.UTF_8)) {
|
||||||
String script = Streams.copyToString(reader);
|
String script = Streams.copyToString(reader);
|
||||||
String cacheKey = getCacheKey(engineService, scriptNameExt.v1());
|
String cacheKey = getCacheKey(engineService, scriptNameExt.v1(), null);
|
||||||
staticCache.put(cacheKey, new CompiledScript(engineService.types()[0], engineService.compile(script)));
|
staticCache.put(cacheKey, new CompiledScript(ScriptType.FILE, scriptNameExt.v1(), engineService.types()[0], engineService.compile(script)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.warn("skipping compile of script file [{}] as all scripted operations are disabled for file scripts", file.toAbsolutePath());
|
logger.warn("skipping compile of script file [{}] as all scripted operations are disabled for file scripts", file.toAbsolutePath());
|
||||||
@ -538,7 +555,7 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
|||||||
ScriptEngineService engineService = getScriptEngineServiceForFileExt(scriptNameExt.v2());
|
ScriptEngineService engineService = getScriptEngineServiceForFileExt(scriptNameExt.v2());
|
||||||
assert engineService != null;
|
assert engineService != null;
|
||||||
logger.info("removing script file [{}]", file.toAbsolutePath());
|
logger.info("removing script file [{}]", file.toAbsolutePath());
|
||||||
staticCache.remove(getCacheKey(engineService, scriptNameExt.v1()));
|
staticCache.remove(getCacheKey(engineService, scriptNameExt.v1(), null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -598,9 +615,9 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getCacheKey(ScriptEngineService scriptEngineService, String script) {
|
private static String getCacheKey(ScriptEngineService scriptEngineService, String name, String code) {
|
||||||
String lang = scriptEngineService.types()[0];
|
String lang = scriptEngineService.types()[0];
|
||||||
return lang + ":" + script;
|
return lang + ":" + (name != null ? ":" + name : "") + (code != null ? ":" + code : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class IndexedScript {
|
private static class IndexedScript {
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
package org.elasticsearch.script.expression;
|
package org.elasticsearch.script.expression;
|
||||||
|
|
||||||
import org.apache.lucene.expressions.Expression;
|
import org.apache.lucene.expressions.Expression;
|
||||||
|
import org.elasticsearch.script.CompiledScript;
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
import org.elasticsearch.script.ExecutableScript;
|
||||||
import org.elasticsearch.script.ScriptException;
|
import org.elasticsearch.script.ScriptException;
|
||||||
|
|
||||||
@ -34,16 +35,18 @@ public class ExpressionExecutableScript implements ExecutableScript {
|
|||||||
|
|
||||||
private final int NO_DOCUMENT = -1;
|
private final int NO_DOCUMENT = -1;
|
||||||
|
|
||||||
public final Expression expression;
|
public final CompiledScript compiledScript;
|
||||||
public final Map<String, ReplaceableConstFunctionValues> functionValuesMap;
|
public final Map<String, ReplaceableConstFunctionValues> functionValuesMap;
|
||||||
public final ReplaceableConstFunctionValues[] functionValuesArray;
|
public final ReplaceableConstFunctionValues[] functionValuesArray;
|
||||||
|
|
||||||
public ExpressionExecutableScript(Object compiledScript, Map<String, Object> vars) {
|
public ExpressionExecutableScript(CompiledScript compiledScript, Map<String, Object> vars) {
|
||||||
expression = (Expression)compiledScript;
|
this.compiledScript = compiledScript;
|
||||||
|
Expression expression = (Expression)this.compiledScript.compiled();
|
||||||
int functionValuesLength = expression.variables.length;
|
int functionValuesLength = expression.variables.length;
|
||||||
|
|
||||||
if (vars.size() != functionValuesLength) {
|
if (vars.size() != functionValuesLength) {
|
||||||
throw new ScriptException("The number of variables in an executable expression script [" +
|
throw new ScriptException("Error using " + compiledScript + ". " +
|
||||||
|
"The number of variables in an executable expression script [" +
|
||||||
functionValuesLength + "] must match the number of variables in the variable map" +
|
functionValuesLength + "] must match the number of variables in the variable map" +
|
||||||
" [" + vars.size() + "].");
|
" [" + vars.size() + "].");
|
||||||
}
|
}
|
||||||
@ -69,17 +72,23 @@ public class ExpressionExecutableScript implements ExecutableScript {
|
|||||||
double doubleValue = ((Number)value).doubleValue();
|
double doubleValue = ((Number)value).doubleValue();
|
||||||
functionValuesMap.get(name).setValue(doubleValue);
|
functionValuesMap.get(name).setValue(doubleValue);
|
||||||
} else {
|
} else {
|
||||||
throw new ScriptException("Executable expressions scripts can only process numbers." +
|
throw new ScriptException("Error using " + compiledScript + ". " +
|
||||||
|
"Executable expressions scripts can only process numbers." +
|
||||||
" The variable [" + name + "] is not a number.");
|
" The variable [" + name + "] is not a number.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new ScriptException("The variable [" + name + "] does not exist in the executable expressions script.");
|
throw new ScriptException("Error using " + compiledScript + ". " +
|
||||||
|
"The variable [" + name + "] does not exist in the executable expressions script.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object run() {
|
public Object run() {
|
||||||
return expression.evaluate(NO_DOCUMENT, functionValuesArray);
|
try {
|
||||||
|
return ((Expression) compiledScript.compiled()).evaluate(NO_DOCUMENT, functionValuesArray);
|
||||||
|
} catch (Exception exception) {
|
||||||
|
throw new ScriptException("Error evaluating " + compiledScript, exception);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -38,6 +38,7 @@ import org.elasticsearch.index.mapper.core.NumberFieldMapper;
|
|||||||
import org.elasticsearch.script.CompiledScript;
|
import org.elasticsearch.script.CompiledScript;
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
import org.elasticsearch.script.ExecutableScript;
|
||||||
import org.elasticsearch.script.ScriptEngineService;
|
import org.elasticsearch.script.ScriptEngineService;
|
||||||
|
import org.elasticsearch.script.ScriptException;
|
||||||
import org.elasticsearch.script.SearchScript;
|
import org.elasticsearch.script.SearchScript;
|
||||||
import org.elasticsearch.search.MultiValueMode;
|
import org.elasticsearch.search.MultiValueMode;
|
||||||
import org.elasticsearch.search.lookup.SearchLookup;
|
import org.elasticsearch.search.lookup.SearchLookup;
|
||||||
@ -99,8 +100,9 @@ public class ExpressionScriptEngineService extends AbstractComponent implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SearchScript search(Object compiledScript, SearchLookup lookup, @Nullable Map<String, Object> vars) {
|
public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, @Nullable Map<String, Object> vars) {
|
||||||
Expression expr = (Expression)compiledScript;
|
try {
|
||||||
|
Expression expr = (Expression)compiledScript.compiled();
|
||||||
MapperService mapper = lookup.doc().mapperService();
|
MapperService mapper = lookup.doc().mapperService();
|
||||||
// NOTE: if we need to do anything complicated with bindings in the future, we can just extend Bindings,
|
// NOTE: if we need to do anything complicated with bindings in the future, we can just extend Bindings,
|
||||||
// instead of complicating SimpleBindings (which should stay simple)
|
// instead of complicating SimpleBindings (which should stay simple)
|
||||||
@ -124,7 +126,7 @@ public class ExpressionScriptEngineService extends AbstractComponent implements
|
|||||||
// but if we were to reverse it, we could provide a way to supply dynamic defaults for documents missing the field?
|
// but if we were to reverse it, we could provide a way to supply dynamic defaults for documents missing the field?
|
||||||
Object value = vars.get(variable);
|
Object value = vars.get(variable);
|
||||||
if (value instanceof Number) {
|
if (value instanceof Number) {
|
||||||
bindings.add(variable, new DoubleConstValueSource(((Number)value).doubleValue()));
|
bindings.add(variable, new DoubleConstValueSource(((Number) value).doubleValue()));
|
||||||
} else {
|
} else {
|
||||||
throw new ExpressionScriptCompilationException("Parameter [" + variable + "] must be a numeric type");
|
throw new ExpressionScriptCompilationException("Parameter [" + variable + "] must be a numeric type");
|
||||||
}
|
}
|
||||||
@ -162,7 +164,7 @@ public class ExpressionScriptEngineService extends AbstractComponent implements
|
|||||||
throw new ExpressionScriptCompilationException("Field [" + fieldname + "] used in expression must be numeric");
|
throw new ExpressionScriptCompilationException("Field [" + fieldname + "] used in expression must be numeric");
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexFieldData<?> fieldData = lookup.doc().fieldDataService().getForField((NumberFieldMapper.NumberFieldType)fieldType);
|
IndexFieldData<?> fieldData = lookup.doc().fieldDataService().getForField((NumberFieldMapper.NumberFieldType) fieldType);
|
||||||
if (methodname == null) {
|
if (methodname == null) {
|
||||||
bindings.add(variable, new FieldDataValueSource(fieldData, MultiValueMode.MIN));
|
bindings.add(variable, new FieldDataValueSource(fieldData, MultiValueMode.MIN));
|
||||||
} else {
|
} else {
|
||||||
@ -171,7 +173,10 @@ public class ExpressionScriptEngineService extends AbstractComponent implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ExpressionSearchScript((Expression)compiledScript, bindings, specialValue);
|
return new ExpressionSearchScript(compiledScript, bindings, specialValue);
|
||||||
|
} catch (Exception exception) {
|
||||||
|
throw new ScriptException("Error during search with " + compiledScript, exception);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ValueSource getMethodValueSource(MappedFieldType fieldType, IndexFieldData<?> fieldData, String fieldName, String methodName) {
|
protected ValueSource getMethodValueSource(MappedFieldType fieldType, IndexFieldData<?> fieldData, String fieldName, String methodName) {
|
||||||
@ -214,12 +219,12 @@ public class ExpressionScriptEngineService extends AbstractComponent implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExecutableScript executable(Object compiledScript, Map<String, Object> vars) {
|
public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> vars) {
|
||||||
return new ExpressionExecutableScript(compiledScript, vars);
|
return new ExpressionExecutableScript(compiledScript, vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object execute(Object compiledScript, Map<String, Object> vars) {
|
public Object execute(CompiledScript compiledScript, Map<String, Object> vars) {
|
||||||
ExpressionExecutableScript expressionExecutableScript = new ExpressionExecutableScript(compiledScript, vars);
|
ExpressionExecutableScript expressionExecutableScript = new ExpressionExecutableScript(compiledScript, vars);
|
||||||
return expressionExecutableScript.run();
|
return expressionExecutableScript.run();
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,9 @@ import org.apache.lucene.queries.function.FunctionValues;
|
|||||||
import org.apache.lucene.queries.function.ValueSource;
|
import org.apache.lucene.queries.function.ValueSource;
|
||||||
import org.apache.lucene.search.Scorer;
|
import org.apache.lucene.search.Scorer;
|
||||||
import org.elasticsearch.common.lucene.Lucene;
|
import org.elasticsearch.common.lucene.Lucene;
|
||||||
|
import org.elasticsearch.script.CompiledScript;
|
||||||
import org.elasticsearch.script.LeafSearchScript;
|
import org.elasticsearch.script.LeafSearchScript;
|
||||||
|
import org.elasticsearch.script.ScriptException;
|
||||||
import org.elasticsearch.script.SearchScript;
|
import org.elasticsearch.script.SearchScript;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -40,17 +42,17 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
class ExpressionSearchScript implements SearchScript {
|
class ExpressionSearchScript implements SearchScript {
|
||||||
|
|
||||||
final Expression expression;
|
final CompiledScript compiledScript;
|
||||||
final SimpleBindings bindings;
|
final SimpleBindings bindings;
|
||||||
final ValueSource source;
|
final ValueSource source;
|
||||||
final ReplaceableConstValueSource specialValue; // _value
|
final ReplaceableConstValueSource specialValue; // _value
|
||||||
Scorer scorer;
|
Scorer scorer;
|
||||||
int docid;
|
int docid;
|
||||||
|
|
||||||
ExpressionSearchScript(Expression e, SimpleBindings b, ReplaceableConstValueSource v) {
|
ExpressionSearchScript(CompiledScript c, SimpleBindings b, ReplaceableConstValueSource v) {
|
||||||
expression = e;
|
compiledScript = c;
|
||||||
bindings = b;
|
bindings = b;
|
||||||
source = expression.getValueSource(bindings);
|
source = ((Expression)compiledScript.compiled()).getValueSource(bindings);
|
||||||
specialValue = v;
|
specialValue = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +63,11 @@ class ExpressionSearchScript implements SearchScript {
|
|||||||
FunctionValues values = source.getValues(Collections.singletonMap("scorer", Lucene.illegalScorer("Scores are not available in the current context")), leaf);
|
FunctionValues values = source.getValues(Collections.singletonMap("scorer", Lucene.illegalScorer("Scores are not available in the current context")), leaf);
|
||||||
|
|
||||||
double evaluate() {
|
double evaluate() {
|
||||||
|
try {
|
||||||
return values.doubleVal(docid);
|
return values.doubleVal(docid);
|
||||||
|
} catch (Exception exception) {
|
||||||
|
throw new ScriptException("Error evaluating " + compiledScript, exception);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -91,7 +97,7 @@ class ExpressionSearchScript implements SearchScript {
|
|||||||
// We have a new binding for the scorer so we need to reset the values
|
// We have a new binding for the scorer so we need to reset the values
|
||||||
values = source.getValues(Collections.singletonMap("scorer", scorer), leaf);
|
values = source.getValues(Collections.singletonMap("scorer", scorer), leaf);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IllegalStateException("Can't get values", e);
|
throw new IllegalStateException("Can't get values using " + compiledScript, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +115,7 @@ class ExpressionSearchScript implements SearchScript {
|
|||||||
if (value instanceof Number) {
|
if (value instanceof Number) {
|
||||||
specialValue.setValue(((Number)value).doubleValue());
|
specialValue.setValue(((Number)value).doubleValue());
|
||||||
} else {
|
} else {
|
||||||
throw new ExpressionScriptExecutionException("Cannot use expression with text variable");
|
throw new ExpressionScriptExecutionException("Cannot use expression with text variable using " + compiledScript);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -135,21 +135,21 @@ public class GroovyScriptEngineService extends AbstractComponent implements Scri
|
|||||||
|
|
||||||
@SuppressWarnings({"unchecked"})
|
@SuppressWarnings({"unchecked"})
|
||||||
@Override
|
@Override
|
||||||
public ExecutableScript executable(Object compiledScript, Map<String, Object> vars) {
|
public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> vars) {
|
||||||
try {
|
try {
|
||||||
Map<String, Object> allVars = new HashMap<>();
|
Map<String, Object> allVars = new HashMap<>();
|
||||||
if (vars != null) {
|
if (vars != null) {
|
||||||
allVars.putAll(vars);
|
allVars.putAll(vars);
|
||||||
}
|
}
|
||||||
return new GroovyScript(createScript(compiledScript, allVars), this.logger);
|
return new GroovyScript(compiledScript, createScript(compiledScript.compiled(), allVars), this.logger);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ScriptException("failed to build executable script", e);
|
throw new ScriptException("failed to build executable " + compiledScript, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked"})
|
@SuppressWarnings({"unchecked"})
|
||||||
@Override
|
@Override
|
||||||
public SearchScript search(final Object compiledScript, final SearchLookup lookup, @Nullable final Map<String, Object> vars) {
|
public SearchScript search(final CompiledScript compiledScript, final SearchLookup lookup, @Nullable final Map<String, Object> vars) {
|
||||||
return new SearchScript() {
|
return new SearchScript() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -162,26 +162,26 @@ public class GroovyScriptEngineService extends AbstractComponent implements Scri
|
|||||||
}
|
}
|
||||||
Script scriptObject;
|
Script scriptObject;
|
||||||
try {
|
try {
|
||||||
scriptObject = createScript(compiledScript, allVars);
|
scriptObject = createScript(compiledScript.compiled(), allVars);
|
||||||
} catch (InstantiationException | IllegalAccessException e) {
|
} catch (InstantiationException | IllegalAccessException e) {
|
||||||
throw new ScriptException("failed to build search script", e);
|
throw new ScriptException("failed to build search " + compiledScript, e);
|
||||||
}
|
}
|
||||||
return new GroovyScript(scriptObject, leafLookup, logger);
|
return new GroovyScript(compiledScript, scriptObject, leafLookup, logger);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object execute(Object compiledScript, Map<String, Object> vars) {
|
public Object execute(CompiledScript compiledScript, Map<String, Object> vars) {
|
||||||
try {
|
try {
|
||||||
Map<String, Object> allVars = new HashMap<>();
|
Map<String, Object> allVars = new HashMap<>();
|
||||||
if (vars != null) {
|
if (vars != null) {
|
||||||
allVars.putAll(vars);
|
allVars.putAll(vars);
|
||||||
}
|
}
|
||||||
Script scriptObject = createScript(compiledScript, allVars);
|
Script scriptObject = createScript(compiledScript.compiled(), allVars);
|
||||||
return scriptObject.run();
|
return scriptObject.run();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ScriptException("failed to execute script", e);
|
throw new ScriptException("failed to execute " + compiledScript, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,17 +196,19 @@ public class GroovyScriptEngineService extends AbstractComponent implements Scri
|
|||||||
|
|
||||||
public static final class GroovyScript implements ExecutableScript, LeafSearchScript {
|
public static final class GroovyScript implements ExecutableScript, LeafSearchScript {
|
||||||
|
|
||||||
|
private final CompiledScript compiledScript;
|
||||||
private final Script script;
|
private final Script script;
|
||||||
private final LeafSearchLookup lookup;
|
private final LeafSearchLookup lookup;
|
||||||
private final Map<String, Object> variables;
|
private final Map<String, Object> variables;
|
||||||
private final ESLogger logger;
|
private final ESLogger logger;
|
||||||
|
|
||||||
public GroovyScript(Script script, ESLogger logger) {
|
public GroovyScript(CompiledScript compiledScript, Script script, ESLogger logger) {
|
||||||
this(script, null, logger);
|
this(compiledScript, script, null, logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public GroovyScript(Script script, @Nullable LeafSearchLookup lookup, ESLogger logger) {
|
public GroovyScript(CompiledScript compiledScript, Script script, @Nullable LeafSearchLookup lookup, ESLogger logger) {
|
||||||
|
this.compiledScript = compiledScript;
|
||||||
this.script = script;
|
this.script = script;
|
||||||
this.lookup = lookup;
|
this.lookup = lookup;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
@ -244,9 +246,9 @@ public class GroovyScriptEngineService extends AbstractComponent implements Scri
|
|||||||
return script.run();
|
return script.run();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("exception running Groovy script", e);
|
logger.trace("failed to run " + compiledScript, e);
|
||||||
}
|
}
|
||||||
throw new GroovyScriptExecutionException(ExceptionsHelper.detailedMessage(e));
|
throw new GroovyScriptExecutionException("failed to run " + compiledScript + ": " + ExceptionsHelper.detailedMessage(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
package org.elasticsearch.script.mustache;
|
package org.elasticsearch.script.mustache;
|
||||||
|
|
||||||
import com.github.mustachejava.Mustache;
|
import com.github.mustachejava.Mustache;
|
||||||
|
import org.elasticsearch.ExceptionsHelper;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
import org.elasticsearch.common.component.AbstractComponent;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
@ -29,6 +30,7 @@ import org.elasticsearch.common.settings.Settings;
|
|||||||
import org.elasticsearch.script.CompiledScript;
|
import org.elasticsearch.script.CompiledScript;
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
import org.elasticsearch.script.ExecutableScript;
|
||||||
import org.elasticsearch.script.ScriptEngineService;
|
import org.elasticsearch.script.ScriptEngineService;
|
||||||
|
import org.elasticsearch.script.ScriptException;
|
||||||
import org.elasticsearch.script.SearchScript;
|
import org.elasticsearch.script.SearchScript;
|
||||||
import org.elasticsearch.search.lookup.SearchLookup;
|
import org.elasticsearch.search.lookup.SearchLookup;
|
||||||
|
|
||||||
@ -98,20 +100,13 @@ public class MustacheScriptEngineService extends AbstractComponent implements Sc
|
|||||||
* @return the processed string with all given variables substitued.
|
* @return the processed string with all given variables substitued.
|
||||||
* */
|
* */
|
||||||
@Override
|
@Override
|
||||||
public Object execute(Object template, Map<String, Object> vars) {
|
public Object execute(CompiledScript template, Map<String, Object> vars) {
|
||||||
BytesStreamOutput result = new BytesStreamOutput();
|
BytesStreamOutput result = new BytesStreamOutput();
|
||||||
UTF8StreamWriter writer = utf8StreamWriter().setOutput(result);
|
try (UTF8StreamWriter writer = utf8StreamWriter().setOutput(result)) {
|
||||||
((Mustache) template).execute(writer, vars);
|
((Mustache) template.compiled()).execute(writer, vars);
|
||||||
try {
|
} catch (Exception e) {
|
||||||
writer.flush();
|
logger.error("Error executing " + template, e);
|
||||||
} catch (IOException e) {
|
throw new ScriptException("Error executing " + template, e);
|
||||||
logger.error("Could not execute query template (failed to flush writer): ", e);
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
writer.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.error("Could not execute query template (failed to close writer): ", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result.bytes();
|
return result.bytes();
|
||||||
}
|
}
|
||||||
@ -132,13 +127,13 @@ public class MustacheScriptEngineService extends AbstractComponent implements Sc
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExecutableScript executable(Object mustache,
|
public ExecutableScript executable(CompiledScript compiledScript,
|
||||||
@Nullable Map<String, Object> vars) {
|
@Nullable Map<String, Object> vars) {
|
||||||
return new MustacheExecutableScript((Mustache) mustache, vars);
|
return new MustacheExecutableScript(compiledScript, vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SearchScript search(Object compiledScript, SearchLookup lookup,
|
public SearchScript search(CompiledScript compiledScript, SearchLookup lookup,
|
||||||
@Nullable Map<String, Object> vars) {
|
@Nullable Map<String, Object> vars) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
@ -162,18 +157,17 @@ public class MustacheScriptEngineService extends AbstractComponent implements Sc
|
|||||||
* Used at query execution time by script service in order to execute a query template.
|
* Used at query execution time by script service in order to execute a query template.
|
||||||
* */
|
* */
|
||||||
private class MustacheExecutableScript implements ExecutableScript {
|
private class MustacheExecutableScript implements ExecutableScript {
|
||||||
/** Compiled template object. */
|
/** Compiled template object wrapper. */
|
||||||
private Mustache mustache;
|
private CompiledScript template;
|
||||||
/** Parameters to fill above object with. */
|
/** Parameters to fill above object with. */
|
||||||
private Map<String, Object> vars;
|
private Map<String, Object> vars;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mustache the compiled template object
|
* @param template the compiled template object wrapper
|
||||||
* @param vars the parameters to fill above object with
|
* @param vars the parameters to fill above object with
|
||||||
**/
|
**/
|
||||||
public MustacheExecutableScript(Mustache mustache,
|
public MustacheExecutableScript(CompiledScript template, Map<String, Object> vars) {
|
||||||
Map<String, Object> vars) {
|
this.template = template;
|
||||||
this.mustache = mustache;
|
|
||||||
this.vars = vars == null ? Collections.<String, Object>emptyMap() : vars;
|
this.vars = vars == null ? Collections.<String, Object>emptyMap() : vars;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,18 +179,11 @@ public class MustacheScriptEngineService extends AbstractComponent implements Sc
|
|||||||
@Override
|
@Override
|
||||||
public Object run() {
|
public Object run() {
|
||||||
BytesStreamOutput result = new BytesStreamOutput();
|
BytesStreamOutput result = new BytesStreamOutput();
|
||||||
UTF8StreamWriter writer = utf8StreamWriter().setOutput(result);
|
try (UTF8StreamWriter writer = utf8StreamWriter().setOutput(result)) {
|
||||||
mustache.execute(writer, vars);
|
((Mustache) template.compiled()).execute(writer, vars);
|
||||||
try {
|
} catch (Exception e) {
|
||||||
writer.flush();
|
logger.error("Error running " + template, e);
|
||||||
} catch (IOException e) {
|
throw new ScriptException("Error running " + template, e);
|
||||||
logger.error("Could not execute query template (failed to flush writer): ", e);
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
writer.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.error("Could not execute query template (failed to close writer): ", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result.bytes();
|
return result.bytes();
|
||||||
}
|
}
|
||||||
|
@ -287,17 +287,17 @@ public class ScriptModesTests extends ElasticsearchTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExecutableScript executable(Object compiledScript, @Nullable Map<String, Object> vars) {
|
public ExecutableScript executable(CompiledScript compiledScript, @Nullable Map<String, Object> vars) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SearchScript search(Object compiledScript, SearchLookup lookup, @Nullable Map<String, Object> vars) {
|
public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, @Nullable Map<String, Object> vars) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object execute(Object compiledScript, Map<String, Object> vars) {
|
public Object execute(CompiledScript compiledScript, Map<String, Object> vars) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ public class ScriptServiceTests extends ElasticsearchTestCase {
|
|||||||
scriptService.compile(new Script("test_script", ScriptType.FILE, "test", null), ScriptContext.Standard.SEARCH);
|
scriptService.compile(new Script("test_script", ScriptType.FILE, "test", null), ScriptContext.Standard.SEARCH);
|
||||||
fail("the script test_script should no longer exist");
|
fail("the script test_script should no longer exist");
|
||||||
} catch (IllegalArgumentException ex) {
|
} catch (IllegalArgumentException ex) {
|
||||||
assertThat(ex.getMessage(), containsString("Unable to find on disk script test_script"));
|
assertThat(ex.getMessage(), containsString("Unable to find on disk file script [test_script] using lang [test]"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +171,7 @@ public class ScriptServiceTests extends ElasticsearchTestCase {
|
|||||||
randomFrom(scriptContexts));
|
randomFrom(scriptContexts));
|
||||||
CompiledScript compiledScript2 = scriptService.compile(new Script("1+1", ScriptType.INLINE, "test", null),
|
CompiledScript compiledScript2 = scriptService.compile(new Script("1+1", ScriptType.INLINE, "test", null),
|
||||||
randomFrom(scriptContexts));
|
randomFrom(scriptContexts));
|
||||||
assertThat(compiledScript1, sameInstance(compiledScript2));
|
assertThat(compiledScript1.compiled(), sameInstance(compiledScript2.compiled()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -181,7 +181,7 @@ public class ScriptServiceTests extends ElasticsearchTestCase {
|
|||||||
randomFrom(scriptContexts));
|
randomFrom(scriptContexts));
|
||||||
CompiledScript compiledScript2 = scriptService.compile(new Script("script", ScriptType.INLINE, "test2", null),
|
CompiledScript compiledScript2 = scriptService.compile(new Script("script", ScriptType.INLINE, "test2", null),
|
||||||
randomFrom(scriptContexts));
|
randomFrom(scriptContexts));
|
||||||
assertThat(compiledScript1, sameInstance(compiledScript2));
|
assertThat(compiledScript1.compiled(), sameInstance(compiledScript2.compiled()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -192,7 +192,7 @@ public class ScriptServiceTests extends ElasticsearchTestCase {
|
|||||||
randomFrom(scriptContexts));
|
randomFrom(scriptContexts));
|
||||||
CompiledScript compiledScript2 = scriptService.compile(new Script("file_script", ScriptType.FILE, "test2", null),
|
CompiledScript compiledScript2 = scriptService.compile(new Script("file_script", ScriptType.FILE, "test2", null),
|
||||||
randomFrom(scriptContexts));
|
randomFrom(scriptContexts));
|
||||||
assertThat(compiledScript1, sameInstance(compiledScript2));
|
assertThat(compiledScript1.compiled(), sameInstance(compiledScript2.compiled()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -431,17 +431,17 @@ public class ScriptServiceTests extends ElasticsearchTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExecutableScript executable(final Object compiledScript, @Nullable Map<String, Object> vars) {
|
public ExecutableScript executable(final CompiledScript compiledScript, @Nullable Map<String, Object> vars) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SearchScript search(Object compiledScript, SearchLookup lookup, @Nullable Map<String, Object> vars) {
|
public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, @Nullable Map<String, Object> vars) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object execute(Object compiledScript, Map<String, Object> vars) {
|
public Object execute(CompiledScript compiledScript, Map<String, Object> vars) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,9 +29,11 @@ import org.elasticsearch.action.search.SearchType;
|
|||||||
import org.elasticsearch.action.update.UpdateRequestBuilder;
|
import org.elasticsearch.action.update.UpdateRequestBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||||
|
import org.elasticsearch.index.engine.Engine;
|
||||||
import org.elasticsearch.index.query.QueryBuilders;
|
import org.elasticsearch.index.query.QueryBuilders;
|
||||||
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilder;
|
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilder;
|
||||||
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
|
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
|
||||||
|
import org.elasticsearch.script.CompiledScript;
|
||||||
import org.elasticsearch.script.Script;
|
import org.elasticsearch.script.Script;
|
||||||
import org.elasticsearch.script.ScriptException;
|
import org.elasticsearch.script.ScriptException;
|
||||||
import org.elasticsearch.script.ScriptService.ScriptType;
|
import org.elasticsearch.script.ScriptService.ScriptType;
|
||||||
@ -414,8 +416,9 @@ public class ExpressionScriptTests extends ElasticsearchIntegrationTest {
|
|||||||
vars.put("xyz", -1);
|
vars.put("xyz", -1);
|
||||||
|
|
||||||
Expression expr = JavascriptCompiler.compile("a+b+xyz");
|
Expression expr = JavascriptCompiler.compile("a+b+xyz");
|
||||||
|
CompiledScript compiledScript = new CompiledScript(ScriptType.INLINE, "", "expression", expr);
|
||||||
|
|
||||||
ExpressionExecutableScript ees = new ExpressionExecutableScript(expr, vars);
|
ExpressionExecutableScript ees = new ExpressionExecutableScript(compiledScript, vars);
|
||||||
assertEquals((Double) ees.run(), 4.5, 0.001);
|
assertEquals((Double) ees.run(), 4.5, 0.001);
|
||||||
|
|
||||||
ees.setNextVar("b", -2.5);
|
ees.setNextVar("b", -2.5);
|
||||||
@ -431,7 +434,7 @@ public class ExpressionScriptTests extends ElasticsearchIntegrationTest {
|
|||||||
try {
|
try {
|
||||||
vars = new HashMap<>();
|
vars = new HashMap<>();
|
||||||
vars.put("a", 1);
|
vars.put("a", 1);
|
||||||
ees = new ExpressionExecutableScript(expr, vars);
|
ees = new ExpressionExecutableScript(compiledScript, vars);
|
||||||
ees.run();
|
ees.run();
|
||||||
fail("An incorrect number of variables were allowed to be used in an expression.");
|
fail("An incorrect number of variables were allowed to be used in an expression.");
|
||||||
} catch (ScriptException se) {
|
} catch (ScriptException se) {
|
||||||
@ -444,7 +447,7 @@ public class ExpressionScriptTests extends ElasticsearchIntegrationTest {
|
|||||||
vars.put("a", 1);
|
vars.put("a", 1);
|
||||||
vars.put("b", 3);
|
vars.put("b", 3);
|
||||||
vars.put("c", -1);
|
vars.put("c", -1);
|
||||||
ees = new ExpressionExecutableScript(expr, vars);
|
ees = new ExpressionExecutableScript(compiledScript, vars);
|
||||||
ees.run();
|
ees.run();
|
||||||
fail("A variable was allowed to be set that does not exist in the expression.");
|
fail("A variable was allowed to be set that does not exist in the expression.");
|
||||||
} catch (ScriptException se) {
|
} catch (ScriptException se) {
|
||||||
@ -457,7 +460,7 @@ public class ExpressionScriptTests extends ElasticsearchIntegrationTest {
|
|||||||
vars.put("a", 1);
|
vars.put("a", 1);
|
||||||
vars.put("b", 3);
|
vars.put("b", 3);
|
||||||
vars.put("xyz", "hello");
|
vars.put("xyz", "hello");
|
||||||
ees = new ExpressionExecutableScript(expr, vars);
|
ees = new ExpressionExecutableScript(compiledScript, vars);
|
||||||
ees.run();
|
ees.run();
|
||||||
fail("A non-number was allowed to be use in the expression.");
|
fail("A non-number was allowed to be use in the expression.");
|
||||||
} catch (ScriptException se) {
|
} catch (ScriptException se) {
|
||||||
|
@ -20,6 +20,8 @@ package org.elasticsearch.script.mustache;
|
|||||||
|
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
import org.elasticsearch.common.bytes.BytesReference;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.script.CompiledScript;
|
||||||
|
import org.elasticsearch.script.ScriptService;
|
||||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -52,7 +54,7 @@ public class MustacheScriptEngineTest extends ElasticsearchTestCase {
|
|||||||
+ "\"negative\": {\"term\": {\"body\": {\"value\": \"solr\"}" + "}}, \"negative_boost\": {{boost_val}} } }}";
|
+ "\"negative\": {\"term\": {\"body\": {\"value\": \"solr\"}" + "}}, \"negative_boost\": {{boost_val}} } }}";
|
||||||
Map<String, Object> vars = new HashMap<>();
|
Map<String, Object> vars = new HashMap<>();
|
||||||
vars.put("boost_val", "0.3");
|
vars.put("boost_val", "0.3");
|
||||||
BytesReference o = (BytesReference) qe.execute(qe.compile(template), vars);
|
BytesReference o = (BytesReference) qe.execute(new CompiledScript(ScriptService.ScriptType.INLINE, "", "mustache", qe.compile(template)), vars);
|
||||||
assertEquals("GET _search {\"query\": {\"boosting\": {\"positive\": {\"match\": {\"body\": \"gift\"}},"
|
assertEquals("GET _search {\"query\": {\"boosting\": {\"positive\": {\"match\": {\"body\": \"gift\"}},"
|
||||||
+ "\"negative\": {\"term\": {\"body\": {\"value\": \"solr\"}}}, \"negative_boost\": 0.3 } }}",
|
+ "\"negative\": {\"term\": {\"body\": {\"value\": \"solr\"}}}, \"negative_boost\": 0.3 } }}",
|
||||||
new String(o.toBytes(), Charset.forName("UTF-8")));
|
new String(o.toBytes(), Charset.forName("UTF-8")));
|
||||||
@ -63,7 +65,7 @@ public class MustacheScriptEngineTest extends ElasticsearchTestCase {
|
|||||||
Map<String, Object> vars = new HashMap<>();
|
Map<String, Object> vars = new HashMap<>();
|
||||||
vars.put("boost_val", "0.3");
|
vars.put("boost_val", "0.3");
|
||||||
vars.put("body_val", "\"quick brown\"");
|
vars.put("body_val", "\"quick brown\"");
|
||||||
BytesReference o = (BytesReference) qe.execute(qe.compile(template), vars);
|
BytesReference o = (BytesReference) qe.execute(new CompiledScript(ScriptService.ScriptType.INLINE, "", "mustache", qe.compile(template)), vars);
|
||||||
assertEquals("GET _search {\"query\": {\"boosting\": {\"positive\": {\"match\": {\"body\": \"gift\"}},"
|
assertEquals("GET _search {\"query\": {\"boosting\": {\"positive\": {\"match\": {\"body\": \"gift\"}},"
|
||||||
+ "\"negative\": {\"term\": {\"body\": {\"value\": \"\\\"quick brown\\\"\"}}}, \"negative_boost\": 0.3 } }}",
|
+ "\"negative\": {\"term\": {\"body\": {\"value\": \"\\\"quick brown\\\"\"}}}, \"negative_boost\": 0.3 } }}",
|
||||||
new String(o.toBytes(), Charset.forName("UTF-8")));
|
new String(o.toBytes(), Charset.forName("UTF-8")));
|
||||||
|
@ -105,7 +105,7 @@ public class JavaScriptScriptEngineService extends AbstractComponent implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExecutableScript executable(Object compiledScript, Map<String, Object> vars) {
|
public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> vars) {
|
||||||
Context ctx = Context.enter();
|
Context ctx = Context.enter();
|
||||||
try {
|
try {
|
||||||
ctx.setWrapFactory(wrapFactory);
|
ctx.setWrapFactory(wrapFactory);
|
||||||
@ -117,14 +117,14 @@ public class JavaScriptScriptEngineService extends AbstractComponent implements
|
|||||||
ScriptableObject.putProperty(scope, entry.getKey(), entry.getValue());
|
ScriptableObject.putProperty(scope, entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new JavaScriptExecutableScript((Script) compiledScript, scope);
|
return new JavaScriptExecutableScript((Script) compiledScript.compiled(), scope);
|
||||||
} finally {
|
} finally {
|
||||||
Context.exit();
|
Context.exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SearchScript search(final Object compiledScript, final SearchLookup lookup, @Nullable final Map<String, Object> vars) {
|
public SearchScript search(final CompiledScript compiledScript, final SearchLookup lookup, @Nullable final Map<String, Object> vars) {
|
||||||
Context ctx = Context.enter();
|
Context ctx = Context.enter();
|
||||||
try {
|
try {
|
||||||
ctx.setWrapFactory(wrapFactory);
|
ctx.setWrapFactory(wrapFactory);
|
||||||
@ -148,7 +148,7 @@ public class JavaScriptScriptEngineService extends AbstractComponent implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new JavaScriptSearchScript((Script) compiledScript, scope, leafLookup);
|
return new JavaScriptSearchScript((Script) compiledScript.compiled(), scope, leafLookup);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} finally {
|
} finally {
|
||||||
@ -157,11 +157,11 @@ public class JavaScriptScriptEngineService extends AbstractComponent implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object execute(Object compiledScript, Map<String, Object> vars) {
|
public Object execute(CompiledScript compiledScript, Map<String, Object> vars) {
|
||||||
Context ctx = Context.enter();
|
Context ctx = Context.enter();
|
||||||
ctx.setWrapFactory(wrapFactory);
|
ctx.setWrapFactory(wrapFactory);
|
||||||
try {
|
try {
|
||||||
Script script = (Script) compiledScript;
|
Script script = (Script) compiledScript.compiled();
|
||||||
Scriptable scope = ctx.newObject(globalScope);
|
Scriptable scope = ctx.newObject(globalScope);
|
||||||
scope.setPrototype(globalScope);
|
scope.setPrototype(globalScope);
|
||||||
scope.setParentScope(null);
|
scope.setParentScope(null);
|
||||||
|
@ -21,7 +21,9 @@ package org.elasticsearch.script.javascript;
|
|||||||
|
|
||||||
import org.elasticsearch.common.collect.MapBuilder;
|
import org.elasticsearch.common.collect.MapBuilder;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.script.CompiledScript;
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
import org.elasticsearch.script.ExecutableScript;
|
||||||
|
import org.elasticsearch.script.ScriptService;
|
||||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@ -55,7 +57,7 @@ public class JavaScriptScriptEngineTests extends ElasticsearchTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testSimpleEquation() {
|
public void testSimpleEquation() {
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
Map<String, Object> vars = new HashMap<String, Object>();
|
||||||
Object o = se.execute(se.compile("1 + 2"), vars);
|
Object o = se.execute(new CompiledScript(ScriptService.ScriptType.INLINE, "testSimpleEquation", "js", se.compile("1 + 2")), vars);
|
||||||
assertThat(((Number) o).intValue(), equalTo(3));
|
assertThat(((Number) o).intValue(), equalTo(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,20 +68,21 @@ public class JavaScriptScriptEngineTests extends ElasticsearchTestCase {
|
|||||||
Map<String, Object> obj2 = MapBuilder.<String, Object>newMapBuilder().put("prop2", "value2").map();
|
Map<String, Object> obj2 = MapBuilder.<String, Object>newMapBuilder().put("prop2", "value2").map();
|
||||||
Map<String, Object> obj1 = MapBuilder.<String, Object>newMapBuilder().put("prop1", "value1").put("obj2", obj2).put("l", Arrays.asList("2", "1")).map();
|
Map<String, Object> obj1 = MapBuilder.<String, Object>newMapBuilder().put("prop1", "value1").put("obj2", obj2).put("l", Arrays.asList("2", "1")).map();
|
||||||
vars.put("obj1", obj1);
|
vars.put("obj1", obj1);
|
||||||
Object o = se.execute(se.compile("obj1"), vars);
|
Object o = se.execute(new CompiledScript(ScriptService.ScriptType.INLINE, "testMapAccess", "js", se.compile("obj1")), vars);
|
||||||
assertThat(o, instanceOf(Map.class));
|
assertThat(o, instanceOf(Map.class));
|
||||||
obj1 = (Map<String, Object>) o;
|
obj1 = (Map<String, Object>) o;
|
||||||
assertThat((String) obj1.get("prop1"), equalTo("value1"));
|
assertThat((String) obj1.get("prop1"), equalTo("value1"));
|
||||||
assertThat((String) ((Map<String, Object>) obj1.get("obj2")).get("prop2"), equalTo("value2"));
|
assertThat((String) ((Map<String, Object>) obj1.get("obj2")).get("prop2"), equalTo("value2"));
|
||||||
|
|
||||||
o = se.execute(se.compile("obj1.l[0]"), vars);
|
o = se.execute(new CompiledScript(ScriptService.ScriptType.INLINE, "testMapAccess", "js", se.compile("obj1.l[0]")), vars);
|
||||||
assertThat(((String) o), equalTo("2"));
|
assertThat(((String) o), equalTo("2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testJavaScriptObjectToMap() {
|
public void testJavaScriptObjectToMap() {
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
Map<String, Object> vars = new HashMap<String, Object>();
|
||||||
Object o = se.execute(se.compile("var obj1 = {}; obj1.prop1 = 'value1'; obj1.obj2 = {}; obj1.obj2.prop2 = 'value2'; obj1"), vars);
|
Object o = se.execute(new CompiledScript(ScriptService.ScriptType.INLINE, "testJavaScriptObjectToMap", "js",
|
||||||
|
se.compile("var obj1 = {}; obj1.prop1 = 'value1'; obj1.obj2 = {}; obj1.obj2.prop2 = 'value2'; obj1")), vars);
|
||||||
Map obj1 = (Map) o;
|
Map obj1 = (Map) o;
|
||||||
assertThat((String) obj1.get("prop1"), equalTo("value1"));
|
assertThat((String) obj1.get("prop1"), equalTo("value1"));
|
||||||
assertThat((String) ((Map<String, Object>) obj1.get("obj2")).get("prop2"), equalTo("value2"));
|
assertThat((String) ((Map<String, Object>) obj1.get("obj2")).get("prop2"), equalTo("value2"));
|
||||||
@ -94,7 +97,8 @@ public class JavaScriptScriptEngineTests extends ElasticsearchTestCase {
|
|||||||
ctx.put("obj1", obj1);
|
ctx.put("obj1", obj1);
|
||||||
vars.put("ctx", ctx);
|
vars.put("ctx", ctx);
|
||||||
|
|
||||||
se.execute(se.compile("ctx.obj2 = {}; ctx.obj2.prop2 = 'value2'; ctx.obj1.prop1 = 'uvalue1'"), vars);
|
se.execute(new CompiledScript(ScriptService.ScriptType.INLINE, "testJavaScriptObjectMapInter", "js",
|
||||||
|
se.compile("ctx.obj2 = {}; ctx.obj2.prop2 = 'value2'; ctx.obj1.prop1 = 'uvalue1'")), vars);
|
||||||
ctx = (Map<String, Object>) se.unwrap(vars.get("ctx"));
|
ctx = (Map<String, Object>) se.unwrap(vars.get("ctx"));
|
||||||
assertThat(ctx.containsKey("obj1"), equalTo(true));
|
assertThat(ctx.containsKey("obj1"), equalTo(true));
|
||||||
assertThat((String) ((Map<String, Object>) ctx.get("obj1")).get("prop1"), equalTo("uvalue1"));
|
assertThat((String) ((Map<String, Object>) ctx.get("obj1")).get("prop1"), equalTo("uvalue1"));
|
||||||
@ -108,8 +112,9 @@ public class JavaScriptScriptEngineTests extends ElasticsearchTestCase {
|
|||||||
Map<String, Object> doc = new HashMap<String, Object>();
|
Map<String, Object> doc = new HashMap<String, Object>();
|
||||||
ctx.put("doc", doc);
|
ctx.put("doc", doc);
|
||||||
|
|
||||||
Object complied = se.compile("ctx.doc.field1 = ['value1', 'value2']");
|
Object compiled = se.compile("ctx.doc.field1 = ['value1', 'value2']");
|
||||||
ExecutableScript script = se.executable(complied, new HashMap<String, Object>());
|
ExecutableScript script = se.executable(new CompiledScript(ScriptService.ScriptType.INLINE, "testJavaScriptInnerArrayCreation", "js",
|
||||||
|
compiled), new HashMap<String, Object>());
|
||||||
script.setNextVar("ctx", ctx);
|
script.setNextVar("ctx", ctx);
|
||||||
script.run();
|
script.run();
|
||||||
|
|
||||||
@ -125,18 +130,22 @@ public class JavaScriptScriptEngineTests extends ElasticsearchTestCase {
|
|||||||
Map<String, Object> obj1 = MapBuilder.<String, Object>newMapBuilder().put("prop1", "value1").put("obj2", obj2).map();
|
Map<String, Object> obj1 = MapBuilder.<String, Object>newMapBuilder().put("prop1", "value1").put("obj2", obj2).map();
|
||||||
vars.put("l", Arrays.asList("1", "2", "3", obj1));
|
vars.put("l", Arrays.asList("1", "2", "3", obj1));
|
||||||
|
|
||||||
Object o = se.execute(se.compile("l.length"), vars);
|
Object o = se.execute(new CompiledScript(ScriptService.ScriptType.INLINE, "testAccessInScript", "js",
|
||||||
|
se.compile("l.length")), vars);
|
||||||
assertThat(((Number) o).intValue(), equalTo(4));
|
assertThat(((Number) o).intValue(), equalTo(4));
|
||||||
|
|
||||||
o = se.execute(se.compile("l[0]"), vars);
|
o = se.execute(new CompiledScript(ScriptService.ScriptType.INLINE, "testAccessInScript", "js",
|
||||||
|
se.compile("l[0]")), vars);
|
||||||
assertThat(((String) o), equalTo("1"));
|
assertThat(((String) o), equalTo("1"));
|
||||||
|
|
||||||
o = se.execute(se.compile("l[3]"), vars);
|
o = se.execute(new CompiledScript(ScriptService.ScriptType.INLINE, "testAccessInScript", "js",
|
||||||
|
se.compile("l[3]")), vars);
|
||||||
obj1 = (Map<String, Object>) o;
|
obj1 = (Map<String, Object>) o;
|
||||||
assertThat((String) obj1.get("prop1"), equalTo("value1"));
|
assertThat((String) obj1.get("prop1"), equalTo("value1"));
|
||||||
assertThat((String) ((Map<String, Object>) obj1.get("obj2")).get("prop2"), equalTo("value2"));
|
assertThat((String) ((Map<String, Object>) obj1.get("obj2")).get("prop2"), equalTo("value2"));
|
||||||
|
|
||||||
o = se.execute(se.compile("l[3].prop1"), vars);
|
o = se.execute(new CompiledScript(ScriptService.ScriptType.INLINE, "testAccessInScript", "js",
|
||||||
|
se.compile("l[3].prop1")), vars);
|
||||||
assertThat(((String) o), equalTo("value1"));
|
assertThat(((String) o), equalTo("value1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +156,8 @@ public class JavaScriptScriptEngineTests extends ElasticsearchTestCase {
|
|||||||
vars.put("ctx", ctx);
|
vars.put("ctx", ctx);
|
||||||
Object compiledScript = se.compile("ctx.value");
|
Object compiledScript = se.compile("ctx.value");
|
||||||
|
|
||||||
ExecutableScript script = se.executable(compiledScript, vars);
|
ExecutableScript script = se.executable(new CompiledScript(ScriptService.ScriptType.INLINE, "testChangingVarsCrossExecution1", "js",
|
||||||
|
compiledScript), vars);
|
||||||
ctx.put("value", 1);
|
ctx.put("value", 1);
|
||||||
Object o = script.run();
|
Object o = script.run();
|
||||||
assertThat(((Number) o).intValue(), equalTo(1));
|
assertThat(((Number) o).intValue(), equalTo(1));
|
||||||
@ -162,7 +172,8 @@ public class JavaScriptScriptEngineTests extends ElasticsearchTestCase {
|
|||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
Map<String, Object> vars = new HashMap<String, Object>();
|
||||||
Object compiledScript = se.compile("value");
|
Object compiledScript = se.compile("value");
|
||||||
|
|
||||||
ExecutableScript script = se.executable(compiledScript, vars);
|
ExecutableScript script = se.executable(new CompiledScript(ScriptService.ScriptType.INLINE, "testChangingVarsCrossExecution2", "js",
|
||||||
|
compiledScript), vars);
|
||||||
script.setNextVar("value", 1);
|
script.setNextVar("value", 1);
|
||||||
Object o = script.run();
|
Object o = script.run();
|
||||||
assertThat(((Number) o).intValue(), equalTo(1));
|
assertThat(((Number) o).intValue(), equalTo(1));
|
||||||
|
@ -20,7 +20,9 @@
|
|||||||
package org.elasticsearch.script.javascript;
|
package org.elasticsearch.script.javascript;
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.script.CompiledScript;
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
import org.elasticsearch.script.ExecutableScript;
|
||||||
|
import org.elasticsearch.script.ScriptService;
|
||||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ -59,7 +61,7 @@ public class JavaScriptScriptMultiThreadedTest extends ElasticsearchTestCase {
|
|||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
Map<String, Object> vars = new HashMap<String, Object>();
|
||||||
vars.put("x", x);
|
vars.put("x", x);
|
||||||
vars.put("y", y);
|
vars.put("y", y);
|
||||||
ExecutableScript script = se.executable(compiled, vars);
|
ExecutableScript script = se.executable(new CompiledScript(ScriptService.ScriptType.INLINE, "testExecutableNoRuntimeParams", "js", compiled), vars);
|
||||||
for (int i = 0; i < 100000; i++) {
|
for (int i = 0; i < 100000; i++) {
|
||||||
long result = ((Number) script.run()).longValue();
|
long result = ((Number) script.run()).longValue();
|
||||||
assertThat(result, equalTo(addition));
|
assertThat(result, equalTo(addition));
|
||||||
@ -100,7 +102,7 @@ public class JavaScriptScriptMultiThreadedTest extends ElasticsearchTestCase {
|
|||||||
long x = ThreadLocalRandom.current().nextInt();
|
long x = ThreadLocalRandom.current().nextInt();
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
Map<String, Object> vars = new HashMap<String, Object>();
|
||||||
vars.put("x", x);
|
vars.put("x", x);
|
||||||
ExecutableScript script = se.executable(compiled, vars);
|
ExecutableScript script = se.executable(new CompiledScript(ScriptService.ScriptType.INLINE, "testExecutableNoRuntimeParams", "js", compiled), vars);
|
||||||
for (int i = 0; i < 100000; i++) {
|
for (int i = 0; i < 100000; i++) {
|
||||||
long y = ThreadLocalRandom.current().nextInt();
|
long y = ThreadLocalRandom.current().nextInt();
|
||||||
long addition = x + y;
|
long addition = x + y;
|
||||||
@ -147,7 +149,7 @@ public class JavaScriptScriptMultiThreadedTest extends ElasticsearchTestCase {
|
|||||||
long addition = x + y;
|
long addition = x + y;
|
||||||
runtimeVars.put("x", x);
|
runtimeVars.put("x", x);
|
||||||
runtimeVars.put("y", y);
|
runtimeVars.put("y", y);
|
||||||
long result = ((Number) se.execute(compiled, runtimeVars)).longValue();
|
long result = ((Number) se.execute(new CompiledScript(ScriptService.ScriptType.INLINE, "testExecutableNoRuntimeParams", "js", compiled), runtimeVars)).longValue();
|
||||||
assertThat(result, equalTo(addition));
|
assertThat(result, equalTo(addition));
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
@ -21,7 +21,9 @@ package org.elasticsearch.script.javascript;
|
|||||||
|
|
||||||
import org.elasticsearch.common.StopWatch;
|
import org.elasticsearch.common.StopWatch;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.script.CompiledScript;
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
import org.elasticsearch.script.ExecutableScript;
|
||||||
|
import org.elasticsearch.script.ScriptService;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -34,32 +36,33 @@ public class SimpleBench {
|
|||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
JavaScriptScriptEngineService se = new JavaScriptScriptEngineService(Settings.Builder.EMPTY_SETTINGS);
|
JavaScriptScriptEngineService se = new JavaScriptScriptEngineService(Settings.Builder.EMPTY_SETTINGS);
|
||||||
Object compiled = se.compile("x + y");
|
Object compiled = se.compile("x + y");
|
||||||
|
CompiledScript compiledScript = new CompiledScript(ScriptService.ScriptType.INLINE, "testExecutableNoRuntimeParams", "js", compiled);
|
||||||
|
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
Map<String, Object> vars = new HashMap<String, Object>();
|
||||||
// warm up
|
// warm up
|
||||||
for (int i = 0; i < 1000; i++) {
|
for (int i = 0; i < 1000; i++) {
|
||||||
vars.put("x", i);
|
vars.put("x", i);
|
||||||
vars.put("y", i + 1);
|
vars.put("y", i + 1);
|
||||||
se.execute(compiled, vars);
|
se.execute(compiledScript, vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
final long ITER = 100000;
|
final long ITER = 100000;
|
||||||
|
|
||||||
StopWatch stopWatch = new StopWatch().start();
|
StopWatch stopWatch = new StopWatch().start();
|
||||||
for (long i = 0; i < ITER; i++) {
|
for (long i = 0; i < ITER; i++) {
|
||||||
se.execute(compiled, vars);
|
se.execute(compiledScript, vars);
|
||||||
}
|
}
|
||||||
System.out.println("Execute Took: " + stopWatch.stop().lastTaskTime());
|
System.out.println("Execute Took: " + stopWatch.stop().lastTaskTime());
|
||||||
|
|
||||||
stopWatch = new StopWatch().start();
|
stopWatch = new StopWatch().start();
|
||||||
ExecutableScript executableScript = se.executable(compiled, vars);
|
ExecutableScript executableScript = se.executable(compiledScript, vars);
|
||||||
for (long i = 0; i < ITER; i++) {
|
for (long i = 0; i < ITER; i++) {
|
||||||
executableScript.run();
|
executableScript.run();
|
||||||
}
|
}
|
||||||
System.out.println("Executable Took: " + stopWatch.stop().lastTaskTime());
|
System.out.println("Executable Took: " + stopWatch.stop().lastTaskTime());
|
||||||
|
|
||||||
stopWatch = new StopWatch().start();
|
stopWatch = new StopWatch().start();
|
||||||
executableScript = se.executable(compiled, vars);
|
executableScript = se.executable(compiledScript, vars);
|
||||||
for (long i = 0; i < ITER; i++) {
|
for (long i = 0; i < ITER; i++) {
|
||||||
for (Map.Entry<String, Object> entry : vars.entrySet()) {
|
for (Map.Entry<String, Object> entry : vars.entrySet()) {
|
||||||
executableScript.setNextVar(entry.getKey(), entry.getValue());
|
executableScript.setNextVar(entry.getKey(), entry.getValue());
|
||||||
|
@ -78,26 +78,26 @@ public class PythonScriptEngineService extends AbstractComponent implements Scri
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExecutableScript executable(Object compiledScript, Map<String, Object> vars) {
|
public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> vars) {
|
||||||
return new PythonExecutableScript((PyCode) compiledScript, vars);
|
return new PythonExecutableScript((PyCode) compiledScript.compiled(), vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SearchScript search(final Object compiledScript, final SearchLookup lookup, @Nullable final Map<String, Object> vars) {
|
public SearchScript search(final CompiledScript compiledScript, final SearchLookup lookup, @Nullable final Map<String, Object> vars) {
|
||||||
return new SearchScript() {
|
return new SearchScript() {
|
||||||
@Override
|
@Override
|
||||||
public LeafSearchScript getLeafSearchScript(LeafReaderContext context) throws IOException {
|
public LeafSearchScript getLeafSearchScript(LeafReaderContext context) throws IOException {
|
||||||
final LeafSearchLookup leafLookup = lookup.getLeafSearchLookup(context);
|
final LeafSearchLookup leafLookup = lookup.getLeafSearchLookup(context);
|
||||||
return new PythonSearchScript((PyCode) compiledScript, vars, leafLookup);
|
return new PythonSearchScript((PyCode) compiledScript.compiled(), vars, leafLookup);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object execute(Object compiledScript, Map<String, Object> vars) {
|
public Object execute(CompiledScript compiledScript, Map<String, Object> vars) {
|
||||||
PyObject pyVars = Py.java2py(vars);
|
PyObject pyVars = Py.java2py(vars);
|
||||||
interp.setLocals(pyVars);
|
interp.setLocals(pyVars);
|
||||||
PyObject ret = interp.eval((PyCode) compiledScript);
|
PyObject ret = interp.eval((PyCode) compiledScript.compiled());
|
||||||
if (ret == null) {
|
if (ret == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,9 @@ package org.elasticsearch.script.python;
|
|||||||
|
|
||||||
import org.elasticsearch.common.collect.MapBuilder;
|
import org.elasticsearch.common.collect.MapBuilder;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.script.CompiledScript;
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
import org.elasticsearch.script.ExecutableScript;
|
||||||
|
import org.elasticsearch.script.ScriptService;
|
||||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@ -57,7 +59,7 @@ public class PythonScriptEngineTests extends ElasticsearchTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testSimpleEquation() {
|
public void testSimpleEquation() {
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
Map<String, Object> vars = new HashMap<String, Object>();
|
||||||
Object o = se.execute(se.compile("1 + 2"), vars);
|
Object o = se.execute(new CompiledScript(ScriptService.ScriptType.INLINE, "testSimpleEquation", "python", se.compile("1 + 2")), vars);
|
||||||
assertThat(((Number) o).intValue(), equalTo(3));
|
assertThat(((Number) o).intValue(), equalTo(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,13 +70,13 @@ public class PythonScriptEngineTests extends ElasticsearchTestCase {
|
|||||||
Map<String, Object> obj2 = MapBuilder.<String, Object>newMapBuilder().put("prop2", "value2").map();
|
Map<String, Object> obj2 = MapBuilder.<String, Object>newMapBuilder().put("prop2", "value2").map();
|
||||||
Map<String, Object> obj1 = MapBuilder.<String, Object>newMapBuilder().put("prop1", "value1").put("obj2", obj2).put("l", Arrays.asList("2", "1")).map();
|
Map<String, Object> obj1 = MapBuilder.<String, Object>newMapBuilder().put("prop1", "value1").put("obj2", obj2).put("l", Arrays.asList("2", "1")).map();
|
||||||
vars.put("obj1", obj1);
|
vars.put("obj1", obj1);
|
||||||
Object o = se.execute(se.compile("obj1"), vars);
|
Object o = se.execute(new CompiledScript(ScriptService.ScriptType.INLINE, "testMapAccess", "python", se.compile("obj1")), vars);
|
||||||
assertThat(o, instanceOf(Map.class));
|
assertThat(o, instanceOf(Map.class));
|
||||||
obj1 = (Map<String, Object>) o;
|
obj1 = (Map<String, Object>) o;
|
||||||
assertThat((String) obj1.get("prop1"), equalTo("value1"));
|
assertThat((String) obj1.get("prop1"), equalTo("value1"));
|
||||||
assertThat((String) ((Map<String, Object>) obj1.get("obj2")).get("prop2"), equalTo("value2"));
|
assertThat((String) ((Map<String, Object>) obj1.get("obj2")).get("prop2"), equalTo("value2"));
|
||||||
|
|
||||||
o = se.execute(se.compile("obj1['l'][0]"), vars);
|
o = se.execute(new CompiledScript(ScriptService.ScriptType.INLINE, "testMapAccess", "python", se.compile("obj1['l'][0]")), vars);
|
||||||
assertThat(((String) o), equalTo("2"));
|
assertThat(((String) o), equalTo("2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +89,8 @@ public class PythonScriptEngineTests extends ElasticsearchTestCase {
|
|||||||
ctx.put("obj1", obj1);
|
ctx.put("obj1", obj1);
|
||||||
vars.put("ctx", ctx);
|
vars.put("ctx", ctx);
|
||||||
|
|
||||||
se.execute(se.compile("ctx['obj2'] = { 'prop2' : 'value2' }; ctx['obj1']['prop1'] = 'uvalue1'"), vars);
|
se.execute(new CompiledScript(ScriptService.ScriptType.INLINE, "testObjectInterMap", "python",
|
||||||
|
se.compile("ctx['obj2'] = { 'prop2' : 'value2' }; ctx['obj1']['prop1'] = 'uvalue1'")), vars);
|
||||||
ctx = (Map<String, Object>) se.unwrap(vars.get("ctx"));
|
ctx = (Map<String, Object>) se.unwrap(vars.get("ctx"));
|
||||||
assertThat(ctx.containsKey("obj1"), equalTo(true));
|
assertThat(ctx.containsKey("obj1"), equalTo(true));
|
||||||
assertThat((String) ((Map<String, Object>) ctx.get("obj1")).get("prop1"), equalTo("uvalue1"));
|
assertThat((String) ((Map<String, Object>) ctx.get("obj1")).get("prop1"), equalTo("uvalue1"));
|
||||||
@ -106,15 +109,15 @@ public class PythonScriptEngineTests extends ElasticsearchTestCase {
|
|||||||
// Object o = se.execute(se.compile("l.length"), vars);
|
// Object o = se.execute(se.compile("l.length"), vars);
|
||||||
// assertThat(((Number) o).intValue(), equalTo(4));
|
// assertThat(((Number) o).intValue(), equalTo(4));
|
||||||
|
|
||||||
Object o = se.execute(se.compile("l[0]"), vars);
|
Object o = se.execute(new CompiledScript(ScriptService.ScriptType.INLINE, "testAccessListInScript", "python", se.compile("l[0]")), vars);
|
||||||
assertThat(((String) o), equalTo("1"));
|
assertThat(((String) o), equalTo("1"));
|
||||||
|
|
||||||
o = se.execute(se.compile("l[3]"), vars);
|
o = se.execute(new CompiledScript(ScriptService.ScriptType.INLINE, "testAccessListInScript", "python", se.compile("l[3]")), vars);
|
||||||
obj1 = (Map<String, Object>) o;
|
obj1 = (Map<String, Object>) o;
|
||||||
assertThat((String) obj1.get("prop1"), equalTo("value1"));
|
assertThat((String) obj1.get("prop1"), equalTo("value1"));
|
||||||
assertThat((String) ((Map<String, Object>) obj1.get("obj2")).get("prop2"), equalTo("value2"));
|
assertThat((String) ((Map<String, Object>) obj1.get("obj2")).get("prop2"), equalTo("value2"));
|
||||||
|
|
||||||
o = se.execute(se.compile("l[3]['prop1']"), vars);
|
o = se.execute(new CompiledScript(ScriptService.ScriptType.INLINE, "testAccessListInScript", "python", se.compile("l[3]['prop1']")), vars);
|
||||||
assertThat(((String) o), equalTo("value1"));
|
assertThat(((String) o), equalTo("value1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +128,7 @@ public class PythonScriptEngineTests extends ElasticsearchTestCase {
|
|||||||
vars.put("ctx", ctx);
|
vars.put("ctx", ctx);
|
||||||
Object compiledScript = se.compile("ctx['value']");
|
Object compiledScript = se.compile("ctx['value']");
|
||||||
|
|
||||||
ExecutableScript script = se.executable(compiledScript, vars);
|
ExecutableScript script = se.executable(new CompiledScript(ScriptService.ScriptType.INLINE, "testChangingVarsCrossExecution1", "python", compiledScript), vars);
|
||||||
ctx.put("value", 1);
|
ctx.put("value", 1);
|
||||||
Object o = script.run();
|
Object o = script.run();
|
||||||
assertThat(((Number) o).intValue(), equalTo(1));
|
assertThat(((Number) o).intValue(), equalTo(1));
|
||||||
@ -141,7 +144,7 @@ public class PythonScriptEngineTests extends ElasticsearchTestCase {
|
|||||||
Map<String, Object> ctx = new HashMap<String, Object>();
|
Map<String, Object> ctx = new HashMap<String, Object>();
|
||||||
Object compiledScript = se.compile("value");
|
Object compiledScript = se.compile("value");
|
||||||
|
|
||||||
ExecutableScript script = se.executable(compiledScript, vars);
|
ExecutableScript script = se.executable(new CompiledScript(ScriptService.ScriptType.INLINE, "testChangingVarsCrossExecution2", "python", compiledScript), vars);
|
||||||
script.setNextVar("value", 1);
|
script.setNextVar("value", 1);
|
||||||
Object o = script.run();
|
Object o = script.run();
|
||||||
assertThat(((Number) o).intValue(), equalTo(1));
|
assertThat(((Number) o).intValue(), equalTo(1));
|
||||||
|
@ -20,7 +20,9 @@
|
|||||||
package org.elasticsearch.script.python;
|
package org.elasticsearch.script.python;
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.script.CompiledScript;
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
import org.elasticsearch.script.ExecutableScript;
|
||||||
|
import org.elasticsearch.script.ScriptService;
|
||||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -50,6 +52,7 @@ public class PythonScriptMultiThreadedTest extends ElasticsearchTestCase {
|
|||||||
public void testExecutableNoRuntimeParams() throws Exception {
|
public void testExecutableNoRuntimeParams() throws Exception {
|
||||||
final PythonScriptEngineService se = new PythonScriptEngineService(Settings.Builder.EMPTY_SETTINGS);
|
final PythonScriptEngineService se = new PythonScriptEngineService(Settings.Builder.EMPTY_SETTINGS);
|
||||||
final Object compiled = se.compile("x + y");
|
final Object compiled = se.compile("x + y");
|
||||||
|
final CompiledScript compiledScript = new CompiledScript(ScriptService.ScriptType.INLINE, "testExecutableNoRuntimeParams", "python", compiled);
|
||||||
final AtomicBoolean failed = new AtomicBoolean();
|
final AtomicBoolean failed = new AtomicBoolean();
|
||||||
|
|
||||||
Thread[] threads = new Thread[4];
|
Thread[] threads = new Thread[4];
|
||||||
@ -67,7 +70,7 @@ public class PythonScriptMultiThreadedTest extends ElasticsearchTestCase {
|
|||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
Map<String, Object> vars = new HashMap<String, Object>();
|
||||||
vars.put("x", x);
|
vars.put("x", x);
|
||||||
vars.put("y", y);
|
vars.put("y", y);
|
||||||
ExecutableScript script = se.executable(compiled, vars);
|
ExecutableScript script = se.executable(compiledScript, vars);
|
||||||
for (int i = 0; i < 10000; i++) {
|
for (int i = 0; i < 10000; i++) {
|
||||||
long result = ((Number) script.run()).longValue();
|
long result = ((Number) script.run()).longValue();
|
||||||
assertThat(result, equalTo(addition));
|
assertThat(result, equalTo(addition));
|
||||||
@ -136,6 +139,7 @@ public class PythonScriptMultiThreadedTest extends ElasticsearchTestCase {
|
|||||||
public void testExecute() throws Exception {
|
public void testExecute() throws Exception {
|
||||||
final PythonScriptEngineService se = new PythonScriptEngineService(Settings.Builder.EMPTY_SETTINGS);
|
final PythonScriptEngineService se = new PythonScriptEngineService(Settings.Builder.EMPTY_SETTINGS);
|
||||||
final Object compiled = se.compile("x + y");
|
final Object compiled = se.compile("x + y");
|
||||||
|
final CompiledScript compiledScript = new CompiledScript(ScriptService.ScriptType.INLINE, "testExecute", "python", compiled);
|
||||||
final AtomicBoolean failed = new AtomicBoolean();
|
final AtomicBoolean failed = new AtomicBoolean();
|
||||||
|
|
||||||
Thread[] threads = new Thread[4];
|
Thread[] threads = new Thread[4];
|
||||||
@ -154,7 +158,7 @@ public class PythonScriptMultiThreadedTest extends ElasticsearchTestCase {
|
|||||||
long addition = x + y;
|
long addition = x + y;
|
||||||
runtimeVars.put("x", x);
|
runtimeVars.put("x", x);
|
||||||
runtimeVars.put("y", y);
|
runtimeVars.put("y", y);
|
||||||
long result = ((Number) se.execute(compiled, runtimeVars)).longValue();
|
long result = ((Number) se.execute(compiledScript, runtimeVars)).longValue();
|
||||||
assertThat(result, equalTo(addition));
|
assertThat(result, equalTo(addition));
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
@ -21,7 +21,9 @@ package org.elasticsearch.script.python;
|
|||||||
|
|
||||||
import org.elasticsearch.common.StopWatch;
|
import org.elasticsearch.common.StopWatch;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.script.CompiledScript;
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
import org.elasticsearch.script.ExecutableScript;
|
||||||
|
import org.elasticsearch.script.ScriptService;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -34,32 +36,34 @@ public class SimpleBench {
|
|||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
PythonScriptEngineService se = new PythonScriptEngineService(Settings.Builder.EMPTY_SETTINGS);
|
PythonScriptEngineService se = new PythonScriptEngineService(Settings.Builder.EMPTY_SETTINGS);
|
||||||
Object compiled = se.compile("x + y");
|
Object compiled = se.compile("x + y");
|
||||||
|
CompiledScript compiledScript = new CompiledScript(ScriptService.ScriptType.INLINE, "SimpleBench", "python", compiled);
|
||||||
|
|
||||||
|
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
Map<String, Object> vars = new HashMap<String, Object>();
|
||||||
// warm up
|
// warm up
|
||||||
for (int i = 0; i < 1000; i++) {
|
for (int i = 0; i < 1000; i++) {
|
||||||
vars.put("x", i);
|
vars.put("x", i);
|
||||||
vars.put("y", i + 1);
|
vars.put("y", i + 1);
|
||||||
se.execute(compiled, vars);
|
se.execute(compiledScript, vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
final long ITER = 100000;
|
final long ITER = 100000;
|
||||||
|
|
||||||
StopWatch stopWatch = new StopWatch().start();
|
StopWatch stopWatch = new StopWatch().start();
|
||||||
for (long i = 0; i < ITER; i++) {
|
for (long i = 0; i < ITER; i++) {
|
||||||
se.execute(compiled, vars);
|
se.execute(compiledScript, vars);
|
||||||
}
|
}
|
||||||
System.out.println("Execute Took: " + stopWatch.stop().lastTaskTime());
|
System.out.println("Execute Took: " + stopWatch.stop().lastTaskTime());
|
||||||
|
|
||||||
stopWatch = new StopWatch().start();
|
stopWatch = new StopWatch().start();
|
||||||
ExecutableScript executableScript = se.executable(compiled, vars);
|
ExecutableScript executableScript = se.executable(compiledScript, vars);
|
||||||
for (long i = 0; i < ITER; i++) {
|
for (long i = 0; i < ITER; i++) {
|
||||||
executableScript.run();
|
executableScript.run();
|
||||||
}
|
}
|
||||||
System.out.println("Executable Took: " + stopWatch.stop().lastTaskTime());
|
System.out.println("Executable Took: " + stopWatch.stop().lastTaskTime());
|
||||||
|
|
||||||
stopWatch = new StopWatch().start();
|
stopWatch = new StopWatch().start();
|
||||||
executableScript = se.executable(compiled, vars);
|
executableScript = se.executable(compiledScript, vars);
|
||||||
for (long i = 0; i < ITER; i++) {
|
for (long i = 0; i < ITER; i++) {
|
||||||
for (Map.Entry<String, Object> entry : vars.entrySet()) {
|
for (Map.Entry<String, Object> entry : vars.entrySet()) {
|
||||||
executableScript.setNextVar(entry.getKey(), entry.getValue());
|
executableScript.setNextVar(entry.getKey(), entry.getValue());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user