Backports for _source bug fix in scripting (#57068)

* Update DeprecationMap to DynamicMap (#56149)

This renames DeprecationMap to DynamicMap, and changes the deprecation
messages Map to accept a Map of String (keys) to Functions (updated values)
instead. This creates more flexibility in either logging or updating values from
params within a script. This change is required to fix (#52103) in a future PR.

* Fix Source Return Bug in Scripting (#56831)

This change ensures that when a user returns _source directly no matter where 
accessed within scripting, the value is a Map of the converted source as 
opposed to a SourceLookup.
This commit is contained in:
Jack Conradson 2020-05-21 17:07:38 -07:00 committed by GitHub
parent 4cf49bc05e
commit 35c546b388
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 242 additions and 182 deletions

View File

@ -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<String, String> DEPRECATIONS;
static {
Map<String, String> 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<String, Function<Object, Object>> 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;
}

View File

@ -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<String, Object> params = new HashMap<>();
Map<String, Object> 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"));
}

View File

@ -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<String, String> DEPRECATIONS;
static {
Map<String, String> 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<String, Function<Object, Object>> 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() {

View File

@ -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<String, String> DEPRECATIONS;
static {
Map<String, String> 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<String, Function<Object, Object>> 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<String, Object> 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() {

View File

@ -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<Factory> CONTEXT = new ScriptContext<>("aggs", Factory.class);
private static final Map<String, String> DEPRECATIONS;
static {
Map<String, String> 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<String, Function<Object, Object>> 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<String, Object> 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());
}

View File

@ -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<String, Object> {
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<String, Object> {
private final Map<String, Object> delegate;
private final Map<String, String> deprecations;
private final Map<String, Function<Object, Object>> functions;
private final String logKeyPrefix;
public DeprecationMap(Map<String, Object> delegate, Map<String, String> deprecations, String logKeyPrefix) {
public DynamicMap(Map<String, Object> delegate, Map<String, Function<Object, Object>> functions) {
this.delegate = delegate;
this.deprecations = deprecations;
this.logKeyPrefix = logKeyPrefix;
this.functions = functions;
}
@Override
@ -65,11 +63,12 @@ public final class DeprecationMap implements Map<String, Object> {
@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<Object, Object> function = functions.get(key);
if (function != null) {
value = function.apply(value);
}
return delegate.get(key);
return value;
}
@Override

View File

@ -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<String, String> DEPRECATIONS;
static {
Map<String, String> 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<String, Function<Object, Object>> 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<String, Object> 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

View File

@ -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<String, String> DEPRECATIONS;
static {
Map<String, String> 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<String, Function<Object, Object>> 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;
}
}

View File

@ -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<String, String> DEPRECATIONS;
static {
Map<String, String> 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<String, Function<Object, Object>> 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<String, Object> params;
private final Map<String, Object> 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;
}

View File

@ -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<Factory> CONTEXT = new ScriptContext<>("terms_set", Factory.class);
private static final Map<String, String> DEPRECATIONS;
static {
Map<String, String> 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<String, Function<Object, Object>> 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<String, Object> 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() {

View File

@ -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<String, String> DEPRECATIONS;
static {
Map<String, String> 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<String, Function<Object, Object>> 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<String, Object> params, Map<String, Object> 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. */

View File

@ -54,7 +54,11 @@ public class SourceLookup implements Map {
return sourceContentType;
}
private Map<String, Object> 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<String, Object> loadSourceIfNeeded() {
if (source != null) {
return source;
}