Watcher: Fix TransformInput toXContent serialization (elastic/x-pack-elasticsearch#4061)

The toXContent serialization of the transform input was broken, which
could lead to the bad case that a watch could be stored with an invalid
toXContent serialization, that could not be read again, when the watch
should either be executed or even just returned by the Get watch API.

relates elastic/x-pack-elasticsearch#4049

Original commit: elastic/x-pack-elasticsearch@f06ad768b8
This commit is contained in:
Alexander Reelsen 2018-03-14 15:53:39 -07:00 committed by GitHub
parent 76e141d390
commit c30256e9b5
3 changed files with 72 additions and 20 deletions

View File

@ -42,7 +42,7 @@ public class TransformInput implements Input {
@Override @Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
transform.toXContent(builder, params); builder.startObject().field(transform.type(), transform, params).endObject();
return builder; return builder;
} }

View File

@ -44,7 +44,7 @@ public class TransformInputTests extends ESTestCase {
private ScriptService scriptService; private ScriptService scriptService;
@Before @Before
public void setupScriptService() throws Exception { public void setupScriptService() {
Map<String, ScriptEngine> engines = new HashMap<>(); Map<String, ScriptEngine> engines = new HashMap<>();
engines.put(MockScriptEngine.NAME, new MockScriptEngine(MockScriptEngine.NAME, Collections.singletonMap("1", s -> "2"))); engines.put(MockScriptEngine.NAME, new MockScriptEngine(MockScriptEngine.NAME, Collections.singletonMap("1", s -> "2")));
Map<String, ScriptContext<?>> contexts = new HashMap<>(); Map<String, ScriptContext<?>> contexts = new HashMap<>();
@ -54,7 +54,7 @@ public class TransformInputTests extends ESTestCase {
scriptService = new ScriptService(Settings.EMPTY, engines, contexts); scriptService = new ScriptService(Settings.EMPTY, engines, contexts);
} }
public void testExecute() throws Exception { public void testExecute() {
Script script = new Script(ScriptType.INLINE, MockScriptEngine.NAME, "1", Collections.emptyMap(), Collections.emptyMap()); Script script = new Script(ScriptType.INLINE, MockScriptEngine.NAME, "1", Collections.emptyMap(), Collections.emptyMap());
ScriptTransform scriptTransform = ScriptTransform.builder(script).build(); ScriptTransform scriptTransform = ScriptTransform.builder(script).build();
TransformInput transformInput = new TransformInput(scriptTransform); TransformInput transformInput = new TransformInput(scriptTransform);
@ -110,4 +110,25 @@ public class TransformInputTests extends ESTestCase {
result.toXContent(builder, ToXContent.EMPTY_PARAMS); result.toXContent(builder, ToXContent.EMPTY_PARAMS);
} }
} }
public void testTransformInputToXContentIsSameAsParsing() throws Exception {
Map<String, TransformFactory> transformFactories = Collections.singletonMap("script",
new ScriptTransformFactory(Settings.EMPTY, scriptService));
TransformRegistry registry = new TransformRegistry(Settings.EMPTY, transformFactories);
TransformInputFactory factory = new TransformInputFactory(Settings.EMPTY, registry);
XContentBuilder jsonBuilder = jsonBuilder().startObject().startObject("script")
.field("source", "1")
.field("lang", "mockscript")
.endObject().endObject();
XContentParser parser = createParser(jsonBuilder);
parser.nextToken();
TransformInput transformInput = factory.parseInput("whatever", parser);
XContentBuilder output = jsonBuilder();
transformInput.toXContent(output, ToXContent.EMPTY_PARAMS);
assertThat(jsonBuilder.string(), is(output.string()));
}
} }

View File

@ -13,6 +13,10 @@
"schedule" : { "cron" : "0 0 0 1 * ? 2099" } "schedule" : { "cron" : "0 0 0 1 * ? 2099" }
}, },
"input" : { "input" : {
"chain" : {
"inputs" : [
{
"first" : {
"search" : { "search" : {
"request" : { "request" : {
"indices" : [ "logstash*" ], "indices" : [ "logstash*" ],
@ -37,6 +41,19 @@
} }
} }
} }
}
},
{
"second" : {
"transform" : {
"script" : {
"source": "return [ 'hits' : [ 'total' : ctx.payload.first.hits.total ]]"
}
}
}
}
]
}
}, },
"condition" : { "condition" : {
"script" : { "script" : {
@ -46,6 +63,12 @@
}, },
"actions" : { "actions" : {
"email_admin" : { "email_admin" : {
"transform" : {
"script" : {
"source" : "return ['foo': 'bar']",
"lang" : "painless"
}
},
"email" : { "email" : {
"to" : "someone@domain.host.com", "to" : "someone@domain.host.com",
"subject" : "404 recently encountered" "subject" : "404 recently encountered"
@ -55,6 +78,14 @@
} }
- match: { _id: "my_exe_watch" } - match: { _id: "my_exe_watch" }
- do:
xpack.watcher.get_watch:
id: "my_exe_watch"
- match: { _id: "my_exe_watch" }
- match: { watch.actions.email_admin.transform.script.source: "return ['foo': 'bar']" }
- match: { watch.input.chain.inputs.1.second.transform.script.source: "return [ 'hits' : [ 'total' : ctx.payload.first.hits.total ]]" }
- do: - do:
xpack.watcher.execute_watch: xpack.watcher.execute_watch:
id: "my_exe_watch" id: "my_exe_watch"