From 92281077bea770770441fb4b7f101e90c4df2c1f Mon Sep 17 00:00:00 2001 From: Lee Hinman Date: Fri, 14 Apr 2023 13:46:15 -0600 Subject: [PATCH] Fix Watcher email actions not using WebhookService for HTTP requests (#95196) (#95256) This commit fixes a bug where the internal `WebhookService` was not being used for Watcher's `email` attachment `reporting` or `url` types. This meant that why the additional token configured as part of #93426 was sent for `webhook` Watcher actions, it was not being sent in the HTTP request made when resolving the attachments of the `email` action. To accomplish this, the parts of `WebhookService` that modify and make the request have been extracted, and the `WebhookService` is now used by the `ReportingAttachmentParser` and `HttpEmailAttachmentParser` to perform their HTTP requests. Additionally, some debug logging has been added for when the token is sent (and when a `WebhookService` request is executed). --- docs/changelog/95196.yaml | 5 + .../elasticsearch/xpack/watcher/Watcher.java | 4 +- .../watcher/notification/WebhookService.java | 82 ++++++++---- .../HttpEmailAttachementParser.java | 10 +- .../attachment/ReportingAttachmentParser.java | 12 +- .../actions/email/EmailActionTests.java | 22 +++- .../notification/WebhookServiceTests.java | 118 ++++++++++++++++++ .../HttpEmailAttachementParserTests.java | 26 +++- .../ReportingAttachmentParserTests.java | 20 ++- 9 files changed, 258 insertions(+), 41 deletions(-) create mode 100644 docs/changelog/95196.yaml create mode 100644 x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/notification/WebhookServiceTests.java diff --git a/docs/changelog/95196.yaml b/docs/changelog/95196.yaml new file mode 100644 index 0000000000000..33ea2c4b408b6 --- /dev/null +++ b/docs/changelog/95196.yaml @@ -0,0 +1,5 @@ +pr: 95196 +summary: Add logging for debug to Watcher webhook service +area: Watcher +type: bug +issues: [] diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java index 4553db34069b2..0b477399a9a34 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java @@ -352,11 +352,11 @@ public Collection createComponents( TextTemplateEngine templateEngine = new TextTemplateEngine(scriptService); Map> emailAttachmentParsers = new HashMap<>(); - emailAttachmentParsers.put(HttpEmailAttachementParser.TYPE, new HttpEmailAttachementParser(httpClient, templateEngine)); + emailAttachmentParsers.put(HttpEmailAttachementParser.TYPE, new HttpEmailAttachementParser(webhookService, templateEngine)); emailAttachmentParsers.put(DataAttachmentParser.TYPE, new DataAttachmentParser()); emailAttachmentParsers.put( ReportingAttachmentParser.TYPE, - new ReportingAttachmentParser(settings, httpClient, templateEngine, clusterService.getClusterSettings()) + new ReportingAttachmentParser(settings, webhookService, templateEngine, clusterService.getClusterSettings()) ); EmailAttachmentsParser emailAttachmentsParser = new EmailAttachmentsParser(emailAttachmentParsers); diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/WebhookService.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/WebhookService.java index f4e2ce84bded4..dac784900abc7 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/WebhookService.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/WebhookService.java @@ -15,6 +15,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsException; import org.elasticsearch.common.util.LazyInitializable; +import org.elasticsearch.core.Tuple; import org.elasticsearch.logging.LogManager; import org.elasticsearch.logging.Logger; import org.elasticsearch.xpack.core.watcher.actions.Action; @@ -121,34 +122,28 @@ public Action.Result execute( Map model = Variables.createCtxParamsMap(ctx, payload); // Render the original request - HttpRequest request = action.getRequest().render(templateEngine, model); + HttpRequest originalRequest = action.getRequest().render(templateEngine, model); - // If applicable, add the extra token to the headers - boolean tokenAdded = false; - WebhookAccount account = getAccount(NAME); - if (this.additionalTokenEnabled && account.hostTokenMap.size() > 0) { - // Generate a string like example.com:9200 to match against the list of hosts where the - // additional token should be provided. The token will only be added to the headers if - // the request matches the list. - String reqHostAndPort = request.host() + ":" + request.port(); - if (Strings.hasText(account.hostTokenMap.get(reqHostAndPort))) { - // Add the additional token - tokenAdded = true; - request = request.copy().setHeader(TOKEN_HEADER_NAME, account.hostTokenMap.get(reqHostAndPort)).build(); - } + if (ctx.simulateAction(actionId)) { + HttpRequest request = maybeModifyHttpRequest(originalRequest); + // If the request was modified, then the request has had the token added + boolean tokenAdded = originalRequest != request; + // Skip execution, return only the simulated (and redacted if necessary) response + return new WebhookAction.Result.Simulated( + tokenAdded ? request.copy().setHeader(TOKEN_HEADER_NAME, WatcherXContentParser.REDACTED_PASSWORD).build() : request + ); } + final Tuple respTup = modifyAndExecuteHttpRequest(originalRequest); + final HttpRequest request = respTup.v1(); + final HttpResponse response = respTup.v2(); + // If the request was modified, then the request has had the token added + final boolean tokenAdded = originalRequest != request; + final Function redactToken = tokenAdded ? req -> req.copy().setHeader(TOKEN_HEADER_NAME, WatcherXContentParser.REDACTED_PASSWORD).build() : Function.identity(); - if (ctx.simulateAction(actionId)) { - // Skip execution, return only the simulated (and redacted if necessary) response - return new WebhookAction.Result.Simulated(redactToken.apply(request)); - } - - HttpResponse response = httpClient.execute(request); - if (response.status() >= 400) { return new WebhookAction.Result.Failure(redactToken.apply(request), response); } else { @@ -156,6 +151,51 @@ public Action.Result execute( } } + /** + * Makes any additional modifications to the {@link HttpRequest} if necessary. + * If no modifications are made the same instance is returned, otherwise a new + * HttpRequest is returned. + */ + HttpRequest maybeModifyHttpRequest(HttpRequest request) { + WebhookAccount account = getAccount(NAME); + if (this.additionalTokenEnabled && account.hostTokenMap.size() > 0) { + // Generate a string like example.com:9200 to match against the list of hosts where the + // additional token should be provided. The token will only be added to the headers if + // the request matches the list. + String reqHostAndPort = request.host() + ":" + request.port(); + if (Strings.hasText(account.hostTokenMap.get(reqHostAndPort))) { + // Add the additional token + logger.debug( + "additional [{}] header token added to watcher webhook request for {}://{}:{}", + TOKEN_HEADER_NAME, + request.scheme().scheme(), + request.host(), + request.port() + ); + return request.copy().setHeader(TOKEN_HEADER_NAME, account.hostTokenMap.get(reqHostAndPort)).build(); + } + } + return request; + } + + /** + * Executes the given {@link HttpRequest} after any necessary modifications. + * A tuple of the modified (or unmodified) {@link HttpRequest} and + * {@link HttpResponse} is returned. + */ + public Tuple modifyAndExecuteHttpRequest(HttpRequest request) throws IOException { + final HttpRequest modifiedRequest = maybeModifyHttpRequest(request); + final HttpResponse response = httpClient.execute(modifiedRequest); + logger.debug( + "executed watcher webhook request for {}://{}:{}, response code: {}", + modifiedRequest.scheme().scheme(), + modifiedRequest.host(), + modifiedRequest.port(), + response.status() + ); + return Tuple.tuple(modifiedRequest, response); + } + public static final class WebhookAccount { private final Map hostTokenMap; diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/email/attachment/HttpEmailAttachementParser.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/email/attachment/HttpEmailAttachementParser.java index 7227dd6a2a2fa..e4d7fcc3a2935 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/email/attachment/HttpEmailAttachementParser.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/email/attachment/HttpEmailAttachementParser.java @@ -14,11 +14,11 @@ import org.elasticsearch.xcontent.XContentParser; import org.elasticsearch.xpack.core.watcher.execution.WatchExecutionContext; import org.elasticsearch.xpack.core.watcher.watch.Payload; -import org.elasticsearch.xpack.watcher.common.http.HttpClient; import org.elasticsearch.xpack.watcher.common.http.HttpRequest; import org.elasticsearch.xpack.watcher.common.http.HttpRequestTemplate; import org.elasticsearch.xpack.watcher.common.http.HttpResponse; import org.elasticsearch.xpack.watcher.common.text.TextTemplateEngine; +import org.elasticsearch.xpack.watcher.notification.WebhookService; import org.elasticsearch.xpack.watcher.notification.email.Attachment; import org.elasticsearch.xpack.watcher.support.Variables; @@ -34,11 +34,11 @@ public interface Fields { } public static final String TYPE = "http"; - private final HttpClient httpClient; + private final WebhookService webhookService; private final TextTemplateEngine templateEngine; - public HttpEmailAttachementParser(HttpClient httpClient, TextTemplateEngine templateEngine) { - this.httpClient = httpClient; + public HttpEmailAttachementParser(WebhookService webhookService, TextTemplateEngine templateEngine) { + this.webhookService = webhookService; this.templateEngine = templateEngine; } @@ -82,7 +82,7 @@ public Attachment toAttachment(WatchExecutionContext context, Payload payload, H Map model = Variables.createCtxParamsMap(context, payload); HttpRequest httpRequest = attachment.getRequestTemplate().render(templateEngine, model); - HttpResponse response = httpClient.execute(httpRequest); + HttpResponse response = webhookService.modifyAndExecuteHttpRequest(httpRequest).v2(); // check for status 200, only then append attachment if (response.status() >= 200 && response.status() < 300) { if (response.hasContent()) { diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/email/attachment/ReportingAttachmentParser.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/email/attachment/ReportingAttachmentParser.java index 8961c1133c7a1..4ce302628d99c 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/email/attachment/ReportingAttachmentParser.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/notification/email/attachment/ReportingAttachmentParser.java @@ -26,7 +26,6 @@ import org.elasticsearch.xpack.core.watcher.execution.WatchExecutionContext; import org.elasticsearch.xpack.core.watcher.watch.Payload; import org.elasticsearch.xpack.watcher.common.http.BasicAuth; -import org.elasticsearch.xpack.watcher.common.http.HttpClient; import org.elasticsearch.xpack.watcher.common.http.HttpMethod; import org.elasticsearch.xpack.watcher.common.http.HttpProxy; import org.elasticsearch.xpack.watcher.common.http.HttpRequest; @@ -34,6 +33,7 @@ import org.elasticsearch.xpack.watcher.common.http.HttpResponse; import org.elasticsearch.xpack.watcher.common.text.TextTemplate; import org.elasticsearch.xpack.watcher.common.text.TextTemplateEngine; +import org.elasticsearch.xpack.watcher.notification.WebhookService; import org.elasticsearch.xpack.watcher.notification.email.Attachment; import org.elasticsearch.xpack.watcher.support.Variables; @@ -120,20 +120,20 @@ public static List> getSettings() { private final Logger logger; private final TimeValue interval; private final int retries; - private HttpClient httpClient; + private final WebhookService webhookService; private final TextTemplateEngine templateEngine; private boolean warningEnabled = REPORT_WARNING_ENABLED_SETTING.getDefault(Settings.EMPTY); private final Map customWarnings = new ConcurrentHashMap<>(1); public ReportingAttachmentParser( Settings settings, - HttpClient httpClient, + WebhookService webhookService, TextTemplateEngine templateEngine, ClusterSettings clusterSettings ) { this.interval = INTERVAL_SETTING.get(settings); this.retries = RETRIES_SETTING.get(settings); - this.httpClient = httpClient; + this.webhookService = webhookService; this.templateEngine = templateEngine; this.logger = LogManager.getLogger(getClass()); clusterSettings.addSettingsUpdateConsumer(REPORT_WARNING_ENABLED_SETTING, this::setWarningEnabled); @@ -210,7 +210,7 @@ public Attachment toAttachment(WatchExecutionContext context, Payload payload, R // IMPORTANT NOTE: This is only a temporary solution until we made the execution of watcher more async // This still blocks other executions on the thread and we have to get away from that sleep(sleepMillis, context, attachment); - HttpResponse response = httpClient.execute(pollingRequest); + HttpResponse response = webhookService.modifyAndExecuteHttpRequest(pollingRequest).v2(); if (response.status() == 503) { // requires us to interval another run, no action to take, except logging @@ -322,7 +322,7 @@ private long getSleepMillis(WatchExecutionContext context, ReportingAttachment a * Trigger the initial report generation and catch possible exceptions */ private HttpResponse requestReportGeneration(String watchId, String attachmentId, HttpRequest request) throws IOException { - HttpResponse response = httpClient.execute(request); + HttpResponse response = webhookService.modifyAndExecuteHttpRequest(request).v2(); if (response.status() != 200) { throw new ElasticsearchException( "Watch[{}] reporting[{}] Error response when trying to trigger reporting generation " diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/actions/email/EmailActionTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/actions/email/EmailActionTests.java index 0303e67932549..f097ffe5c4da2 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/actions/email/EmailActionTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/actions/email/EmailActionTests.java @@ -9,6 +9,7 @@ import io.netty.handler.codec.http.HttpHeaders; import org.elasticsearch.ElasticsearchParseException; +import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.Strings; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.collect.MapBuilder; @@ -35,6 +36,7 @@ import org.elasticsearch.xpack.watcher.common.http.HttpResponse; import org.elasticsearch.xpack.watcher.common.text.TextTemplate; import org.elasticsearch.xpack.watcher.common.text.TextTemplateEngine; +import org.elasticsearch.xpack.watcher.notification.WebhookService; import org.elasticsearch.xpack.watcher.notification.email.Attachment; import org.elasticsearch.xpack.watcher.notification.email.Authentication; import org.elasticsearch.xpack.watcher.notification.email.Email; @@ -62,6 +64,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import static java.util.Collections.emptyMap; import static java.util.Collections.singletonMap; @@ -92,7 +95,10 @@ public void addEmailAttachmentParsers() { Map> emailAttachmentParsers = new HashMap<>(); emailAttachmentParsers.put( HttpEmailAttachementParser.TYPE, - new HttpEmailAttachementParser(httpClient, new MockTextTemplateEngine()) + new HttpEmailAttachementParser( + new WebhookService(Settings.EMPTY, httpClient, mockClusterService().getClusterSettings()), + new MockTextTemplateEngine() + ) ); emailAttachmentParsers.put(DataAttachmentParser.TYPE, new DataAttachmentParser()); emailAttachmentParser = new EmailAttachmentsParser(emailAttachmentParsers); @@ -547,7 +553,13 @@ public void testThatOneFailedEmailAttachmentResultsInActionFailure() throws Exce // setup email attachment parsers Map> attachmentParsers = new HashMap<>(); - attachmentParsers.put(HttpEmailAttachementParser.TYPE, new HttpEmailAttachementParser(httpClient, engine)); + attachmentParsers.put( + HttpEmailAttachementParser.TYPE, + new HttpEmailAttachementParser( + new WebhookService(Settings.EMPTY, httpClient, mockClusterService().getClusterSettings()), + engine + ) + ); EmailAttachmentsParser emailAttachmentsParser = new EmailAttachmentsParser(attachmentParsers); XContentBuilder builder = jsonBuilder().startObject() @@ -666,4 +678,10 @@ public EmailSent send(Email email, Authentication auth, Profile profile, String } } + private ClusterService mockClusterService() { + ClusterService clusterService = mock(ClusterService.class); + ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, Set.of()); + when(clusterService.getClusterSettings()).thenReturn(clusterSettings); + return clusterService; + } } diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/notification/WebhookServiceTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/notification/WebhookServiceTests.java new file mode 100644 index 0000000000000..c46ef96582640 --- /dev/null +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/notification/WebhookServiceTests.java @@ -0,0 +1,118 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.watcher.notification; + +import org.elasticsearch.common.settings.ClusterSettings; +import org.elasticsearch.common.settings.MockSecureSettings; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.watcher.common.http.HttpClient; +import org.elasticsearch.xpack.watcher.common.http.HttpMethod; +import org.elasticsearch.xpack.watcher.common.http.HttpRequest; +import org.elasticsearch.xpack.watcher.common.http.HttpResponse; +import org.elasticsearch.xpack.watcher.common.http.Scheme; + +import java.io.IOException; +import java.util.Set; + +import static org.hamcrest.Matchers.equalTo; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class WebhookServiceTests extends ESTestCase { + public void testModifyRequest() throws IOException { + Settings.Builder builder = Settings.builder(); + builder.put(WebhookService.SETTING_WEBHOOK_TOKEN_ENABLED.getKey(), true); + MockSecureSettings secureSettings = new MockSecureSettings(); + secureSettings.setString( + WebhookService.SETTING_WEBHOOK_HOST_TOKEN_PAIRS.getKey(), + "host1.com:1234=token1234,host2.org:2345=token2345" + ); + builder.setSecureSettings(secureSettings); + Settings finalSettings = builder.build(); + + HttpClient mockClient = mock(HttpClient.class); + WebhookService service = new WebhookService( + finalSettings, + mockClient, + new ClusterSettings( + finalSettings, + Set.of(WebhookService.SETTING_WEBHOOK_TOKEN_ENABLED, WebhookService.SETTING_WEBHOOK_HOST_TOKEN_PAIRS) + ) + ); + + HttpRequest nonTokenReq = new HttpRequest( + "example.com", + 80, + Scheme.HTTP, + HttpMethod.GET, + "/", + null, + null, + null, + null, + null, + null, + null + ); + HttpRequest host1Req = new HttpRequest( + "host1.com", + 1234, + Scheme.HTTP, + HttpMethod.GET, + "/", + null, + null, + null, + null, + null, + null, + null + ); + HttpRequest host1WrongPortReq = new HttpRequest( + "host1.com", + 3456, + Scheme.HTTP, + HttpMethod.GET, + "/", + null, + null, + null, + null, + null, + null, + null + ); + HttpRequest host2Req = new HttpRequest( + "host2.org", + 2345, + Scheme.HTTP, + HttpMethod.GET, + "/", + null, + null, + null, + null, + null, + null, + null + ); + + assertSame(service.maybeModifyHttpRequest(nonTokenReq), nonTokenReq); + assertSame(service.maybeModifyHttpRequest(host1WrongPortReq), host1WrongPortReq); + assertThat(service.maybeModifyHttpRequest(host2Req).headers().get(WebhookService.TOKEN_HEADER_NAME), equalTo("token2345")); + + HttpRequest host1ModReq = service.maybeModifyHttpRequest(host1Req); + assertThat(host1ModReq.headers().get(WebhookService.TOKEN_HEADER_NAME), equalTo("token1234")); + when(mockClient.execute(any(HttpRequest.class))).thenReturn(new HttpResponse(200, "{}")); + service.modifyAndExecuteHttpRequest(host1Req); + verify(mockClient).execute(host1ModReq); + } +} diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/notification/email/attachment/HttpEmailAttachementParserTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/notification/email/attachment/HttpEmailAttachementParserTests.java index 0a79ea101f7aa..3ea4a7c787ec2 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/notification/email/attachment/HttpEmailAttachementParserTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/notification/email/attachment/HttpEmailAttachementParserTests.java @@ -7,8 +7,11 @@ package org.elasticsearch.xpack.watcher.notification.email.attachment; import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.Strings; import org.elasticsearch.common.collect.MapBuilder; +import org.elasticsearch.common.settings.ClusterSettings; +import org.elasticsearch.common.settings.Settings; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xcontent.ToXContent; import org.elasticsearch.xcontent.XContentBuilder; @@ -20,6 +23,7 @@ import org.elasticsearch.xpack.watcher.common.http.HttpRequest; import org.elasticsearch.xpack.watcher.common.http.HttpRequestTemplate; import org.elasticsearch.xpack.watcher.common.http.HttpResponse; +import org.elasticsearch.xpack.watcher.notification.WebhookService; import org.elasticsearch.xpack.watcher.notification.email.attachment.EmailAttachmentParser.EmailAttachment; import org.elasticsearch.xpack.watcher.test.MockTextTemplateEngine; import org.junit.Before; @@ -31,9 +35,14 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import static java.nio.charset.StandardCharsets.UTF_8; import static org.elasticsearch.xcontent.XContentFactory.jsonBuilder; +import static org.elasticsearch.xpack.watcher.notification.email.attachment.ReportingAttachmentParser.INTERVAL_SETTING; +import static org.elasticsearch.xpack.watcher.notification.email.attachment.ReportingAttachmentParser.REPORT_WARNING_ENABLED_SETTING; +import static org.elasticsearch.xpack.watcher.notification.email.attachment.ReportingAttachmentParser.REPORT_WARNING_TEXT; +import static org.elasticsearch.xpack.watcher.notification.email.attachment.ReportingAttachmentParser.RETRIES_SETTING; import static org.elasticsearch.xpack.watcher.test.WatcherTestUtils.mockExecutionContextBuilder; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.core.Is.is; @@ -52,7 +61,13 @@ public void init() throws Exception { httpClient = mock(HttpClient.class); attachmentParsers = new HashMap<>(); - attachmentParsers.put(HttpEmailAttachementParser.TYPE, new HttpEmailAttachementParser(httpClient, new MockTextTemplateEngine())); + attachmentParsers.put( + HttpEmailAttachementParser.TYPE, + new HttpEmailAttachementParser( + new WebhookService(Settings.EMPTY, httpClient, mockClusterService().getClusterSettings()), + new MockTextTemplateEngine() + ) + ); emailAttachmentsParser = new EmailAttachmentsParser(attachmentParsers); } @@ -172,4 +187,13 @@ private WatchExecutionContext createWatchExecutionContext() { .buildMock(); } + private ClusterService mockClusterService() { + ClusterService clusterService = mock(ClusterService.class); + ClusterSettings clusterSettings = new ClusterSettings( + Settings.EMPTY, + Set.of(INTERVAL_SETTING, RETRIES_SETTING, REPORT_WARNING_ENABLED_SETTING, REPORT_WARNING_TEXT) + ); + when(clusterService.getClusterSettings()).thenReturn(clusterSettings); + return clusterService; + } } diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/notification/email/attachment/ReportingAttachmentParserTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/notification/email/attachment/ReportingAttachmentParserTests.java index 075182af8798d..a8eee3d0f9f1d 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/notification/email/attachment/ReportingAttachmentParserTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/notification/email/attachment/ReportingAttachmentParserTests.java @@ -29,6 +29,7 @@ import org.elasticsearch.xpack.watcher.common.http.HttpResponse; import org.elasticsearch.xpack.watcher.common.text.TextTemplate; import org.elasticsearch.xpack.watcher.common.text.TextTemplateEngine; +import org.elasticsearch.xpack.watcher.notification.WebhookService; import org.elasticsearch.xpack.watcher.notification.email.Attachment; import org.elasticsearch.xpack.watcher.notification.email.attachment.EmailAttachmentParser.EmailAttachment; import org.elasticsearch.xpack.watcher.test.MockTextTemplateEngine; @@ -83,7 +84,8 @@ public class ReportingAttachmentParserTests extends ESTestCase { public void init() throws Exception { httpClient = mock(HttpClient.class); clusterSettings = mockClusterService().getClusterSettings(); - reportingAttachmentParser = new ReportingAttachmentParser(Settings.EMPTY, httpClient, templateEngine, clusterSettings); + WebhookService webhookService = new WebhookService(Settings.EMPTY, httpClient, clusterSettings); + reportingAttachmentParser = new ReportingAttachmentParser(Settings.EMPTY, webhookService, templateEngine, clusterSettings); attachmentParsers.put(ReportingAttachmentParser.TYPE, reportingAttachmentParser); emailAttachmentsParser = new EmailAttachmentsParser(attachmentParsers); } @@ -413,7 +415,12 @@ public void testPollingDefaultCanBeOverriddenBySettings() throws Exception { Settings settings = Settings.builder().put(INTERVAL_SETTING.getKey(), "1ms").put(RETRIES_SETTING.getKey(), retries).build(); - reportingAttachmentParser = new ReportingAttachmentParser(settings, httpClient, templateEngine, clusterSettings); + reportingAttachmentParser = new ReportingAttachmentParser( + settings, + new WebhookService(settings, httpClient, clusterSettings), + templateEngine, + clusterSettings + ); expectThrows( ElasticsearchException.class, () -> reportingAttachmentParser.toAttachment(createWatchExecutionContext(), Payload.EMPTY, attachment) @@ -445,7 +452,7 @@ public String render(TextTemplate textTemplate, Map model) { ); reportingAttachmentParser = new ReportingAttachmentParser( Settings.EMPTY, - httpClient, + new WebhookService(Settings.EMPTY, httpClient, clusterSettings), replaceHttpWithHttpsTemplateEngine, clusterSettings ); @@ -468,7 +475,12 @@ public void testRetrySettingCannotBeNegative() throws Exception { Settings invalidSettings = Settings.builder().put("xpack.notification.reporting.retries", -10).build(); e = expectThrows( IllegalArgumentException.class, - () -> new ReportingAttachmentParser(invalidSettings, httpClient, templateEngine, clusterSettings) + () -> new ReportingAttachmentParser( + invalidSettings, + new WebhookService(invalidSettings, httpClient, clusterSettings), + templateEngine, + clusterSettings + ) ); assertThat(e.getMessage(), is("Failed to parse value [-10] for setting [xpack.notification.reporting.retries] must be >= 0")); }