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 legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2006-2010 Sun Microsystems, Inc.
025 *      Portions Copyright 2014-2015 ForgeRock AS
026 */
027package org.opends.server.api;
028
029import java.util.List;
030import java.util.concurrent.Executors;
031import java.util.concurrent.ScheduledExecutorService;
032import java.util.concurrent.ScheduledFuture;
033import java.util.concurrent.ThreadFactory;
034import java.util.concurrent.TimeUnit;
035
036import org.forgerock.i18n.LocalizableMessage;
037import org.forgerock.opendj.config.server.ConfigException;
038import org.opends.server.admin.std.server.MonitorProviderCfg;
039import org.opends.server.types.Attribute;
040import org.opends.server.types.DirectoryConfig;
041import org.opends.server.types.InitializationException;
042import org.opends.server.types.ObjectClass;
043
044import static org.opends.server.util.ServerConstants.*;
045
046/**
047 * This class defines the set of methods and structures that must be
048 * implemented by a Directory Server module that can provide usage,
049 * performance, availability, or other kinds of monitor information to clients.
050 *
051 * @param  <T>  The type of configuration handled by this monitor provider.
052 */
053@org.opends.server.types.PublicAPI(
054     stability=org.opends.server.types.StabilityLevel.VOLATILE,
055     mayInstantiate=false,
056     mayExtend=true,
057     mayInvoke=false)
058public abstract class MonitorProvider<T extends MonitorProviderCfg>
059{
060  /** The scheduler. */
061  private static final ScheduledExecutorService SCHEDULER =
062      Executors.newSingleThreadScheduledExecutor(
063          new MonitorThreadFactory());
064
065  /** Thread factory used by the scheduled execution service. */
066  private static final class MonitorThreadFactory implements ThreadFactory
067  {
068    @Override
069    public Thread newThread(Runnable r)
070    {
071      Thread t = new DirectoryThread(r, "Monitor Provider State Updater");
072      t.setDaemon(true);
073      return t;
074    }
075  }
076
077  private ScheduledFuture<?> scheduledFuture;
078
079  /**
080   * Initializes this monitor provider based on the information in the provided configuration entry.
081   *
082   * @param configuration
083   *          The configuration to use to initialize this monitor provider.
084   * @throws ConfigException
085   *           If an unrecoverable problem arises in the process of performing the initialization.
086   * @throws InitializationException
087   *           If a problem occurs during initialization that is not related to the server
088   *           configuration.
089   */
090  public void initializeMonitorProvider(T configuration) throws ConfigException, InitializationException
091  {
092    // here to override
093  }
094
095
096
097  /**
098   * Indicates whether the provided configuration is acceptable for
099   * this monitor provider.  It should be possible to call this method
100   * on an uninitialized monitor provider instance in order to
101   * determine whether the monitor provider would be able to use the
102   * provided configuration.
103   * <BR><BR>
104   * Note that implementations which use a subclass of the provided
105   * configuration class will likely need to cast the configuration
106   * to the appropriate subclass type.
107   *
108   * @param  configuration        The monitor provider configuration
109   *                              for which to make the determination.
110   * @param  unacceptableReasons  A list that may be used to hold the
111   *                              reasons that the provided
112   *                              configuration is not acceptable.
113   *
114   * @return  {@code true} if the provided configuration is acceptable
115   *          for this monitor provider, or {@code false} if not.
116   */
117  public boolean isConfigurationAcceptable(
118                      MonitorProviderCfg configuration,
119                      List<LocalizableMessage> unacceptableReasons)
120  {
121    // This default implementation does not perform any special
122    // validation.  It should be overridden by monitor provider
123    // implementations that wish to perform more detailed validation.
124    return true;
125  }
126
127
128
129  /**
130   * Finalizes this monitor provider so that it may be unloaded and
131   * taken out of service.  This method should be overridden by any
132   * monitor provider that has resources that should be released when
133   * the monitor is no longer needed.  Any monitor that does override
134   * this method must first invoke this version by calling
135   * {@code super.finalizeMonitorProvider}.
136   */
137  public void finalizeMonitorProvider()
138  {
139    if(scheduledFuture != null)
140    {
141      scheduledFuture.cancel(true);
142    }
143  }
144
145
146
147  /**
148   * Retrieves the name of this monitor provider.  It should be unique
149   * among all monitor providers, including all instances of the same
150   * monitor provider.
151   *
152   * @return  The name of this monitor provider.
153   */
154  public abstract String getMonitorInstanceName();
155
156
157
158  /**
159   * Retrieves the objectclass that should be included in the monitor
160   * entry created from this monitor provider.  This may be overridden
161   * by subclasses that wish to include their own custom objectclass
162   * in the monitor entry (e.g., to make it easier to search for
163   * monitor entries of that type).  The default implementation
164   * returns the "extensibleObject" objectclass.
165   *
166   * @return  The objectclass that should be included in the monitor
167   *          entry created from this monitor provider.
168   */
169  public ObjectClass getMonitorObjectClass()
170  {
171    return DirectoryConfig.getObjectClass(OC_EXTENSIBLE_OBJECT_LC, true);
172  }
173
174
175  /**
176   * Schedules any periodic processing that may be desired
177   * to update the information associated with this monitor.  Note
178   * that best-effort attempts will be made to ensure that calls to
179   * this method come {@code getUpdateInterval} milliseconds apart,
180   * but no guarantees will be made.
181   *
182   * @param updater The updater to execute.
183   * @param initialDelay The time to delay first execution.
184   * @param period The period between successive executions.
185   * @param unit The time unit of the initialDelay and period
186   *             parameters.
187   */
188  protected final void scheduleUpdate(Runnable updater,
189                                      long initialDelay,
190                                      long period, TimeUnit unit)
191  {
192    if(scheduledFuture != null)
193    {
194      scheduledFuture.cancel(true);
195    }
196    scheduledFuture = SCHEDULER.scheduleAtFixedRate(updater, initialDelay, period, unit);
197  }
198
199
200
201  /**
202   * Retrieves a set of attributes containing monitor data that should
203   * be returned to the client if the corresponding monitor entry is
204   * requested.
205   *
206   * @return  A set of attributes containing monitor data that should
207   *          be returned to the client if the corresponding monitor
208   *          entry is requested.
209   */
210  public abstract List<Attribute> getMonitorData();
211}
212