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