/* * #%L * ACS AEM Commons Bundle * %% * Copyright (C) 2016 Adobe * %% * Licensed 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. * #L% */ package com.adobe.acs.commons.hc.impl; import com.day.cq.commons.mail.MailTemplate; import com.day.cq.mailer.MessageGateway; import com.day.cq.mailer.MessageGatewayService; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.CharEncoding; import org.apache.commons.lang.text.StrLookup; import org.apache.commons.mail.SimpleEmail; import org.apache.felix.scr.annotations.*; import org.apache.felix.scr.annotations.Properties; import org.apache.sling.commons.osgi.PropertiesUtil; import org.apache.sling.hc.api.HealthCheck; import org.apache.sling.hc.api.Result; import org.apache.sling.hc.util.FormattingResultLog; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.mail.internet.InternetAddress; import java.util.*; @Component(metatype = true, label = "ACS AEM Commons - Health Check - SMTP E-Mail Service", description = "Checks if the AEM E-Mail Service can connect and send mail via the configured SMTP server.", policy = ConfigurationPolicy.REQUIRE ) @Properties({ @Property( name = HealthCheck.NAME, value = "SMTP Mail Service", propertyPrivate = true), @Property( label = "Tags", name = HealthCheck.TAGS, unbounded = PropertyUnbounded.ARRAY, value = {"integrations", "smtp", "email"}, description = "Tags for this check to be used by composite health checks."), @Property( name = HealthCheck.MBEAN_NAME, value = "smtpMailService", propertyPrivate = true)}) @Service public class SMTPMailServiceHealthCheck implements HealthCheck { private static final Logger log = LoggerFactory.getLogger(SMTPMailServiceHealthCheck.class); // 10 seconds private static final int TIMEOUT = 1000 * 10; private static String MAIL_TEMPLATE = System.getProperty("line.separator") + "Sling Health Check for AEM E-mail Service connectivity"; private static final String DEFAULT_EMAIL = "healthcheck@example.com"; @Property( label = "Test E-mail Address", description = "E-mail address to send test message to.", value = DEFAULT_EMAIL) private static final String PROP_EMAIL = "email"; private String email; @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY) private MessageGatewayService messageGatewayService; @Activate protected void activate(Map<String, Object> properties) { this.email = PropertiesUtil.toString(properties.get(PROP_EMAIL), DEFAULT_EMAIL); } @Override public Result execute() { final FormattingResultLog resultLog = new FormattingResultLog(); if (messageGatewayService == null) { resultLog.critical("MessageGatewayService OSGi service could not be found."); resultLog.info("Verify the Default Mail Service is active: http://<host>:<port>/system/console/components/com.day.cq.mailer.impl.CqMailingService"); } else { final MessageGateway<SimpleEmail> messageGateway = messageGatewayService.getGateway(SimpleEmail.class); if (messageGateway == null) { resultLog.critical("The AEM Default Mail Service is INACTIVE, thus e-mails cannot be sent."); resultLog.info("Verify the Default Mail Service is active and configured: http://<host>:<port>/system/console/components/com.day.cq.mailer.DefaultMailService"); log.warn("Could not retrieve a SimpleEmail Message Gateway"); } else { try { List<InternetAddress> emailAddresses = new ArrayList<InternetAddress>(); emailAddresses.add(new InternetAddress(this.email)); MailTemplate mailTemplate = new MailTemplate(IOUtils.toInputStream(MAIL_TEMPLATE), CharEncoding.UTF_8); SimpleEmail email = mailTemplate.getEmail(StrLookup.mapLookup(Collections.emptyMap()), SimpleEmail.class); email.setSubject("AEM E-mail Service Health Check"); email.setTo(emailAddresses); email.setSocketConnectionTimeout(TIMEOUT); email.setSocketTimeout(TIMEOUT); try { messageGateway.send(email); resultLog.info("The E-mail Service appears to be working properly. Verify the health check e-mail was sent to [ {} ]", this.email); } catch (Exception e) { resultLog.critical("Failed sending e-mail. Unable to send a test email via the configured E-mail server: " + e.getMessage(), e); log.warn("Failed to send E-mail for E-mail Service health check", e); } logMailServiceConfig(resultLog, email); } catch (Exception e) { resultLog.healthCheckError("Sling Health check could not formulate a test email: " + e.getMessage(), e); log.error("Unable to execute E-mail health check", e); } } } return new Result(resultLog); } private void logMailServiceConfig(FormattingResultLog resultLog, SimpleEmail email) { resultLog.info("SMTP Host: {}", email.getHostName()); resultLog.info("SMTP use SSL: {}", email.isSSL()); if (email.isSSL()) { resultLog.info("SMTP SSL Port: {}", email.getSslSmtpPort()); } else { resultLog.info("SMTP Port: {}", email.getSmtpPort()); } resultLog.info("SMTP From Address: {}", email.getFromAddress()); resultLog.info("Socket Connection Timeout: {} seconds", email.getSocketConnectionTimeout() / 1000); resultLog.info("Socket IO Timeout: {} seconds", email.getSocketTimeout() / 1000); } }