Add types deprecation to script contexts (#37554)

This adds deprecation to _type in the script contexts for ingest and update. 
This adds a DeprecationMap that wraps the ctx Map containing _type for these 
specific contexts.
This commit is contained in:
Jack Conradson 2019-01-18 09:13:49 -08:00 committed by GitHub
parent 6846666b6b
commit de55b4dfd1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 133 additions and 13 deletions

View File

@ -30,6 +30,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.IngestScript;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptException;
@ -37,6 +38,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 static org.elasticsearch.ingest.ConfigurationUtils.newConfigurationException;
@ -46,6 +49,16 @@ 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);
}
public static final String TYPE = "script";
private final Script script;
@ -72,7 +85,8 @@ public final class ScriptProcessor extends AbstractProcessor {
@Override
public IngestDocument execute(IngestDocument document) {
IngestScript.Factory factory = scriptService.compile(script, IngestScript.CONTEXT);
factory.newInstance(script.getParams()).execute(document.getSourceAndMetadata());
factory.newInstance(script.getParams()).execute(
new DeprecationMap(document.getSourceAndMetadata(), DEPRECATIONS, "script_processor"));
CollectionUtils.ensureNoSelfReferences(document.getSourceAndMetadata(), "ingest script");
return document;
}

View File

@ -74,4 +74,28 @@ public class ScriptProcessorTests extends ESTestCase {
assertThat(ingestDocument.getSourceAndMetadata(), hasKey("bytes_total"));
assertThat(ingestDocument.getSourceAndMetadata().get("bytes_total"), is(randomBytesTotal));
}
public void testTypeDeprecation() throws Exception {
String scriptName = "script";
ScriptService scriptService = new ScriptService(Settings.builder().build(),
Collections.singletonMap(
Script.DEFAULT_SCRIPT_LANG, new MockScriptEngine(
Script.DEFAULT_SCRIPT_LANG,
Collections.singletonMap(
scriptName, ctx -> {
ctx.get("_type");
return null;
}
),
Collections.emptyMap()
)
),
new HashMap<>(ScriptModule.CORE_CONTEXTS)
);
Script script = new Script(ScriptType.INLINE, Script.DEFAULT_SCRIPT_LANG, scriptName, Collections.emptyMap());
IngestDocument ingestDocument = RandomDocumentPicks.randomIngestDocument(random(), Collections.emptyMap());
ScriptProcessor processor = new ScriptProcessor(randomAlphaOfLength(10), script, scriptService);
processor.execute(ingestDocument);
assertWarnings("[types removal] Looking up doc types [_type] in scripts is deprecated.");
}
}

View File

@ -58,7 +58,7 @@ public abstract class AbstractAsyncBulkByScrollActionScriptTestCase<
UpdateScript.Factory factory = (params, ctx) -> new UpdateScript(Collections.emptyMap(), ctx) {
@Override
public void execute() {
scriptBody.accept(ctx);
scriptBody.accept(getCtx());
}
};;
when(scriptService.compile(any(), eq(UpdateScript.CONTEXT))).thenReturn(factory);
@ -67,6 +67,11 @@ public abstract class AbstractAsyncBulkByScrollActionScriptTestCase<
return (result != null) ? (T) result.self() : null;
}
public void testTypeDeprecation() {
applyScript((Map<String, Object> ctx) -> ctx.get("_type"));
assertWarnings("[types removal] Looking up doc types [_type] in scripts is deprecated.");
}
public void testScriptAddingJunkToCtxIsError() {
try {
applyScript((Map<String, Object> ctx) -> ctx.put("junk", "junk"));

View File

@ -23,6 +23,7 @@ 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,12 +32,24 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
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 {
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);
}
static final String TYPE = "conditional";
private final Script condition;
@ -81,7 +94,8 @@ public class ConditionalProcessor extends AbstractProcessor {
boolean evaluate(IngestDocument ingestDocument) {
IngestConditionalScript script =
scriptService.compile(condition, IngestConditionalScript.CONTEXT).newInstance(condition.getParams());
return script.execute(new UnmodifiableIngestData(ingestDocument.getSourceAndMetadata()));
return script.execute(new UnmodifiableIngestData(
new DeprecationMap(ingestDocument.getSourceAndMetadata(), DEPRECATIONS, "conditional-processor")));
}
Processor getProcessor() {

View File

@ -66,7 +66,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);
this.params = new DeprecationMap(parameters, DEPRECATIONS, "sort-script");
}
protected AbstractSortScript() {

View File

@ -71,7 +71,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);
this.params = new DeprecationMap(new HashMap<>(params), DEPRECATIONS, "aggregation-script");
this.leafLookup = lookup.getLeafSearchLookup(leafContext);
this.params.putAll(leafLookup.asMap());
}

View File

@ -35,9 +35,12 @@ public final class DeprecationMap implements Map<String, Object> {
private final Map<String, String> deprecations;
public DeprecationMap(Map<String, Object> delegate, Map<String, String> deprecations) {
private final String logKeyPrefix;
public DeprecationMap(Map<String, Object> delegate, Map<String, String> deprecations, String logKeyPrefix) {
this.delegate = delegate;
this.deprecations = deprecations;
this.logKeyPrefix = logKeyPrefix;
}
@Override
@ -64,7 +67,7 @@ public final class DeprecationMap implements Map<String, Object> {
public Object get(final Object key) {
String deprecationMessage = deprecations.get(key);
if (deprecationMessage != null) {
deprecationLogger.deprecated(deprecationMessage);
deprecationLogger.deprecatedAndMaybeLog(logKeyPrefix + "_" + key, deprecationMessage);
}
return delegate.get(key);
}

View File

@ -63,7 +63,7 @@ public abstract class FieldScript {
this.leafLookup = lookup.getLeafSearchLookup(leafContext);
params = new HashMap<>(params);
params.putAll(leafLookup.asMap());
this.params = new DeprecationMap(params, DEPRECATIONS);
this.params = new DeprecationMap(params, DEPRECATIONS, "field-script");
}
// for expression engine

View File

@ -73,7 +73,7 @@ public abstract class ScoreScript {
this.leafLookup = lookup.getLeafSearchLookup(leafContext);
params = new HashMap<>(params);
params.putAll(leafLookup.asMap());
this.params = new DeprecationMap(params, DEPRECATIONS);
this.params = new DeprecationMap(params, DEPRECATIONS, "score-script");
}
}

View File

@ -95,7 +95,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); // wrap with deprecations
params = new DeprecationMap(params, DEPRECATIONS, "map-script"); // wrap with deprecations
}
this.params = params;
}

View File

@ -64,7 +64,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);
this.params = new DeprecationMap(parameters, DEPRECATIONS, "term-set-query-script");
}
protected TermsSetQueryScript() {

View File

@ -20,6 +20,8 @@
package org.elasticsearch.script;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
@ -27,6 +29,16 @@ import java.util.Map;
*/
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);
}
public static final String[] PARAMETERS = { };
/** The context used to compile {@link UpdateScript} factories. */
@ -40,7 +52,7 @@ public abstract class UpdateScript {
public UpdateScript(Map<String, Object> params, Map<String, Object> ctx) {
this.params = params;
this.ctx = ctx;
this.ctx = new DeprecationMap(ctx, DEPRECATIONS, "update-script");
}
/** Return the parameters for this script. */

View File

@ -44,7 +44,7 @@ public class LeafDocLookup implements Map<String, ScriptDocValues<?>> {
= new DeprecationLogger(LogManager.getLogger(LeafDocLookup.class));
static final String TYPES_DEPRECATION_KEY = "type-field-doc-lookup";
static final String TYPES_DEPRECATION_MESSAGE =
"[types removal] Looking up doc types in scripts is deprecated.";
"[types removal] Looking up doc types [_type] in scripts is deprecated.";
private final Map<String, ScriptDocValues<?>> localCacheFieldData = new HashMap<>(4);

View File

@ -133,6 +133,54 @@ public class ConditionalProcessorTests extends ESTestCase {
assertMutatingCtxThrows(ctx -> ((List<Object>)ctx.get("listField")).remove("bar"));
}
public void testTypeDeprecation() throws Exception {
String scriptName = "conditionalScript";
ScriptService scriptService = new ScriptService(Settings.builder().build(),
Collections.singletonMap(
Script.DEFAULT_SCRIPT_LANG,
new MockScriptEngine(
Script.DEFAULT_SCRIPT_LANG,
Collections.singletonMap(
scriptName, ctx -> {
ctx.get("_type");
return true;
}
),
Collections.emptyMap()
)
),
new HashMap<>(ScriptModule.CORE_CONTEXTS)
);
LongSupplier relativeTimeProvider = mock(LongSupplier.class);
when(relativeTimeProvider.getAsLong()).thenReturn(0L, TimeUnit.MILLISECONDS.toNanos(1), 0L, TimeUnit.MILLISECONDS.toNanos(2));
ConditionalProcessor processor = new ConditionalProcessor(
randomAlphaOfLength(10),
new Script(
ScriptType.INLINE, Script.DEFAULT_SCRIPT_LANG,
scriptName, Collections.emptyMap()), scriptService,
new Processor() {
@Override
public IngestDocument execute(final IngestDocument ingestDocument){
return ingestDocument;
}
@Override
public String getType() {
return null;
}
@Override
public String getTag() {
return null;
}
}, relativeTimeProvider);
IngestDocument ingestDocument = RandomDocumentPicks.randomIngestDocument(random(), Collections.emptyMap());
processor.execute(ingestDocument);
assertWarnings("[types removal] Looking up doc types [_type] in scripts is deprecated.");
}
private static void assertMutatingCtxThrows(Consumer<Map<String, Object>> mutation) throws Exception {
String scriptName = "conditionalScript";
CompletableFuture<Exception> expectedException = new CompletableFuture<>();