mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-26 06:46:10 +00:00
Watcher: Fail email action on attachment download issues
In case that a single email attachment cannot be downloaded, this ensures that the whole action fails with a correct Action.Failure. This also fixes an NPE that would occur otherwise. Original commit: elastic/x-pack-elasticsearch@7bb042a719
This commit is contained in:
parent
cc8109bc87
commit
1f113e07f4
@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.elasticsearch.watcher.actions.email;
|
package org.elasticsearch.watcher.actions.email;
|
||||||
|
|
||||||
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.common.logging.ESLogger;
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
import org.elasticsearch.watcher.actions.Action;
|
import org.elasticsearch.watcher.actions.Action;
|
||||||
import org.elasticsearch.watcher.actions.ExecutableAction;
|
import org.elasticsearch.watcher.actions.ExecutableAction;
|
||||||
@ -52,8 +53,12 @@ public class ExecutableEmailAction extends ExecutableAction<EmailAction> {
|
|||||||
if (action.getAttachments() != null && action.getAttachments().getAttachments().size() > 0) {
|
if (action.getAttachments() != null && action.getAttachments().getAttachments().size() > 0) {
|
||||||
for (EmailAttachmentParser.EmailAttachment emailAttachment : action.getAttachments().getAttachments()) {
|
for (EmailAttachmentParser.EmailAttachment emailAttachment : action.getAttachments().getAttachments()) {
|
||||||
EmailAttachmentParser parser = emailAttachmentParsers.get(emailAttachment.type());
|
EmailAttachmentParser parser = emailAttachmentParsers.get(emailAttachment.type());
|
||||||
Attachment attachment = parser.toAttachment(ctx, payload, emailAttachment);
|
try {
|
||||||
attachments.put(attachment.id(), attachment);
|
Attachment attachment = parser.toAttachment(ctx, payload, emailAttachment);
|
||||||
|
attachments.put(attachment.id(), attachment);
|
||||||
|
} catch (ElasticsearchException e) {
|
||||||
|
return new EmailAction.Result.Failure(action.type(), e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.elasticsearch.watcher.actions.email.service.attachment;
|
package org.elasticsearch.watcher.actions.email.service.attachment;
|
||||||
|
|
||||||
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.watcher.actions.email.service.Attachment;
|
import org.elasticsearch.watcher.actions.email.service.Attachment;
|
||||||
@ -48,6 +49,6 @@ public interface EmailAttachmentParser<T extends EmailAttachmentParser.EmailAtta
|
|||||||
* @param attachment The typed attachment
|
* @param attachment The typed attachment
|
||||||
* @return An attachment that is ready to be used in a MimeMessage
|
* @return An attachment that is ready to be used in a MimeMessage
|
||||||
*/
|
*/
|
||||||
Attachment toAttachment(WatchExecutionContext context, Payload payload, T attachment);
|
Attachment toAttachment(WatchExecutionContext context, Payload payload, T attachment) throws ElasticsearchException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.elasticsearch.watcher.actions.email.service.attachment;
|
package org.elasticsearch.watcher.actions.email.service.attachment;
|
||||||
|
|
||||||
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.ElasticsearchParseException;
|
import org.elasticsearch.ElasticsearchParseException;
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.ParseFieldMatcher;
|
import org.elasticsearch.common.ParseFieldMatcher;
|
||||||
@ -81,7 +82,8 @@ public class HttpEmailAttachementParser implements EmailAttachmentParser<HttpReq
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Attachment toAttachment(WatchExecutionContext context, Payload payload, HttpRequestAttachment attachment) {
|
public Attachment toAttachment(WatchExecutionContext context, Payload payload,
|
||||||
|
HttpRequestAttachment attachment) throws ElasticsearchException {
|
||||||
Map<String, Object> model = Variables.createCtxModel(context, payload);
|
Map<String, Object> model = Variables.createCtxModel(context, payload);
|
||||||
HttpRequest httpRequest = attachment.getRequestTemplate().render(templateEngine, model);
|
HttpRequest httpRequest = attachment.getRequestTemplate().render(templateEngine, model);
|
||||||
|
|
||||||
@ -106,6 +108,7 @@ public class HttpEmailAttachementParser implements EmailAttachmentParser<HttpReq
|
|||||||
httpRequest.method(), httpRequest.path(), e.getMessage());
|
httpRequest.method(), httpRequest.path(), e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
throw new ElasticsearchException("Unable to get attachment of type [{}] with id [{}] in watch [{}] aborting watch execution",
|
||||||
|
type(), attachment.getId(), context.watch().id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -513,6 +513,65 @@ public class EmailActionTests extends ESTestCase {
|
|||||||
assertThat(dataAttachment.contentType(), is("application/yaml"));
|
assertThat(dataAttachment.contentType(), is("application/yaml"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testThatOneFailedEmailAttachmentResultsInActionFailure() throws Exception {
|
||||||
|
EmailService emailService = new AbstractWatcherIntegrationTestCase.NoopEmailService();
|
||||||
|
TextTemplateEngine engine = mock(TextTemplateEngine.class);
|
||||||
|
HtmlSanitizer htmlSanitizer = mock(HtmlSanitizer.class);
|
||||||
|
HttpClient httpClient = mock(HttpClient.class);
|
||||||
|
|
||||||
|
// setup mock response, second one is an error
|
||||||
|
Map<String, String[]> headers = new HashMap<>(1);
|
||||||
|
headers.put(HttpHeaders.Names.CONTENT_TYPE, new String[]{"plain/text"});
|
||||||
|
when(httpClient.execute(any(HttpRequest.class)))
|
||||||
|
.thenReturn(new HttpResponse(200, "body", headers))
|
||||||
|
.thenReturn(new HttpResponse(403));
|
||||||
|
|
||||||
|
// setup email attachment parsers
|
||||||
|
HttpRequestTemplate.Parser httpRequestTemplateParser = new HttpRequestTemplate.Parser(registry);
|
||||||
|
Map<String, EmailAttachmentParser> attachmentParsers = new HashMap<>();
|
||||||
|
attachmentParsers.put(HttpEmailAttachementParser.TYPE, new HttpEmailAttachementParser(httpClient, httpRequestTemplateParser,
|
||||||
|
engine));
|
||||||
|
EmailAttachmentsParser emailAttachmentsParser = new EmailAttachmentsParser(attachmentParsers);
|
||||||
|
|
||||||
|
XContentBuilder builder = jsonBuilder().startObject()
|
||||||
|
.startObject("attachments")
|
||||||
|
.startObject("first")
|
||||||
|
.startObject("http")
|
||||||
|
.startObject("request").field("url", "http://localhost/first").endObject()
|
||||||
|
.endObject()
|
||||||
|
.endObject()
|
||||||
|
.startObject("second")
|
||||||
|
.startObject("http")
|
||||||
|
.startObject("request").field("url", "http://localhost/second").endObject()
|
||||||
|
.endObject()
|
||||||
|
.endObject()
|
||||||
|
.endObject()
|
||||||
|
.endObject();
|
||||||
|
XContentParser parser = JsonXContent.jsonXContent.createParser(builder.bytes());
|
||||||
|
logger.info("JSON: {}", builder.string());
|
||||||
|
|
||||||
|
parser.nextToken();
|
||||||
|
|
||||||
|
ExecutableEmailAction executableEmailAction = new EmailActionFactory(Settings.EMPTY, emailService, engine, htmlSanitizer,
|
||||||
|
emailAttachmentsParser).parseExecutable(randomAsciiOfLength(3), randomAsciiOfLength(7), parser);
|
||||||
|
|
||||||
|
DateTime now = DateTime.now(DateTimeZone.UTC);
|
||||||
|
Wid wid = new Wid(randomAsciiOfLength(5), randomLong(), now);
|
||||||
|
Map<String, Object> metadata = MapBuilder.<String, Object>newMapBuilder().put("_key", "_val").map();
|
||||||
|
WatchExecutionContext ctx = mockExecutionContextBuilder("watch1")
|
||||||
|
.wid(wid)
|
||||||
|
.payload(new Payload.Simple())
|
||||||
|
.time("watch1", now)
|
||||||
|
.metadata(metadata)
|
||||||
|
.buildMock();
|
||||||
|
|
||||||
|
Action.Result result = executableEmailAction.execute("test", ctx, new Payload.Simple());
|
||||||
|
assertThat(result, instanceOf(EmailAction.Result.Failure.class));
|
||||||
|
EmailAction.Result.Failure failure = (EmailAction.Result.Failure) result;
|
||||||
|
assertThat(failure.reason(),
|
||||||
|
is("Unable to get attachment of type [http] with id [second] in watch [watch1] aborting watch execution"));
|
||||||
|
}
|
||||||
|
|
||||||
private EmailActionFactory createEmailActionFactory() {
|
private EmailActionFactory createEmailActionFactory() {
|
||||||
EmailService emailService = new AbstractWatcherIntegrationTestCase.NoopEmailService();
|
EmailService emailService = new AbstractWatcherIntegrationTestCase.NoopEmailService();
|
||||||
TextTemplateEngine engine = mock(TextTemplateEngine.class);
|
TextTemplateEngine engine = mock(TextTemplateEngine.class);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user