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-2014 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.broker.internal.IdentityBrokerExtension;
036    import com.unboundid.directory.sdk.common.config.MonitorProviderConfig;
037    import com.unboundid.directory.sdk.common.internal.ExampleUsageProvider;
038    import com.unboundid.directory.sdk.common.internal.Reconfigurable;
039    import com.unboundid.directory.sdk.common.internal.UnboundIDExtension;
040    import com.unboundid.directory.sdk.common.types.ServerContext;
041    import com.unboundid.directory.sdk.ds.internal.DirectoryServerExtension;
042    import com.unboundid.directory.sdk.metrics.internal.MetricsEngineExtension;
043    import com.unboundid.directory.sdk.proxy.internal.DirectoryProxyServerExtension;
044    import com.unboundid.directory.sdk.sync.internal.SynchronizationServerExtension;
045    import com.unboundid.ldap.sdk.Attribute;
046    import com.unboundid.ldap.sdk.LDAPException;
047    import com.unboundid.ldap.sdk.ResultCode;
048    import com.unboundid.util.Extensible;
049    import com.unboundid.util.ThreadSafety;
050    import com.unboundid.util.ThreadSafetyLevel;
051    import com.unboundid.util.args.ArgumentException;
052    import 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    @IdentityBrokerExtension()
094    @ThreadSafety(level=ThreadSafetyLevel.INTERFACE_THREADSAFE)
095    public 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 access logger.
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    }