From 27f6239fe9dd73e8a64be7f096798cbccc1ec94e Mon Sep 17 00:00:00 2001 From: Brian Murphy Date: Wed, 1 Apr 2015 20:38:02 -0400 Subject: [PATCH] Add HttpRequest support to webhook action. Also add docs for HttpRequest support in webhook action Closes elastic/elasticsearch#156 Original commit: elastic/x-pack-elasticsearch@3e1e3dbe95fa2feffce76e273befdd01fc546abd --- .../watcher/actions/ActionBuilders.java | 9 +- .../actions/webhook/WebhookAction.java | 178 +++++--------- .../watcher/support/http/HttpClient.java | 12 - .../watcher/support/http/HttpRequest.java | 12 + .../watcher/support/http/HttpResponse.java | 2 +- .../support/http/TemplatedHttpRequest.java | 33 +++ .../actions/webhook/WebhookActionTests.java | 227 +++++++++--------- .../watcher/history/WatchRecordTests.java | 15 +- .../watcher/test/WatcherTestUtils.java | 13 +- .../watcher/watch/WatchTests.java | 17 +- 10 files changed, 260 insertions(+), 258 deletions(-) diff --git a/src/main/java/org/elasticsearch/watcher/actions/ActionBuilders.java b/src/main/java/org/elasticsearch/watcher/actions/ActionBuilders.java index 84e7650aa74..d996385e7ac 100644 --- a/src/main/java/org/elasticsearch/watcher/actions/ActionBuilders.java +++ b/src/main/java/org/elasticsearch/watcher/actions/ActionBuilders.java @@ -8,7 +8,7 @@ package org.elasticsearch.watcher.actions; import org.elasticsearch.watcher.actions.email.EmailAction; import org.elasticsearch.watcher.actions.index.IndexAction; import org.elasticsearch.watcher.actions.webhook.WebhookAction; -import org.elasticsearch.watcher.support.Script; +import org.elasticsearch.watcher.support.http.TemplatedHttpRequest; /** * @@ -26,11 +26,8 @@ public final class ActionBuilders { return new IndexAction.SourceBuilder(index, type); } - public static WebhookAction.SourceBuilder webhookAction(String url) { - return new WebhookAction.SourceBuilder(url); + public static WebhookAction.SourceBuilder webhookAction(TemplatedHttpRequest request) { + return new WebhookAction.SourceBuilder(request); } - public static WebhookAction.SourceBuilder webhookAction(Script url) { - return new WebhookAction.SourceBuilder(url); - } } diff --git a/src/main/java/org/elasticsearch/watcher/actions/webhook/WebhookAction.java b/src/main/java/org/elasticsearch/watcher/actions/webhook/WebhookAction.java index bfb0a0bde86..727bbff5b93 100644 --- a/src/main/java/org/elasticsearch/watcher/actions/webhook/WebhookAction.java +++ b/src/main/java/org/elasticsearch/watcher/actions/webhook/WebhookAction.java @@ -14,16 +14,14 @@ import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.watcher.WatcherSettingsException; import org.elasticsearch.watcher.actions.Action; import org.elasticsearch.watcher.actions.ActionException; import org.elasticsearch.watcher.actions.ActionSettingsException; -import org.elasticsearch.watcher.support.Script; import org.elasticsearch.watcher.support.Variables; import org.elasticsearch.watcher.support.http.HttpClient; -import org.elasticsearch.watcher.support.http.HttpMethod; +import org.elasticsearch.watcher.support.http.HttpRequest; import org.elasticsearch.watcher.support.http.HttpResponse; -import org.elasticsearch.watcher.support.template.Template; +import org.elasticsearch.watcher.support.http.TemplatedHttpRequest; import org.elasticsearch.watcher.transform.Transform; import org.elasticsearch.watcher.transform.TransformRegistry; import org.elasticsearch.watcher.watch.Payload; @@ -32,7 +30,10 @@ import org.elasticsearch.watcher.watch.WatchExecutionContext; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** */ @@ -42,16 +43,16 @@ public class WebhookAction extends Action { private final HttpClient httpClient; - final HttpMethod method; - final Template url; - final @Nullable Template body; + private final TemplatedHttpRequest templatedHttpRequest; - public WebhookAction(ESLogger logger, @Nullable Transform transform, HttpClient httpClient, HttpMethod method, Template url, Template body) { + public WebhookAction(ESLogger logger, @Nullable Transform transform, HttpClient httpClient, TemplatedHttpRequest templatedHttpRequest) { super(logger, transform); this.httpClient = httpClient; - this.method = method; - this.url = url; - this.body = body; + this.templatedHttpRequest = templatedHttpRequest; + } + + public TemplatedHttpRequest templatedHttpRequest() { + return templatedHttpRequest; } @Override @@ -62,28 +63,22 @@ public class WebhookAction extends Action { @Override protected Result execute(WatchExecutionContext ctx, Payload payload) throws IOException { Map model = Variables.createCtxModel(ctx, payload); - Map urlSafeModel = new HashMap<>(model.size()); - for (Map.Entry entry : model.entrySet()) { - urlSafeModel.put(entry.getKey(), makeURLSafe(entry.getValue())); - } - - String urlText = url.render(urlSafeModel); - String bodyText = body != null ? body.render(model) : ""; //If body is null send an empty body + HttpRequest httpRequest = templatedHttpRequest.render(model); try { - try (HttpResponse response = httpClient.execute(method, urlText, bodyText)) { + try (HttpResponse response = httpClient.execute(httpRequest)) { int status = response.status(); if (status >= 400) { - logger.warn("got status [" + status + "] when connecting to [" + urlText + "]"); + logger.warn("got status [" + status + "] when connecting to [" + httpRequest.host() + "] [" + httpRequest.path() + "]"); } else { if (status >= 300) { logger.warn("a 200 range return code was expected, but got [" + status + "]"); } } - return new Result.Executed(status, urlText, bodyText); + return new Result.Executed(status, httpRequest, response.body()); } } catch (IOException ioe) { - logger.error("failed to connect to [{}] for watch [{}]", ioe, urlText, ctx.watch().name()); + logger.error("failed to connect to [{}] for watch [{}]", ioe, httpRequest.toString(), ctx.watch().name()); return new Result.Failure("failed to send http request. " + ioe.getMessage()); } } @@ -96,11 +91,7 @@ public class WebhookAction extends Action { .field(transform.type(), transform) .endObject(); } - builder.field(Parser.METHOD_FIELD.getPreferredName(), method.method()); - builder.field(Parser.URL_FIELD.getPreferredName(), url); - if (body != null) { - builder.field(Parser.BODY_FIELD.getPreferredName(), body); - } + builder.field(Parser.REQUEST_FIELD.getPreferredName(), templatedHttpRequest); return builder.endObject(); } @@ -111,21 +102,15 @@ public class WebhookAction extends Action { WebhookAction that = (WebhookAction) o; - if (body != null ? !body.equals(that.body) : that.body != null) return false; - if (!method.equals(that.method)) return false; - if (!url.equals(that.url)) return false; - if (transform != null ? !transform.equals(that.transform) : that.transform != null) return false; + if (templatedHttpRequest != null ? !templatedHttpRequest.equals(that.templatedHttpRequest) : that.templatedHttpRequest != null) + return false; return true; } @Override public int hashCode() { - int result = method.hashCode(); - result = 31 * result + url.hashCode(); - result = 31 * result + (body != null ? body.hashCode() : 0); - result = 31 * result + (transform != null ? transform.hashCode() : 0); - return result; + return templatedHttpRequest != null ? templatedHttpRequest.hashCode() : 0; } public abstract static class Result extends Action.Result { @@ -141,34 +126,34 @@ public class WebhookAction extends Action { public static class Executed extends Result { private final int httpStatus; - private final String url; - private final String body; + private final byte[] responseBody; + private final HttpRequest httpRequest; - public Executed(int httpStatus, String url, String body) { + public Executed(int httpStatus, HttpRequest httpRequest, byte[] responseBody) { super(TYPE, httpStatus < 400); this.httpStatus = httpStatus; - this.url = url; - this.body = body; + this.responseBody = responseBody; + this.httpRequest = httpRequest; } public int httpStatus() { return httpStatus; } - public String url() { - return url; + public byte[] responseBody() { + return responseBody; } - public String body() { - return body; + public HttpRequest httpRequest() { + return httpRequest; } @Override protected XContentBuilder xContentBody(XContentBuilder builder, Params params) throws IOException { return builder.field(SUCCESS_FIELD.getPreferredName(), success()) .field(WebhookAction.Parser.HTTP_STATUS_FIELD.getPreferredName(), httpStatus) - .field(WebhookAction.Parser.URL_FIELD.getPreferredName(), url) - .field(WebhookAction.Parser.BODY_FIELD.getPreferredName(), body); + .field(Parser.REQUEST_FIELD.getPreferredName(), httpRequest) + .field(Parser.RESPONSE_BODY.getPreferredName(), responseBody); } } @@ -195,22 +180,26 @@ public class WebhookAction extends Action { public static class Parser extends AbstractComponent implements Action.Parser { - public static final ParseField METHOD_FIELD = new ParseField("method"); - public static final ParseField URL_FIELD = new ParseField("url"); - public static final ParseField BODY_FIELD = new ParseField("body"); + public static final ParseField REQUEST_FIELD = new ParseField("request"); public static final ParseField HTTP_STATUS_FIELD = new ParseField("http_status"); + public static final ParseField RESPONSE_BODY = new ParseField("response_body"); public static final ParseField REASON_FIELD = new ParseField("reason"); - private final Template.Parser templateParser; private final HttpClient httpClient; private final TransformRegistry transformRegistry; + private final HttpRequest.Parser requestParser; + private final TemplatedHttpRequest.Parser templatedRequestParser; + @Inject - public Parser(Settings settings, Template.Parser templateParser, HttpClient httpClient, TransformRegistry transformRegistry) { + public Parser(Settings settings, HttpClient httpClient, + TransformRegistry transformRegistry, HttpRequest.Parser requestParser, + TemplatedHttpRequest.Parser templatedRequestParser) { super(settings); - this.templateParser = templateParser; this.httpClient = httpClient; this.transformRegistry = transformRegistry; + this.requestParser = requestParser; + this.templatedRequestParser = templatedRequestParser; } @Override @@ -221,9 +210,7 @@ public class WebhookAction extends Action { @Override public WebhookAction parse(XContentParser parser) throws IOException { Transform transform = null; - HttpMethod method = HttpMethod.POST; - Template urlTemplate = null; - Template bodyTemplate = null; + TemplatedHttpRequest templatedHttpRequest = null; String currentFieldName = null; XContentParser.Token token; @@ -231,24 +218,9 @@ public class WebhookAction extends Action { while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); - } else if ((token.isValue() || token == XContentParser.Token.START_OBJECT) && currentFieldName != null ) { - if (METHOD_FIELD.match(currentFieldName)) { - method = HttpMethod.valueOf(parser.text().toUpperCase(Locale.ROOT)); - if (method != HttpMethod.POST && method != HttpMethod.GET && method != HttpMethod.PUT) { - throw new ActionSettingsException("could not parse webhook action. unsupported http method [" + method.method() + "]"); - } - } else if (URL_FIELD.match(currentFieldName)) { - try { - urlTemplate = templateParser.parse(parser); - } catch (Template.Parser.ParseException pe) { - throw new WatcherSettingsException("could not parse webhook action [url] template", pe); - } - } else if (BODY_FIELD.match(currentFieldName)) { - try { - bodyTemplate = templateParser.parse(parser); - } catch (Template.Parser.ParseException pe) { - throw new ActionSettingsException("could not parse webhook action [body] template", pe); - } + } else if ((token == XContentParser.Token.START_OBJECT) && currentFieldName != null ) { + if (REQUEST_FIELD.match(currentFieldName)) { + templatedHttpRequest = templatedRequestParser.parse(parser); } else if (Transform.Parser.TRANSFORM_FIELD.match(currentFieldName)) { transform = transformRegistry.parse(parser); } else { @@ -259,11 +231,11 @@ public class WebhookAction extends Action { } } - if (urlTemplate == null) { - throw new ActionSettingsException("could not parse webhook action. [url_template] is required"); + if (templatedHttpRequest == null) { + throw new ActionSettingsException("could not parse webhook action. [" + REQUEST_FIELD.getPreferredName() + "] is required"); } - return new WebhookAction(logger, transform, httpClient, method, urlTemplate, bodyTemplate); + return new WebhookAction(logger, transform, httpClient, templatedHttpRequest); } @Override @@ -272,19 +244,15 @@ public class WebhookAction extends Action { String currentFieldName = null; XContentParser.Token token; Boolean success = null; - String url = null; - String body = null; String reason = null; + HttpRequest request = null; + byte[] responseBody = null; int httpStatus = -1; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); } else if (token.isValue()) { - if (URL_FIELD.match(currentFieldName)) { - url = parser.text(); - } else if (BODY_FIELD.match(currentFieldName)) { - body = parser.text(); - } else if (HTTP_STATUS_FIELD.match(currentFieldName)) { + if (HTTP_STATUS_FIELD.match(currentFieldName)) { httpStatus = parser.intValue(); } else if (REASON_FIELD.match(currentFieldName)) { reason = parser.text(); @@ -294,12 +262,18 @@ public class WebhookAction extends Action { } else { throw new ActionException("could not parse webhook result. unexpected boolean field [" + currentFieldName + "]"); } - } else { + } else if (RESPONSE_BODY.match(currentFieldName)) { + responseBody = parser.binaryValue(); + }else { throw new ActionException("unable to parse webhook action result. unexpected field [" + currentFieldName + "]"); } } else if (token == XContentParser.Token.START_OBJECT) { if (Transform.Parser.TRANSFORM_RESULT_FIELD.match(currentFieldName)) { transformResult = transformRegistry.parseResult(parser); + } else if (REQUEST_FIELD.match(currentFieldName)) { + request = requestParser.parse(parser); + } else { + throw new ActionException("unable to parse webhook action result. unexpected field [" + currentFieldName + "]" ); } } else { throw new ActionException("unable to parse webhook action result. unexpected field [" + currentFieldName + "]" ); @@ -311,7 +285,7 @@ public class WebhookAction extends Action { } - Result result = (reason == null) ? new Result.Executed(httpStatus, url, body) : new Result.Failure(reason); + Result result = (reason == null) ? new Result.Executed(httpStatus, request, responseBody) : new Result.Failure(reason); if (transformResult != null) { result.transformResult(transformResult); } @@ -343,26 +317,10 @@ public class WebhookAction extends Action { public static class SourceBuilder implements Action.SourceBuilder { - private final Script url; - private HttpMethod method; - private Script body = null; + private final TemplatedHttpRequest httpRequest; - public SourceBuilder(String url) { - this(new Script(url)); - } - - public SourceBuilder(Script url) { - this.url = url; - } - - public SourceBuilder method(HttpMethod method) { - this.method = method; - return this; - } - - public SourceBuilder body(Script body) { - this.body = body; - return this; + public SourceBuilder(TemplatedHttpRequest httpRequest) { + this.httpRequest = httpRequest; } @Override @@ -373,13 +331,7 @@ public class WebhookAction extends Action { @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); - builder.field(Parser.URL_FIELD.getPreferredName(), url); - if (method != null) { - builder.field(Parser.METHOD_FIELD.getPreferredName(), method.method()); - } - if (body != null) { - builder.field(Parser.BODY_FIELD.getPreferredName(), body); - } + builder.field(Parser.REQUEST_FIELD.getPreferredName(), httpRequest); return builder.endObject(); } } diff --git a/src/main/java/org/elasticsearch/watcher/support/http/HttpClient.java b/src/main/java/org/elasticsearch/watcher/support/http/HttpClient.java index fc00ba44449..d39990f3088 100644 --- a/src/main/java/org/elasticsearch/watcher/support/http/HttpClient.java +++ b/src/main/java/org/elasticsearch/watcher/support/http/HttpClient.java @@ -54,14 +54,6 @@ public class HttpClient extends AbstractComponent { } } - // TODO: Remove this when webhook action has been refactored to use this client properly - public HttpResponse execute(HttpMethod method, String urlString, String body) throws IOException { - URL url = new URL(urlString); - HttpRequest request = new HttpRequest(); - request.method(method); - return doExecute(url, request); - } - public HttpResponse execute(HttpRequest request) throws IOException { String queryString = null; if (request.params() != null) { @@ -84,11 +76,7 @@ public class HttpClient extends AbstractComponent { throw ExceptionsHelper.convertToElastic(e); } URL url = uri.toURL(); - return doExecute(url, request); - } - // TODO: Embed this method in execute() when webhook action has been refactored to use this client properly - private HttpResponse doExecute(URL url, HttpRequest request) throws IOException { logger.debug("making [{}] request to [{}]", request.method().method(), url); logger.trace("sending [{}] as body of request", request.body()); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); diff --git a/src/main/java/org/elasticsearch/watcher/support/http/HttpRequest.java b/src/main/java/org/elasticsearch/watcher/support/http/HttpRequest.java index 3a9a599ff61..019a3d3d424 100644 --- a/src/main/java/org/elasticsearch/watcher/support/http/HttpRequest.java +++ b/src/main/java/org/elasticsearch/watcher/support/http/HttpRequest.java @@ -166,6 +166,18 @@ public class HttpRequest implements ToXContent { return result; } + @Override + public String toString() { + return "HttpRequest{" + + "auth=[" + (auth != null ? "******" : null) + + "], body=[" + body + '\'' + + "], path=[" + path + '\'' + + "], method=[" + method + + "], port=[" + port + + "], host=[" + host + '\'' + + "]}"; + } + public static class Parser { public static final ParseField SCHEME_FIELD = new ParseField("scheme"); diff --git a/src/main/java/org/elasticsearch/watcher/support/http/HttpResponse.java b/src/main/java/org/elasticsearch/watcher/support/http/HttpResponse.java index a60ba717246..f3953905444 100644 --- a/src/main/java/org/elasticsearch/watcher/support/http/HttpResponse.java +++ b/src/main/java/org/elasticsearch/watcher/support/http/HttpResponse.java @@ -27,7 +27,7 @@ public class HttpResponse implements Closeable { } public byte[] body() { - if (body == null) { + if (body == null && inputStream != null) { try { body = ByteStreams.toByteArray(inputStream); inputStream.close(); diff --git a/src/main/java/org/elasticsearch/watcher/support/http/TemplatedHttpRequest.java b/src/main/java/org/elasticsearch/watcher/support/http/TemplatedHttpRequest.java index 86f0eb17736..5b39da4627d 100644 --- a/src/main/java/org/elasticsearch/watcher/support/http/TemplatedHttpRequest.java +++ b/src/main/java/org/elasticsearch/watcher/support/http/TemplatedHttpRequest.java @@ -32,6 +32,7 @@ public class TemplatedHttpRequest implements ToXContent { private Map params; private Map headers; private HttpAuth auth; + private Template body; public TemplatedHttpRequest() { @@ -164,6 +165,38 @@ public class TemplatedHttpRequest implements ToXContent { return builder.endObject(); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + TemplatedHttpRequest that = (TemplatedHttpRequest) o; + + if (port != that.port) return false; + if (auth != null ? !auth.equals(that.auth) : that.auth != null) return false; + if (body != null ? !body.equals(that.body) : that.body != null) return false; + if (headers != null ? !headers.equals(that.headers) : that.headers != null) return false; + if (host != null ? !host.equals(that.host) : that.host != null) return false; + if (method != that.method) return false; + if (params != null ? !params.equals(that.params) : that.params != null) return false; + if (path != null ? !path.equals(that.path) : that.path != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = host != null ? host.hashCode() : 0; + result = 31 * result + port; + result = 31 * result + (method != null ? method.hashCode() : 0); + result = 31 * result + (path != null ? path.hashCode() : 0); + result = 31 * result + (params != null ? params.hashCode() : 0); + result = 31 * result + (headers != null ? headers.hashCode() : 0); + result = 31 * result + (auth != null ? auth.hashCode() : 0); + result = 31 * result + (body != null ? body.hashCode() : 0); + return result; + } + public static class Parser { public static final ParseField SCHEME_FIELD = new ParseField("scheme"); diff --git a/src/test/java/org/elasticsearch/watcher/actions/webhook/WebhookActionTests.java b/src/test/java/org/elasticsearch/watcher/actions/webhook/WebhookActionTests.java index 66294c40d69..3d5af069074 100644 --- a/src/test/java/org/elasticsearch/watcher/actions/webhook/WebhookActionTests.java +++ b/src/test/java/org/elasticsearch/watcher/actions/webhook/WebhookActionTests.java @@ -6,6 +6,7 @@ package org.elasticsearch.watcher.actions.webhook; import com.carrotsearch.randomizedtesting.annotations.Repeat; +import org.elasticsearch.common.collect.ImmutableMap; import org.elasticsearch.common.joda.time.DateTime; import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.Settings; @@ -28,10 +29,10 @@ import org.elasticsearch.watcher.actions.email.service.Authentication; import org.elasticsearch.watcher.actions.email.service.Email; import org.elasticsearch.watcher.actions.email.service.EmailService; import org.elasticsearch.watcher.actions.email.service.Profile; -import org.elasticsearch.watcher.support.Script; -import org.elasticsearch.watcher.support.http.HttpClient; -import org.elasticsearch.watcher.support.http.HttpMethod; -import org.elasticsearch.watcher.support.http.HttpResponse; +import org.elasticsearch.watcher.support.http.*; +import org.elasticsearch.watcher.support.http.auth.BasicAuth; +import org.elasticsearch.watcher.support.http.auth.HttpAuth; +import org.elasticsearch.watcher.support.http.auth.HttpAuthRegistry; import org.elasticsearch.watcher.support.init.proxy.ClientProxy; import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy; import org.elasticsearch.watcher.support.template.ScriptTemplate; @@ -50,7 +51,6 @@ import org.junit.Test; import javax.mail.internet.AddressException; import java.io.IOException; -import java.net.URI; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -62,9 +62,7 @@ import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.lessThanOrEqualTo; import static org.hamcrest.core.Is.is; -import static org.mockito.AdditionalMatchers.not; import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -72,11 +70,17 @@ import static org.mockito.Mockito.when; */ public class WebhookActionTests extends ElasticsearchTestCase { - static final String TEST_BODY = "ERROR HAPPENED"; - static final String TEST_URL = "http://test.com/testurl"; + static final String TEST_HOST = "test.com"; private ThreadPool tp = null; private ScriptServiceProxy scriptService; + private HttpAuthRegistry authRegistry; + private Template testBody; + private Template testPath; + + static final String TEST_BODY_STRING = "ERROR HAPPENED"; + static final String TEST_PATH_STRING = "/testPath"; + @Before public void init() throws IOException { @@ -86,6 +90,9 @@ public class WebhookActionTests extends ElasticsearchTestCase { Set engineServiceSet = new HashSet<>(); engineServiceSet.add(mustacheScriptEngineService); scriptService = ScriptServiceProxy.of(new ScriptService(settings, new Environment(), engineServiceSet, new ResourceWatcherService(settings, tp), new NodeSettingsService(settings))); + testBody = new ScriptTemplate(scriptService, TEST_BODY_STRING ); + testPath = new ScriptTemplate(scriptService, TEST_PATH_STRING); + authRegistry = new HttpAuthRegistry(ImmutableMap.of("basic", (HttpAuth.Parser) new BasicAuth.Parser())); } @After @@ -104,13 +111,13 @@ public class WebhookActionTests extends ElasticsearchTestCase { final Transform transform = randomBoolean() ? null : new TransformMocks.TransformMock(); final String account = "account1"; + TemplatedHttpRequest httpRequest = getTemplatedHttpRequest(method, TEST_HOST, testPath, testBody); + WebhookAction webhookAction = new WebhookAction(logger, transform, httpClient, - method, - new ScriptTemplate(scriptService, TEST_URL), - new ScriptTemplate(scriptService, TEST_BODY)); + httpRequest); Watch watch = createWatch("test_watch", client, account); WatchExecutionContext ctx = new WatchExecutionContext("testid", watch, new DateTime(), new ScheduleTriggerEvent(new DateTime(), new DateTime())); @@ -119,27 +126,38 @@ public class WebhookActionTests extends ElasticsearchTestCase { scenario.assertResult(actionResult); } + private TemplatedHttpRequest getTemplatedHttpRequest(HttpMethod method, String host, Template path, Template body) { + TemplatedHttpRequest httpRequest = new TemplatedHttpRequest(); + if (host != null) { + httpRequest.host(host); + } + if (path != null) { + httpRequest.path(path); + } + if (body != null) { + httpRequest.body(body); + } + if (method != null) { + httpRequest.method(method); + } + return httpRequest; + } + @Test @Repeat(iterations = 10) public void testParser() throws Exception { final Transform transform = randomBoolean() ? null : new TransformMocks.TransformMock(); TransformRegistry transformRegistry = transform == null ? mock(TransformRegistry.class) : new TransformMocks.TransformRegistryMock(transform); Template body = randomBoolean() ? new ScriptTemplate(scriptService, "_subject") : null; - Template url = new ScriptTemplate(scriptService, "_url"); + Template path = new ScriptTemplate(scriptService, "_url"); + String host = "test.host"; HttpMethod method = randomFrom(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, null); - + TemplatedHttpRequest request = getTemplatedHttpRequest(method, host, path, body); XContentBuilder builder = jsonBuilder(); builder.startObject(); { - builder.field(WebhookAction.Parser.URL_FIELD.getPreferredName(), url); - - if (method != null) { - builder.field(WebhookAction.Parser.METHOD_FIELD.getPreferredName(), method.method()); - } - if (body != null) { - builder.field(WebhookAction.Parser.BODY_FIELD.getPreferredName(), body); - } + builder.field(WebhookAction.Parser.REQUEST_FIELD.getPreferredName(), request); if (transform != null) { builder.startObject(Transform.Parser.TRANSFORM_FIELD.getPreferredName()) @@ -148,27 +166,14 @@ public class WebhookActionTests extends ElasticsearchTestCase { } builder.endObject(); - WebhookAction.Parser actionParser = new WebhookAction.Parser(ImmutableSettings.EMPTY, - new ScriptTemplate.Parser(ImmutableSettings.EMPTY, scriptService), - ExecuteScenario.Success.client(), transformRegistry); + WebhookAction.Parser actionParser = getParser(transformRegistry, ExecuteScenario.Success.client() ); XContentParser parser = JsonXContent.jsonXContent.createParser(builder.bytes()); parser.nextToken(); WebhookAction action = actionParser.parse(parser); - if (method != null) { - assertThat(action.method, equalTo(method)); - } else { - assertThat(action.method, equalTo(HttpMethod.POST)); - } - - if (body != null) { - assertThat(action.body, equalTo(body)); - } - - assertThat(action.url, equalTo(url)); - + assertThat(action.templatedHttpRequest(), equalTo(request)); if (transform != null) { assertThat(action.transform(), equalTo(transform)); } @@ -179,44 +184,45 @@ public class WebhookActionTests extends ElasticsearchTestCase { final Transform transform = randomBoolean() ? null : new TransformMocks.TransformMock(); TransformRegistry transformRegistry = transform == null ? mock(TransformRegistry.class) : new TransformMocks.TransformRegistryMock(transform); Template body = randomBoolean() ? new ScriptTemplate(scriptService, "_body") : null; - Template url = new ScriptTemplate(scriptService, "_url"); - HttpMethod method = randomFrom(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT); + Template path = new ScriptTemplate(scriptService, "_url"); + String host = "test.host"; - WebhookAction webhookAction = new WebhookAction(logger, transform, ExecuteScenario.Success.client(), method, url, body); + HttpMethod method = randomFrom(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, null); + + TemplatedHttpRequest request = getTemplatedHttpRequest(method, host, path, body); + WebhookAction webhookAction = new WebhookAction(logger, transform, ExecuteScenario.Success.client(), request); XContentBuilder builder = jsonBuilder(); webhookAction.toXContent(builder, ToXContent.EMPTY_PARAMS); - WebhookAction.Parser actionParser = new WebhookAction.Parser(ImmutableSettings.EMPTY, - new ScriptTemplate.Parser(ImmutableSettings.EMPTY, scriptService), - ExecuteScenario.Success.client(), transformRegistry); + WebhookAction.Parser actionParser = getParser(transformRegistry, ExecuteScenario.Success.client()); XContentParser parser = JsonXContent.jsonXContent.createParser(builder.bytes()); parser.nextToken(); - WebhookAction parsedAction = actionParser.parse(parser); + WebhookAction action = actionParser.parse(parser); + + assertThat(action.templatedHttpRequest(), equalTo(request)); + if (transform != null) { + assertThat(action.transform(), equalTo(transform)); + } - assertThat(webhookAction.body, equalTo(parsedAction.body)); - assertThat(webhookAction.method, equalTo(parsedAction.method)); - assertThat(webhookAction.url, equalTo(parsedAction.url)); - assertThat(webhookAction.transform(), equalTo(parsedAction.transform())); } @Test @Repeat(iterations = 10) public void testParser_SourceBuilder() throws Exception { - Script body = randomBoolean() ? new Script("_body", ScriptService.ScriptType.INLINE, "mustache") : null; - Script url = new Script("_url", ScriptService.ScriptType.INLINE, "mustache"); - HttpMethod method = randomFrom(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT); - WebhookAction.SourceBuilder sourceBuilder = new WebhookAction.SourceBuilder(url); - sourceBuilder.method(method); - sourceBuilder.body(body); + Template body = randomBoolean() ? new ScriptTemplate(scriptService, "_body") : null; + Template path = new ScriptTemplate(scriptService, "_url"); + String host = "test.host"; + HttpMethod method = randomFrom(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, null); + TemplatedHttpRequest request = getTemplatedHttpRequest(method, host, path, body); + + WebhookAction.SourceBuilder sourceBuilder = new WebhookAction.SourceBuilder(request); XContentBuilder builder = jsonBuilder(); sourceBuilder.toXContent(builder, ToXContent.EMPTY_PARAMS); - WebhookAction.Parser actionParser = new WebhookAction.Parser(ImmutableSettings.EMPTY, - new ScriptTemplate.Parser(ImmutableSettings.EMPTY, scriptService), - ExecuteScenario.Success.client(), null); + WebhookAction.Parser actionParser = getParser(null, ExecuteScenario.Success.client()); XContentParser parser = JsonXContent.jsonXContent.createParser(builder.bytes()); parser.nextToken(); @@ -224,33 +230,17 @@ public class WebhookActionTests extends ElasticsearchTestCase { Map emptyModel = new HashMap<>(); WebhookAction parsedAction = actionParser.parse(parser); - if (body != null) { - assertThat(body.script(), equalTo(parsedAction.body.render(emptyModel))); - } else { - assertThat(parsedAction.body, equalTo(null)); - } - assertThat(url.script(), equalTo(parsedAction.url.render(emptyModel))); - assertThat(method, equalTo(parsedAction.method)); + assertThat(request, equalTo(parsedAction.templatedHttpRequest())); } @Test(expected = ActionException.class) public void testParser_Failure() throws Exception { final Transform transform = randomBoolean() ? null : new TransformMocks.TransformMock(); TransformRegistry transformRegistry = transform == null ? mock(TransformRegistry.class) : new TransformMocks.TransformRegistryMock(transform); - Template body = randomBoolean() ? new ScriptTemplate(scriptService, "_subject") : null; - HttpMethod method = randomFrom(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, null); - XContentBuilder builder = jsonBuilder(); builder.startObject(); { - if (method != null) { - builder.field(WebhookAction.Parser.METHOD_FIELD.getPreferredName(), method.method()); - } - if (body != null) { - builder.field(WebhookAction.Parser.BODY_FIELD.getPreferredName(), body); - } - if (transform != null) { builder.startObject(Transform.Parser.TRANSFORM_FIELD.getPreferredName()) .field(transform.type(), transform); @@ -258,9 +248,7 @@ public class WebhookActionTests extends ElasticsearchTestCase { } builder.endObject(); - WebhookAction.Parser actionParser = new WebhookAction.Parser(ImmutableSettings.EMPTY, - new ScriptTemplate.Parser(ImmutableSettings.EMPTY, scriptService), - ExecuteScenario.Success.client(), transformRegistry); + WebhookAction.Parser actionParser = getParser(transformRegistry, ExecuteScenario.Success.client()); XContentParser parser = JsonXContent.jsonXContent.createParser(builder.bytes()); parser.nextToken(); @@ -278,17 +266,31 @@ public class WebhookActionTests extends ElasticsearchTestCase { TransformRegistry transformRegistry = transformResult != null ? new TransformMocks.TransformRegistryMock(transformResult) : mock(TransformRegistry.class); String body = "_body"; - String url = "_url"; + String host = "test.host"; + String path = "/_url"; String reason = "_reason"; + HttpMethod method = randomFrom(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT); + + byte[] responseBody = new byte[randomIntBetween(1,100)]; + for (int i = 0; i < responseBody.length; ++i) { + responseBody[i] = randomByte(); + } + + HttpRequest httpRequest = new HttpRequest(); + httpRequest.host(host); + httpRequest.body(body); + httpRequest.path(path); + httpRequest.method(method); int responseCode = randomIntBetween(200, 599); boolean error = randomBoolean(); boolean success = !error && responseCode < 400; - WebhookAction.Parser actionParser = new WebhookAction.Parser(ImmutableSettings.EMPTY, - new ScriptTemplate.Parser(ImmutableSettings.EMPTY, scriptService), - ExecuteScenario.Success.client(), transformRegistry); + HttpClient client = ExecuteScenario.Success.client(); + + WebhookAction.Parser actionParser = getParser(transformRegistry, client); + XContentBuilder builder = jsonBuilder(); builder.startObject(); @@ -296,8 +298,8 @@ public class WebhookActionTests extends ElasticsearchTestCase { builder.field(Action.Result.SUCCESS_FIELD.getPreferredName(), success); if (!error) { builder.field(WebhookAction.Parser.HTTP_STATUS_FIELD.getPreferredName(), responseCode); - builder.field(WebhookAction.Parser.BODY_FIELD.getPreferredName(), body); - builder.field(WebhookAction.Parser.URL_FIELD.getPreferredName(), url); + builder.field(WebhookAction.Parser.RESPONSE_BODY.getPreferredName(), responseBody); + builder.field(WebhookAction.Parser.REQUEST_FIELD.getPreferredName(), httpRequest); if (transformResult != null) { builder.startObject("transform_result") .startObject("_transform_type") @@ -320,9 +322,9 @@ public class WebhookActionTests extends ElasticsearchTestCase { if (!error) { assertThat(result, instanceOf(WebhookAction.Result.Executed.class)); WebhookAction.Result.Executed executedResult = (WebhookAction.Result.Executed) result; - assertThat(executedResult.body(), equalTo(body)); + assertThat(executedResult.responseBody(), equalTo(responseBody)); assertThat(executedResult.httpStatus(), equalTo(responseCode)); - assertThat(executedResult.url(), equalTo(url)); + assertThat(executedResult.httpRequest(), equalTo(httpRequest)); if (transformResult != null) { assertThat(transformResult, equalTo(executedResult.transformResult())); } @@ -333,27 +335,35 @@ public class WebhookActionTests extends ElasticsearchTestCase { } } + private WebhookAction.Parser getParser(TransformRegistry transformRegistry, HttpClient client) { + return new WebhookAction.Parser(ImmutableSettings.EMPTY, + client, transformRegistry, new HttpRequest.Parser(authRegistry), + new TemplatedHttpRequest.Parser(new ScriptTemplate.Parser(ImmutableSettings.EMPTY, scriptService), + authRegistry) ); + } + @Test @Repeat(iterations = 100) public void testValidUrls() throws Exception { HttpClient httpClient = ExecuteScenario.Success.client(); - HttpMethod method = HttpMethod.GET; + HttpMethod method = HttpMethod.POST; + Template path = new ScriptTemplate(scriptService, "/test_{{ctx.watch_name}}"); + String host = "test.host"; + TemplatedHttpRequest templatedHttpRequest = getTemplatedHttpRequest(method, host, path, testBody); WebhookAction webhookAction = new WebhookAction(logger, null, httpClient, - method, - new ScriptTemplate(scriptService, "http://test.com/test_{{ctx.watch_name}}"), - new ScriptTemplate(scriptService, TEST_BODY)); + templatedHttpRequest); + + String watchName = "test_url_encode" + randomAsciiOfLength(10); Watch watch = createWatch(watchName, mock(ClientProxy.class), "account1"); WatchExecutionContext ctx = new WatchExecutionContext("testid", watch, new DateTime(), new ScheduleTriggerEvent(new DateTime(), new DateTime())); WebhookAction.Result result = webhookAction.execute(ctx, new Payload.Simple()); assertThat(result, Matchers.instanceOf(WebhookAction.Result.Executed.class)); - WebhookAction.Result.Executed executed = (WebhookAction.Result.Executed)result; - URI.create(executed.url()); //This will throw an IllegalArgumentException if the url is invalid } private Watch createWatch(String watchName, ClientProxy client, final String account) throws AddressException, IOException { @@ -381,7 +391,7 @@ public class WebhookActionTests extends ElasticsearchTestCase { @Override public HttpClient client() throws IOException { HttpClient client = mock(HttpClient.class); - when(client.execute(any(HttpMethod.class), any(String.class), any(String.class))) + when(client.execute(any(HttpRequest.class))) .thenReturn(new HttpResponse(randomIntBetween(400,599))); return client; } @@ -393,8 +403,8 @@ public class WebhookActionTests extends ElasticsearchTestCase { WebhookAction.Result.Executed executedActionResult = (WebhookAction.Result.Executed) actionResult; assertThat(executedActionResult.httpStatus(), greaterThanOrEqualTo(400)); assertThat(executedActionResult.httpStatus(), lessThanOrEqualTo(599)); - assertThat(executedActionResult.body(), equalTo(TEST_BODY)); - assertThat(executedActionResult.url(), equalTo(TEST_URL)); + assertThat(executedActionResult.httpRequest().body(), equalTo(TEST_BODY_STRING)); + assertThat(executedActionResult.httpRequest().path(), equalTo(TEST_PATH_STRING)); } }, @@ -402,7 +412,7 @@ public class WebhookActionTests extends ElasticsearchTestCase { @Override public HttpClient client() throws IOException { HttpClient client = mock(HttpClient.class); - when(client.execute(any(HttpMethod.class), any(String.class), any(String.class))) + when(client.execute(any(HttpRequest.class))) .thenThrow(new IOException("Unable to connect")); return client; } @@ -419,7 +429,7 @@ public class WebhookActionTests extends ElasticsearchTestCase { @Override public HttpClient client() throws IOException{ HttpClient client = mock(HttpClient.class); - when(client.execute(any(HttpMethod.class), any(String.class), any(String.class))) + when(client.execute(any(HttpRequest.class))) .thenReturn(new HttpResponse(randomIntBetween(200,399))); return client; } @@ -431,29 +441,8 @@ public class WebhookActionTests extends ElasticsearchTestCase { WebhookAction.Result.Executed executedActionResult = (WebhookAction.Result.Executed) actionResult; assertThat(executedActionResult.httpStatus(), greaterThanOrEqualTo(200)); assertThat(executedActionResult.httpStatus(), lessThanOrEqualTo(399)); - assertThat(executedActionResult.body(), equalTo(TEST_BODY)); - assertThat(executedActionResult.url(), equalTo(TEST_URL)); - } - }, - - SuccessVerify() { - @Override - public HttpClient client() throws IOException{ - HttpClient client = mock(HttpClient.class); - when(client.execute(any(HttpMethod.class), eq(TEST_URL), eq(TEST_BODY))) - .thenReturn(new HttpResponse(200)); - when(client.execute(any(HttpMethod.class), eq(not(TEST_URL)), eq(not(TEST_BODY)))).thenThrow(new IOException("bad url or body")); - return client; - } - - @Override - public void assertResult(WebhookAction.Result actionResult) { - assertThat(actionResult, instanceOf(WebhookAction.Result.Executed.class)); - assertThat(actionResult, instanceOf(WebhookAction.Result.Executed.class)); - WebhookAction.Result.Executed executedActionResult = (WebhookAction.Result.Executed) actionResult; - assertThat(executedActionResult.httpStatus(), equalTo(200)); - assertThat(executedActionResult.body(), equalTo(TEST_BODY)); - assertThat(executedActionResult.url(), equalTo(TEST_URL)); + assertThat(executedActionResult.httpRequest().body(), equalTo(TEST_BODY_STRING)); + assertThat(executedActionResult.httpRequest().path(), equalTo(TEST_PATH_STRING)); } }; diff --git a/src/test/java/org/elasticsearch/watcher/history/WatchRecordTests.java b/src/test/java/org/elasticsearch/watcher/history/WatchRecordTests.java index a0d05946c7d..7a2ee2b1405 100644 --- a/src/test/java/org/elasticsearch/watcher/history/WatchRecordTests.java +++ b/src/test/java/org/elasticsearch/watcher/history/WatchRecordTests.java @@ -16,6 +16,7 @@ import org.elasticsearch.watcher.condition.simple.AlwaysFalseCondition; import org.elasticsearch.watcher.condition.simple.AlwaysTrueCondition; import org.elasticsearch.watcher.input.Input; import org.elasticsearch.watcher.input.simple.SimpleInput; +import org.elasticsearch.watcher.support.http.HttpRequest; import org.elasticsearch.watcher.test.AbstractWatcherIntegrationTests; import org.elasticsearch.watcher.test.WatcherTestUtils; import org.elasticsearch.watcher.throttle.Throttler; @@ -55,7 +56,12 @@ public class WatchRecordTests extends AbstractWatcherIntegrationTests { WatchRecord watchRecord = new WatchRecord(watch, event); WatchExecutionContext ctx = new WatchExecutionContext(watchRecord.id(), watch, new DateTime(), event); ctx.onActionResult(new EmailAction.Result.Failure("failed to send because blah")); - ctx.onActionResult(new WebhookAction.Result.Executed(300, "http://localhost:8000/watchfoo", "{'awesome' : 'us'}")); + HttpRequest request = new HttpRequest(); + request.host("localhost"); + request.port(8000); + request.path("/watchfoo"); + request.body("{'awesome' : 'us'}"); + ctx.onActionResult(new WebhookAction.Result.Executed(300, request, new byte[0])); Input.Result inputResult = new SimpleInput.Result(SimpleInput.TYPE, new Payload.Simple()); Condition.Result conditionResult = AlwaysTrueCondition.RESULT; ctx.onThrottleResult(Throttler.NO_THROTTLE.throttle(ctx)); @@ -80,7 +86,12 @@ public class WatchRecordTests extends AbstractWatcherIntegrationTests { WatchRecord watchRecord = new WatchRecord(watch, event); WatchExecutionContext ctx = new WatchExecutionContext(watchRecord.id(), watch, new DateTime(), event); ctx.onActionResult(new EmailAction.Result.Failure("failed to send because blah")); - ctx.onActionResult(new WebhookAction.Result.Executed(300, "http://localhost:8000/watchfoo", "{'awesome' : 'us'}")); + HttpRequest request = new HttpRequest(); + request.host("localhost"); + request.port(8000); + request.path("/watchfoo"); + request.body("{'awesome' : 'us'}"); + ctx.onActionResult(new WebhookAction.Result.Executed(300, request, new byte[0])); Input.Result inputResult = new SimpleInput.Result(SimpleInput.TYPE, new Payload.Simple()); Condition.Result conditionResult = AlwaysFalseCondition.RESULT; ctx.onThrottleResult(Throttler.NO_THROTTLE.throttle(ctx)); diff --git a/src/test/java/org/elasticsearch/watcher/test/WatcherTestUtils.java b/src/test/java/org/elasticsearch/watcher/test/WatcherTestUtils.java index 12531b0732f..6a682344f8e 100644 --- a/src/test/java/org/elasticsearch/watcher/test/WatcherTestUtils.java +++ b/src/test/java/org/elasticsearch/watcher/test/WatcherTestUtils.java @@ -31,6 +31,7 @@ import org.elasticsearch.watcher.support.WatcherUtils; import org.elasticsearch.watcher.support.clock.SystemClock; import org.elasticsearch.watcher.support.http.HttpClient; import org.elasticsearch.watcher.support.http.HttpMethod; +import org.elasticsearch.watcher.support.http.TemplatedHttpRequest; import org.elasticsearch.watcher.support.init.proxy.ClientProxy; import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy; import org.elasticsearch.watcher.support.template.ScriptTemplate; @@ -124,10 +125,16 @@ public final class WatcherTestUtils { List actions = new ArrayList<>(); - Template url = new ScriptTemplate(scriptService, "http://localhost/foobarbaz/{{watch_name}}"); - Template body = new ScriptTemplate(scriptService, "{{watch_name}} executed with {{response.hits.total}} hits"); + TemplatedHttpRequest httpRequest = new TemplatedHttpRequest(); - actions.add(new WebhookAction(logger, null, httpClient, HttpMethod.GET, url, body)); + Template path = new ScriptTemplate(scriptService, "/foobarbaz/{{ctx.watch_name}}"); + httpRequest.path(path); + Template body = new ScriptTemplate(scriptService, "{{ctx.watch_name}} executed with {{ctx.payload.response.hits.total_hits}} hits"); + httpRequest.body(body); + httpRequest.host("localhost"); + httpRequest.method(HttpMethod.POST); + + actions.add(new WebhookAction(logger, null, httpClient, httpRequest)); Email.Address from = new Email.Address("from@test.com"); List emailAddressList = new ArrayList<>(); diff --git a/src/test/java/org/elasticsearch/watcher/watch/WatchTests.java b/src/test/java/org/elasticsearch/watcher/watch/WatchTests.java index 4b7c6e327cb..c01712c6a82 100644 --- a/src/test/java/org/elasticsearch/watcher/watch/WatchTests.java +++ b/src/test/java/org/elasticsearch/watcher/watch/WatchTests.java @@ -40,6 +40,11 @@ import org.elasticsearch.watcher.support.WatcherUtils; import org.elasticsearch.watcher.support.clock.SystemClock; import org.elasticsearch.watcher.support.http.HttpClient; import org.elasticsearch.watcher.support.http.HttpMethod; +import org.elasticsearch.watcher.support.http.HttpRequest; +import org.elasticsearch.watcher.support.http.TemplatedHttpRequest; +import org.elasticsearch.watcher.support.http.auth.BasicAuth; +import org.elasticsearch.watcher.support.http.auth.HttpAuth; +import org.elasticsearch.watcher.support.http.auth.HttpAuthRegistry; import org.elasticsearch.watcher.support.init.proxy.ClientProxy; import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy; import org.elasticsearch.watcher.support.template.ScriptTemplate; @@ -69,6 +74,7 @@ public class WatchTests extends ElasticsearchTestCase { private HttpClient httpClient; private EmailService emailService; private Template.Parser templateParser; + private HttpAuthRegistry authRegistry; private ESLogger logger; private Settings settings = ImmutableSettings.EMPTY; @@ -79,6 +85,7 @@ public class WatchTests extends ElasticsearchTestCase { httpClient = mock(HttpClient.class); emailService = mock(EmailService.class); templateParser = new ScriptTemplate.Parser(settings, scriptService); + authRegistry = new HttpAuthRegistry(ImmutableMap.of("basic", (HttpAuth.Parser) new BasicAuth.Parser())); logger = Loggers.getLogger(WatchTests.class); } @@ -260,7 +267,11 @@ public class WatchTests extends ElasticsearchTestCase { list.add(new IndexAction(logger, randomTransform(), client, "_index", "_type")); } if (randomBoolean()) { - list.add(new WebhookAction(logger, randomTransform(), httpClient, randomFrom(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT), new ScriptTemplate(scriptService, "_url"), null)); + TemplatedHttpRequest httpRequest = new TemplatedHttpRequest(); + httpRequest.method(randomFrom(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT)); + httpRequest.host("test.host"); + httpRequest.path(new ScriptTemplate(scriptService, "_url")); + list.add(new WebhookAction(logger, randomTransform(), httpClient, httpRequest)); } return new Actions(list.build()); } @@ -276,7 +287,9 @@ public class WatchTests extends ElasticsearchTestCase { parsers.put(IndexAction.TYPE, new IndexAction.Parser(settings, client, transformRegistry)); break; case WebhookAction.TYPE: - parsers.put(WebhookAction.TYPE, new WebhookAction.Parser(settings, templateParser, httpClient, transformRegistry)); + parsers.put(WebhookAction.TYPE, new WebhookAction.Parser(settings, httpClient, transformRegistry, + new HttpRequest.Parser(authRegistry), + new TemplatedHttpRequest.Parser(new ScriptTemplate.Parser(settings, scriptService), authRegistry))); break; } }