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