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 2016-2024 Ping Identity Corporation 026 */ 027package com.unboundid.directory.sdk.broker.api; 028 029import com.unboundid.directory.sdk.broker.config.StoreAdapterPluginConfig; 030import com.unboundid.directory.sdk.broker.internal.BrokerExtension; 031import com.unboundid.directory.sdk.broker.types.BrokerContext; 032import com.unboundid.directory.sdk.broker.types.StorePostCreateRequestContext; 033import com.unboundid.directory.sdk.broker.types.StorePostDeleteRequestContext; 034import com.unboundid.directory.sdk.broker.types.StorePostRetrieveRequestContext; 035import com.unboundid.directory.sdk.broker.types.StorePostSearchEntryContext; 036import com.unboundid.directory.sdk.broker.types.StorePostUpdateRequestContext; 037import com.unboundid.directory.sdk.broker.types.StorePreCreateRequestContext; 038import com.unboundid.directory.sdk.broker.types.StorePreDeleteRequestContext; 039import com.unboundid.directory.sdk.broker.types.StorePreRetrieveRequestContext; 040import com.unboundid.directory.sdk.broker.types.StorePreSearchRequestContext; 041import com.unboundid.directory.sdk.broker.types.StorePreUpdateRequestContext; 042import com.unboundid.directory.sdk.common.internal.Configurable; 043import com.unboundid.directory.sdk.common.internal.ExampleUsageProvider; 044import com.unboundid.directory.sdk.common.internal.UnboundIDExtension; 045import com.unboundid.scim2.common.exceptions.ScimException; 046import com.unboundid.util.Extensible; 047import com.unboundid.util.ThreadSafety; 048import com.unboundid.util.ThreadSafetyLevel; 049import com.unboundid.util.args.ArgumentException; 050import com.unboundid.util.args.ArgumentParser; 051 052import java.util.Collections; 053import java.util.List; 054import java.util.Map; 055 056 057 058/** 059 * This class defines an API that must be implemented by extensions that need 060 * to intercept operations processed by a Store Adapter. The API has 061 * pre-request methods to intercept and make changes to store adapter requests 062 * before they are processed by the Store Adapter, and corresponding 063 * post-request methods to intercept and make changes to the results returned 064 * by the Store Adapter. All SCIM attributes in this API refer to native Store 065 * Adapter attributes, not attributes in the external client SCIM schema. 066 * <p> 067 * The Store Adapter Plugin is defined in the configuration and then referenced 068 * by a Store Adapter configuration object. 069 */ 070@Extensible() 071@BrokerExtension 072@ThreadSafety(level= ThreadSafetyLevel.INTERFACE_THREADSAFE) 073public abstract class StoreAdapterPlugin implements UnboundIDExtension, 074 Configurable, ExampleUsageProvider 075{ 076 /** 077 * Creates a new instance of this store adapter plugin. All 078 * implementations must include a default constructor, but any 079 * initialization should generally be done in the 080 * {@link #initializeStoreAdapterPlugin} method. 081 */ 082 public StoreAdapterPlugin() 083 { 084 // No implementation is required. 085 } 086 087 /** 088 * {@inheritDoc} 089 */ 090 @Override 091 public abstract String getExtensionName(); 092 093 /** 094 * {@inheritDoc} 095 */ 096 @Override 097 public abstract String[] getExtensionDescription(); 098 099 /** 100 * {@inheritDoc} 101 */ 102 @Override 103 public Map<List<String>,String> getExamplesArgumentSets() 104 { 105 return Collections.emptyMap(); 106 } 107 108 /** 109 * {@inheritDoc} 110 */ 111 @Override 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 store adapter plugin. Any initialization should be 120 * performed here. This method should generally store the 121 * {@link BrokerContext} in a class member so that it can be used elsewhere in 122 * the implementation. 123 * <p> 124 * The default implementation is empty. 125 * 126 * @param serverContext A handle to the server context for the server in 127 * which this extension is running. Extensions should 128 * typically store this in a class member. 129 * @param config The general configuration for this object. 130 * @param parser The argument parser which has been initialized from 131 * the configuration for this store adapter plugin. 132 * @throws Exception If a problem occurs while initializing this store 133 * adapter plugin. 134 */ 135 public void initializeStoreAdapterPlugin( 136 final BrokerContext serverContext, 137 final StoreAdapterPluginConfig config, 138 final ArgumentParser parser) 139 throws Exception 140 { 141 // No initialization will be performed by default. 142 } 143 144 /** 145 * This hook is called when the store adapter plugin is disabled or the 146 * PingAuthorize Server shuts down. Any clean-up of this store adapter plugin 147 * should be performed here. 148 * <p> 149 * The default implementation is empty. 150 */ 151 public void finalizeStoreAdapterPlugin() 152 { 153 // No finalization will be performed by default. 154 } 155 156 /** 157 * This method is called before an entry is created in the native data store. 158 * 159 * @param context The store adapter request context. 160 * @throws ScimException If thrown, the operation will be aborted and a 161 * corresponding SCIM ErrorResponse will be returned to 162 * the client. 163 */ 164 public void preCreate(final StorePreCreateRequestContext context) 165 throws ScimException 166 { 167 // No implementation is required by default. 168 } 169 170 /** 171 * This method is called after an entry is created in the native data store. 172 * This method will not be called if the create fails. 173 * 174 * @param context The store adapter request context. 175 * @throws ScimException If thrown, a corresponding SCIM ErrorResponse will be 176 * returned to the client. No attempt is made to roll 177 * back the committed create operation. 178 */ 179 public void postCreate(final StorePostCreateRequestContext context) 180 throws ScimException 181 { 182 // No implementation is required by default. 183 } 184 185 /** 186 * This method is called before an entry is retrieved from the native data 187 * store in the following cases: 188 * <UL> 189 * <LI> 190 * To fetch an entry for a SCIM retrieve operation. 191 * </LI> 192 * <LI> 193 * To fetch an entry from a secondary store adapter for each primary store 194 * adapter entry obtained during a SCIM search. 195 * </LI> 196 * <LI> 197 * To fetch an entry from the primary store adapter for each secondary 198 * store adapter entry obtained when a SCIM search filter is processed 199 * by a secondary store adapter. 200 * </LI> 201 * </UL> 202 * 203 * @param context The store adapter request context. 204 * @throws ScimException If thrown, the operation will be aborted and a 205 * corresponding SCIM ErrorResponse will be returned to 206 * the client. 207 */ 208 public void preRetrieve(final StorePreRetrieveRequestContext context) 209 throws ScimException 210 { 211 // No implementation is required by default. 212 } 213 214 /** 215 * This method is called after an entry is retrieved from the native data 216 * store. 217 * This method will not be called if the retrieve fails. 218 * 219 * @param context The store adapter request context. 220 * @throws ScimException If thrown, a corresponding SCIM ErrorResponse will be 221 * returned to the client. 222 */ 223 public void postRetrieve(final StorePostRetrieveRequestContext context) 224 throws ScimException 225 { 226 // No implementation is required by default. 227 } 228 229 /** 230 * This method is called before an entry is updated in the native data 231 * store. 232 * 233 * @param context The store adapter request context. 234 * @throws ScimException If thrown, the operation will be aborted and a 235 * corresponding SCIM ErrorResponse will be returned to 236 * the client. 237 */ 238 public void preUpdate(final StorePreUpdateRequestContext context) 239 throws ScimException 240 { 241 // No implementation is required by default. 242 } 243 244 /** 245 * This method is called after an entry is updated in the native data 246 * store. 247 * This method will not be called if the update fails. 248 * 249 * @param context The store adapter request context. 250 * @throws ScimException If thrown, a corresponding SCIM ErrorResponse will be 251 * returned to the client. No attempt is made to roll 252 * back the committed update operation. 253 */ 254 public void postUpdate(final StorePostUpdateRequestContext context) 255 throws ScimException 256 { 257 // No implementation is required by default. 258 } 259 260 /** 261 * This method is called before an entry is deleted in the native data 262 * store. 263 * 264 * @param context The store adapter request context. 265 * @throws ScimException If thrown, the operation will be aborted and a 266 * corresponding SCIM ErrorResponse will be returned to 267 * the client. 268 */ 269 public void preDelete(final StorePreDeleteRequestContext context) 270 throws ScimException 271 { 272 // No implementation is required by default. 273 } 274 275 /** 276 * This method is called after an entry is deleted in the native data 277 * store. 278 * This method will not be called if the delete fails. 279 * 280 * @param context The store adapter request context. 281 * @throws ScimException If thrown, a corresponding SCIM ErrorResponse will be 282 * returned to the client. No attempt is made to roll 283 * back the committed delete operation. 284 */ 285 public void postDelete(final StorePostDeleteRequestContext context) 286 throws ScimException 287 { 288 // No implementation is required by default. 289 } 290 291 /** 292 * This method is called before searching for entries in the native data 293 * store. 294 * <p> 295 * Note that the contract for store adapter searches allows the store adapter 296 * to return a superset of entries matching the original search filter. The 297 * results from the store adapter are subsequently filtered by the 298 * PingAuthorize Server. 299 * 300 * @param context The store adapter request context. 301 * @throws ScimException If thrown, the operation will be aborted and a 302 * corresponding SCIM ErrorResponse will be returned to 303 * the client. 304 */ 305 public void preSearch(final StorePreSearchRequestContext context) 306 throws ScimException 307 { 308 // No implementation is required by default. 309 } 310 311 /** 312 * This method is called for each entry found during a search in the native 313 * data store. 314 * This method will not be called if the search fails. 315 * <p> 316 * Note that the contract for store adapter searches allows the store adapter 317 * to return a superset of entries matching the original search filter. The 318 * results from the store adapter are subsequently filtered by the 319 * PingAuthorize Server. 320 * 321 * @param context The store adapter request context. 322 */ 323 public void postSearchEntry(final StorePostSearchEntryContext context) 324 { 325 // No implementation is required by default. 326 } 327}