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.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. It may be {@code null} if
217 * a default object class should be used.
218 *
219 * @return The name of the object class that will be used for monitor entries
220 * created from this monitor provider.
221 */
222 public String getMonitorObjectClass()
223 {
224 return null;
225 }
226
227
228
229 /**
230 * Retrieves the update interval in milliseconds that should be used for this
231 * monitor provider. A value that is greater than zero will cause the
232 * {@link #updateMonitorData} method to be repeatedly invoked at that
233 * interval. A value less than or equal to zero indicates that the monitor
234 * provider should not be periodically updated.
235 *
236 * @return The update interval in milliseconds that should be used for this
237 * monitor provider.
238 */
239 public long getUpdateIntervalMillis()
240 {
241 // This monitor provider will not be periodically updated by default.
242 return 0L;
243 }
244
245
246
247 /**
248 * Updates the information collected by this monitor provider. This method
249 * will be periodically invoked if the {@link #getUpdateIntervalMillis} method
250 * returns a positive value.
251 */
252 public void updateMonitorData()
253 {
254 // No implementation provided by default.
255 }
256
257
258
259 /**
260 * Retrieves a list of attributes containing the data to include in the
261 * monitor entry generated from this monitor provider.
262 *
263 * @return A list of attributes containing the data to include in the monitor
264 * entry generated from this monitor provider.
265 */
266 public abstract List<Attribute> getMonitorAttributes();
267
268
269
270 /**
271 * {@inheritDoc}
272 */
273 public Map<List<String>,String> getExamplesArgumentSets()
274 {
275 return Collections.emptyMap();
276 }
277 }