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