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.ErrorLoggerConfig;
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.LogCategory;
041    import com.unboundid.directory.sdk.common.types.LogSeverity;
042    import com.unboundid.directory.sdk.common.types.ServerContext;
043    import com.unboundid.directory.sdk.ds.internal.DirectoryServerExtension;
044    import com.unboundid.directory.sdk.metrics.internal.MetricsEngineExtension;
045    import com.unboundid.directory.sdk.proxy.internal.DirectoryProxyServerExtension;
046    import com.unboundid.directory.sdk.sync.internal.SynchronizationServerExtension;
047    import com.unboundid.ldap.sdk.LDAPException;
048    import com.unboundid.ldap.sdk.ResultCode;
049    import com.unboundid.util.Extensible;
050    import com.unboundid.util.ThreadSafety;
051    import com.unboundid.util.ThreadSafetyLevel;
052    import com.unboundid.util.args.ArgumentException;
053    import com.unboundid.util.args.ArgumentParser;
054    
055    
056    
057    /**
058     * This class defines an API that must be implemented by extensions which
059     * record information about warnings, errors, and events which occur in the
060     * server.
061     * <BR><BR>
062     * Each error logger may configured to indicate whether whether to include or
063     * exclude log messages based on their category and/or severity.  This is
064     * handled automatically by the server, so individual error logger
065     * implementations no not need to attempt to perform that filtering on their
066     * own.  However, they may perform additional processing if desired to further
067     * narrow the set of messages that should be logged.
068     * <BR>
069     * <H2>Configuring Error Loggers</H2>
070     * In order to configure an error logger created using this API, use a command
071     * like:
072     * <PRE>
073     *      dsconfig create-log-publisher \
074     *           --publisher-name "<I>{logger-name}</I>" \
075     *           --type third-party-error \
076     *           --set enabled:true \
077     *           --set "extension-class:<I>{class-name}</I>" \
078     *           --set "extension-argument:<I>{name=value}</I>"
079     * </PRE>
080     * where "<I>{logger-name}</I>" is the name to use for the error logger
081     * instance, "<I>{class-name}</I>" is the fully-qualified name of the Java class
082     * that extends {@code com.unboundid.directory.sdk.common.api.ErrorLogger},
083     * and "<I>{name=value}</I>" represents name-value pairs for any arguments to
084     * provide to the logger.  If multiple arguments should be provided to the
085     * logger, then the "<CODE>--set extension-argument:<I>{name=value}</I></CODE>"
086     * option should be provided multiple times.
087     *
088     * @see  FileBasedErrorLogger
089     * @see  com.unboundid.directory.sdk.common.scripting.ScriptedErrorLogger
090     * @see
091     *    com.unboundid.directory.sdk.common.scripting.ScriptedFileBasedErrorLogger
092     */
093    @Extensible()
094    @DirectoryServerExtension()
095    @DirectoryProxyServerExtension(appliesToLocalContent=true,
096         appliesToRemoteContent=true)
097    @SynchronizationServerExtension(appliesToLocalContent=true,
098         appliesToSynchronizedContent=true)
099    @MetricsEngineExtension()
100    @IdentityBrokerExtension()
101    @ThreadSafety(level=ThreadSafetyLevel.INTERFACE_THREADSAFE)
102    public abstract class ErrorLogger
103           implements UnboundIDExtension, Reconfigurable<ErrorLoggerConfig>,
104                      ExampleUsageProvider
105    {
106      /**
107       * Creates a new instance of this error logger.  All error logger
108       * implementations must include a default constructor, but any initialization
109       * should generally be done in the {@code initializeErrorLogger} method.
110       */
111      public ErrorLogger()
112      {
113        // No implementation is required.
114      }
115    
116    
117    
118      /**
119       * {@inheritDoc}
120       */
121      public abstract String getExtensionName();
122    
123    
124    
125      /**
126       * {@inheritDoc}
127       */
128      public abstract String[] getExtensionDescription();
129    
130    
131    
132      /**
133       * {@inheritDoc}
134       */
135      public void defineConfigArguments(final ArgumentParser parser)
136             throws ArgumentException
137      {
138        // No arguments will be allowed by default.
139      }
140    
141    
142    
143      /**
144       * Initializes this error logger.
145       *
146       * @param  serverContext  A handle to the server context for the server in
147       *                        which this extension is running.
148       * @param  config         The general configuration for this error logger.
149       * @param  parser         The argument parser which has been initialized from
150       *                        the configuration for this error logger.
151       *
152       * @throws  LDAPException  If a problem occurs while initializing this error
153       *                         logger.
154       */
155      public void initializeErrorLogger(final ServerContext serverContext,
156                                        final ErrorLoggerConfig config,
157                                        final ArgumentParser parser)
158             throws LDAPException
159      {
160        // No initialization will be performed by default.
161      }
162    
163    
164    
165      /**
166       * {@inheritDoc}
167       */
168      public boolean isConfigurationAcceptable(final ErrorLoggerConfig config,
169                          final ArgumentParser parser,
170                          final List<String> unacceptableReasons)
171      {
172        // No extended validation will be performed by default.
173        return true;
174      }
175    
176    
177    
178      /**
179       * {@inheritDoc}
180       */
181      public ResultCode applyConfiguration(final ErrorLoggerConfig config,
182                                           final ArgumentParser parser,
183                                           final List<String> adminActionsRequired,
184                                           final List<String> messages)
185      {
186        // By default, no configuration changes will be applied.  If there are any
187        // arguments, then add an admin action message indicating that the extension
188        // needs to be restarted for any changes to take effect.
189        if (! parser.getNamedArguments().isEmpty())
190        {
191          adminActionsRequired.add(
192               "No configuration change has actually been applied.  The new " +
193                    "configuration will not take effect until this error logger " +
194                    "is disabled and re-enabled or until the server is restarted.");
195        }
196    
197        return ResultCode.SUCCESS;
198      }
199    
200    
201    
202      /**
203       * Performs any cleanup which may be necessary when this error logger is to
204       * be taken out of service.
205       */
206      public void finalizeErrorLogger()
207      {
208        // No implementation is required.
209      }
210    
211    
212    
213      /**
214       * Records information about the provided message, if appropriate.
215       *
216       * @param  category   The category for the message to be logged.
217       * @param  severity   The severity for the message to be logged.
218       * @param  messageID  The unique identifier with which the message text is
219       *                    associated.
220       * @param  message    The message to be logged.
221       */
222      public abstract void logError(final LogCategory category,
223                                    final LogSeverity severity,
224                                    final long messageID,
225                                    final String message);
226    
227    
228    
229      /**
230       * {@inheritDoc}
231       */
232      public Map<List<String>,String> getExamplesArgumentSets()
233      {
234        return Collections.emptyMap();
235      }
236    }