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 *      Portions Copyright 2010-2024 Ping Identity Corporation
026 */
027package com.unboundid.directory.sdk.broker.api;
028
029import com.unboundid.directory.sdk.broker.internal.BrokerExtension;
030import com.unboundid.directory.sdk.broker.config.PolicyDecisionLoggerConfig;
031import com.unboundid.directory.sdk.common.internal.ExampleUsageProvider;
032import com.unboundid.directory.sdk.common.internal.Reconfigurable;
033import com.unboundid.directory.sdk.common.internal.UnboundIDExtension;
034import com.unboundid.directory.sdk.broker.types.PolicyMessageType;
035import com.unboundid.directory.sdk.common.types.ServerContext;
036import com.unboundid.ldap.sdk.LDAPException;
037import com.unboundid.ldap.sdk.ResultCode;
038import com.unboundid.util.Extensible;
039import com.unboundid.util.ThreadSafety;
040import com.unboundid.util.ThreadSafetyLevel;
041import com.unboundid.util.args.ArgumentException;
042import com.unboundid.util.args.ArgumentParser;
043
044import java.util.Collections;
045import java.util.List;
046import java.util.Map;
047
048/**
049 * This class defines an API that must be implemented by extensions which
050 * record information about PingAuthorize policy enforcement point
051 * (PEP) and policy decision point (PDP) activity
052 * <BR><BR>
053 * Each policy decision logger may be configured to indicate whether to
054 * include the PDP response or exclude log messages based on their Policy
055 * Message Type.  This is handled automatically by the server, so individual
056 * policy decision logger implementations do not need to attempt to perform that
057 * filtering on their own.  However, they may perform additional processing
058 * if desired to further narrow the set of messages that should be logged.
059 * <BR>
060 * <H2>Configuring Policy Decision Loggers</H2>
061 * To configure a policy decision created using this API, use a command
062 * like:
063 * <PRE>
064 *      dsconfig create-log-publisher \
065 *           --publisher-name "<I>{logger-name}</I>" \
066 *           --type third-party-policy-decision \
067 *           --set enabled:true \
068 *           --set "extension-class:<I>{class-name}</I>" \
069 *           --set "extension-argument:<I>{name=value}</I>"
070 * </PRE>
071 * where "<I>{logger-name}</I>" is the name
072 * to use for the policy decision logger
073 * instance, "<I>{class-name}</I>" is the fully-qualified name of the Java class
074 * that extends {@code com.unboundid.directory.sdk.common.api
075 * .PolicyDecisionLogger},
076 * and "<I>{name=value}</I>" represents name-value pairs for any arguments to
077 * provide to the logger.  If multiple arguments should be provided to the
078 * logger, then the "<CODE>--set extension-argument:<I>{name=value}</I></CODE>"
079 * option should be provided multiple times.
080 *
081 */
082@Extensible()
083@BrokerExtension()
084@ThreadSafety(level= ThreadSafetyLevel.INTERFACE_THREADSAFE)
085public abstract class PolicyDecisionLogger implements UnboundIDExtension,
086        Reconfigurable<PolicyDecisionLoggerConfig>, ExampleUsageProvider {
087
088    /**
089     * Creates a new instance of this policy decision logger.
090     * All policy decision logger implementations must include a default
091     * constructor, but any initialization should generally be done in
092     * the {@code initializePolicyDecisionLogger} method.
093     */
094    public PolicyDecisionLogger()
095    {
096        // No implementation is required.
097    }
098
099    /**
100     * {@inheritDoc}
101     */
102    public abstract String getExtensionName();
103
104    /**
105     * {@inheritDoc}
106     */
107    public abstract String[] getExtensionDescription();
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     * Initializes this policy decision logger.
120     *
121     * @param  serverContext  A handle to the server context for the server in
122     *                        which this extension is running.
123     * @param  config         The general configuration for
124     *                        this policy decision logger.
125     * @param  parser         The argument parser which
126     *                        has been initialized from the configuration
127     *                        for this policy decision logger.
128     *
129     * @throws LDAPException  If a problem occurs while initializing
130     * this policy decision logger.
131     */
132    public void initializePolicyDecisionLogger(
133            final ServerContext serverContext,
134                                      final PolicyDecisionLoggerConfig config,
135                                      final ArgumentParser parser)
136            throws LDAPException
137    {
138        // No initialization will be performed by default.
139    }
140
141    /**
142     * {@inheritDoc}
143     */
144    public boolean isConfigurationAcceptable(
145            final PolicyDecisionLoggerConfig config,
146            final ArgumentParser parser,
147            final List<String> unacceptableReasons)
148    {
149        // No extended validation will be performed by default.
150        return true;
151    }
152
153
154
155    /**
156     * {@inheritDoc}
157     */
158    public ResultCode applyConfiguration(
159            final PolicyDecisionLoggerConfig config,
160            final ArgumentParser parser,
161            final List<String> adminActionsRequired,
162            final List<String> messages)
163    {
164        // By default, no configuration changes will be applied.
165        // If there are any arguments,
166        // then add an admin action message indicating that the extension
167        // needs to be restarted for any changes to take effect.
168        if (! parser.getNamedArguments().isEmpty())
169        {
170            adminActionsRequired.add(
171                    "No configuration change has actually been applied." +
172                    " The new configuration will not take effect" +
173                    " until this policy decision logger is disabled" +
174                    " and re-enabled or until the server is restarted.");
175        }
176        return ResultCode.SUCCESS;
177    }
178
179    /**
180     * Performs any cleanup which may be necessary when this
181     * policy decision logger is to be taken out of service.
182     */
183    public void finalizePolicyDecisionLogger()
184    {
185        // No implementation is required.
186    }
187
188    /**
189     * Logs a message.
190     *
191     * @param messageType The {@link PolicyMessageType}.
192     *                    This is an indication of what stage in the decision
193     *                    processing lifecycle is being logged.
194     *                    <p>
195     *                    This can be either {@link PolicyMessageType#ADVICE}
196     *                    or {@link PolicyMessageType#DECISION}
197     *                    </p>
198     * @param logContext   A set of key/value pairs summarizing and providing
199     *                    context for the policy decision or advice.
200     * @param message     This is {@code null} when include-pdp-response
201     *                    is disabled and for message types that do not record
202     *                    a policy decision response
203     *                    (like {@link PolicyMessageType#ADVICE}).
204     */
205    public abstract void log(
206            final PolicyMessageType messageType,
207            final Map<String, String> logContext,
208            final String message);
209
210
211
212    /**
213     * {@inheritDoc}
214     */
215    public Map<List<String>,String> getExamplesArgumentSets()
216    {
217        return Collections.emptyMap();
218    }
219}