com.unboundid.directory.sdk.sync.scripting.ScriptedSyncDestination Maven / Gradle / Ivy
Show all versions of server-sdk Show documentation
/*
* 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 2010-2024 Ping Identity Corporation
*/
package com.unboundid.directory.sdk.sync.scripting;
import java.util.List;
import com.unboundid.directory.sdk.common.internal.Configurable;
import com.unboundid.directory.sdk.sync.config.SyncDestinationConfig;
import com.unboundid.directory.sdk.sync.internal.SynchronizationServerExtension;
import com.unboundid.directory.sdk.sync.types.EndpointException;
import com.unboundid.directory.sdk.sync.types.SyncOperation;
import com.unboundid.directory.sdk.sync.types.SyncServerContext;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.Modification;
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 scripted extensions
* that wish to push changes processed by the ${SYNC_SERVER_BASE_NAME} to an
* arbitrary destination. This type of sync destination is generic and can
* support a wide range of endpoints. In addition, this type of sync destination
* supports one-way notifications, where the source and destination entries are
* never compared but instead changes are pushed straight through.
*
* Configuring Scripted Sync Destinations
* In order to configure a sync destination created using this API, use
* a command like:
*
* dsconfig create-sync-destination \
* --sync-destination-name "{name}" \
* --type groovy-scripted \
* --set "script-class:{class-name}" \
* --set "script-argument:{name=value}"
*
* where "{name}" is the name to use for the sync destination
* instance, "{script-name}" is the fully-qualified name of the Java
* class that extends
* {@code com.unboundid.directory.sdk.sync.scripting.ScriptedSyncDestination},
* and "{name=value}" represents name-value pairs for any arguments to
* provide to the sync destination. If multiple arguments should be
* provided to extension, then the
* "--set script-argument:{name=value}
" option should be
* provided multiple times.
*
* @see
* com.unboundid.directory.sdk.sync.api.SyncDestination
*/
@Extensible()
@SynchronizationServerExtension(appliesToLocalContent=false,
appliesToSynchronizedContent=true)
@ThreadSafety(level = ThreadSafetyLevel.MOSTLY_THREADSAFE)
public abstract class ScriptedSyncDestination implements Configurable
{
/**
* {@inheritDoc}
*/
public void defineConfigArguments(final ArgumentParser parser)
throws ArgumentException
{
// No arguments will be allowed by default.
}
/**
* Initializes this sync destination. This is called when a Sync Pipe
* first starts up, or when the resync process first starts up. Any
* initialization should be performed here. This method should generally store
* the {@link SyncServerContext} in a class member so that it can be used
* elsewhere in the implementation.
*
* The default implementation is empty.
*
* @param serverContext A handle to the server context for the server in
* which this extension is running. Extensions should
* typically store this in a class member.
* @param config The general configuration for this object.
* @param parser The argument parser which has been initialized from
* the configuration for this sync destination.
* @throws EndpointException
* if a problem occurs while initializing this
* sync destination.
*/
public void initializeSyncDestination(
final SyncServerContext serverContext,
final SyncDestinationConfig config,
final ArgumentParser parser)
throws EndpointException
{
// No initialization will be performed by default.
}
/**
* This hook is called when a Sync Pipe shuts down, or when the resync
* process shuts down. Any clean-up of this sync destination should be
* performed here.
*
* The default implementation is empty.
*/
public void finalizeSyncDestination()
{
// No implementation is performed by default.
}
/**
* Return the URL or path identifying the destination endpoint
* to which this extension is transmitting data. This is used for logging
* purposes only, so it could just be a server name or hostname and port, etc.
*
* @return the path to the destination endpoint
*/
public abstract String getCurrentEndpointURL();
/**
* Return a full destination entry (in LDAP form) from the destination
* endpoint, corresponding to the source {@link Entry} that is passed in.
* This method should perform any queries necessary to gather the latest
* values for all the attributes to be synchronized and return them in an
* Entry.
*
* This method only needs to be implemented if the 'synchronization-mode' on
* the Sync Pipe is set to 'standard'. If it is set to 'notification', this
* method will never be called, and the pipe will pass changes straight
* through to one of {@link #createEntry}, {@link #modifyEntry}, or
* {@link #deleteEntry}.
*
* Note that the if the source entry was renamed (see
* {@link SyncOperation#isModifyDN}), the
* destEntryMappedFromSrc
will have the new DN; the old DN can
* be obtained by calling
* {@link SyncOperation#getDestinationEntryBeforeChange()} and getting the DN
* from there. This method should return the entry in its existing form
* (i.e. with the old DN, before it is changed).
*
* This method must be thread safe, as it will be called repeatedly and
* concurrently by each of the Sync Pipe worker threads as they process
* entries.
* @param destEntryMappedFromSrc
* the LDAP entry which corresponds to the destination "entry" to
* fetch
* @param operation
* the sync operation for this change
* @return a list containing the full LDAP entries that matched this search
* (there may be more than one), or an empty list if no such entry
* exists
* @throws EndpointException
* if there is an error fetching the entry
*/
public List fetchEntry(final Entry destEntryMappedFromSrc,
final SyncOperation operation)
throws EndpointException
{
throw new UnsupportedOperationException(
"The fetchEntry() method must be implemented in the " +
"ScriptedSyncDestination if the Sync Pipe is " +
"running in standard mode (see 'synchronization-mode' " +
"in the Sync Pipe configuration).");
}
/**
* Creates a full destination "entry", corresponding to the LDAP
* {@link Entry} that is passed in. This method is responsible for
* transforming the contents of the entry into the desired format and
* transmitting it to the target destination. It should perform any inserts or
* updates necessary to make sure the entry is fully created on the
* destination endpoint.
*
* This method must be thread safe, as it will be called repeatedly and
* concurrently by the Sync Pipe worker threads as they process CREATE
* operations.
* @param entryToCreate
* the LDAP entry which corresponds to the destination
* "entry" to create
* @param operation
* the sync operation for this change
* @throws EndpointException
* if there is an error creating the entry
*/
public abstract void createEntry(final Entry entryToCreate,
final SyncOperation operation)
throws EndpointException;
/**
* Modify an "entry" on the destination, corresponding to the LDAP
* {@link Entry} that is passed in. This method is responsible for
* transforming the contents of the entry into the desired format and
* transmitting it to the target destination. It may perform multiple updates
* (including inserting or deleting other attributes) in order to fully
* synchronize the entire entry on the destination endpoint.
*
* Note that the if the source entry was renamed (see
* {@link SyncOperation#isModifyDN}), the
* fetchedDestEntry
will have the old DN; the new DN can
* be obtained by calling
* {@link SyncOperation#getDestinationEntryAfterChange()} and getting the DN
* from there.
*
* This method must be thread safe, as it will be called repeatedly and
* concurrently by the Sync Pipe worker threads as they process MODIFY
* operations.
* @param entryToModify
* the LDAP entry which corresponds to the destination
* "entry" to modify. If the synchronization mode is 'standard',
* this will be the entry that was returned by {@link #fetchEntry};
* otherwise if the synchronization mode is 'notification', this
* will be the mapped destination entry.
* @param modsToApply
* a list of Modification objects which should be applied
* @param operation
* the sync operation for this change
* @throws EndpointException
* if there is an error modifying the entry
*/
public abstract void modifyEntry(final Entry entryToModify,
final List modsToApply,
final SyncOperation operation)
throws EndpointException;
/**
* Delete a full "entry" from the destination, corresponding to the LDAP
* {@link Entry} that is passed in. This method may perform multiple deletes
* or updates if necessary to fully delete the entry from the destination
* endpoint.
*
* This method must be thread safe, as it will be called repeatedly and
* concurrently by the Sync Pipe worker threads as they process DELETE
* operations.
* @param entryToDelete
* the LDAP entry which corresponds to the destination
* "entry" to delete. If the synchronization mode is 'standard',
* this will be the entry that was returned by {@link #fetchEntry};
* otherwise if the synchronization mode is 'notification', this
* will be the mapped destination entry.
* @param operation
* the sync operation for this change
* @throws EndpointException
* if there is an error deleting the entry
*/
public abstract void deleteEntry(final Entry entryToDelete,
final SyncOperation operation)
throws EndpointException;
}