Merge pull request #16286 from fforbeck/fix/15269
Skipping hidden files compilation for script service
This commit is contained in:
commit
1bc8d0249f
|
@ -55,7 +55,6 @@ import org.elasticsearch.common.xcontent.XContentParser;
|
|||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.index.query.TemplateQueryParser;
|
||||
import org.elasticsearch.search.internal.SearchContext;
|
||||
import org.elasticsearch.search.lookup.SearchLookup;
|
||||
import org.elasticsearch.watcher.FileChangesListener;
|
||||
import org.elasticsearch.watcher.FileWatcher;
|
||||
|
@ -225,6 +224,8 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
|||
return scriptEngineService;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a script can be executed and compiles it if needed, or returns the previously compiled and cached script.
|
||||
*/
|
||||
|
@ -516,46 +517,53 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
|||
|
||||
private class ScriptChangesListener extends FileChangesListener {
|
||||
|
||||
private Tuple<String, String> scriptNameExt(Path file) {
|
||||
private Tuple<String, String> getScriptNameExt(Path file) {
|
||||
Path scriptPath = scriptsDirectory.relativize(file);
|
||||
int extIndex = scriptPath.toString().lastIndexOf('.');
|
||||
if (extIndex != -1) {
|
||||
String ext = scriptPath.toString().substring(extIndex + 1);
|
||||
String scriptName = scriptPath.toString().substring(0, extIndex).replace(scriptPath.getFileSystem().getSeparator(), "_");
|
||||
return new Tuple<>(scriptName, ext);
|
||||
} else {
|
||||
if (extIndex <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String ext = scriptPath.toString().substring(extIndex + 1);
|
||||
if (ext.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String scriptName = scriptPath.toString().substring(0, extIndex).replace(scriptPath.getFileSystem().getSeparator(), "_");
|
||||
return new Tuple<>(scriptName, ext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFileInit(Path file) {
|
||||
Tuple<String, String> scriptNameExt = getScriptNameExt(file);
|
||||
if (scriptNameExt == null) {
|
||||
logger.debug("Skipped script with invalid extension : [{}]", file);
|
||||
return;
|
||||
}
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Loading script file : [{}]", file);
|
||||
}
|
||||
Tuple<String, String> scriptNameExt = scriptNameExt(file);
|
||||
if (scriptNameExt != null) {
|
||||
ScriptEngineService engineService = getScriptEngineServiceForFileExt(scriptNameExt.v2());
|
||||
if (engineService == null) {
|
||||
logger.warn("no script engine found for [{}]", scriptNameExt.v2());
|
||||
} else {
|
||||
try {
|
||||
//we don't know yet what the script will be used for, but if all of the operations for this lang
|
||||
// with file scripts are disabled, it makes no sense to even compile it and cache it.
|
||||
if (isAnyScriptContextEnabled(engineService.getTypes().get(0), engineService, ScriptType.FILE)) {
|
||||
logger.info("compiling script file [{}]", file.toAbsolutePath());
|
||||
try(InputStreamReader reader = new InputStreamReader(Files.newInputStream(file), StandardCharsets.UTF_8)) {
|
||||
String script = Streams.copyToString(reader);
|
||||
CacheKey cacheKey = new CacheKey(engineService, scriptNameExt.v1(), null, Collections.emptyMap());
|
||||
staticCache.put(cacheKey, new CompiledScript(ScriptType.FILE, scriptNameExt.v1(), engineService.getTypes().get(0), engineService.compile(script, Collections.emptyMap())));
|
||||
scriptMetrics.onCompilation();
|
||||
}
|
||||
} else {
|
||||
logger.warn("skipping compile of script file [{}] as all scripted operations are disabled for file scripts", file.toAbsolutePath());
|
||||
|
||||
ScriptEngineService engineService = getScriptEngineServiceForFileExt(scriptNameExt.v2());
|
||||
if (engineService == null) {
|
||||
logger.warn("No script engine found for [{}]", scriptNameExt.v2());
|
||||
} else {
|
||||
try {
|
||||
//we don't know yet what the script will be used for, but if all of the operations for this lang
|
||||
// with file scripts are disabled, it makes no sense to even compile it and cache it.
|
||||
if (isAnyScriptContextEnabled(engineService.getTypes().get(0), engineService, ScriptType.FILE)) {
|
||||
logger.info("compiling script file [{}]", file.toAbsolutePath());
|
||||
try (InputStreamReader reader = new InputStreamReader(Files.newInputStream(file), StandardCharsets.UTF_8)) {
|
||||
String script = Streams.copyToString(reader);
|
||||
CacheKey cacheKey = new CacheKey(engineService, scriptNameExt.v1(), null, Collections.emptyMap());
|
||||
staticCache.put(cacheKey, new CompiledScript(ScriptType.FILE, scriptNameExt.v1(), engineService.getTypes().get(0), engineService.compile(script, Collections.emptyMap())));
|
||||
scriptMetrics.onCompilation();
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
logger.warn("failed to load/compile script [{}]", e, scriptNameExt.v1());
|
||||
} else {
|
||||
logger.warn("skipping compile of script file [{}] as all scripted operations are disabled for file scripts", file.toAbsolutePath());
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
logger.warn("failed to load/compile script [{}]", e, scriptNameExt.v1());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -567,7 +575,7 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
|||
|
||||
@Override
|
||||
public void onFileDeleted(Path file) {
|
||||
Tuple<String, String> scriptNameExt = scriptNameExt(file);
|
||||
Tuple<String, String> scriptNameExt = getScriptNameExt(file);
|
||||
if (scriptNameExt != null) {
|
||||
ScriptEngineService engineService = getScriptEngineServiceForFileExt(scriptNameExt.v2());
|
||||
assert engineService != null;
|
||||
|
|
|
@ -122,26 +122,21 @@ public class ScriptServiceTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testScriptsWithoutExtensions() throws IOException {
|
||||
|
||||
buildScriptService(Settings.EMPTY);
|
||||
logger.info("--> setup two test files one with extension and another without");
|
||||
Path testFileNoExt = scriptsFilePath.resolve("test_no_ext");
|
||||
Path testFileWithExt = scriptsFilePath.resolve("test_script.tst");
|
||||
Streams.copy("test_file_no_ext".getBytes("UTF-8"), Files.newOutputStream(testFileNoExt));
|
||||
Streams.copy("test_file".getBytes("UTF-8"), Files.newOutputStream(testFileWithExt));
|
||||
resourceWatcherService.notifyNow();
|
||||
|
||||
logger.info("--> verify that file with extension was correctly processed");
|
||||
CompiledScript compiledScript = scriptService.compile(new Script("test_script", ScriptType.FILE, "test", null),
|
||||
ScriptContext.Standard.SEARCH, Collections.emptyMap());
|
||||
assertThat(compiledScript.compiled(), equalTo((Object) "compiled_test_file"));
|
||||
|
||||
logger.info("--> delete both files");
|
||||
Files.delete(testFileNoExt);
|
||||
Files.delete(testFileWithExt);
|
||||
resourceWatcherService.notifyNow();
|
||||
|
||||
logger.info("--> verify that file with extension was correctly removed");
|
||||
try {
|
||||
scriptService.compile(new Script("test_script", ScriptType.FILE, "test", null), ScriptContext.Standard.SEARCH,
|
||||
Collections.emptyMap());
|
||||
|
@ -151,6 +146,25 @@ public class ScriptServiceTests extends ESTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void testScriptCompiledOnceHiddenFileDetected() throws IOException {
|
||||
buildScriptService(Settings.EMPTY);
|
||||
|
||||
Path testHiddenFile = scriptsFilePath.resolve(".hidden_file");
|
||||
Streams.copy("test_hidden_file".getBytes("UTF-8"), Files.newOutputStream(testHiddenFile));
|
||||
|
||||
Path testFileScript = scriptsFilePath.resolve("file_script.tst");
|
||||
Streams.copy("test_file_script".getBytes("UTF-8"), Files.newOutputStream(testFileScript));
|
||||
resourceWatcherService.notifyNow();
|
||||
|
||||
CompiledScript compiledScript = scriptService.compile(new Script("file_script", ScriptType.FILE, "test", null),
|
||||
ScriptContext.Standard.SEARCH, Collections.emptyMap());
|
||||
assertThat(compiledScript.compiled(), equalTo((Object) "compiled_test_file_script"));
|
||||
|
||||
Files.delete(testHiddenFile);
|
||||
Files.delete(testFileScript);
|
||||
resourceWatcherService.notifyNow();
|
||||
}
|
||||
|
||||
public void testInlineScriptCompiledOnceCache() throws IOException {
|
||||
buildScriptService(Settings.EMPTY);
|
||||
CompiledScript compiledScript1 = scriptService.compile(new Script("1+1", ScriptType.INLINE, "test", null),
|
||||
|
|
Loading…
Reference in New Issue