Java tutorial
/* * 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.impl; import org.apache.eagle.alert.engine.coordinator.Publishment; import org.apache.eagle.alert.engine.model.AlertStreamEvent; import org.apache.eagle.alert.engine.publisher.PublishConstants; import org.apache.eagle.alert.engine.publisher.email.AlertEmailConstants; import org.apache.eagle.alert.engine.publisher.email.AlertEmailGenerator; import org.apache.eagle.alert.engine.publisher.email.AlertEmailGeneratorBuilder; import com.typesafe.config.Config; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.eagle.alert.service.MetadataServiceClientImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import static org.apache.eagle.alert.service.MetadataServiceClientImpl.*; import static org.apache.eagle.common.mail.AlertEmailConstants.*; public class AlertEmailPublisher extends AbstractPublishPlugin { private static final Logger LOG = LoggerFactory.getLogger(AlertEmailPublisher.class); private static final int DEFAULT_THREAD_POOL_CORE_SIZE = 4; private static final int DEFAULT_THREAD_POOL_MAX_SIZE = 8; private static final long DEFAULT_THREAD_POOL_SHRINK_TIME = 60000L; // 1 minute private AlertEmailGenerator emailGenerator; private Map<String, Object> emailConfig; private transient ThreadPoolExecutor executorPool; private String serverHost; private int serverPort; private Properties mailClientProperties; @Override @SuppressWarnings("rawtypes") public void init(Config config, Publishment publishment, Map conf) throws Exception { super.init(config, publishment, conf); this.serverHost = config.hasPath(MetadataServiceClientImpl.EAGLE_CORRELATION_SERVICE_HOST) ? config.getString(MetadataServiceClientImpl.EAGLE_CORRELATION_SERVICE_HOST) : "localhost"; this.serverPort = config.hasPath(MetadataServiceClientImpl.EAGLE_CORRELATION_SERVICE_PORT) ? config.getInt(MetadataServiceClientImpl.EAGLE_CORRELATION_SERVICE_PORT) : 80; this.mailClientProperties = parseMailClientConfig(config); executorPool = new ThreadPoolExecutor(DEFAULT_THREAD_POOL_CORE_SIZE, DEFAULT_THREAD_POOL_MAX_SIZE, DEFAULT_THREAD_POOL_SHRINK_TIME, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); LOG.info(" Creating Email Generator... "); if (publishment.getProperties() != null) { emailConfig = new HashMap<>(publishment.getProperties()); emailGenerator = createEmailGenerator(emailConfig); } } private Properties parseMailClientConfig(Config config) { Properties props = new Properties(); Config mailConfig = null; if (config.hasPath(EAGLE_COORDINATOR_EMAIL_SERVICE)) { mailConfig = config.getConfig(EAGLE_COORDINATOR_EMAIL_SERVICE); } else if (config.hasPath(EAGLE_APPLICATION_EMAIL_SERVICE)) { mailConfig = config.getConfig(EAGLE_APPLICATION_EMAIL_SERVICE); } String mailSmtpServer = mailConfig.getString(EAGLE_EMAIL_SMTP_SERVER); String mailSmtpPort = mailConfig.getString(EAGLE_EMAIL_SMTP_PORT); String mailSmtpAuth = mailConfig.getString(EAGLE_EMAIL_SMTP_AUTH); props.put(AlertEmailConstants.CONF_MAIL_HOST, mailSmtpServer); props.put(AlertEmailConstants.CONF_MAIL_PORT, mailSmtpPort); props.put(AlertEmailConstants.CONF_MAIL_AUTH, mailSmtpAuth); if (Boolean.parseBoolean(mailSmtpAuth)) { String mailSmtpUsername = mailConfig.getString(EAGLE_EMAIL_SMTP_USERNAME); String mailSmtpPassword = mailConfig.getString(EAGLE_EMAIL_SMTP_PASSWORD); props.put(AlertEmailConstants.CONF_AUTH_USER, mailSmtpUsername); props.put(AlertEmailConstants.CONF_AUTH_PASSWORD, mailSmtpPassword); } String mailSmtpConn = mailConfig.hasPath(EAGLE_EMAIL_SMTP_CONN) ? mailConfig.getString(EAGLE_EMAIL_SMTP_CONN) : AlertEmailConstants.CONN_PLAINTEXT; if (mailSmtpConn.equalsIgnoreCase(AlertEmailConstants.CONN_TLS)) { props.put("mail.smtp.starttls.enable", "true"); } if (mailSmtpConn.equalsIgnoreCase(AlertEmailConstants.CONN_SSL)) { props.put("mail.smtp.socketFactory.port", "465"); props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); } String mailSmtpDebug = mailConfig.hasPath(EAGLE_EMAIL_SMTP_DEBUG) ? mailConfig.getString(EAGLE_EMAIL_SMTP_DEBUG) : "false"; props.put(AlertEmailConstants.CONF_MAIL_DEBUG, mailSmtpDebug); return props; } @Override public void onAlert(AlertStreamEvent event) throws Exception { if (emailGenerator == null) { LOG.warn("emailGenerator is null due to the incorrect configurations"); return; } List<AlertStreamEvent> outputEvents = dedup(event); if (outputEvents == null) { return; } boolean isSuccess = true; for (AlertStreamEvent outputEvent : outputEvents) { if (!emailGenerator.sendAlertEmail(outputEvent)) { isSuccess = false; } } PublishStatus status = new PublishStatus(); if (!isSuccess) { status.errorMessage = "Failed to send email"; status.successful = false; } else { status.errorMessage = ""; status.successful = true; } this.status = status; } @Override public void update(String dedupIntervalMin, Map<String, Object> pluginProperties) { super.update(dedupIntervalMin, pluginProperties); if (pluginProperties != null && !emailConfig.equals(pluginProperties)) { emailConfig = new HashMap<>(pluginProperties); emailGenerator = createEmailGenerator(pluginProperties); } } @Override public void close() { this.executorPool.shutdown(); } private AlertEmailGenerator createEmailGenerator(Map<String, Object> notificationConfig) { String tplFileName = (String) notificationConfig.get(PublishConstants.TEMPLATE); if (tplFileName == null || tplFileName.equals("")) { // tplFileName = "ALERT_DEFAULT_TEMPLATE.vm"; // tplFileName = "ALERT_LIGHT_TEMPLATE.vm"; tplFileName = "ALERT_INLINED_TEMPLATE.vm"; } String subject = (String) notificationConfig.get(PublishConstants.SUBJECT); if (subject == null) { subject = "No subject"; } String sender = (String) notificationConfig.get(PublishConstants.SENDER); String recipients = (String) notificationConfig.get(PublishConstants.RECIPIENTS); if (sender == null || recipients == null) { LOG.warn("email sender or recipients is null"); return null; } AlertEmailGenerator gen = AlertEmailGeneratorBuilder.newBuilder().withMailProps(this.mailClientProperties) .withSubject(subject).withSender(sender).withRecipients(recipients).withTplFile(tplFileName) .withExecutorPool(this.executorPool).withServerHost(this.serverHost).withServerPort(this.serverPort) .build(); return gen; } @Override public int hashCode() { return new HashCodeBuilder().append(getClass().getCanonicalName()).toHashCode(); } @Override public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof AlertEmailPublisher)) { return false; } return true; } @Override protected Logger getLogger() { return LOG; } }