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 }