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.AbstractProcessor;
import org.elasticsearch.ingest.IngestDocument; import org.elasticsearch.ingest.IngestDocument;
import org.elasticsearch.ingest.Processor; import org.elasticsearch.ingest.Processor;
import org.elasticsearch.script.DeprecationMap;
import org.elasticsearch.script.IngestScript; import org.elasticsearch.script.IngestScript;
import org.elasticsearch.script.Script; import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptException; import org.elasticsearch.script.ScriptException;
@ -37,6 +38,8 @@ import org.elasticsearch.script.ScriptService;
import java.io.InputStream; import java.io.InputStream;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import static org.elasticsearch.ingest.ConfigurationUtils.newConfigurationException; import static org.elasticsearch.ingest.ConfigurationUtils.newConfigurationException;
@ -46,6 +49,16 @@ import static org.elasticsearch.ingest.ConfigurationUtils.newConfigurationExcept
*/ */
public final class ScriptProcessor extends AbstractProcessor { 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"; public static final String TYPE = "script";
private final Script script; private final Script script;
@ -72,7 +85,8 @@ public final class ScriptProcessor extends AbstractProcessor {
@Override @Override
public IngestDocument execute(IngestDocument document) { public IngestDocument execute(IngestDocument document) {
IngestScript.Factory factory = scriptService.compile(script, IngestScript.CONTEXT); 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"); CollectionUtils.ensureNoSelfReferences(document.getSourceAndMetadata(), "ingest script");
return document; return document;
} }

View File

@ -74,4 +74,28 @@ public class ScriptProcessorTests extends ESTestCase {
assertThat(ingestDocument.getSourceAndMetadata(), hasKey("bytes_total")); assertThat(ingestDocument.getSourceAndMetadata(), hasKey("bytes_total"));
assertThat(ingestDocument.getSourceAndMetadata().get("bytes_total"), is(randomBytesTotal)); 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) { UpdateScript.Factory factory = (params, ctx) -> new UpdateScript(Collections.emptyMap(), ctx) {
@Override @Override
public void execute() { public void execute() {
scriptBody.accept(ctx); scriptBody.accept(getCtx());
} }
};; };;
when(scriptService.compile(any(), eq(UpdateScript.CONTEXT))).thenReturn(factory); when(scriptService.compile(any(), eq(UpdateScript.CONTEXT))).thenReturn(factory);
@ -67,6 +67,11 @@ public abstract class AbstractAsyncBulkByScrollActionScriptTestCase<
return (result != null) ? (T) result.self() : null; 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() { public void testScriptAddingJunkToCtxIsError() {
try { try {
applyScript((Map<String, Object> ctx) -> ctx.put("junk", "junk")); 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.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
@ -31,12 +32,24 @@ import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.LongSupplier; import java.util.function.LongSupplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.elasticsearch.script.DeprecationMap;
import org.elasticsearch.script.IngestConditionalScript; import org.elasticsearch.script.IngestConditionalScript;
import org.elasticsearch.script.Script; import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptService; import org.elasticsearch.script.ScriptService;
public class ConditionalProcessor extends AbstractProcessor { 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"; static final String TYPE = "conditional";
private final Script condition; private final Script condition;
@ -81,7 +94,8 @@ public class ConditionalProcessor extends AbstractProcessor {
boolean evaluate(IngestDocument ingestDocument) { boolean evaluate(IngestDocument ingestDocument) {
IngestConditionalScript script = IngestConditionalScript script =
scriptService.compile(condition, IngestConditionalScript.CONTEXT).newInstance(condition.getParams()); 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() { Processor getProcessor() {

View File

@ -66,7 +66,7 @@ abstract class AbstractSortScript implements ScorerAware {
this.leafLookup = lookup.getLeafSearchLookup(leafContext); this.leafLookup = lookup.getLeafSearchLookup(leafContext);
Map<String, Object> parameters = new HashMap<>(params); Map<String, Object> parameters = new HashMap<>(params);
parameters.putAll(leafLookup.asMap()); parameters.putAll(leafLookup.asMap());
this.params = new DeprecationMap(parameters, DEPRECATIONS); this.params = new DeprecationMap(parameters, DEPRECATIONS, "sort-script");
} }
protected AbstractSortScript() { protected AbstractSortScript() {

View File

@ -71,7 +71,7 @@ public abstract class AggregationScript implements ScorerAware {
private Object value; private Object value;
public AggregationScript(Map<String, Object> params, SearchLookup lookup, LeafReaderContext leafContext) { 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.leafLookup = lookup.getLeafSearchLookup(leafContext);
this.params.putAll(leafLookup.asMap()); 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; 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.delegate = delegate;
this.deprecations = deprecations; this.deprecations = deprecations;
this.logKeyPrefix = logKeyPrefix;
} }
@Override @Override
@ -64,7 +67,7 @@ public final class DeprecationMap implements Map<String, Object> {
public Object get(final Object key) { public Object get(final Object key) {
String deprecationMessage = deprecations.get(key); String deprecationMessage = deprecations.get(key);
if (deprecationMessage != null) { if (deprecationMessage != null) {
deprecationLogger.deprecated(deprecationMessage); deprecationLogger.deprecatedAndMaybeLog(logKeyPrefix + "_" + key, deprecationMessage);
} }
return delegate.get(key); return delegate.get(key);
} }

View File

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

View File

@ -73,7 +73,7 @@ public abstract class ScoreScript {
this.leafLookup = lookup.getLeafSearchLookup(leafContext); this.leafLookup = lookup.getLeafSearchLookup(leafContext);
params = new HashMap<>(params); params = new HashMap<>(params);
params.putAll(leafLookup.asMap()); 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) { if (leafLookup != null) {
params = new HashMap<>(params); // copy params so we aren't modifying input params = new HashMap<>(params); // copy params so we aren't modifying input
params.putAll(leafLookup.asMap()); // add lookup vars 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; this.params = params;
} }

View File

@ -64,7 +64,7 @@ public abstract class TermsSetQueryScript {
Map<String, Object> parameters = new HashMap<>(params); Map<String, Object> parameters = new HashMap<>(params);
this.leafLookup = lookup.getLeafSearchLookup(leafContext); this.leafLookup = lookup.getLeafSearchLookup(leafContext);
parameters.putAll(leafLookup.asMap()); parameters.putAll(leafLookup.asMap());
this.params = new DeprecationMap(parameters, DEPRECATIONS); this.params = new DeprecationMap(parameters, DEPRECATIONS, "term-set-query-script");
} }
protected TermsSetQueryScript() { protected TermsSetQueryScript() {

View File

@ -20,6 +20,8 @@
package org.elasticsearch.script; package org.elasticsearch.script;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
@ -27,6 +29,16 @@ import java.util.Map;
*/ */
public abstract class UpdateScript { 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 = { }; public static final String[] PARAMETERS = { };
/** The context used to compile {@link UpdateScript} factories. */ /** 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) { public UpdateScript(Map<String, Object> params, Map<String, Object> ctx) {
this.params = params; this.params = params;
this.ctx = ctx; this.ctx = new DeprecationMap(ctx, DEPRECATIONS, "update-script");
} }
/** Return the parameters for this 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)); = new DeprecationLogger(LogManager.getLogger(LeafDocLookup.class));
static final String TYPES_DEPRECATION_KEY = "type-field-doc-lookup"; static final String TYPES_DEPRECATION_KEY = "type-field-doc-lookup";
static final String TYPES_DEPRECATION_MESSAGE = 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); 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")); 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 { private static void assertMutatingCtxThrows(Consumer<Map<String, Object>> mutation) throws Exception {
String scriptName = "conditionalScript"; String scriptName = "conditionalScript";
CompletableFuture<Exception> expectedException = new CompletableFuture<>(); CompletableFuture<Exception> expectedException = new CompletableFuture<>();