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-2021 Ping Identity Corporation
026 */
027package com.unboundid.directory.sdk.common.api;
028
029
030
031import java.util.Collections;
032import java.util.List;
033import java.util.Map;
034
035import com.unboundid.directory.sdk.broker.internal.BrokerExtension;
036import com.unboundid.directory.sdk.common.config.ErrorLoggerConfig;
037import com.unboundid.directory.sdk.common.internal.ExampleUsageProvider;
038import com.unboundid.directory.sdk.common.internal.Reconfigurable;
039import com.unboundid.directory.sdk.common.internal.UnboundIDExtension;
040import com.unboundid.directory.sdk.common.types.LogCategory;
041import com.unboundid.directory.sdk.common.types.LogSeverity;
042import com.unboundid.directory.sdk.common.types.ServerContext;
043import com.unboundid.directory.sdk.ds.internal.DirectoryServerExtension;
044import com.unboundid.directory.sdk.metrics.internal.MetricsEngineExtension;
045import com.unboundid.directory.sdk.proxy.internal.DirectoryProxyServerExtension;
046import com.unboundid.directory.sdk.sync.internal.SynchronizationServerExtension;
047import com.unboundid.ldap.sdk.LDAPException;
048import com.unboundid.ldap.sdk.ResultCode;
049import com.unboundid.util.Extensible;
050import com.unboundid.util.ThreadSafety;
051import com.unboundid.util.ThreadSafetyLevel;
052import com.unboundid.util.args.ArgumentException;
053import 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 be configured to indicate 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@BrokerExtension()
101@ThreadSafety(level=ThreadSafetyLevel.INTERFACE_THREADSAFE)
102public 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}