/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at
* docs/licenses/cddl.txt
* or http://www.opensource.org/licenses/cddl1.php.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at
* docs/licenses/cddl.txt. If applicable,
* add the following below this CDDL HEADER, with the fields enclosed
* by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2016-2020 Ping Identity Corporation
*/
package com.unboundid.directory.sdk.examples;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.unboundid.directory.sdk.common.api.LogFileRotationListener;
import com.unboundid.directory.sdk.common.config.LogFileRotationListenerConfig;
import com.unboundid.directory.sdk.common.types.ServerContext;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.ResultCode;
import com.unboundid.util.StaticUtils;
import com.unboundid.util.args.ArgumentException;
import com.unboundid.util.args.ArgumentParser;
import com.unboundid.util.args.FileArgument;
/**
* This class provides a simple example of a log file rotation listener that
* will just write a record of each log rotation to a specified file. It has
* one configuration argument:
* <UL>
* <LI>output-file -- The path to the file that should be updated
* whenever a log file is rotated.</LI>
* </UL>
*/
public final class ExampleLogFileRotationListener
extends LogFileRotationListener
{
/**
* The name of the argument that will be used to specify the path to the file
* to be updated whenever a log file is rotated.
*/
private static final String ARG_NAME_OUTPUT_FILE = "output-file";
// The output file to be written.
private volatile File outputFile;
/**
* Creates a new instance of this log file rotation listener. All log file
* rotation listener implementations must include a default constructor, but
* any initialization should generally be done in the
* {@code initializeLogFileRotationListener} method.
*/
public ExampleLogFileRotationListener()
{
// No implementation required.
}
/**
* Retrieves a human-readable name for this extension.
*
* @return A human-readable name for this extension.
*/
@Override()
public String getExtensionName()
{
return "Example Log File Rotation Listener";
}
/**
* Retrieves a human-readable description for this extension. Each element
* of the array that is returned will be considered a separate paragraph in
* generated documentation.
*
* @return A human-readable description for this extension, or {@code null}
* or an empty array if no description should be available.
*/
@Override()
public String[] getExtensionDescription()
{
return new String[]
{
"This log file rotation listener serves an example that may be used to " +
"demonstrate the process for creating a third-party log file " +
"rotation listener. It simply records a message in a specified " +
"output file whenever a log file is rotated."
};
}
/**
* Updates the provided argument parser to define any configuration arguments
* which may be used by this log file rotation listener. The argument parser
* may also be updated to define relationships between arguments (e.g., to
* specify required, exclusive, or dependent argument sets).
*
* @param parser The argument parser to be updated with the configuration
* arguments which may be used by this log file rotation
* listener.
*
* @throws ArgumentException If a problem is encountered while updating the
* provided argument parser.
*/
@Override()
public void defineConfigArguments(final ArgumentParser parser)
throws ArgumentException
{
// Add an argument that allows you to specify the output file.
final Character shortIdentifier = null;
final String longIdentifier = ARG_NAME_OUTPUT_FILE;
final boolean required = true;
final int maxOccurrences = 1;
final String placeholder = "{path}";
final String description =
"The output file to update whenever a log file is rotated.";
final boolean fileMustExist = false;
final boolean parentMustExist = true;
final boolean mustBeFile = true;
final boolean mustBeDirectory = false;
parser.addArgument(new FileArgument(shortIdentifier, longIdentifier,
required, maxOccurrences, placeholder, description, fileMustExist,
parentMustExist, mustBeFile, mustBeDirectory));
}
/**
* Initializes this log file rotation listener.
*
* @param serverContext A handle to the server context for the server in
* which this extension is running.
* @param config The general configuration for this log file rotation
* listener.
* @param parser The argument parser which has been initialized from
* the configuration for this log file rotation
* listener.
*
* @throws LDAPException If a problem occurs while initializing this log
* file rotation listener.
*/
@Override()
public void initializeLogFileRotationListener(
final ServerContext serverContext,
final LogFileRotationListenerConfig config,
final ArgumentParser parser)
throws LDAPException
{
serverContext.debugInfo(
"Beginning log file rotation listener initialization");
// Get the output file.
final FileArgument outputFileArg =
(FileArgument) parser.getNamedArgument(ARG_NAME_OUTPUT_FILE);
outputFile = outputFileArg.getValue();
}
/**
* Indicates whether the configuration contained in the provided argument
* parser represents a valid configuration for this extension.
*
* @param config The general configuration for this log file
* rotation listener.
* @param parser The argument parser which has been initialized
* with the proposed configuration.
* @param unacceptableReasons A list that can be updated with reasons that
* the proposed configuration is not acceptable.
*
* @return {@code true} if the proposed configuration is acceptable, or
* {@code false} if not.
*/
@Override()
public boolean isConfigurationAcceptable(
final LogFileRotationListenerConfig config,
final ArgumentParser parser,
final List<String> unacceptableReasons)
{
// No special validation is required.
return true;
}
/**
* Attempts to apply the configuration contained in the provided argument
* parser.
*
* @param config The general configuration for this log file
* rotation listener.
* @param parser The argument parser which has been
* initialized with the new configuration.
* @param adminActionsRequired A list that can be updated with information
* about any administrative actions that may be
* required before one or more of the
* configuration changes will be applied.
* @param messages A list that can be updated with information
* about the result of applying the new
* configuration.
*
* @return A result code that provides information about the result of
* attempting to apply the configuration change.
*/
@Override()
public ResultCode applyConfiguration(
final LogFileRotationListenerConfig config,
final ArgumentParser parser,
final List<String> adminActionsRequired,
final List<String> messages)
{
// Get the new output file.
final FileArgument outputFileArg =
(FileArgument) parser.getNamedArgument(ARG_NAME_OUTPUT_FILE);
outputFile = outputFileArg.getValue();
return ResultCode.SUCCESS;
}
/**
* Performs any cleanup which may be necessary when this log file rotation
* listener is to be taken out of service.
*/
@Override()
public void finalizeLogFileRotationListener()
{
// No finalization is required.
}
/**
* Performs any appropriate processing for a log file that has been rotated.
*
* @param f The log file that has been rotated. This file must not be
* deleted, moved, renamed, or otherwise altered during processing.
*
* @throws LDAPException If a problem is encountered during processing.
*/
@Override()
public void doPostRotationProcessing(final File f)
throws LDAPException
{
final PrintWriter writer;
try
{
final boolean appendToFile = true;
writer = new PrintWriter(new FileWriter(outputFile, appendToFile));
}
catch (final Exception e)
{
throw new LDAPException(ResultCode.LOCAL_ERROR,
"Unable to open output file " + outputFile.getAbsolutePath() +
" to record information about newly-rotated log file " +
f.getAbsolutePath() + ": " +
StaticUtils.getExceptionMessage(e),
e);
}
try
{
writer.println(
StaticUtils.encodeGeneralizedTime(System.currentTimeMillis()) +
'\t' + f.getAbsolutePath());
}
catch (final Exception e)
{
throw new LDAPException(ResultCode.LOCAL_ERROR,
"An error occurred while attempting to update output file " +
outputFile.getAbsolutePath() + " with information about " +
"newly-rotated log file " + f.getAbsolutePath() + ": " +
StaticUtils.getExceptionMessage(e),
e);
}
finally
{
writer.close();
}
}
/**
* Retrieves a map containing examples of configurations that may be used for
* this extension. The map key should be a list of sample arguments, and the
* corresponding value should be a description of the behavior that will be
* exhibited by the extension when used with that configuration.
*
* @return A map containing examples of configurations that may be used for
* this extension. It may be {@code null} or empty if there should
* not be any example argument sets.
*/
@Override()
public Map<List<String>,String> getExamplesArgumentSets()
{
final LinkedHashMap<List<String>,String> exampleMap =
new LinkedHashMap<List<String>,String>(1);
exampleMap.put(
Arrays.asList(
ARG_NAME_OUTPUT_FILE + "=logs/rotation.log"),
"Update the logs/rotation.log file with a message every time a " +
"log file is rotated.");
return exampleMap;
}
}