From b70047a8f044aa91e726568bac902c61227f6e13 Mon Sep 17 00:00:00 2001 From: Luca Cavanna Date: Wed, 15 Jul 2020 21:50:57 +0200 Subject: [PATCH] Runtime fields: rework script service injection Instead of relying no createComponents to get the script service, we rely on the query shard context supplier that's available in the parser context, yet we only carry around as callback that allows us to compile the script --- .../xpack/runtimefields/RuntimeFields.java | 36 +---------------- .../mapper/ScriptFieldMapper.java | 39 ++++++++++--------- 2 files changed, 22 insertions(+), 53 deletions(-) diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/RuntimeFields.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/RuntimeFields.java index 167960c33dc4d..d24779e92f1d5 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/RuntimeFields.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/RuntimeFields.java @@ -6,60 +6,26 @@ package org.elasticsearch.xpack.runtimefields; -import org.elasticsearch.client.Client; -import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; -import org.elasticsearch.cluster.service.ClusterService; -import org.elasticsearch.common.io.stream.NamedWriteableRegistry; -import org.elasticsearch.common.xcontent.NamedXContentRegistry; -import org.elasticsearch.env.Environment; -import org.elasticsearch.env.NodeEnvironment; import org.elasticsearch.index.mapper.Mapper; import org.elasticsearch.plugins.MapperPlugin; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.ScriptPlugin; -import org.elasticsearch.repositories.RepositoriesService; import org.elasticsearch.script.ScriptContext; -import org.elasticsearch.script.ScriptService; -import org.elasticsearch.threadpool.ThreadPool; -import org.elasticsearch.watcher.ResourceWatcherService; import org.elasticsearch.xpack.runtimefields.mapper.ScriptFieldMapper; -import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.function.Supplier; public final class RuntimeFields extends Plugin implements MapperPlugin, ScriptPlugin { - private final ScriptFieldMapper.TypeParser typeParser = new ScriptFieldMapper.TypeParser(); - @Override public Map getMappers() { - return Collections.singletonMap(ScriptFieldMapper.CONTENT_TYPE, typeParser); + return Collections.singletonMap(ScriptFieldMapper.CONTENT_TYPE, new ScriptFieldMapper.TypeParser()); } @Override public List> getContexts() { return List.of(DoubleScriptFieldScript.CONTEXT, LongScriptFieldScript.CONTEXT, StringScriptFieldScript.CONTEXT); } - - @Override - public Collection createComponents( - Client client, - ClusterService clusterService, - ThreadPool threadPool, - ResourceWatcherService resourceWatcherService, - ScriptService scriptService, - NamedXContentRegistry xContentRegistry, - Environment environment, - NodeEnvironment nodeEnvironment, - NamedWriteableRegistry namedWriteableRegistry, - IndexNameExpressionResolver indexNameExpressionResolver, - Supplier repositoriesServiceSupplier - ) { - // TODO getMappers gets called before createComponents. We should wire the script service differently - typeParser.setScriptService(scriptService); - return Collections.emptyList(); - } } diff --git a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java index 9826d1bbd07dc..0ddcb5e0d03c7 100644 --- a/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java +++ b/x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptFieldMapper.java @@ -6,7 +6,6 @@ package org.elasticsearch.xpack.runtimefields.mapper; -import org.apache.lucene.util.SetOnce; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.index.mapper.FieldMapper; import org.elasticsearch.index.mapper.MappedFieldType; @@ -15,7 +14,7 @@ import org.elasticsearch.index.mapper.ParametrizedFieldMapper; import org.elasticsearch.index.mapper.ParseContext; import org.elasticsearch.script.Script; -import org.elasticsearch.script.ScriptService; +import org.elasticsearch.script.ScriptContext; import org.elasticsearch.script.ScriptType; import org.elasticsearch.xpack.runtimefields.StringScriptFieldScript; @@ -29,7 +28,7 @@ public final class ScriptFieldMapper extends ParametrizedFieldMapper { private final String runtimeType; private final Script script; - private final ScriptService scriptService; + private final ScriptCompiler scriptCompiler; protected ScriptFieldMapper( String simpleName, @@ -38,17 +37,17 @@ protected ScriptFieldMapper( CopyTo copyTo, String runtimeType, Script script, - ScriptService scriptService + ScriptCompiler scriptCompiler ) { super(simpleName, mappedFieldType, multiFields, copyTo); this.runtimeType = runtimeType; this.script = script; - this.scriptService = scriptService; + this.scriptCompiler = scriptCompiler; } @Override public ParametrizedFieldMapper.Builder getMergeBuilder() { - return new ScriptFieldMapper.Builder(simpleName(), scriptService).init(this); + return new ScriptFieldMapper.Builder(simpleName(), scriptCompiler).init(this); } @Override @@ -99,11 +98,11 @@ private static ScriptFieldMapper toType(FieldMapper in) { } }); - private final ScriptService scriptService; + private final ScriptCompiler scriptCompiler; - protected Builder(String name, ScriptService scriptService) { + protected Builder(String name, ScriptCompiler scriptCompiler) { super(name); - this.scriptService = scriptService; + this.scriptCompiler = scriptCompiler; } @Override @@ -115,7 +114,7 @@ protected List> getParameters() { public ScriptFieldMapper build(BuilderContext context) { MappedFieldType mappedFieldType; if (runtimeType.getValue().equals("keyword")) { - StringScriptFieldScript.Factory factory = scriptService.compile(script.getValue(), StringScriptFieldScript.CONTEXT); + StringScriptFieldScript.Factory factory = scriptCompiler.compile(script.getValue(), StringScriptFieldScript.CONTEXT); mappedFieldType = new RuntimeKeywordMappedFieldType(buildFullName(context), script.getValue(), factory, meta.getValue()); } else { throw new IllegalArgumentException("runtime_type [" + runtimeType + "] not supported"); @@ -128,7 +127,7 @@ public ScriptFieldMapper build(BuilderContext context) { copyTo.build(), runtimeType.getValue(), script.getValue(), - scriptService + scriptCompiler ); } @@ -143,19 +142,23 @@ static Script parseScript(String name, Mapper.TypeParser.ParserContext parserCon public static class TypeParser implements Mapper.TypeParser { - private final SetOnce scriptService = new SetOnce<>(); - - public void setScriptService(ScriptService scriptService) { - this.scriptService.set(scriptService); - } - @Override public ScriptFieldMapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { - ScriptFieldMapper.Builder builder = new ScriptFieldMapper.Builder(name, scriptService.get()); + ScriptFieldMapper.Builder builder = new ScriptFieldMapper.Builder(name, new ScriptCompiler() { + @Override + public FactoryType compile(Script script, ScriptContext context) { + return parserContext.queryShardContextSupplier().get().compile(script, context); + } + }); builder.parse(name, parserContext, node); return builder; } } + + @FunctionalInterface + private interface ScriptCompiler { + FactoryType compile(Script script, ScriptContext context); + } }