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 }