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