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