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 static org.opends.server.loggers.ErrorLogger.logError;
033 import static org.opends.messages.ExtensionMessages.*;
034
035
036 import java.util.ArrayList;
037 import java.util.HashSet;
038 import java.util.List;
039
040 import org.opends.server.admin.server.ConfigurationChangeListener;
041 import org.opends.server.admin.std.meta.
042 ErrorLogAccountStatusNotificationHandlerCfgDefn;
043 import org.opends.server.admin.std.server.AccountStatusNotificationHandlerCfg;
044 import org.opends.server.admin.std.server.
045 ErrorLogAccountStatusNotificationHandlerCfg;
046 import org.opends.server.api.AccountStatusNotificationHandler;
047 import org.opends.server.config.ConfigException;
048 import org.opends.server.types.AccountStatusNotification;
049 import org.opends.server.types.AccountStatusNotificationType;
050 import org.opends.server.types.ConfigChangeResult;
051 import org.opends.server.types.DN;
052 import org.opends.server.types.InitializationException;
053 import org.opends.server.types.ResultCode;
054
055
056
057 /**
058 * This class defines an account status notification handler that will write
059 * information about status notifications using the Directory Server's error
060 * logging facility.
061 */
062 public class ErrorLogAccountStatusNotificationHandler
063 extends
064 AccountStatusNotificationHandler
065 <ErrorLogAccountStatusNotificationHandlerCfg>
066 implements
067 ConfigurationChangeListener
068 <ErrorLogAccountStatusNotificationHandlerCfg>
069 {
070 /**
071 * The set of names for the account status notification types that may be
072 * logged by this notification handler.
073 */
074 private static final HashSet<String> NOTIFICATION_TYPE_NAMES =
075 new HashSet<String>();
076
077 static
078 {
079 for (AccountStatusNotificationType t :
080 AccountStatusNotificationType.values())
081 {
082 NOTIFICATION_TYPE_NAMES.add(t.getName());
083 }
084 }
085
086
087 // The DN of the configuration entry for this notification handler.
088 private DN configEntryDN;
089
090 // The set of notification types that should generate log messages.
091 private HashSet<AccountStatusNotificationType> notificationTypes;
092
093
094
095 /**
096 * {@inheritDoc}
097 */
098 public void initializeStatusNotificationHandler(
099 ErrorLogAccountStatusNotificationHandlerCfg configuration
100 )
101 throws ConfigException, InitializationException
102 {
103 configuration.addErrorLogChangeListener (this);
104 configEntryDN = configuration.dn();
105
106 // Read configuration and apply changes.
107 boolean applyChanges = true;
108 processNotificationHandlerConfig (configuration, applyChanges);
109 }
110
111
112
113 /**
114 * {@inheritDoc}
115 */
116 public void handleStatusNotification(
117 AccountStatusNotification notification)
118 {
119 logError(NOTE_ERRORLOG_ACCTNOTHANDLER_NOTIFICATION.get(
120 notification.getNotificationType().getName(),
121 String.valueOf(notification.getUserDN()),
122 notification.getMessage().getDescriptor().getId(),
123 notification.getMessage()));
124 }
125
126
127
128 /**
129 * {@inheritDoc}
130 */
131 @Override()
132 public boolean isConfigurationAcceptable(
133 AccountStatusNotificationHandlerCfg configuration,
134 List<Message> unacceptableReasons)
135 {
136 ErrorLogAccountStatusNotificationHandlerCfg config =
137 (ErrorLogAccountStatusNotificationHandlerCfg) configuration;
138 return isConfigurationChangeAcceptable(config, unacceptableReasons);
139 }
140
141
142
143 /**
144 * {@inheritDoc}
145 */
146 public boolean isConfigurationChangeAcceptable(
147 ErrorLogAccountStatusNotificationHandlerCfg configuration,
148 List<Message> unacceptableReasons
149 )
150 {
151 // Make sure that we can process the defined notification handler.
152 // If so, then we'll accept the new configuration.
153 boolean applyChanges = false;
154 boolean isAcceptable = processNotificationHandlerConfig (
155 configuration, applyChanges
156 );
157
158 return isAcceptable;
159 }
160
161
162
163 /**
164 * Makes a best-effort attempt to apply the configuration contained in the
165 * provided entry. Information about the result of this processing should be
166 * added to the provided message list. Information should always be added to
167 * this list if a configuration change could not be applied. If detailed
168 * results are requested, then information about the changes applied
169 * successfully (and optionally about parameters that were not changed) should
170 * also be included.
171 *
172 * @param configuration The entry containing the new configuration to
173 * apply for this component.
174 * @param detailedResults Indicates whether detailed information about the
175 * processing should be added to the list.
176 *
177 * @return Information about the result of the configuration update.
178 */
179 public ConfigChangeResult applyConfigurationChange (
180 ErrorLogAccountStatusNotificationHandlerCfg configuration,
181 boolean detailedResults
182 )
183 {
184 ConfigChangeResult changeResult = applyConfigurationChange (configuration);
185 return changeResult;
186 }
187
188
189
190 /**
191 * {@inheritDoc}
192 */
193 public ConfigChangeResult applyConfigurationChange (
194 ErrorLogAccountStatusNotificationHandlerCfg configuration
195 )
196 {
197 ResultCode resultCode = ResultCode.SUCCESS;
198 boolean adminActionRequired = false;
199 ArrayList<Message> messages = new ArrayList<Message>();
200 ConfigChangeResult changeResult = new ConfigChangeResult(
201 resultCode, adminActionRequired, messages
202 );
203
204 // Initialize the set of notification types that should generate log
205 // messages.
206 boolean applyChanges = false;
207 processNotificationHandlerConfig (
208 configuration, applyChanges
209 );
210
211 return changeResult;
212 }
213
214
215 /**
216 * Parses the provided configuration and configure the notification handler.
217 *
218 * @param configuration The new configuration containing the changes.
219 * @param applyChanges If true then take into account the new configuration.
220 *
221 * @return The mapping between strings of character set values and the
222 * minimum number of characters required from those sets.
223 */
224 public boolean processNotificationHandlerConfig(
225 ErrorLogAccountStatusNotificationHandlerCfg configuration,
226 boolean applyChanges
227 )
228 {
229 // false if the configuration is not acceptable
230 boolean isAcceptable = true;
231
232 // The set of notification types that should generate log messages.
233 HashSet<AccountStatusNotificationType> newNotificationTypes =
234 new HashSet<AccountStatusNotificationType>();
235
236 // Initialize the set of notification types that should generate log
237 // messages.
238 for (ErrorLogAccountStatusNotificationHandlerCfgDefn.
239 AccountStatusNotificationType configNotificationType:
240 configuration.getAccountStatusNotificationType())
241 {
242 newNotificationTypes.add (getNotificationType (configNotificationType));
243 }
244
245 if (applyChanges && isAcceptable)
246 {
247 notificationTypes = newNotificationTypes;
248 }
249
250 return isAcceptable;
251 }
252
253
254 /**
255 * Gets the OpenDS notification type object that corresponds to the
256 * configuration counterpart.
257 *
258 * @param configNotificationType The configuration notification type for
259 * which to retrieve the OpenDS notification
260 * type.
261 */
262 private AccountStatusNotificationType getNotificationType(
263 ErrorLogAccountStatusNotificationHandlerCfgDefn.
264 AccountStatusNotificationType configNotificationType
265 )
266 {
267 AccountStatusNotificationType nt = null;
268
269 switch (configNotificationType)
270 {
271 case ACCOUNT_TEMPORARILY_LOCKED:
272 nt = AccountStatusNotificationType.ACCOUNT_TEMPORARILY_LOCKED;
273 break;
274 case ACCOUNT_PERMANENTLY_LOCKED:
275 nt = AccountStatusNotificationType.ACCOUNT_PERMANENTLY_LOCKED;
276 break;
277 case ACCOUNT_UNLOCKED:
278 nt = AccountStatusNotificationType.ACCOUNT_UNLOCKED;
279 break;
280 case ACCOUNT_IDLE_LOCKED:
281 nt = AccountStatusNotificationType.ACCOUNT_IDLE_LOCKED;
282 break;
283 case ACCOUNT_RESET_LOCKED:
284 nt = AccountStatusNotificationType.ACCOUNT_RESET_LOCKED;
285 break;
286 case ACCOUNT_DISABLED:
287 nt = AccountStatusNotificationType.ACCOUNT_DISABLED;
288 break;
289 case ACCOUNT_ENABLED:
290 nt = AccountStatusNotificationType.ACCOUNT_ENABLED;
291 break;
292 case ACCOUNT_EXPIRED:
293 nt = AccountStatusNotificationType.ACCOUNT_EXPIRED;
294 break;
295 case PASSWORD_EXPIRED:
296 nt = AccountStatusNotificationType.PASSWORD_EXPIRED;
297 break;
298 case PASSWORD_EXPIRING:
299 nt = AccountStatusNotificationType.PASSWORD_EXPIRING;
300 break;
301 case PASSWORD_RESET:
302 nt = AccountStatusNotificationType.PASSWORD_RESET;
303 break;
304 case PASSWORD_CHANGED:
305 nt = AccountStatusNotificationType.PASSWORD_CHANGED;
306 break;
307 }
308
309 return nt;
310 }
311
312 }
313