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 2013-2023 Ping Identity Corporation
026 */
027package com.unboundid.directory.sdk.ds.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.internal.ExampleUsageProvider;
037import com.unboundid.directory.sdk.common.internal.Reconfigurable;
038import com.unboundid.directory.sdk.common.internal.UnboundIDExtension;
039import com.unboundid.directory.sdk.common.types.ClientContext;
040import com.unboundid.directory.sdk.ds.config.ConnectionCriteriaConfig;
041import com.unboundid.directory.sdk.ds.types.DirectoryServerContext;
042import com.unboundid.directory.sdk.ds.internal.DirectoryServerExtension;
043import com.unboundid.directory.sdk.metrics.internal.MetricsEngineExtension;
044import com.unboundid.directory.sdk.proxy.internal.DirectoryProxyServerExtension;
045import com.unboundid.directory.sdk.sync.internal.SynchronizationServerExtension;
046import com.unboundid.ldap.sdk.LDAPException;
047import com.unboundid.ldap.sdk.ResultCode;
048import com.unboundid.util.Extensible;
049import com.unboundid.util.ThreadSafety;
050import com.unboundid.util.ThreadSafetyLevel;
051import com.unboundid.util.args.ArgumentException;
052import com.unboundid.util.args.ArgumentParser;
053
054
055
056/**
057 * This class defines an API that must be implemented by extensions which can
058 * be used to classify client connections.
059 * <BR>
060 * <H2>Configuring Connection Criteria</H2>
061 * In order to configure a connection criteria object created using this API,
062 * use a command like:
063 * <PRE>
064 *      dsconfig create-connection-criteria \
065 *           --criteria-name "<I>{criteria-name}</I>" \
066 *           --type third-party \
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>{criteria-name}</I>" is the name to use for the connection criteria
072 * instance, "<I>{class-name}</I>" is the fully-qualified name of the Java class
073 * that extends {@code com.unboundid.directory.sdk.ds.api.ConnectionCriteria},
074 * and "<I>{name=value}</I>" represents name-value pairs for any arguments to
075 * provide to the connection criteria.  If multiple arguments should be provided
076 * to the connection criteria instance, then the
077 * "<CODE>--set extension-argument:<I>{name=value}</I></CODE>" option should be
078 * provided multiple times.
079 */
080@Extensible()
081@DirectoryServerExtension()
082@DirectoryProxyServerExtension(appliesToLocalContent=true,
083     appliesToRemoteContent=true)
084@SynchronizationServerExtension(appliesToLocalContent=true,
085     appliesToSynchronizedContent=false)
086@MetricsEngineExtension()
087@BrokerExtension()
088@ThreadSafety(level=ThreadSafetyLevel.INTERFACE_THREADSAFE)
089public abstract class ConnectionCriteria
090       implements UnboundIDExtension,
091                  Reconfigurable<ConnectionCriteriaConfig>,
092                  ExampleUsageProvider
093{
094  /**
095   * Creates a new instance of this connection criteria.  All connection
096   * criteria implementations must include a default constructor, but any
097   * initialization should generally be done in the
098   * {@code initializeConnectionCriteria} method.
099   */
100  public ConnectionCriteria()
101  {
102    // No implementation is required.
103  }
104
105
106
107  /**
108   * {@inheritDoc}
109   */
110  public abstract String getExtensionName();
111
112
113
114  /**
115   * {@inheritDoc}
116   */
117  public abstract String[] getExtensionDescription();
118
119
120
121  /**
122   * {@inheritDoc}
123   */
124  public void defineConfigArguments(final ArgumentParser parser)
125         throws ArgumentException
126  {
127    // No arguments will be allowed by default.
128  }
129
130
131
132  /**
133   * Initializes this connection criteria.
134   *
135   * @param  serverContext  A handle to the server context for the server in
136   *                        which this extension is running.
137   * @param  config         The general configuration for this connection
138   *                        criteria.
139   * @param  parser         The argument parser which has been initialized from
140   *                        the configuration for this connection criteria.
141   *
142   * @throws  LDAPException  If a problem occurs while initializing this
143   *                         connection criteria.
144   */
145  public void initializeConnectionCriteria(
146                   final DirectoryServerContext serverContext,
147                   final ConnectionCriteriaConfig config,
148                   final ArgumentParser parser)
149         throws LDAPException
150  {
151    // No initialization will be performed by default.
152  }
153
154
155
156  /**
157   * {@inheritDoc}
158   */
159  public boolean isConfigurationAcceptable(
160                      final ConnectionCriteriaConfig config,
161                      final ArgumentParser parser,
162                      final List<String> unacceptableReasons)
163  {
164    // No extended validation will be performed by default.
165    return true;
166  }
167
168
169
170  /**
171   * {@inheritDoc}
172   */
173  public ResultCode applyConfiguration(final ConnectionCriteriaConfig config,
174                                       final ArgumentParser parser,
175                                       final List<String> adminActionsRequired,
176                                       final List<String> messages)
177  {
178    // By default, no configuration changes will be applied.  If there are any
179    // arguments, then add an admin action message indicating that the extension
180    // needs to be restarted for any changes to take effect.
181    if (! parser.getNamedArguments().isEmpty())
182    {
183      adminActionsRequired.add(
184           "No configuration change has actually been applied.  The new " +
185                "configuration will not take effect until this connection " +
186                "criteria is disabled and re-enabled or until the server is " +
187                "restarted.");
188    }
189
190    return ResultCode.SUCCESS;
191  }
192
193
194
195  /**
196   * Performs any cleanup which may be necessary when this connection criteria
197   * is to be taken out of service.
198   */
199  public void finalizeConnectionCriteria()
200  {
201    // No implementation is required.
202  }
203
204
205
206  /**
207   * Indicates whether the provided client connection matches the criteria for
208   * this connection criteria object.
209   *
210   * @param  c  The client connection for which to make the determination.
211   *
212   * @return  {@code true} if the provided client connection matches the
213   *          criteria for this connection criteria object, or {@code false} if
214   *          not.
215   */
216  public abstract boolean matches(final ClientContext c);
217
218
219
220  /**
221   * {@inheritDoc}
222   */
223  public Map<List<String>,String> getExamplesArgumentSets()
224  {
225    return Collections.emptyMap();
226  }
227}