diff --git a/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/ScriptProcessor.java b/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/ScriptProcessor.java index fcc6c680142..01c8530df80 100644 --- a/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/ScriptProcessor.java +++ b/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/ScriptProcessor.java @@ -19,7 +19,9 @@ package org.elasticsearch.ingest.common; +import org.apache.logging.log4j.LogManager; import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.logging.DeprecationLogger; import org.elasticsearch.common.util.CollectionUtils; import org.elasticsearch.common.xcontent.LoggingDeprecationHandler; import org.elasticsearch.common.xcontent.NamedXContentRegistry; @@ -30,7 +32,7 @@ import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.ingest.AbstractProcessor; import org.elasticsearch.ingest.IngestDocument; import org.elasticsearch.ingest.Processor; -import org.elasticsearch.script.DeprecationMap; +import org.elasticsearch.script.DynamicMap; import org.elasticsearch.script.IngestScript; import org.elasticsearch.script.Script; import org.elasticsearch.script.ScriptException; @@ -38,9 +40,8 @@ import org.elasticsearch.script.ScriptService; import java.io.InputStream; import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; import java.util.Map; +import java.util.function.Function; import static org.elasticsearch.ingest.ConfigurationUtils.newConfigurationException; @@ -49,15 +50,14 @@ import static org.elasticsearch.ingest.ConfigurationUtils.newConfigurationExcept */ public final class ScriptProcessor extends AbstractProcessor { - private static final Map DEPRECATIONS; - static { - Map deprecations = new HashMap<>(); - deprecations.put( - "_type", - "[types removal] Looking up doc types [_type] in scripts is deprecated." - ); - DEPRECATIONS = Collections.unmodifiableMap(deprecations); - } + private static final DeprecationLogger deprecationLogger = + new DeprecationLogger(LogManager.getLogger(DynamicMap.class)); + private static final Map> PARAMS_FUNCTIONS = org.elasticsearch.common.collect.Map.of( + "_type", value -> { + deprecationLogger.deprecatedAndMaybeLog("script_processor", + "[types removal] Looking up doc types [_type] in scripts is deprecated."); + return value; + }); public static final String TYPE = "script"; @@ -86,7 +86,7 @@ public final class ScriptProcessor extends AbstractProcessor { public IngestDocument execute(IngestDocument document) { IngestScript.Factory factory = scriptService.compile(script, IngestScript.CONTEXT); factory.newInstance(script.getParams()).execute( - new DeprecationMap(document.getSourceAndMetadata(), DEPRECATIONS, "script_processor")); + new DynamicMap(document.getSourceAndMetadata(), PARAMS_FUNCTIONS)); CollectionUtils.ensureNoSelfReferences(document.getSourceAndMetadata(), "ingest script"); return document; } diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/ScriptedMetricAggContextsTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/ScriptedMetricAggContextsTests.java index 2d33853b88f..41f56c0285f 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/ScriptedMetricAggContextsTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/ScriptedMetricAggContextsTests.java @@ -91,6 +91,33 @@ public class ScriptedMetricAggContextsTests extends ScriptTestCase { assertEquals(1.0, state.get("testField")); } + public void testReturnSource() throws IOException { + ScriptedMetricAggContexts.MapScript.Factory factory = scriptEngine.compile("test", + "state._source = params._source", ScriptedMetricAggContexts.MapScript.CONTEXT, Collections.emptyMap()); + + Map params = new HashMap<>(); + Map state = new HashMap<>(); + + MemoryIndex index = new MemoryIndex(); + // we don't need a real index, just need to construct a LeafReaderContext which cannot be mocked + LeafReaderContext leafReaderContext = index.createSearcher().getIndexReader().leaves().get(0); + + SearchLookup lookup = mock(SearchLookup.class); + LeafSearchLookup leafLookup = mock(LeafSearchLookup.class); + when(lookup.getLeafSearchLookup(leafReaderContext)).thenReturn(leafLookup); + SourceLookup sourceLookup = mock(SourceLookup.class); + when(leafLookup.asMap()).thenReturn(Collections.singletonMap("_source", sourceLookup)); + when(sourceLookup.loadSourceIfNeeded()).thenReturn(Collections.singletonMap("test", 1)); + ScriptedMetricAggContexts.MapScript.LeafFactory leafFactory = factory.newFactory(params, state, lookup); + ScriptedMetricAggContexts.MapScript script = leafFactory.newInstance(leafReaderContext); + + script.execute(); + + assertTrue(state.containsKey("_source")); + assertTrue(state.get("_source") instanceof Map && ((Map)state.get("_source")).containsKey("test")); + assertEquals(1, ((Map)state.get("_source")).get("test")); + } + public void testMapSourceAccess() throws IOException { ScriptedMetricAggContexts.MapScript.Factory factory = scriptEngine.compile("test", "state.testField = params._source.three", ScriptedMetricAggContexts.MapScript.CONTEXT, Collections.emptyMap()); @@ -107,13 +134,13 @@ public class ScriptedMetricAggContextsTests extends ScriptTestCase { when(lookup.getLeafSearchLookup(leafReaderContext)).thenReturn(leafLookup); SourceLookup sourceLookup = mock(SourceLookup.class); when(leafLookup.asMap()).thenReturn(Collections.singletonMap("_source", sourceLookup)); - when(sourceLookup.get("three")).thenReturn(3); + when(sourceLookup.loadSourceIfNeeded()).thenReturn(Collections.singletonMap("three", 3)); ScriptedMetricAggContexts.MapScript.LeafFactory leafFactory = factory.newFactory(params, state, lookup); ScriptedMetricAggContexts.MapScript script = leafFactory.newInstance(leafReaderContext); script.execute(); - assert(state.containsKey("testField")); + assertTrue(state.containsKey("testField")); assertEquals(3, state.get("testField")); } diff --git a/server/src/main/java/org/elasticsearch/ingest/ConditionalProcessor.java b/server/src/main/java/org/elasticsearch/ingest/ConditionalProcessor.java index 72d50ee663b..18fb136d41f 100644 --- a/server/src/main/java/org/elasticsearch/ingest/ConditionalProcessor.java +++ b/server/src/main/java/org/elasticsearch/ingest/ConditionalProcessor.java @@ -19,11 +19,17 @@ package org.elasticsearch.ingest; +import org.apache.logging.log4j.LogManager; +import org.elasticsearch.common.logging.DeprecationLogger; +import org.elasticsearch.script.DynamicMap; +import org.elasticsearch.script.IngestConditionalScript; +import org.elasticsearch.script.Script; +import org.elasticsearch.script.ScriptService; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.ListIterator; @@ -31,25 +37,20 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; +import java.util.function.Function; import java.util.function.LongSupplier; import java.util.stream.Collectors; -import org.elasticsearch.script.DeprecationMap; -import org.elasticsearch.script.IngestConditionalScript; -import org.elasticsearch.script.Script; -import org.elasticsearch.script.ScriptService; - public class ConditionalProcessor extends AbstractProcessor implements WrappingProcessor { - private static final Map DEPRECATIONS; - static { - Map deprecations = new HashMap<>(); - deprecations.put( - "_type", - "[types removal] Looking up doc types [_type] in scripts is deprecated." - ); - DEPRECATIONS = Collections.unmodifiableMap(deprecations); - } + private static final DeprecationLogger deprecationLogger = + new DeprecationLogger(LogManager.getLogger(DynamicMap.class)); + private static final Map> FUNCTIONS = org.elasticsearch.common.collect.Map.of( + "_type", value -> { + deprecationLogger.deprecatedAndMaybeLog("conditional-processor__type", + "[types removal] Looking up doc types [_type] in scripts is deprecated."); + return value; + }); static final String TYPE = "conditional"; @@ -110,8 +111,7 @@ public class ConditionalProcessor extends AbstractProcessor implements WrappingP boolean evaluate(IngestDocument ingestDocument) { IngestConditionalScript script = scriptService.compile(condition, IngestConditionalScript.CONTEXT).newInstance(condition.getParams()); - return script.execute(new UnmodifiableIngestData( - new DeprecationMap(ingestDocument.getSourceAndMetadata(), DEPRECATIONS, "conditional-processor"))); + return script.execute(new UnmodifiableIngestData(new DynamicMap(ingestDocument.getSourceAndMetadata(), FUNCTIONS))); } public Processor getInnerProcessor() { diff --git a/server/src/main/java/org/elasticsearch/script/AbstractSortScript.java b/server/src/main/java/org/elasticsearch/script/AbstractSortScript.java index 13b109766af..39bc3a649d5 100644 --- a/server/src/main/java/org/elasticsearch/script/AbstractSortScript.java +++ b/server/src/main/java/org/elasticsearch/script/AbstractSortScript.java @@ -18,36 +18,41 @@ */ package org.elasticsearch.script; -import java.io.IOException; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; +import org.apache.logging.log4j.LogManager; import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.search.Scorable; import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.common.logging.DeprecationLogger; import org.elasticsearch.common.lucene.ScorerAware; import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.search.lookup.LeafSearchLookup; import org.elasticsearch.search.lookup.SearchLookup; +import org.elasticsearch.search.lookup.SourceLookup; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; abstract class AbstractSortScript implements ScorerAware { - private static final Map DEPRECATIONS; - - static { - Map deprecations = new HashMap<>(); - deprecations.put( - "doc", - "Accessing variable [doc] via [params.doc] from within a sort-script " + - "is deprecated in favor of directly accessing [doc]." - ); - deprecations.put( - "_doc", - "Accessing variable [doc] via [params._doc] from within a sort-script " + - "is deprecated in favor of directly accessing [doc]." - ); - DEPRECATIONS = Collections.unmodifiableMap(deprecations); - } + private static final DeprecationLogger deprecationLogger = + new DeprecationLogger(LogManager.getLogger(DynamicMap.class)); + private static final Map> PARAMS_FUNCTIONS = org.elasticsearch.common.collect.Map.of( + "doc", value -> { + deprecationLogger.deprecatedAndMaybeLog("sort-script_doc", + "Accessing variable [doc] via [params.doc] from within an sort-script " + + "is deprecated in favor of directly accessing [doc]."); + return value; + }, + "_doc", value -> { + deprecationLogger.deprecatedAndMaybeLog("sort-script__doc", + "Accessing variable [doc] via [params._doc] from within an sort-script " + + "is deprecated in favor of directly accessing [doc]."); + return value; + }, + "_source", value -> ((SourceLookup)value).loadSourceIfNeeded() + ); /** * The generic runtime parameters for the script. @@ -66,7 +71,7 @@ abstract class AbstractSortScript implements ScorerAware { this.leafLookup = lookup.getLeafSearchLookup(leafContext); Map parameters = new HashMap<>(params); parameters.putAll(leafLookup.asMap()); - this.params = new DeprecationMap(parameters, DEPRECATIONS, "sort-script"); + this.params = new DynamicMap(parameters, PARAMS_FUNCTIONS); } protected AbstractSortScript() { diff --git a/server/src/main/java/org/elasticsearch/script/AggregationScript.java b/server/src/main/java/org/elasticsearch/script/AggregationScript.java index 302d3cb6479..6b164fc0724 100644 --- a/server/src/main/java/org/elasticsearch/script/AggregationScript.java +++ b/server/src/main/java/org/elasticsearch/script/AggregationScript.java @@ -18,17 +18,21 @@ */ package org.elasticsearch.script; -import java.io.IOException; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; +import org.apache.logging.log4j.LogManager; import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.search.Scorable; import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.common.logging.DeprecationLogger; import org.elasticsearch.common.lucene.ScorerAware; import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.search.lookup.LeafSearchLookup; import org.elasticsearch.search.lookup.SearchLookup; +import org.elasticsearch.search.lookup.SourceLookup; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; public abstract class AggregationScript implements ScorerAware { @@ -36,22 +40,23 @@ public abstract class AggregationScript implements ScorerAware { public static final ScriptContext CONTEXT = new ScriptContext<>("aggs", Factory.class); - private static final Map DEPRECATIONS; - - static { - Map deprecations = new HashMap<>(); - deprecations.put( - "doc", - "Accessing variable [doc] via [params.doc] from within an aggregation-script " + - "is deprecated in favor of directly accessing [doc]." - ); - deprecations.put( - "_doc", - "Accessing variable [doc] via [params._doc] from within an aggregation-script " + - "is deprecated in favor of directly accessing [doc]." - ); - DEPRECATIONS = Collections.unmodifiableMap(deprecations); - } + private static final DeprecationLogger deprecationLogger = + new DeprecationLogger(LogManager.getLogger(DynamicMap.class)); + private static final Map> PARAMS_FUNCTIONS = org.elasticsearch.common.collect.Map.of( + "doc", value -> { + deprecationLogger.deprecatedAndMaybeLog("aggregation-script_doc", + "Accessing variable [doc] via [params.doc] from within an aggregation-script " + + "is deprecated in favor of directly accessing [doc]."); + return value; + }, + "_doc", value -> { + deprecationLogger.deprecatedAndMaybeLog("aggregation-script__doc", + "Accessing variable [doc] via [params._doc] from within an aggregation-script " + + "is deprecated in favor of directly accessing [doc]."); + return value; + }, + "_source", value -> ((SourceLookup)value).loadSourceIfNeeded() + ); /** * The generic runtime parameters for the script. @@ -71,7 +76,7 @@ public abstract class AggregationScript implements ScorerAware { private Object value; public AggregationScript(Map params, SearchLookup lookup, LeafReaderContext leafContext) { - this.params = new DeprecationMap(new HashMap<>(params), DEPRECATIONS, "aggregation-script"); + this.params = new DynamicMap(new HashMap<>(params), PARAMS_FUNCTIONS); this.leafLookup = lookup.getLeafSearchLookup(leafContext); this.params.putAll(leafLookup.asMap()); } diff --git a/server/src/main/java/org/elasticsearch/script/DeprecationMap.java b/server/src/main/java/org/elasticsearch/script/DynamicMap.java similarity index 72% rename from server/src/main/java/org/elasticsearch/script/DeprecationMap.java rename to server/src/main/java/org/elasticsearch/script/DynamicMap.java index 094baa9e0bd..30dc6147072 100644 --- a/server/src/main/java/org/elasticsearch/script/DeprecationMap.java +++ b/server/src/main/java/org/elasticsearch/script/DynamicMap.java @@ -19,28 +19,26 @@ package org.elasticsearch.script; -import org.apache.logging.log4j.LogManager; -import org.elasticsearch.common.logging.DeprecationLogger; - import java.util.Collection; import java.util.Map; import java.util.Set; +import java.util.function.Function; -public final class DeprecationMap implements Map { - - private static final DeprecationLogger deprecationLogger = - new DeprecationLogger(LogManager.getLogger(DeprecationMap.class)); +/** + * DynamicMap is used to wrap a Map for a script parameter. A set of + * functions is provided for the overridden values where the function + * is applied to the existing value when one exists for the + * corresponding key. + */ +public final class DynamicMap implements Map { private final Map delegate; - private final Map deprecations; + private final Map> functions; - private final String logKeyPrefix; - - public DeprecationMap(Map delegate, Map deprecations, String logKeyPrefix) { + public DynamicMap(Map delegate, Map> functions) { this.delegate = delegate; - this.deprecations = deprecations; - this.logKeyPrefix = logKeyPrefix; + this.functions = functions; } @Override @@ -65,11 +63,12 @@ public final class DeprecationMap implements Map { @Override public Object get(final Object key) { - String deprecationMessage = deprecations.get(key); - if (deprecationMessage != null) { - deprecationLogger.deprecatedAndMaybeLog(logKeyPrefix + "_" + key, deprecationMessage); + Object value = delegate.get(key); + Function function = functions.get(key); + if (function != null) { + value = function.apply(value); } - return delegate.get(key); + return value; } @Override diff --git a/server/src/main/java/org/elasticsearch/script/FieldScript.java b/server/src/main/java/org/elasticsearch/script/FieldScript.java index b68bef276ed..09eac056987 100644 --- a/server/src/main/java/org/elasticsearch/script/FieldScript.java +++ b/server/src/main/java/org/elasticsearch/script/FieldScript.java @@ -19,15 +19,18 @@ package org.elasticsearch.script; +import org.apache.logging.log4j.LogManager; import org.apache.lucene.index.LeafReaderContext; +import org.elasticsearch.common.logging.DeprecationLogger; import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.search.lookup.LeafSearchLookup; import org.elasticsearch.search.lookup.SearchLookup; +import org.elasticsearch.search.lookup.SourceLookup; import java.io.IOException; -import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.function.Function; /** * A script to produce dynamic values for return fields. @@ -36,22 +39,23 @@ public abstract class FieldScript { public static final String[] PARAMETERS = {}; - private static final Map DEPRECATIONS; - - static { - Map deprecations = new HashMap<>(); - deprecations.put( - "doc", - "Accessing variable [doc] via [params.doc] from within a field script " + - "is deprecated in favor of directly accessing [doc]." - ); - deprecations.put( - "_doc", - "Accessing variable [doc] via [params._doc] from within a field script " + - "is deprecated in favor of directly accessing [doc]." - ); - DEPRECATIONS = Collections.unmodifiableMap(deprecations); - } + private static final DeprecationLogger deprecationLogger = + new DeprecationLogger(LogManager.getLogger(DynamicMap.class)); + private static final Map> PARAMS_FUNCTIONS = org.elasticsearch.common.collect.Map.of( + "doc", value -> { + deprecationLogger.deprecatedAndMaybeLog("field-script_doc", + "Accessing variable [doc] via [params.doc] from within an field-script " + + "is deprecated in favor of directly accessing [doc]."); + return value; + }, + "_doc", value -> { + deprecationLogger.deprecatedAndMaybeLog("field-script__doc", + "Accessing variable [doc] via [params._doc] from within an field-script " + + "is deprecated in favor of directly accessing [doc]."); + return value; + }, + "_source", value -> ((SourceLookup)value).loadSourceIfNeeded() + ); /** The generic runtime parameters for the script. */ private final Map params; @@ -63,7 +67,7 @@ public abstract class FieldScript { this.leafLookup = lookup.getLeafSearchLookup(leafContext); params = new HashMap<>(params); params.putAll(leafLookup.asMap()); - this.params = new DeprecationMap(params, DEPRECATIONS, "field-script"); + this.params = new DynamicMap(params, PARAMS_FUNCTIONS); } // for expression engine diff --git a/server/src/main/java/org/elasticsearch/script/ScoreScript.java b/server/src/main/java/org/elasticsearch/script/ScoreScript.java index 76f6de4285c..a72fdea5288 100644 --- a/server/src/main/java/org/elasticsearch/script/ScoreScript.java +++ b/server/src/main/java/org/elasticsearch/script/ScoreScript.java @@ -18,20 +18,23 @@ */ package org.elasticsearch.script; +import org.apache.logging.log4j.LogManager; import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.search.Explanation; import org.apache.lucene.search.Scorable; import org.elasticsearch.Version; +import org.elasticsearch.common.logging.DeprecationLogger; import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.search.lookup.LeafSearchLookup; import org.elasticsearch.search.lookup.SearchLookup; +import org.elasticsearch.search.lookup.SourceLookup; import java.io.IOException; import java.io.UncheckedIOException; -import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.function.DoubleSupplier; +import java.util.function.Function; /** * A script used for adjusting the score on a per document basis. @@ -62,21 +65,23 @@ public abstract class ScoreScript { } } - private static final Map DEPRECATIONS; - static { - Map deprecations = new HashMap<>(); - deprecations.put( - "doc", - "Accessing variable [doc] via [params.doc] from within a score script " + - "is deprecated in favor of directly accessing [doc]." - ); - deprecations.put( - "_doc", - "Accessing variable [doc] via [params._doc] from within a score script " + - "is deprecated in favor of directly accessing [doc]." - ); - DEPRECATIONS = Collections.unmodifiableMap(deprecations); - } + private static final DeprecationLogger deprecationLogger = + new DeprecationLogger(LogManager.getLogger(DynamicMap.class)); + private static final Map> PARAMS_FUNCTIONS = org.elasticsearch.common.collect.Map.of( + "doc", value -> { + deprecationLogger.deprecatedAndMaybeLog("score-script_doc", + "Accessing variable [doc] via [params.doc] from within an score-script " + + "is deprecated in favor of directly accessing [doc]."); + return value; + }, + "_doc", value -> { + deprecationLogger.deprecatedAndMaybeLog("score-script__doc", + "Accessing variable [doc] via [params._doc] from within an score-script " + + "is deprecated in favor of directly accessing [doc]."); + return value; + }, + "_source", value -> ((SourceLookup)value).loadSourceIfNeeded() + ); public static final String[] PARAMETERS = new String[]{ "explanation" }; @@ -106,7 +111,7 @@ public abstract class ScoreScript { this.leafLookup = lookup.getLeafSearchLookup(leafContext); params = new HashMap<>(params); params.putAll(leafLookup.asMap()); - this.params = new DeprecationMap(params, DEPRECATIONS, "score-script"); + this.params = new DynamicMap(params, PARAMS_FUNCTIONS); this.docBase = leafContext.docBase; } } diff --git a/server/src/main/java/org/elasticsearch/script/ScriptedMetricAggContexts.java b/server/src/main/java/org/elasticsearch/script/ScriptedMetricAggContexts.java index 3fc97b60ba9..941a8acb679 100644 --- a/server/src/main/java/org/elasticsearch/script/ScriptedMetricAggContexts.java +++ b/server/src/main/java/org/elasticsearch/script/ScriptedMetricAggContexts.java @@ -19,18 +19,21 @@ package org.elasticsearch.script; +import org.apache.logging.log4j.LogManager; import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.search.Scorable; import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.common.logging.DeprecationLogger; import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.search.lookup.LeafSearchLookup; import org.elasticsearch.search.lookup.SearchLookup; +import org.elasticsearch.search.lookup.SourceLookup; import java.io.IOException; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.Function; public class ScriptedMetricAggContexts { @@ -62,27 +65,29 @@ public class ScriptedMetricAggContexts { } public abstract static class MapScript { - private static final Map DEPRECATIONS; - static { - Map deprecations = new HashMap<>(); - deprecations.put( - "doc", - "Accessing variable [doc] via [params.doc] from within a scripted metric agg map script " + - "is deprecated in favor of directly accessing [doc]." - ); - deprecations.put( - "_doc", - "Accessing variable [doc] via [params._doc] from within a scripted metric agg map script " + - "is deprecated in favor of directly accessing [doc]." - ); - deprecations.put( - "_agg", - "Accessing variable [_agg] via [params._agg] from within a scripted metric agg map script " + - "is deprecated in favor of using [state]." - ); - DEPRECATIONS = Collections.unmodifiableMap(deprecations); - } + private static final DeprecationLogger deprecationLogger = + new DeprecationLogger(LogManager.getLogger(DynamicMap.class)); + private static final Map> PARAMS_FUNCTIONS = org.elasticsearch.common.collect.Map.of( + "doc", value -> { + deprecationLogger.deprecatedAndMaybeLog("map-script_doc", + "Accessing variable [doc] via [params.doc] from within an scripted metric agg map script " + + "is deprecated in favor of directly accessing [doc]."); + return value; + }, + "_doc", value -> { + deprecationLogger.deprecatedAndMaybeLog("map-script__doc", + "Accessing variable [doc] via [params._doc] from within an scripted metric agg map script " + + "is deprecated in favor of directly accessing [doc]."); + return value; + }, "_agg", value -> { + deprecationLogger.deprecatedAndMaybeLog("map-script__agg", + "Accessing variable [_agg] via [params._agg] from within a scripted metric agg map script " + + "is deprecated in favor of using [state]."); + return value; + }, + "_source", value -> ((SourceLookup)value).loadSourceIfNeeded() + ); private final Map params; private final Map state; @@ -95,7 +100,7 @@ public class ScriptedMetricAggContexts { if (leafLookup != null) { params = new HashMap<>(params); // copy params so we aren't modifying input params.putAll(leafLookup.asMap()); // add lookup vars - params = new DeprecationMap(params, DEPRECATIONS, "map-script"); // wrap with deprecations + params = new DynamicMap(params, PARAMS_FUNCTIONS); // wrap with deprecations } this.params = params; } diff --git a/server/src/main/java/org/elasticsearch/script/TermsSetQueryScript.java b/server/src/main/java/org/elasticsearch/script/TermsSetQueryScript.java index c7ae36c5b01..d06e8ab9691 100644 --- a/server/src/main/java/org/elasticsearch/script/TermsSetQueryScript.java +++ b/server/src/main/java/org/elasticsearch/script/TermsSetQueryScript.java @@ -18,14 +18,18 @@ */ package org.elasticsearch.script; -import java.io.IOException; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; +import org.apache.logging.log4j.LogManager; import org.apache.lucene.index.LeafReaderContext; +import org.elasticsearch.common.logging.DeprecationLogger; import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.search.lookup.LeafSearchLookup; import org.elasticsearch.search.lookup.SearchLookup; +import org.elasticsearch.search.lookup.SourceLookup; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; public abstract class TermsSetQueryScript { @@ -33,22 +37,23 @@ public abstract class TermsSetQueryScript { public static final ScriptContext CONTEXT = new ScriptContext<>("terms_set", Factory.class); - private static final Map DEPRECATIONS; - - static { - Map deprecations = new HashMap<>(); - deprecations.put( - "doc", - "Accessing variable [doc] via [params.doc] from within a terms-set-query-script " + - "is deprecated in favor of directly accessing [doc]." - ); - deprecations.put( - "_doc", - "Accessing variable [doc] via [params._doc] from within a terms-set-query-script " + - "is deprecated in favor of directly accessing [doc]." - ); - DEPRECATIONS = Collections.unmodifiableMap(deprecations); - } + private static final DeprecationLogger deprecationLogger = + new DeprecationLogger(LogManager.getLogger(DynamicMap.class)); + private static final Map> PARAMS_FUNCTIONS = org.elasticsearch.common.collect.Map.of( + "doc", value -> { + deprecationLogger.deprecatedAndMaybeLog("terms-set-query-script_doc", + "Accessing variable [doc] via [params.doc] from within an terms-set-query-script " + + "is deprecated in favor of directly accessing [doc]."); + return value; + }, + "_doc", value -> { + deprecationLogger.deprecatedAndMaybeLog("terms-set-query-script__doc", + "Accessing variable [doc] via [params._doc] from within an terms-set-query-script " + + "is deprecated in favor of directly accessing [doc]."); + return value; + }, + "_source", value -> ((SourceLookup)value).loadSourceIfNeeded() + ); /** * The generic runtime parameters for the script. @@ -64,7 +69,7 @@ public abstract class TermsSetQueryScript { Map parameters = new HashMap<>(params); this.leafLookup = lookup.getLeafSearchLookup(leafContext); parameters.putAll(leafLookup.asMap()); - this.params = new DeprecationMap(parameters, DEPRECATIONS, "term-set-query-script"); + this.params = new DynamicMap(parameters, PARAMS_FUNCTIONS); } protected TermsSetQueryScript() { diff --git a/server/src/main/java/org/elasticsearch/script/UpdateScript.java b/server/src/main/java/org/elasticsearch/script/UpdateScript.java index 765489b7e44..c1bc2a34d2a 100644 --- a/server/src/main/java/org/elasticsearch/script/UpdateScript.java +++ b/server/src/main/java/org/elasticsearch/script/UpdateScript.java @@ -20,24 +20,25 @@ package org.elasticsearch.script; -import java.util.Collections; -import java.util.HashMap; +import org.apache.logging.log4j.LogManager; +import org.elasticsearch.common.logging.DeprecationLogger; + import java.util.Map; +import java.util.function.Function; /** * An update script. */ public abstract class UpdateScript { - private static final Map DEPRECATIONS; - static { - Map deprecations = new HashMap<>(); - deprecations.put( - "_type", - "[types removal] Looking up doc types [_type] in scripts is deprecated." - ); - DEPRECATIONS = Collections.unmodifiableMap(deprecations); - } + private static final DeprecationLogger deprecationLogger = + new DeprecationLogger(LogManager.getLogger(DynamicMap.class)); + private static final Map> PARAMS_FUNCTIONS = org.elasticsearch.common.collect.Map.of( + "_type", value -> { + deprecationLogger.deprecatedAndMaybeLog("update-script", + "[types removal] Looking up doc types [_type] in scripts is deprecated."); + return value; + }); public static final String[] PARAMETERS = { }; @@ -52,7 +53,7 @@ public abstract class UpdateScript { public UpdateScript(Map params, Map ctx) { this.params = params; - this.ctx = new DeprecationMap(ctx, DEPRECATIONS, "update-script"); + this.ctx = new DynamicMap(ctx, PARAMS_FUNCTIONS); } /** Return the parameters for this script. */ diff --git a/server/src/main/java/org/elasticsearch/search/lookup/SourceLookup.java b/server/src/main/java/org/elasticsearch/search/lookup/SourceLookup.java index aa4a641d98e..2cf8b4aac5f 100644 --- a/server/src/main/java/org/elasticsearch/search/lookup/SourceLookup.java +++ b/server/src/main/java/org/elasticsearch/search/lookup/SourceLookup.java @@ -54,7 +54,11 @@ public class SourceLookup implements Map { return sourceContentType; } - private Map loadSourceIfNeeded() { + // Scripting requires this method to be public. Using source() + // is not possible because certain checks use source == null as + // as a determination if source is enabled/disabled, but it should + // never be a null Map for scripting even when disabled. + public Map loadSourceIfNeeded() { if (source != null) { return source; }