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 * docs/licenses/cddl.txt
011 * or http://www.opensource.org/licenses/cddl1.php.
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 * docs/licenses/cddl.txt.  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 *      Portions Copyright 2010-2023 Ping Identity Corporation
026 */
027package com.unboundid.directory.sdk.common.api;
028
029
030
031import java.util.Collections;
032import java.util.List;
033import java.util.Map;
034
035import com.unboundid.directory.sdk.broker.internal.BrokerExtension;
036import com.unboundid.directory.sdk.common.config.MonitorProviderConfig;
037import com.unboundid.directory.sdk.common.internal.ExampleUsageProvider;
038import com.unboundid.directory.sdk.common.internal.Reconfigurable;
039import com.unboundid.directory.sdk.common.internal.UnboundIDExtension;
040import com.unboundid.directory.sdk.common.types.ServerContext;
041import com.unboundid.directory.sdk.ds.internal.DirectoryServerExtension;
042import com.unboundid.directory.sdk.metrics.internal.MetricsEngineExtension;
043import com.unboundid.directory.sdk.proxy.internal.DirectoryProxyServerExtension;
044import com.unboundid.directory.sdk.sync.internal.SynchronizationServerExtension;
045import com.unboundid.ldap.sdk.Attribute;
046import com.unboundid.ldap.sdk.LDAPException;
047import com.unboundid.ldap.sdk.ResultCode;
048import com.unboundid.util.Extensible;
049import com.unboundid.util.ThreadSafety;
050import com.unboundid.util.ThreadSafetyLevel;
051import com.unboundid.util.args.ArgumentException;
052import com.unboundid.util.args.ArgumentParser;
053
054
055
056/**
057 * This class defines an API that must be implemented by extensions which
058 * expose monitoring information about server components.  Each monitor provider
059 * instance will be used by the server to construct a single monitor entry.
060 * The monitor information will be obtained on demand whenever the server
061 * receives a request targeting a monitor entry, but monitor providers may also
062 * indicate that they should be periodically invoked by a background thread so
063 * that they can collect additional information on a regular basis even when no
064 * clients have requested monitor information.
065 * <BR>
066 * <H2>Configuring Monitor Providers</H2>
067 * In order to configure a monitor provider created using this API, use a
068 * command like:
069 * <PRE>
070 *      dsconfig create-monitor-provider \
071 *           --provider-name "<I>{provider-name}</I>" \
072 *           --type third-party \
073 *           --set enabled:true \
074 *           --set "extension-class:<I>{class-name}</I>" \
075 *           --set "extension-argument:<I>{name=value}</I>"
076 * </PRE>
077 * where "<I>{provider-name}</I>" is the name to use for the monitor provider
078 * instance, "<I>{class-name}</I>" is the fully-qualified name of the Java class
079 * that extends {@code com.unboundid.directory.sdk.common.api.MonitorProvider},
080 * and "<I>{name=value}</I>" represents name-value pairs for any arguments to
081 * provide to the monitor provider.  If multiple arguments should be provided to
082 * the monitor provider, then the
083 * "<CODE>--set extension-argument:<I>{name=value}</I></CODE>" option should be
084 * provided multiple times.
085 */
086@Extensible()
087@DirectoryServerExtension()
088@DirectoryProxyServerExtension(appliesToLocalContent=true,
089     appliesToRemoteContent=false)
090@SynchronizationServerExtension(appliesToLocalContent=true,
091     appliesToSynchronizedContent=false)
092@MetricsEngineExtension()
093@BrokerExtension()
094@ThreadSafety(level=ThreadSafetyLevel.INTERFACE_THREADSAFE)
095public abstract class MonitorProvider
096       implements UnboundIDExtension, Reconfigurable<MonitorProviderConfig>,
097                  ExampleUsageProvider
098{
099  /**
100   * Creates a new instance of this monitor provider.  All monitor provider
101   * implementations must include a default constructor, but any initialization
102   * should generally be done in the {@code initializeMonitorProvider} method.
103   */
104  public MonitorProvider()
105  {
106    // No implementation is required.
107  }
108
109
110
111  /**
112   * {@inheritDoc}
113   */
114  public abstract String getExtensionName();
115
116
117
118  /**
119   * {@inheritDoc}
120   */
121  public abstract String[] getExtensionDescription();
122
123
124
125  /**
126   * {@inheritDoc}
127   */
128  public void defineConfigArguments(final ArgumentParser parser)
129         throws ArgumentException
130  {
131    // No arguments will be allowed by default.
132  }
133
134
135
136  /**
137   * Initializes this monitor provider.
138   *
139   * @param  serverContext  A handle to the server context for the server in
140   *                        which this extension is running.
141   * @param  config         The general configuration for this monitor provider.
142   * @param  parser         The argument parser which has been initialized from
143   *                        the configuration for this monitor provider.
144   *
145   * @throws  LDAPException  If a problem occurs while initializing this monitor
146   *                         provider
147   */
148  public void initializeMonitorProvider(final ServerContext serverContext,
149                                        final MonitorProviderConfig config,
150                                        final ArgumentParser parser)
151         throws LDAPException
152  {
153    // No initialization will be performed by default.
154  }
155
156
157
158  /**
159   * {@inheritDoc}
160   */
161  public boolean isConfigurationAcceptable(final MonitorProviderConfig config,
162                      final ArgumentParser parser,
163                      final List<String> unacceptableReasons)
164  {
165    // No extended validation will be performed by default.
166    return true;
167  }
168
169
170
171  /**
172   * {@inheritDoc}
173   */
174  public ResultCode applyConfiguration(final MonitorProviderConfig config,
175                                       final ArgumentParser parser,
176                                       final List<String> adminActionsRequired,
177                                       final List<String> messages)
178  {
179    // By default, no configuration changes will be applied.  If there are any
180    // arguments, then add an admin action message indicating that the extension
181    // needs to be restarted for any changes to take effect.
182    if (! parser.getNamedArguments().isEmpty())
183    {
184      adminActionsRequired.add(
185           "No configuration change has actually been applied.  The new " +
186                "configuration will not take effect until this monitor " +
187                "provider is disabled and re-enabled or until the server is " +
188                "restarted.");
189    }
190
191    return ResultCode.SUCCESS;
192  }
193
194
195
196  /**
197   * Performs any cleanup which may be necessary when this monitor provider is
198   * to be taken out of service.
199   */
200  public void finalizeMonitorProvider()
201  {
202    // No implementation is required.
203  }
204
205
206
207  /**
208   * Retrieves the name that identifies this monitor provider instance.  It
209   * will be used as the value of the naming attribute for monitor entries.
210   * Each monitor provider instance must have a unique name.
211   *
212   * @return  The name that identifies this monitor provider instance.
213   */
214  public abstract String getMonitorInstanceName();
215
216
217
218  /**
219   * Retrieves the name of the object class that will be used for monitor
220   * entries created from this monitor provider. This does not need to be
221   * defined in the server schema. It may be {@code null} if a default object
222   * class should be used.
223   *
224   * @return  The name of the object class that will be used for monitor entries
225   *          created from this monitor provider.
226   */
227  public String getMonitorObjectClass()
228  {
229    return null;
230  }
231
232
233
234  /**
235   * Retrieves the update interval in milliseconds that should be used for this
236   * monitor provider.  A value that is greater than zero will cause the
237   * {@link #updateMonitorData} method to be repeatedly invoked at that
238   * interval.  A value less than or equal to zero indicates that the monitor
239   * provider should not be periodically updated.
240   * <p>
241   * If the initial returned value is greater than zero, then this method will
242   * be invoked between each update to see if the update interval has changed.
243   * This way you can change the interval dynamically.
244   *
245   * @return  The update interval in milliseconds that should be used for this
246   *          monitor provider.
247   */
248  public long getUpdateIntervalMillis()
249  {
250    // This monitor provider will not be periodically updated by default.
251    return 0L;
252  }
253
254
255
256  /**
257   * Updates the information collected by this monitor provider.  This method
258   * will be periodically invoked if the {@link #getUpdateIntervalMillis} method
259   * returns a positive value.
260   */
261  public void updateMonitorData()
262  {
263    // No implementation provided by default.
264  }
265
266
267
268  /**
269   * Retrieves a list of attributes containing the data to include in the
270   * monitor entry generated from this monitor provider.
271   *
272   * @return  A list of attributes containing the data to include in the monitor
273   *          entry generated from this monitor provider.
274   */
275  public abstract List<Attribute> getMonitorAttributes();
276
277
278
279  /**
280   * {@inheritDoc}
281   */
282  public Map<List<String>,String> getExamplesArgumentSets()
283  {
284    return Collections.emptyMap();
285  }
286}