001 /*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License"). You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at
010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012 * See the License for the specific language governing permissions
013 * and limitations under the License.
014 *
015 * When distributing Covered Code, include this CDDL HEADER in each
016 * file and include the License file at
017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
018 * add the following below this CDDL HEADER, with the fields enclosed
019 * by brackets "[]" replaced with your own identifying information:
020 * Portions Copyright [yyyy] [name of copyright owner]
021 *
022 * CDDL HEADER END
023 *
024 *
025 * Copyright 2006-2008 Sun Microsystems, Inc.
026 */
027 package org.opends.server.extensions;
028 import org.opends.messages.Message;
029
030
031
032 import java.util.ArrayList;
033 import java.util.List;
034
035 import org.opends.server.admin.server.ConfigurationChangeListener;
036 import org.opends.server.admin.std.server.AlertHandlerCfg;
037 import org.opends.server.admin.std.server.SMTPAlertHandlerCfg;
038 import org.opends.server.api.AlertGenerator;
039 import org.opends.server.api.AlertHandler;
040 import org.opends.server.core.DirectoryServer;
041 import org.opends.server.config.ConfigException;
042 import org.opends.server.loggers.debug.DebugTracer;
043 import org.opends.server.types.ConfigChangeResult;
044 import org.opends.server.types.DebugLogLevel;
045 import org.opends.server.types.InitializationException;
046 import org.opends.server.types.ResultCode;
047 import org.opends.server.util.EMailMessage;
048
049 import static org.opends.server.loggers.debug.DebugLogger.*;
050 import org.opends.server.loggers.ErrorLogger;
051 import static org.opends.messages.ExtensionMessages.*;
052
053 import org.opends.messages.MessageDescriptor;
054 import static org.opends.server.util.StaticUtils.*;
055
056
057
058 /**
059 * This class implements a Directory Server alert handler that may be used to
060 * send administrative alerts via SMTP.
061 */
062 public class SMTPAlertHandler
063 implements AlertHandler<SMTPAlertHandlerCfg>,
064 ConfigurationChangeListener<SMTPAlertHandlerCfg>
065 {
066 /**
067 * The tracer object for the debug logger.
068 */
069 private static final DebugTracer TRACER = getTracer();
070
071
072
073 // The current configuration for this alert handler.
074 private SMTPAlertHandlerCfg currentConfig;
075
076
077
078 /**
079 * Creates a new instance of this SMTP alert handler.
080 */
081 public SMTPAlertHandler()
082 {
083 super();
084
085 // All initialization should be done in the initializeAlertHandler method.
086 }
087
088
089
090 /**
091 * {@inheritDoc}
092 */
093 public void initializeAlertHandler(SMTPAlertHandlerCfg configuration)
094 throws ConfigException, InitializationException
095 {
096 // Make sure that the Directory Server is configured with information about
097 // at least one SMTP server.
098 if ((DirectoryServer.getMailServerPropertySets() == null) ||
099 DirectoryServer.getMailServerPropertySets().isEmpty())
100 {
101 Message message = ERR_SMTPALERTHANDLER_NO_SMTP_SERVERS.get();
102 throw new ConfigException(message);
103 }
104
105 configuration.addSMTPChangeListener(this);
106 currentConfig = configuration;
107 }
108
109
110
111 /**
112 * {@inheritDoc}
113 */
114 public AlertHandlerCfg getAlertHandlerConfiguration()
115 {
116 return currentConfig;
117 }
118
119
120
121 /**
122 * {@inheritDoc}
123 */
124 public boolean isConfigurationAcceptable(AlertHandlerCfg configuration,
125 List<Message> unacceptableReasons)
126 {
127 return true;
128 }
129
130
131
132 /**
133 * {@inheritDoc}
134 */
135 public void finalizeAlertHandler()
136 {
137 // No action is required.
138 }
139
140
141
142 /**
143 * {@inheritDoc}
144 */
145 public void sendAlertNotification(AlertGenerator generator, String alertType,
146 Message alertMessage)
147 {
148 SMTPAlertHandlerCfg cfg = currentConfig;
149
150 ArrayList<String> recipients =
151 new ArrayList<String>(cfg.getRecipientAddress());
152
153 String alertIDStr;
154 String alertMessageStr;
155 if (alertMessage != null) {
156 alertIDStr = String.valueOf(alertMessage.getDescriptor().getId());
157 alertMessageStr = alertMessage.toString();
158 } else {
159 alertIDStr = String.valueOf(MessageDescriptor.NULL_ID);
160 alertMessageStr = "none";
161 }
162 String subject = replaceTokens(cfg.getMessageSubject(), alertType,
163 alertIDStr, alertMessageStr);
164
165 String body = replaceTokens(cfg.getMessageBody(), alertType, alertIDStr,
166 alertMessageStr);
167
168 EMailMessage message = new EMailMessage(cfg.getSenderAddress(), recipients,
169 subject);
170
171 message.setBody(Message.raw(wrapText(body, 75)));
172
173 try
174 {
175 message.send();
176 }
177 catch (Exception e)
178 {
179 if (debugEnabled())
180 {
181 TRACER.debugCaught(DebugLogLevel.ERROR, e);
182 }
183
184 Message msg = WARN_SMTPALERTHANDLER_ERROR_SENDING_MESSAGE.get(
185 alertType, alertMessage, stackTraceToSingleLineString(e));
186 ErrorLogger.logError(msg);
187 }
188 }
189
190
191
192 /**
193 * Replaces any occurrences of special tokens in the given string with the
194 * appropriate value. Tokens supported include:
195 * <UL>
196 * <LI>%%alert-type%% -- Will be replaced with the alert type string</LI>
197 * <LI>%%alert-id%% -- Will be replaced with the alert ID value</LI>
198 * <LI>%%alert-message%% -- Will be replaced with the alert message</LI>
199 * <LI>\n -- Will be replaced with an end-of-line character.
200 * </UL>
201 *
202 * @param s The string to be processed.
203 * @param alertType The string to use to replace the "%%alert-type%%"
204 * token.
205 * @param alertID The string to use to replace the "%%alert-id%%"
206 * token.
207 * @param alertMessage The string to use to replace the "%%alert-message%%"
208 * token.
209 *
210 * @return A processed version of the provided string.
211 */
212 private String replaceTokens(String s, String alertType, String alertID,
213 String alertMessage)
214 {
215 return s.replace("%%alert-type%%", alertType).
216 replace("%%alert-id%%", alertID).
217 replace("%%alert-message%%", alertMessage).
218 replace("\\n", "\r\n");
219 }
220
221
222
223 /**
224 * {@inheritDoc}
225 */
226 public boolean isConfigurationChangeAcceptable(
227 SMTPAlertHandlerCfg configuration,
228 List<Message> unacceptableReasons)
229 {
230 return true;
231 }
232
233
234
235 /**
236 * {@inheritDoc}
237 */
238 public ConfigChangeResult applyConfigurationChange(
239 SMTPAlertHandlerCfg configuration)
240 {
241 currentConfig = configuration;
242
243 return new ConfigChangeResult(ResultCode.SUCCESS, false);
244 }
245 }
246