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 }