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 2016-2017 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 Broker
146   * shuts down. Any clean-up of this store adapter plugin should be performed
147   * 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 to be updated during a SCIM update operation.
194   *   </LI>
195   *   <LI>
196   *     To fetch an entry from a secondary store adapter for each primary store
197   *     adapter entry obtained during a SCIM search.
198   *   </LI>
199   *   <LI>
200   *     To fetch an entry from the primary store adapter for each secondary
201   *     store adapter entry obtained when a SCIM search filter is processed
202   *     by a secondary store adapter.
203   *   </LI>
204   * </UL>
205   *
206   * @param context The store adapter request context.
207   * @throws ScimException If thrown, the operation will be aborted and a
208   *                       corresponding SCIM ErrorResponse will be returned to
209   *                       the client.
210   */
211  public void preRetrieve(final StorePreRetrieveRequestContext context)
212      throws ScimException
213  {
214    // No implementation is required by default.
215  }
216
217  /**
218   * This method is called after an entry is retrieved from the native data
219   * store.
220   * This method will not be called if the retrieve fails.
221   *
222   * @param context The store adapter request context.
223   * @throws ScimException If thrown, a corresponding SCIM ErrorResponse will be
224   *                       returned to the client.
225   */
226  public void postRetrieve(final StorePostRetrieveRequestContext context)
227      throws ScimException
228  {
229    // No implementation is required by default.
230  }
231
232  /**
233   * This method is called before an entry is updated in the native data
234   * store.
235   *
236   * @param context The store adapter request context.
237   * @throws ScimException If thrown, the operation will be aborted and a
238   *                       corresponding SCIM ErrorResponse will be returned to
239   *                       the client.
240   */
241  public void preUpdate(final StorePreUpdateRequestContext context)
242      throws ScimException
243  {
244    // No implementation is required by default.
245  }
246
247  /**
248   * This method is called after an entry is updated in the native data
249   * store.
250   * This method will not be called if the update fails.
251   *
252   * @param context The store adapter request context.
253   * @throws ScimException If thrown, a corresponding SCIM ErrorResponse will be
254   *                       returned to the client. No attempt is made to roll
255   *                       back the committed update operation.
256   */
257  public void postUpdate(final StorePostUpdateRequestContext context)
258      throws ScimException
259  {
260    // No implementation is required by default.
261  }
262
263  /**
264   * This method is called before an entry is deleted in the native data
265   * store.
266   *
267   * @param context The store adapter request context.
268   * @throws ScimException If thrown, the operation will be aborted and a
269   *                       corresponding SCIM ErrorResponse will be returned to
270   *                       the client.
271   */
272  public void preDelete(final StorePreDeleteRequestContext context)
273      throws ScimException
274  {
275    // No implementation is required by default.
276  }
277
278  /**
279   * This method is called after an entry is deleted in the native data
280   * store.
281   * This method will not be called if the delete fails.
282   *
283   * @param context The store adapter request context.
284   * @throws ScimException If thrown, a corresponding SCIM ErrorResponse will be
285   *                       returned to the client. No attempt is made to roll
286   *                       back the committed delete operation.
287   */
288  public void postDelete(final StorePostDeleteRequestContext context)
289      throws ScimException
290  {
291    // No implementation is required by default.
292  }
293
294  /**
295   * This method is called before searching for entries in the native data
296   * store.
297   *
298   * @param context The store adapter request context.
299   * @throws ScimException If thrown, the operation will be aborted and a
300   *                       corresponding SCIM ErrorResponse will be returned to
301   *                       the client.
302   */
303  public void preSearch(final StorePreSearchRequestContext context)
304      throws ScimException
305  {
306    // No implementation is required by default.
307  }
308
309  /**
310   * This method is called for each entry found during a search in the native
311   * data store.
312   * This method will not be called if the search fails.
313   *
314   * @param context The store adapter request context.
315   */
316  public void postSearchEntry(final StorePostSearchEntryContext context)
317  {
318    // No implementation is required by default.
319  }
320}