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