blob: a57941e43f545146b87bc386c732450edc7a26a3 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/**
*
*/
package org.apache.eagle.alert.engine.publisher.email;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.util.URIUtil;
import org.apache.eagle.alert.engine.model.AlertStreamEvent;
import org.apache.eagle.alert.engine.publisher.PublishConstants;
import org.apache.eagle.common.DateTimeUtil;
import org.apache.eagle.common.Version;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.*;
public class AlertEmailGenerator {
private String tplFile;
private String sender;
private String recipients;
private String subject;
private String serverHost = "localhost";
private int serverPort = 80;
private Properties properties;
private ThreadPoolExecutor executorPool;
private static final Logger LOG = LoggerFactory.getLogger(AlertEmailGenerator.class);
private static final long MAX_TIMEOUT_MS = 60000;
public boolean sendAlertEmail(AlertStreamEvent entity) {
return sendAlertEmail(entity, recipients, null);
}
public boolean sendAlertEmail(AlertStreamEvent entity, String recipients) {
return sendAlertEmail(entity, recipients, null);
}
public boolean sendAlertEmail(AlertStreamEvent event, String recipients, String cc) {
AlertEmailContext email = new AlertEmailContext();
Map<String, String> alertContext = buildAlertContext(event);
email.setAlertContext(alertContext);
email.setVelocityTplFile(tplFile);
if (event.getCategory() != null) {
email.setSubject(String.format("[Eagle Alert][%s][%s] %s",
event.getSeverity(), event.getCategory(), event.getSubject() != null ? event.getSubject() : subject));
} else {
email.setSubject(String.format("[Eagle Alert][%s] %s",
event.getSeverity(), event.getSubject() != null ? event.getSubject() : subject));
}
email.setSender(sender);
email.setRecipients(recipients);
email.setCc(cc);
/** asynchronized email sending. */
AlertEmailSender thread = new AlertEmailSender(email, properties);
if (this.executorPool == null) {
throw new IllegalStateException("Invoking thread executor pool but it's is not set yet");
}
LOG.info("Sending email in asynchronous to: " + recipients + ", cc: " + cc);
Future<?> future = this.executorPool.submit(thread);
Boolean status;
try {
future.get(MAX_TIMEOUT_MS, TimeUnit.MILLISECONDS);
status = true;
//LOG.info(String.format("Successfully send email to %s", recipients));
} catch (InterruptedException | ExecutionException e) {
status = false;
LOG.error(String.format("Failed to send email to %s, due to:%s", recipients, e), e);
} catch (TimeoutException e) {
status = false;
LOG.error(String.format("Failed to send email to %s due to timeout exception, max timeout: %s ms ", recipients, MAX_TIMEOUT_MS), e);
}
return status;
}
private String getAlertBody(AlertStreamEvent event) {
if (event.getBody() == null) {
return String.format("Alert policy \"%s\" was triggered: %s", event.getPolicyId(), generateAlertDataDesc(event));
} else {
return event.getBody();
}
}
private String generateAlertDataDesc(AlertStreamEvent event) {
if (event.getDataMap() == null) {
return "N/A";
}
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, Object> entry : event.getDataMap().entrySet()) {
sb.append(entry.getKey()).append("=").append(entry.getValue()).append(" ");
}
return sb.toString();
}
private Map<String, String> buildAlertContext(AlertStreamEvent event) {
Map<String, String> alertContext = new HashMap<>();
if (event.getContext() != null) {
for (Map.Entry<String, Object> entry : event.getContext().entrySet()) {
if (entry.getValue() == null) {
alertContext.put(entry.getKey(), "N/A");
} else {
alertContext.put(entry.getKey(), entry.getValue().toString());
}
}
}
alertContext.put(PublishConstants.ALERT_EMAIL_SUBJECT, event.getSubject());
alertContext.put(PublishConstants.ALERT_EMAIL_BODY, getAlertBody(event));
alertContext.put(PublishConstants.ALERT_EMAIL_POLICY_ID, event.getPolicyId());
alertContext.put(PublishConstants.ALERT_EMAIL_ALERT_ID, event.getAlertId());
alertContext.put(PublishConstants.ALERT_EMAIL_ALERT_DATA, event.getDataMap().toString());
alertContext.put(PublishConstants.ALERT_EMAIL_ALERT_DATA_DESC, generateAlertDataDesc(event));
alertContext.put(PublishConstants.ALERT_EMAIL_ALERT_CATEGORY, event.getCategory());
alertContext.put(PublishConstants.ALERT_EMAIL_ALERT_SEVERITY, event.getSeverity().toString());
alertContext.put(PublishConstants.ALERT_EMAIL_TIME, String.format("%s %s",
DateTimeUtil.millisecondsToHumanDateWithSeconds(event.getCreatedTime()),
DateTimeUtil.CURRENT_TIME_ZONE.getID()));
alertContext.put(PublishConstants.ALERT_EMAIL_STREAM_ID, event.getStreamId());
alertContext.put(PublishConstants.ALERT_EMAIL_CREATOR, event.getCreatedBy());
alertContext.put(PublishConstants.ALERT_EMAIL_VERSION, Version.version);
String rootUrl = this.getServerPort() == 80 ? String.format("http://%s", this.getServerHost())
: String.format("http://%s:%s", this.getServerHost(), this.getServerPort());
try {
alertContext.put(PublishConstants.ALERT_EMAIL_ALERT_DETAIL_URL,
String.format("%s/#/site/%s/alert/detail/%s", rootUrl, event.getSiteId(), URIUtil.encodeQuery(event.getAlertId(), "UTF-8")));
alertContext.put(PublishConstants.ALERT_EMAIL_POLICY_DETAIL_URL,
String.format("%s/#/site/%s/policy/detail/%s", rootUrl, event.getSiteId(), URIUtil.encodeQuery(event.getPolicyId(), "UTF-8")));
} catch (URIException e) {
LOG.warn(e.getMessage(), e);
alertContext.put(PublishConstants.ALERT_EMAIL_ALERT_DETAIL_URL,
String.format("%s/#/site/%s/alert/detail/%s?timestamp=%s", event.getSiteId(), rootUrl, event.getAlertId(), event.getTimestamp()));
alertContext.put(PublishConstants.ALERT_EMAIL_POLICY_DETAIL_URL,
String.format("%s/#/site/%s/policy/detail/%s", event.getSiteId(), rootUrl, event.getPolicyId()));
}
alertContext.put(PublishConstants.ALERT_EMAIL_HOME_URL, rootUrl);
return alertContext;
}
public String getTplFile() {
return tplFile;
}
public void setTplFile(String tplFile) {
this.tplFile = tplFile;
}
public String getSender() {
return sender;
}
public void setSender(String sender) {
this.sender = sender;
}
public String getRecipients() {
return recipients;
}
public void setRecipients(String recipients) {
this.recipients = recipients;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public void setExecutorPool(ThreadPoolExecutor executorPool) {
this.executorPool = executorPool;
}
public String getServerHost() {
return serverHost;
}
public void setServerHost(String serverHost) {
this.serverHost = serverHost;
}
public int getServerPort() {
return serverPort;
}
public void setServerPort(int serverPort) {
this.serverPort = serverPort;
}
}