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 * Copyright 2023-2024 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.common.internal.ExampleUsageProvider; 036import com.unboundid.directory.sdk.common.internal.Reconfigurable; 037import com.unboundid.directory.sdk.common.internal.UnboundIDExtension; 038import com.unboundid.directory.sdk.ds.config.PostLDIFExportTaskProcessorConfig; 039import com.unboundid.directory.sdk.ds.internal.DirectoryServerExtension; 040import com.unboundid.directory.sdk.ds.types.DirectoryServerContext; 041import com.unboundid.directory.sdk.ds.types.LDIFExportTaskProperties; 042import com.unboundid.directory.sdk.proxy.internal.DirectoryProxyServerExtension; 043import com.unboundid.directory.sdk.sync.internal.SynchronizationServerExtension; 044import com.unboundid.ldap.sdk.LDAPException; 045import com.unboundid.ldap.sdk.ResultCode; 046import com.unboundid.util.Extensible; 047import com.unboundid.util.NotNull; 048import com.unboundid.util.Nullable; 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 that perform 058 * some processing immediately after an LDIF export task has completed. Note 059 * that this is only an option for LDIF exports invoked as administrative 060 * tasks (including as part of a recurring task), and not for standalone 061 * exports not invoked by an administrative task. 062 * <BR> 063 * <H2>Configuring Post-LDIF-Export Task P rocessors</H2> 064 * In order to configure a post-LDIF-export task processor created using this 065 * API, use a command like: 066 * <PRE> 067 * dsconfig create-post-ldif-export-task-processor \ 068 * --processor-name "<I>{processor-name}</I>" \ 069 * --type third-party \ 070 * --set enabled:true \ 071 * --set "extension-class:<I>{class-name}</I>" \ 072 * --set "extension-argument:<I>{name=value}</I>" 073 * </PRE> 074 * where "<I>{processor-name}</I>" is the name to use for the post-LDIF-export 075 * task processor instance, "<I>{class-name}</I>" is the fully-qualified name of 076 * the Java class that extends 077 * {@code com.unboundid.directory.sdk.ds.api.PostLDIFExportTaskProcessor}, and 078 * "<I>{name=value}</I>" represents name-value pairs for any arguments to 079 * provide to the processor. If multiple arguments should be provided to 080 * the processor, then the 081 * "<CODE>--set extension-argument:<I>{name=value}</I></CODE>" option should be 082 * provided multiple times. 083 */ 084@Extensible() 085@DirectoryServerExtension() 086@DirectoryProxyServerExtension(appliesToLocalContent=true, 087 appliesToRemoteContent=false) 088@SynchronizationServerExtension(appliesToLocalContent=true, 089 appliesToSynchronizedContent=false) 090@ThreadSafety(level=ThreadSafetyLevel.INTERFACE_THREADSAFE) 091public abstract class PostLDIFExportTaskProcessor 092 implements UnboundIDExtension, 093 Reconfigurable<PostLDIFExportTaskProcessorConfig>, 094 ExampleUsageProvider 095{ 096 /** 097 * Creates a new instance of this post-LDIF-export task processor. All 098 * post-LDIF-export task processor implementations must include a default 099 * constructor, but any initialization should generally be done in the 100 * {@code initializePostLDIFExportTaskProcessor} method. 101 */ 102 public PostLDIFExportTaskProcessor() 103 { 104 // No implementation is required. 105 } 106 107 108 109 /** 110 * {@inheritDoc} 111 */ 112 @NotNull() 113 public abstract String getExtensionName(); 114 115 116 117 /** 118 * {@inheritDoc} 119 */ 120 @Nullable() 121 public abstract String[] getExtensionDescription(); 122 123 124 125 /** 126 * {@inheritDoc} 127 */ 128 public void defineConfigArguments(@NotNull final ArgumentParser parser) 129 throws ArgumentException 130 { 131 // No arguments will be allowed by default. 132 } 133 134 135 136 /** 137 * Initializes this post-LDIF-export task processor. 138 * 139 * @param serverContext A handle to the server context for the server in 140 * which this extension is running. 141 * @param config The general configuration for this post-LDIF-export 142 * task processor. 143 * @param parser The argument parser which has been initialized from 144 * the configuration for this post-LDIF-export task 145 * processor. 146 * 147 * @throws LDAPException If a problem occurs while initializing this 148 * post-LDIF-export task processor. 149 */ 150 public void initializePostLDIFExportTaskProcessor( 151 @NotNull final DirectoryServerContext serverContext, 152 @NotNull final PostLDIFExportTaskProcessorConfig config, 153 @NotNull final ArgumentParser parser) 154 throws LDAPException 155 { 156 // No initialization will be performed by default. 157 } 158 159 160 161 /** 162 * {@inheritDoc} 163 */ 164 public boolean isConfigurationAcceptable( 165 @NotNull final PostLDIFExportTaskProcessorConfig config, 166 @NotNull final ArgumentParser parser, 167 @NotNull final List<String> unacceptableReasons) 168 { 169 // No extended validation will be performed by default. 170 return true; 171 } 172 173 174 175 /** 176 * {@inheritDoc} 177 */ 178 public ResultCode applyConfiguration( 179 @NotNull final PostLDIFExportTaskProcessorConfig config, 180 @NotNull final ArgumentParser parser, 181 @NotNull final List<String> adminActionsRequired, 182 @NotNull final List<String> messages) 183 { 184 // By default, no configuration changes will be applied. If there are any 185 // arguments, then add an admin action message indicating that the extension 186 // needs to be restarted for any changes to take effect. 187 if (! parser.getNamedArguments().isEmpty()) 188 { 189 adminActionsRequired.add( 190 "No configuration change has actually been applied. The new " + 191 "configuration will not take effect until this " + 192 "post-LDIF-export task processor is disabled and re-enabled " + 193 "or until the server is restarted."); 194 } 195 196 return ResultCode.SUCCESS; 197 } 198 199 200 201 /** 202 * Performs any cleanup which may be necessary when this post-LDIF-export task 203 * processor is to be taken out of service. 204 */ 205 public void finalizePostLDIFExportTaskProcessor() 206 { 207 // No implementation is required. 208 } 209 210 211 212 /** 213 * Performs any appropriate processing for an LDIF export file that has been 214 * generated by an administrative task. Note that while this method may 215 * access the resulting export file (for example, to examine its contents or 216 * copy it to an alternative location), it must not delete, move, rename, or 217 * otherwise alter the file in any way. 218 * 219 * @param exportProperties An object with information about the LDIF export 220 * task that was completed. 221 * 222 * @throws LDAPException If a problem is encountered during processing. 223 */ 224 public abstract void doPostLDIFExportTaskProcessing( 225 @NotNull final LDIFExportTaskProperties exportProperties) 226 throws LDAPException; 227 228 229 230 /** 231 * {@inheritDoc} 232 */ 233 @Nullable() 234 public Map<List<String>,String> getExamplesArgumentSets() 235 { 236 return Collections.emptyMap(); 237 } 238}