com.unboundid.directory.sdk.http.api.HTTPServletExtension Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of server-sdk Show documentation
Show all versions of server-sdk Show documentation
The UnboundID Server SDK is a library that may be used to develop various
types of extensions to Ping Identity server products, including the
PingDirectory Server, PingDirectoryProxy Server, PingDataSync Server,
PingDataMetrics Server, and PingAuthorize Server.
The newest version!
/*
* 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
*
*
* Portions Copyright 2011-2024 Ping Identity Corporation
*/
package com.unboundid.directory.sdk.http.api;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.http.HttpServlet;
import com.unboundid.directory.sdk.broker.internal.BrokerExtension;
import com.unboundid.directory.sdk.common.internal.ExampleUsageProvider;
import com.unboundid.directory.sdk.common.internal.Reconfigurable;
import com.unboundid.directory.sdk.common.internal.UnboundIDExtension;
import com.unboundid.directory.sdk.ds.internal.DirectoryServerExtension;
import com.unboundid.directory.sdk.http.config.HTTPServletExtensionConfig;
import com.unboundid.directory.sdk.http.types.HTTPServerContext;
import com.unboundid.directory.sdk.metrics.internal.MetricsEngineExtension;
import com.unboundid.directory.sdk.proxy.internal.DirectoryProxyServerExtension;
import com.unboundid.directory.sdk.sync.internal.SynchronizationServerExtension;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.ResultCode;
import com.unboundid.util.Extensible;
import com.unboundid.util.ThreadSafety;
import com.unboundid.util.ThreadSafetyLevel;
import com.unboundid.util.args.ArgumentException;
import com.unboundid.util.args.ArgumentParser;
/**
* This class defines an API that must be implemented by extensions which create
* servlets for use with an HTTP connection handler.
*
* Configuring HTTP Servlet Extensions
* In order to configure an HTTP servlet extension created using this API, use a
* command like:
*
* dsconfig create-http-servlet-extension \
* --extension-name "{extension-name}" \
* --type third-party \
* --set "extension-class:{class-name}" \
* --set "extension-argument:{name=value}"
*
* where "{extension-name}" is the name to use for the HTTP servlet
* extension instance, "{class-name}" is the fully-qualified name of the
* Java class that extends
* {@code com.unboundid.directory.sdk.ds.api.HTTPServletExtension},
* and "{name=value}" represents name-value pairs for any arguments to
* provide to the HTTP servlet extension. If multiple arguments should be
* provided to the HTTP servlet extension, then the
* "--set extension-argument:{name=value}
" option should be
* provided multiple times.
*
* Note that the server also provides the ability to run full web applications,
* by creating a Web Application Extension and specifying the necessary
* properties. If that web application needs to perform internal operations or
* interact with the server in any way, then the
* {@link com.unboundid.directory.sdk.http.types.WebAppServerContextFactory}
* class may be called from the web application in order to obtain a server
* context.
*
* @see com.unboundid.directory.sdk.http.scripting.ScriptedHTTPServletExtension
*/
@Extensible()
@DirectoryServerExtension()
@DirectoryProxyServerExtension(appliesToLocalContent=true,
appliesToRemoteContent=true)
@MetricsEngineExtension()
@BrokerExtension()
@SynchronizationServerExtension(appliesToLocalContent=true,
appliesToSynchronizedContent=true)
@ThreadSafety(level=ThreadSafetyLevel.INTERFACE_THREADSAFE)
public abstract class HTTPServletExtension
implements UnboundIDExtension,
Reconfigurable,
ExampleUsageProvider
{
/**
* Creates a new instance of this HTTP servlet extension. All HTTP servlet
* extension implementations must include a default constructor, but any
* initialization should generally be done in the
* {@code createServlet} method.
*/
public HTTPServletExtension()
{
// No implementation is required.
}
/**
* {@inheritDoc}
*/
public abstract String getExtensionName();
/**
* {@inheritDoc}
*/
public abstract String[] getExtensionDescription();
/**
* {@inheritDoc}
*/
public void defineConfigArguments(final ArgumentParser parser)
throws ArgumentException
{
// No arguments will be allowed by default.
}
/**
* {@inheritDoc}
*/
public boolean isConfigurationAcceptable(
final HTTPServletExtensionConfig config,
final ArgumentParser parser,
final List unacceptableReasons)
{
// No extended validation will be performed by default.
return true;
}
/**
* {@inheritDoc}
*/
public ResultCode applyConfiguration(final HTTPServletExtensionConfig config,
final ArgumentParser parser,
final List adminActionsRequired,
final List messages)
{
// By default, no configuration changes will be applied. If there are any
// arguments, then add an admin action message indicating that the extension
// needs to be restarted for any changes to take effect.
if (! parser.getNamedArguments().isEmpty())
{
adminActionsRequired.add(
"No configuration change has actually been applied. The new " +
"configuration will not take effect until this HTTP servlet " +
"extension is disabled and re-enabled or until the server is " +
"restarted.");
}
return ResultCode.SUCCESS;
}
/**
* {@inheritDoc}
*/
public Map,String> getExamplesArgumentSets()
{
return Collections.emptyMap();
}
/**
* Creates an HTTP servlet extension using the provided information.
*
* @param serverContext A handle to the server context for the server in
* which this extension is running.
* @param config The general configuration for this HTTP servlet
* extension.
* @param parser The argument parser which has been initialized from
* the configuration for this HTTP servlet extension.
*
* @return The HTTP servlet that has been created.
*
* @throws LDAPException If a problem is encountered while attempting to
* create the HTTP servlet.
*/
public abstract HttpServlet createServlet(
final HTTPServerContext serverContext,
final HTTPServletExtensionConfig config,
final ArgumentParser parser)
throws LDAPException;
/**
* Retrieves a list of the request paths for which the associated servlet
* should be invoked. This method will be called after the
* {@link #createServlet} method has been used to create the servlet instance.
*
* @return A list of the request paths for which the associated servlet
* should be invoked.
*/
public abstract List getServletPaths();
/**
* Retrieves a map of initialization parameters that should be provided to the
* servlet when it is initialized.
*
* @return A map of initialization parameters that should be provided to the
* servlet when it is initialized, or an empty map if no
* initialization parameters are needed.
*/
public Map getServletInitParameters()
{
return Collections.emptyMap();
}
/**
* Retrieves the order in which the servlet should be started. A value
* greater than or equal to zero guarantees that the servlet will be started
* as soon as the servlet engine has been started, in order of ascending
* servlet init order values, before the {@code doPostRegistrationProcessing}
* method has been called. If the value is less than zero, the servlet may
* not be started until a request is received for one of its registered paths.
*
* @return The order in which the servlet should be started, or a negative
* value if startup order does not matter.
*/
public int getServletInitOrder()
{
return -1;
}
/**
* Retrieves a list of servlet filter instances that should be installed with
* the created servlet instance, in the order they should be invoked. If the
* servlet is to be registered with multiple paths, then these filters will be
* installed for all of those paths.
*
* @return A list of servlet filter instances that should be installed with
* the created servlet instance, in the order that they should be
* invoked. It may be {@code null} or empty if no servlet filters
* should be installed.
*/
public List getServletFilters()
{
return Collections.emptyList();
}
/**
* Performs any processing that may be needed after the servlet has been
* registered with the servlet engine. If the value returned from
* {@link #getServletInitOrder()} is greater than or equal to zero, then the
* servlet will have been started before this method is called. If the value
* returned from {@code getServletInitOrder()} is negative, then the servlet
* may or may not have been started by the time this method is called.
*
* Note that the associated servlet can also perform any necessary
* initialization processing in the {@code init} method provided by the
* servlet API.
*/
public void doPostRegistrationProcessing()
{
// No implementation required by default.
}
/**
* Performs any processing that may be needed after the servlet has been
* taken out of service and the associated servlet engine has been shut down.
*
* Note that the associated servlet can also perform any necessary
* finalization processing in the {@code destroy} method provided by the
* servlet API. That method will be called after the servlet has been taken
* out of service, but before the servlet engine has been shut down.
*/
public void doPostShutdownProcessing()
{
// No implementation required by default.
}
}