mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-03-29 11:28:30 +00:00
Scripting: Allow to define scripts within config/scripts
, automatically compiled and can be referenced by name, closes #429.
This commit is contained in:
parent
503b023eac
commit
ae05ce0551
@ -28,6 +28,8 @@ public interface ScriptEngineService {
|
|||||||
|
|
||||||
String[] types();
|
String[] types();
|
||||||
|
|
||||||
|
String[] extensions();
|
||||||
|
|
||||||
Object compile(String script);
|
Object compile(String script);
|
||||||
|
|
||||||
ExecutableScript executable(Object compiledScript, Map<String, Object> vars);
|
ExecutableScript executable(Object compiledScript, Map<String, Object> vars);
|
||||||
|
@ -25,9 +25,15 @@ import org.elasticsearch.common.collect.ImmutableSet;
|
|||||||
import org.elasticsearch.common.collect.MapMaker;
|
import org.elasticsearch.common.collect.MapMaker;
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
import org.elasticsearch.common.component.AbstractComponent;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
import org.elasticsearch.common.io.Streams;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.common.util.concurrent.ConcurrentCollections;
|
||||||
|
import org.elasticsearch.env.Environment;
|
||||||
import org.elasticsearch.script.mvel.MvelScriptEngineService;
|
import org.elasticsearch.script.mvel.MvelScriptEngineService;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
@ -41,16 +47,18 @@ public class ScriptService extends AbstractComponent {
|
|||||||
|
|
||||||
private final ImmutableMap<String, ScriptEngineService> scriptEngines;
|
private final ImmutableMap<String, ScriptEngineService> scriptEngines;
|
||||||
|
|
||||||
|
private final ConcurrentMap<String, CompiledScript> staticCache = ConcurrentCollections.newConcurrentMap();
|
||||||
|
|
||||||
private final ConcurrentMap<String, CompiledScript> cache = new MapMaker().softValues().makeMap();
|
private final ConcurrentMap<String, CompiledScript> cache = new MapMaker().softValues().makeMap();
|
||||||
|
|
||||||
public ScriptService(Settings settings) {
|
public ScriptService(Settings settings) {
|
||||||
this(settings, ImmutableSet.<ScriptEngineService>builder()
|
this(settings, new Environment(), ImmutableSet.<ScriptEngineService>builder()
|
||||||
.add(new MvelScriptEngineService(settings))
|
.add(new MvelScriptEngineService(settings))
|
||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject public ScriptService(Settings settings, Set<ScriptEngineService> scriptEngines) {
|
@Inject public ScriptService(Settings settings, Environment env, Set<ScriptEngineService> scriptEngines) {
|
||||||
super(settings);
|
super(settings);
|
||||||
|
|
||||||
this.defaultLang = componentSettings.get("default_lang", "mvel");
|
this.defaultLang = componentSettings.get("default_lang", "mvel");
|
||||||
@ -62,6 +70,47 @@ public class ScriptService extends AbstractComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.scriptEngines = builder.build();
|
this.scriptEngines = builder.build();
|
||||||
|
|
||||||
|
// compile static scripts
|
||||||
|
File scriptsFile = new File(env.configFile(), "scripts");
|
||||||
|
if (scriptsFile.exists()) {
|
||||||
|
processScriptsDirectory("", scriptsFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processScriptsDirectory(String prefix, File dir) {
|
||||||
|
for (File file : dir.listFiles()) {
|
||||||
|
if (file.isDirectory()) {
|
||||||
|
processScriptsDirectory(prefix + file.getName() + "_", file);
|
||||||
|
} else {
|
||||||
|
int extIndex = file.getName().lastIndexOf('.');
|
||||||
|
if (extIndex != -1) {
|
||||||
|
String ext = file.getName().substring(extIndex + 1);
|
||||||
|
String scriptName = prefix + file.getName().substring(0, extIndex);
|
||||||
|
boolean found = false;
|
||||||
|
for (ScriptEngineService engineService : scriptEngines.values()) {
|
||||||
|
for (String s : engineService.extensions()) {
|
||||||
|
if (s.equals(ext)) {
|
||||||
|
found = true;
|
||||||
|
try {
|
||||||
|
String script = Streams.copyToString(new InputStreamReader(new FileInputStream(file), "UTF-8"));
|
||||||
|
staticCache.put(scriptName, new CompiledScript(engineService.types()[0], engineService.compile(script)));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.warn("failed to load/compile script [{}]", e, scriptName);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
logger.warn("no script engine found for [{}]", ext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
@ -75,7 +124,11 @@ public class ScriptService extends AbstractComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CompiledScript compile(String lang, String script) {
|
public CompiledScript compile(String lang, String script) {
|
||||||
CompiledScript compiled = cache.get(script);
|
CompiledScript compiled = staticCache.get(script);
|
||||||
|
if (compiled != null) {
|
||||||
|
return compiled;
|
||||||
|
}
|
||||||
|
compiled = cache.get(script);
|
||||||
if (compiled != null) {
|
if (compiled != null) {
|
||||||
return compiled;
|
return compiled;
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,10 @@ public class MvelScriptEngineService extends AbstractComponent implements Script
|
|||||||
return new String[]{"mvel"};
|
return new String[]{"mvel"};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public String[] extensions() {
|
||||||
|
return new String[]{"mvel"};
|
||||||
|
}
|
||||||
|
|
||||||
@Override public Object compile(String script) {
|
@Override public Object compile(String script) {
|
||||||
return MVEL.compileExpression(script, parserContext);
|
return MVEL.compileExpression(script, parserContext);
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,10 @@ public class GroovyScriptEngineService extends AbstractComponent implements Scri
|
|||||||
return new String[]{"groovy"};
|
return new String[]{"groovy"};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public String[] extensions() {
|
||||||
|
return new String[]{"groovy"};
|
||||||
|
}
|
||||||
|
|
||||||
@Override public Object compile(String script) {
|
@Override public Object compile(String script) {
|
||||||
return loader.parseClass(script, generateScriptName());
|
return loader.parseClass(script, generateScriptName());
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,10 @@ public class JavaScriptScriptEngineService extends AbstractComponent implements
|
|||||||
return new String[]{"js", "javascript"};
|
return new String[]{"js", "javascript"};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public String[] extensions() {
|
||||||
|
return new String[]{"js"};
|
||||||
|
}
|
||||||
|
|
||||||
@Override public Object compile(String script) {
|
@Override public Object compile(String script) {
|
||||||
Context ctx = Context.enter();
|
Context ctx = Context.enter();
|
||||||
try {
|
try {
|
||||||
|
@ -50,6 +50,10 @@ public class PythonScriptEngineService extends AbstractComponent implements Scri
|
|||||||
return new String[]{"python"};
|
return new String[]{"python"};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public String[] extensions() {
|
||||||
|
return new String[]{"py"};
|
||||||
|
}
|
||||||
|
|
||||||
@Override public Object compile(String script) {
|
@Override public Object compile(String script) {
|
||||||
return interp.compile(script);
|
return interp.compile(script);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user