Merge branch 'master' into ccr

* master:
  Replace Ingest ScriptContext with Custom Interface (#32003)
  Mute failing tests
This commit is contained in:
Nhat Nguyen 2018-07-13 18:08:34 -04:00
commit 89a590a59a
10 changed files with 110 additions and 39 deletions

View File

@ -31,7 +31,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.ExecutableScript; 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;
import org.elasticsearch.script.ScriptService; import org.elasticsearch.script.ScriptService;
@ -73,10 +73,8 @@ public final class ScriptProcessor extends AbstractProcessor {
*/ */
@Override @Override
public void execute(IngestDocument document) { public void execute(IngestDocument document) {
ExecutableScript.Factory factory = scriptService.compile(script, ExecutableScript.INGEST_CONTEXT); IngestScript.Factory factory = scriptService.compile(script, IngestScript.CONTEXT);
ExecutableScript executableScript = factory.newInstance(script.getParams()); factory.newInstance(script.getParams()).execute(document.getSourceAndMetadata());
executableScript.setNextVar("ctx", document.getSourceAndMetadata());
executableScript.run();
} }
@Override @Override
@ -108,7 +106,7 @@ public final class ScriptProcessor extends AbstractProcessor {
// verify script is able to be compiled before successfully creating processor. // verify script is able to be compiled before successfully creating processor.
try { try {
scriptService.compile(script, ExecutableScript.INGEST_CONTEXT); scriptService.compile(script, IngestScript.CONTEXT);
} catch (ScriptException e) { } catch (ScriptException e) {
throw newConfigurationException(TYPE, processorTag, null, e); throw newConfigurationException(TYPE, processorTag, null, e);
} }

View File

@ -58,9 +58,7 @@ public class IngestRestartIT extends ESIntegTestCase {
public static class CustomScriptPlugin extends MockScriptPlugin { public static class CustomScriptPlugin extends MockScriptPlugin {
@Override @Override
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() { protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
return Collections.singletonMap("my_script", script -> { return Collections.singletonMap("my_script", ctx -> {
@SuppressWarnings("unchecked")
Map<String, Object> ctx = (Map<String, Object>) script.get("ctx");
ctx.put("z", 0); ctx.put("z", 0);
return null; return null;
}); });

View File

@ -19,22 +19,22 @@
package org.elasticsearch.ingest.common; package org.elasticsearch.ingest.common;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.ingest.IngestDocument; import org.elasticsearch.ingest.IngestDocument;
import org.elasticsearch.ingest.RandomDocumentPicks; import org.elasticsearch.ingest.RandomDocumentPicks;
import org.elasticsearch.script.ExecutableScript; import org.elasticsearch.script.MockScriptEngine;
import org.elasticsearch.script.Script; import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptModule;
import org.elasticsearch.script.ScriptService; import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.ScriptType;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import static org.hamcrest.Matchers.hasKey; import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.core.Is.is; import static org.hamcrest.core.Is.is;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class ScriptProcessorTests extends ESTestCase { public class ScriptProcessorTests extends ESTestCase {
@ -42,24 +42,28 @@ public class ScriptProcessorTests extends ESTestCase {
int randomBytesIn = randomInt(); int randomBytesIn = randomInt();
int randomBytesOut = randomInt(); int randomBytesOut = randomInt();
int randomBytesTotal = randomBytesIn + randomBytesOut; int randomBytesTotal = randomBytesIn + randomBytesOut;
String scriptName = "script";
ScriptService scriptService = mock(ScriptService.class); ScriptService scriptService = new ScriptService(Settings.builder().build(),
Script script = mockScript("_script"); Collections.singletonMap(
ExecutableScript.Factory factory = mock(ExecutableScript.Factory.class); Script.DEFAULT_SCRIPT_LANG, new MockScriptEngine(
ExecutableScript executableScript = mock(ExecutableScript.class); Script.DEFAULT_SCRIPT_LANG,
when(scriptService.compile(script, ExecutableScript.INGEST_CONTEXT)).thenReturn(factory); Collections.singletonMap(
when(factory.newInstance(any())).thenReturn(executableScript); scriptName, ctx -> {
ctx.put("bytes_total", randomBytesTotal);
return null;
}
)
)
),
new HashMap<>(ScriptModule.CORE_CONTEXTS)
);
Script script = new Script(ScriptType.INLINE, Script.DEFAULT_SCRIPT_LANG, scriptName, Collections.emptyMap());
Map<String, Object> document = new HashMap<>(); Map<String, Object> document = new HashMap<>();
document.put("bytes_in", randomInt()); document.put("bytes_in", randomInt());
document.put("bytes_out", randomInt()); document.put("bytes_out", randomInt());
IngestDocument ingestDocument = RandomDocumentPicks.randomIngestDocument(random(), document); IngestDocument ingestDocument = RandomDocumentPicks.randomIngestDocument(random(), document);
doAnswer(invocationOnMock -> {
ingestDocument.setFieldValue("bytes_total", randomBytesTotal);
return null;
}).when(executableScript).run();
ScriptProcessor processor = new ScriptProcessor(randomAlphaOfLength(10), script, scriptService); ScriptProcessor processor = new ScriptProcessor(randomAlphaOfLength(10), script, scriptService);
processor.execute(ingestDocument); processor.execute(ingestDocument);

View File

@ -13,8 +13,9 @@ setup:
--- ---
"Nested inner hits": "Nested inner hits":
- skip: - skip:
version: " - 6.1.99" version: "all"
reason: "<= 6.1 nodes don't always include index or id in nested inner hits" reason: "https://github.com/elastic/elasticsearch/issues/32055"
- do: - do:
index: index:
index: test index: test
@ -45,8 +46,8 @@ setup:
"Nested doc version and seqIDs": "Nested doc version and seqIDs":
- skip: - skip:
version: " - 6.3.99" version: "all"
reason: "object notation for docvalue_fields was introduced in 6.4" reason: "https://github.com/elastic/elasticsearch/issues/32055"
- do: - do:
index: index:

View File

@ -107,6 +107,9 @@ setup:
--- ---
"field collapsing and inner_hits": "field collapsing and inner_hits":
- skip:
version: "all"
reason: "https://github.com/elastic/elasticsearch/issues/32055"
- do: - do:
search: search:
@ -146,6 +149,9 @@ setup:
--- ---
"field collapsing, inner_hits and maxConcurrentGroupRequests": "field collapsing, inner_hits and maxConcurrentGroupRequests":
- skip:
version: "all"
reason: "https://github.com/elastic/elasticsearch/issues/32055"
- do: - do:
search: search:
@ -226,6 +232,9 @@ setup:
--- ---
"no hits and inner_hits": "no hits and inner_hits":
- skip:
version: "all"
reason: "https://github.com/elastic/elasticsearch/issues/32055"
- do: - do:
search: search:
@ -240,6 +249,9 @@ setup:
--- ---
"field collapsing and multiple inner_hits": "field collapsing and multiple inner_hits":
- skip:
version: "all"
reason: "https://github.com/elastic/elasticsearch/issues/32055"
- do: - do:
search: search:
@ -292,10 +304,9 @@ setup:
--- ---
"field collapsing, inner_hits and version": "field collapsing, inner_hits and version":
- skip: - skip:
version: " - 6.1.0" version: "all"
reason: "bug fixed in 6.1.1" reason: "https://github.com/elastic/elasticsearch/issues/32055"
- do: - do:
search: search:

View File

@ -50,5 +50,4 @@ public interface ExecutableScript {
// TODO: remove these once each has its own script interface // TODO: remove these once each has its own script interface
ScriptContext<Factory> AGGS_CONTEXT = new ScriptContext<>("aggs_executable", Factory.class); ScriptContext<Factory> AGGS_CONTEXT = new ScriptContext<>("aggs_executable", Factory.class);
ScriptContext<Factory> UPDATE_CONTEXT = new ScriptContext<>("update", Factory.class); ScriptContext<Factory> UPDATE_CONTEXT = new ScriptContext<>("update", Factory.class);
ScriptContext<Factory> INGEST_CONTEXT = new ScriptContext<>("ingest", Factory.class);
} }

View File

@ -0,0 +1,52 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.script;
import java.util.Map;
/**
* A script used by the Ingest Script Processor.
*/
public abstract class IngestScript {
public static final String[] PARAMETERS = { "ctx" };
/** The context used to compile {@link IngestScript} factories. */
public static final ScriptContext<Factory> CONTEXT = new ScriptContext<>("ingest", Factory.class);
/** The generic runtime parameters for the script. */
private final Map<String, Object> params;
public IngestScript(Map<String, Object> params) {
this.params = params;
}
/** Return the parameters for this script. */
public Map<String, Object> getParams() {
return params;
}
public abstract void execute(Map<String, Object> ctx);
public interface Factory {
IngestScript newInstance(Map<String, Object> params);
}
}

View File

@ -51,7 +51,7 @@ public class ScriptModule {
ExecutableScript.CONTEXT, ExecutableScript.CONTEXT,
ExecutableScript.AGGS_CONTEXT, ExecutableScript.AGGS_CONTEXT,
ExecutableScript.UPDATE_CONTEXT, ExecutableScript.UPDATE_CONTEXT,
ExecutableScript.INGEST_CONTEXT, IngestScript.CONTEXT,
FilterScript.CONTEXT, FilterScript.CONTEXT,
SimilarityScript.CONTEXT, SimilarityScript.CONTEXT,
SimilarityWeightScript.CONTEXT, SimilarityWeightScript.CONTEXT,

View File

@ -168,7 +168,7 @@ public class ScriptServiceTests extends ESTestCase {
assertCompileAccepted("painless", "script", ScriptType.INLINE, SearchScript.CONTEXT); assertCompileAccepted("painless", "script", ScriptType.INLINE, SearchScript.CONTEXT);
assertCompileAccepted("painless", "script", ScriptType.INLINE, SearchScript.AGGS_CONTEXT); assertCompileAccepted("painless", "script", ScriptType.INLINE, SearchScript.AGGS_CONTEXT);
assertCompileAccepted("painless", "script", ScriptType.INLINE, ExecutableScript.UPDATE_CONTEXT); assertCompileAccepted("painless", "script", ScriptType.INLINE, ExecutableScript.UPDATE_CONTEXT);
assertCompileAccepted("painless", "script", ScriptType.INLINE, ExecutableScript.INGEST_CONTEXT); assertCompileAccepted("painless", "script", ScriptType.INLINE, IngestScript.CONTEXT);
} }
public void testAllowSomeScriptTypeSettings() throws IOException { public void testAllowSomeScriptTypeSettings() throws IOException {
@ -209,13 +209,13 @@ public class ScriptServiceTests extends ESTestCase {
} }
public void testCompileNonRegisteredContext() throws IOException { public void testCompileNonRegisteredContext() throws IOException {
contexts.remove(ExecutableScript.INGEST_CONTEXT.name); contexts.remove(IngestScript.CONTEXT.name);
buildScriptService(Settings.EMPTY); buildScriptService(Settings.EMPTY);
String type = scriptEngine.getType(); String type = scriptEngine.getType();
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () ->
scriptService.compile(new Script(ScriptType.INLINE, type, "test", Collections.emptyMap()), ExecutableScript.INGEST_CONTEXT)); scriptService.compile(new Script(ScriptType.INLINE, type, "test", Collections.emptyMap()), IngestScript.CONTEXT));
assertThat(e.getMessage(), containsString("script context [" + ExecutableScript.INGEST_CONTEXT.name + "] not supported")); assertThat(e.getMessage(), containsString("script context [" + IngestScript.CONTEXT.name + "] not supported"));
} }
public void testCompileCountedInCompilationStats() throws IOException { public void testCompileCountedInCompilationStats() throws IOException {

View File

@ -88,6 +88,14 @@ public class MockScriptEngine implements ScriptEngine {
} else if (context.instanceClazz.equals(ExecutableScript.class)) { } else if (context.instanceClazz.equals(ExecutableScript.class)) {
ExecutableScript.Factory factory = mockCompiled::createExecutableScript; ExecutableScript.Factory factory = mockCompiled::createExecutableScript;
return context.factoryClazz.cast(factory); return context.factoryClazz.cast(factory);
} else if (context.instanceClazz.equals(IngestScript.class)) {
IngestScript.Factory factory = parameters -> new IngestScript(parameters) {
@Override
public void execute(Map<String, Object> ctx) {
script.apply(ctx);
}
};
return context.factoryClazz.cast(factory);
} else if (context.instanceClazz.equals(TemplateScript.class)) { } else if (context.instanceClazz.equals(TemplateScript.class)) {
TemplateScript.Factory factory = vars -> { TemplateScript.Factory factory = vars -> {
// TODO: need a better way to implement all these new contexts // TODO: need a better way to implement all these new contexts