001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2006-2009 Sun Microsystems, Inc. 015 * Portions Copyright 2014-2016 ForgeRock AS. 016 */ 017package org.opends.server.extensions; 018 019import static org.opends.messages.ExtensionMessages.ERR_SMTPALERTHANDLER_NO_SMTP_SERVERS; 020import static org.opends.messages.ExtensionMessages.WARN_SMTPALERTHANDLER_ERROR_SENDING_MESSAGE; 021import static com.forgerock.opendj.cli.Utils.wrapText; 022 023import java.util.ArrayList; 024import java.util.List; 025 026import org.forgerock.i18n.LocalizableMessage; 027import org.forgerock.i18n.slf4j.LocalizedLogger; 028import org.forgerock.opendj.config.server.ConfigException; 029import org.forgerock.opendj.config.server.ConfigurationChangeListener; 030import org.forgerock.opendj.server.config.server.AlertHandlerCfg; 031import org.forgerock.opendj.server.config.server.SMTPAlertHandlerCfg; 032import org.opends.server.api.AlertGenerator; 033import org.opends.server.api.AlertHandler; 034import org.opends.server.core.DirectoryServer; 035import org.forgerock.opendj.config.server.ConfigChangeResult; 036import org.opends.server.types.InitializationException; 037import org.opends.server.util.EMailMessage; 038 039/** 040 * This class implements a Directory Server alert handler that may be used to 041 * send administrative alerts via SMTP. 042 */ 043public class SMTPAlertHandler 044 implements AlertHandler<SMTPAlertHandlerCfg>, 045 ConfigurationChangeListener<SMTPAlertHandlerCfg> 046{ 047 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 048 049 /** The current configuration for this alert handler. */ 050 private SMTPAlertHandlerCfg currentConfig; 051 052 /** Creates a new instance of this SMTP alert handler. */ 053 public SMTPAlertHandler() 054 { 055 super(); 056 057 // All initialization should be done in the initializeAlertHandler method. 058 } 059 060 @Override 061 public void initializeAlertHandler(SMTPAlertHandlerCfg configuration) 062 throws ConfigException, InitializationException 063 { 064 // Make sure that the Directory Server is configured with information about 065 // at least one SMTP server. 066 if (DirectoryServer.getMailServerPropertySets() == null || 067 DirectoryServer.getMailServerPropertySets().isEmpty()) 068 { 069 throw new ConfigException(ERR_SMTPALERTHANDLER_NO_SMTP_SERVERS.get()); 070 } 071 072 configuration.addSMTPChangeListener(this); 073 currentConfig = configuration; 074 } 075 076 @Override 077 public AlertHandlerCfg getAlertHandlerConfiguration() 078 { 079 return currentConfig; 080 } 081 082 @Override 083 public boolean isConfigurationAcceptable(AlertHandlerCfg configuration, 084 List<LocalizableMessage> unacceptableReasons) 085 { 086 return true; 087 } 088 089 @Override 090 public void finalizeAlertHandler() 091 { 092 // No action is required. 093 } 094 095 @Override 096 public void sendAlertNotification(AlertGenerator generator, String alertType, 097 LocalizableMessage alertMessage) 098 { 099 SMTPAlertHandlerCfg cfg = currentConfig; 100 101 ArrayList<String> recipients = new ArrayList<>(cfg.getRecipientAddress()); 102 103 String alertIDStr; 104 String alertMessageStr; 105 if (alertMessage != null) { 106 alertIDStr = alertMessage.resourceName() + "-" + alertMessage.ordinal(); 107 alertMessageStr = alertMessage.toString(); 108 } else { 109 alertIDStr = "-1"; 110 alertMessageStr = "none"; 111 } 112 String subject = replaceTokens(cfg.getMessageSubject(), alertType, 113 alertIDStr, alertMessageStr); 114 115 String body = replaceTokens(cfg.getMessageBody(), alertType, alertIDStr, 116 alertMessageStr); 117 118 EMailMessage message = new EMailMessage(cfg.getSenderAddress(), recipients, 119 subject); 120 121 message.setBody(LocalizableMessage.raw(wrapText(body, 75))); 122 123 try 124 { 125 message.send(); 126 } 127 catch (Exception e) 128 { 129 logger.traceException(e); 130 logger.error(WARN_SMTPALERTHANDLER_ERROR_SENDING_MESSAGE, 131 alertType, alertMessage, e.getLocalizedMessage()); 132 } 133 } 134 135 /** 136 * Replaces any occurrences of special tokens in the given string with the 137 * appropriate value. Tokens supported include: 138 * <UL> 139 * <LI>%%alert-type%% -- Will be replaced with the alert type string</LI> 140 * <LI>%%alert-id%% -- Will be replaced with the alert ID value</LI> 141 * <LI>%%alert-message%% -- Will be replaced with the alert message</LI> 142 * <LI>\n -- Will be replaced with an end-of-line character. 143 * </UL> 144 * 145 * @param s The string to be processed. 146 * @param alertType The string to use to replace the "%%alert-type%%" 147 * token. 148 * @param alertID The string to use to replace the "%%alert-id%%" 149 * token. 150 * @param alertMessage The string to use to replace the "%%alert-message%%" 151 * token. 152 * 153 * @return A processed version of the provided string. 154 */ 155 private String replaceTokens(String s, String alertType, String alertID, 156 String alertMessage) 157 { 158 return s.replace("%%alert-type%%", alertType). 159 replace("%%alert-id%%", alertID). 160 replace("%%alert-message%%", alertMessage). 161 replace("\\n", "\r\n"); 162 } 163 164 @Override 165 public boolean isConfigurationChangeAcceptable( 166 SMTPAlertHandlerCfg configuration, 167 List<LocalizableMessage> unacceptableReasons) 168 { 169 return true; 170 } 171 172 @Override 173 public ConfigChangeResult applyConfigurationChange( 174 SMTPAlertHandlerCfg configuration) 175 { 176 currentConfig = configuration; 177 return new ConfigChangeResult(); 178 } 179}