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