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@3e1e3dbe95
This commit is contained in:
parent
feb745763b
commit
27f6239fe9
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<WebhookAction.Result> {
|
|||
|
||||
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<WebhookAction.Result> {
|
|||
@Override
|
||||
protected Result execute(WatchExecutionContext ctx, Payload payload) throws IOException {
|
||||
Map<String, Object> model = Variables.createCtxModel(ctx, payload);
|
||||
Map<String, Object> urlSafeModel = new HashMap<>(model.size());
|
||||
|
||||
for (Map.Entry<String, Object> 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<WebhookAction.Result> {
|
|||
.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.Result> {
|
|||
|
||||
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<WebhookAction.Result> {
|
|||
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<WebhookAction.Result> {
|
|||
|
||||
public static class Parser extends AbstractComponent implements Action.Parser<Result, WebhookAction> {
|
||||
|
||||
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<WebhookAction.Result> {
|
|||
@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<WebhookAction.Result> {
|
|||
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<WebhookAction.Result> {
|
|||
}
|
||||
}
|
||||
|
||||
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<WebhookAction.Result> {
|
|||
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<WebhookAction.Result> {
|
|||
} 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<WebhookAction.Result> {
|
|||
}
|
||||
|
||||
|
||||
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<WebhookAction.Result> {
|
|||
|
||||
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<WebhookAction.Result> {
|
|||
@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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -32,6 +32,7 @@ public class TemplatedHttpRequest implements ToXContent {
|
|||
private Map<String, Template> params;
|
||||
private Map<String, Template> 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");
|
||||
|
|
|
@ -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<ScriptEngineService> 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<String, Object> 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));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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<Action> 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<Email.Address> emailAddressList = new ArrayList<>();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue