Watcher: Prevent NPE on chained input toXContent (elastic/elasticsearch#2776)

If a chained input was aborted with an exception, then toXContent ran
into a NPE instead of rendering.

Closes elastic/elasticsearch#2774

Original commit: elastic/x-pack-elasticsearch@a3795f2290
This commit is contained in:
Alexander Reelsen 2016-07-12 09:33:32 +02:00 committed by GitHub
parent 149df1fd44
commit 4360cccad7
3 changed files with 16 additions and 6 deletions

View File

@ -15,6 +15,7 @@ import org.elasticsearch.xpack.watcher.watch.Payload;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ChainInput implements Input {
@ -103,7 +104,7 @@ public class ChainInput implements Input {
public static class Result extends Input.Result {
private List<Tuple<String, Input.Result>> results;
private List<Tuple<String, Input.Result>> results = Collections.emptyList();
protected Result(List<Tuple<String, Input.Result>> results, Payload payload) {
super(TYPE, payload);

View File

@ -40,7 +40,7 @@ public class ExecutableChainInput extends ExecutableInput<ChainInput,ChainInput.
return new ChainInput.Result(results, new Payload.Simple(payloads));
} catch (Exception e) {
logger.error("failed to execute [{}] input for [{}]", e, ChainInput.TYPE, ctx.watch());
logger.error("failed to execute [{}] input for [{}]", e, ChainInput.TYPE, ctx.watch().id());
return new ChainInput.Result(e);
}
}

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.xpack.watcher.input.chain;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ToXContent;
@ -13,7 +14,8 @@ import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.watcher.actions.ActionWrapper;
import org.elasticsearch.xpack.common.http.HttpRequestTemplate;
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuth;
import org.elasticsearch.xpack.watcher.actions.ExecutableActions;
import org.elasticsearch.xpack.watcher.condition.always.ExecutableAlwaysCondition;
import org.elasticsearch.xpack.watcher.execution.TriggeredExecutionContext;
@ -24,8 +26,6 @@ import org.elasticsearch.xpack.watcher.input.http.HttpInput;
import org.elasticsearch.xpack.watcher.input.simple.ExecutableSimpleInput;
import org.elasticsearch.xpack.watcher.input.simple.SimpleInput;
import org.elasticsearch.xpack.watcher.input.simple.SimpleInputFactory;
import org.elasticsearch.xpack.common.http.HttpRequestTemplate;
import org.elasticsearch.xpack.common.http.auth.basic.BasicAuth;
import org.elasticsearch.xpack.watcher.trigger.schedule.IntervalSchedule;
import org.elasticsearch.xpack.watcher.trigger.schedule.ScheduleTrigger;
import org.elasticsearch.xpack.watcher.trigger.schedule.ScheduleTriggerEvent;
@ -48,6 +48,7 @@ import static org.elasticsearch.xpack.watcher.input.InputBuilders.httpInput;
import static org.elasticsearch.xpack.watcher.input.InputBuilders.simpleInput;
import static org.elasticsearch.xpack.watcher.trigger.TriggerBuilders.schedule;
import static org.elasticsearch.xpack.watcher.trigger.schedule.Schedules.interval;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.hasSize;
@ -158,6 +159,14 @@ public class ChainInputTests extends ESTestCase {
// no exception means all good
}
public void testThatSerializationOfFailedInputWorks() throws Exception {
ChainInput.Result chainedResult = new ChainInput.Result(new ElasticsearchException("foo"));
XContentBuilder builder = jsonBuilder();
chainedResult.toXContent(builder, ToXContent.EMPTY_PARAMS);
assertThat(builder.bytes().utf8ToString(), containsString("\"reason\":\"ElasticsearchException[foo]\""));
}
private WatchExecutionContext createContext() {
Watch watch = new Watch("test-watch",
new ScheduleTrigger(new IntervalSchedule(new IntervalSchedule.Interval(1, IntervalSchedule.Interval.Unit.MINUTES))),
@ -165,7 +174,7 @@ public class ChainInputTests extends ESTestCase {
new ExecutableAlwaysCondition(logger),
null,
null,
new ExecutableActions(new ArrayList<ActionWrapper>()),
new ExecutableActions(new ArrayList<>()),
null,
new WatchStatus(new DateTime(0, UTC), emptyMap()));
WatchExecutionContext ctx = new TriggeredExecutionContext(watch,