View Javadoc
1   /*
2    * The contents of this file are subject to the terms of the Common Development and
3    * Distribution License (the License). You may not use this file except in compliance with the
4    * License.
5    *
6    * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
7    * specific language governing permission and limitations under the License.
8    *
9    * When distributing Covered Software, include this CDDL Header Notice in each file and include
10   * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
11   * Header, with the fields enclosed by brackets [] replaced by your own identifying
12   * information: "Portions Copyright [year] [name of copyright owner]".
13   *
14   * Copyright 2012-2015 ForgeRock AS.
15   */
16  
17  package org.forgerock.json.resource;
18  
19  import org.forgerock.services.context.Context;
20  import org.forgerock.util.promise.Promise;
21  
22  /**
23   * Represents the contract with a set of resources.
24   * <p>
25   * The structure and depth of the (potentially nested) resource set it deals
26   * with is up to the implementation. It can choose to just deal with one level,
27   * and hand off to another resource implementation, or it can choose to handle
28   * multiple levels.
29   * <p>
30   * As an example, taking an id of level1/level2/leaf, and assuming that the
31   * resource implementation registers to handle level1 with the router; the
32   * implementation could choose to hand off processing to other implementations
33   * for level2 (or leaf) or it could handle all operations down to leaf.
34   * <p>
35   * Supports either synchronous or asynchronous internal processing, i.e. it does
36   * not have to block the request thread until a response becomes available.
37   * <p>
38   * For synchronous internal processing, immediately return a completed
39   * {@code Promise}, e.g.
40   *
41   * <pre>
42   * return Promises.newResultPromise(result);
43   * </pre>
44   *
45   * <p>
46   * <b>NOTE:</b> field filtering alters the structure of a JSON resource and MUST
47   * only be performed once while processing a request. It is therefore the
48   * responsibility of front-end implementations (e.g. HTTP listeners, Servlets,
49   * etc) to perform field filtering. Request handler and resource provider
50   * implementations SHOULD NOT filter fields, but MAY choose to optimise their
51   * processing in order to return a resource containing only the fields targeted
52   * by the field filters.
53   */
54  public interface RequestHandler {
55  
56      /**
57       * Handles performing an action on a resource, and optionally returns an
58       * associated result. The execution of an action is allowed to incur side
59       * effects.
60       * <p>
61       * Actions are parametric; a set of named parameters is provided as input to
62       * the action. The action result is a JSON object structure composed of
63       * basic Java types; its overall structure is defined by a specific
64       * implementation.
65       * <p>
66       * On completion, the action result (or null) must be used to complete the
67       * returned {@code Promise}. On failure, the returned {@code Promise} must
68       * be completed with the exception.
69       * <p>
70       * Action expects failure exceptions as follows: {@code ForbiddenException}
71       * if access to the resource is forbidden. {@code NotSupportedException} if
72       * the requested functionality is not implemented/supported
73       * {@code BadRequestException} if the passed identifier, parameters or
74       * filter is invalid {@code NotFoundException} if the specified resource
75       * could not be found.
76       *
77       * @param context
78       *            The request server context, such as associated principal.
79       * @param request
80       *            The action request.
81       * @return A {@code Promise} containing the result of the operation.
82       */
83      Promise<ActionResponse, ResourceException> handleAction(Context context, ActionRequest request);
84  
85      /**
86       * Adds a new JSON resource, returning a {@code Promise} that will be
87       * completed when the resource has been added.
88       * <p>
89       * Create expects failure exceptions as follows:
90       * <ul>
91       * <li>{@code ForbiddenException} if access to the resource is forbidden.
92       * <li>{@code NotSupportedException} if the requested functionality is not
93       * implemented/supported
94       * <li>{@code PreconditionFailedException} if a resource with the same ID
95       * already exists
96       * <li>{@code BadRequestException} if the passed identifier or value is
97       * invalid
98       * <li>{@code NotFoundException} if the specified id could not be resolved,
99       * for example when an intermediate resource in the hierarchy does not
100      * exist.
101      * </ul>
102      *
103      * @param context
104      *            The request server context, such as associated principal.
105      * @param request
106      *            The create request.
107      * @return A {@code Promise} containing the result of the operation.
108      */
109     Promise<ResourceResponse, ResourceException> handleCreate(Context context, CreateRequest request);
110 
111     /**
112      * Deletes a JSON resource, returning a {@code Promise} that will be
113      * completed when the resource has been deleted.
114      * <p>
115      * Delete expects failure exceptions as follows:
116      * <ul>
117      * <li>{@code ForbiddenException} if access to the resource is forbidden
118      * <li>{@code NotSupportedException} if the requested functionality is not
119      * implemented/supported
120      * <li>{@code BadRequestException} if the passed identifier is invalid
121      * <li>{@code NotFoundException} if the specified resource could not be
122      * found
123      * <li>{@code PreconditionRequiredException} if version is required, but is
124      * {@code null}
125      * <li>{@code PreconditionFailedException} if version did not match the
126      * existing resource.
127      * </ul>
128      *
129      * @param context
130      *            The request server context, such as associated principal.
131      * @param request
132      *            The delete request.
133      * @return A {@code Promise} containing the result of the operation.
134      */
135     Promise<ResourceResponse, ResourceException> handleDelete(Context context, DeleteRequest request);
136 
137     /**
138      * Updates a JSON resource by applying a set of changes to its existing
139      * content, returning a {@code Promise} that will be completed when the
140      * resource has been updated.
141      * <p>
142      * Patch expects failure exceptions as follows:
143      * <ul>
144      * <li>{@code ForbiddenException} if access to the resource is forbidden
145      * <li>{@code NotSupportedException} if the requested functionality is not
146      * implemented/supported
147      * <li>{@code PreconditionRequiredException} if version is required, but is
148      * {@code null}
149      * <li>{@code PreconditionFailedException} if version did not match the
150      * existing resource
151      * <li>{@code BadRequestException} if the passed identifier or filter is
152      * invalid
153      * <li>{@code NotFoundException} if the specified resource could not be
154      * found
155      * <li>{@code ConflictException} if patch could not be applied for the given
156      * resource state.
157      * </ul>
158      *
159      * @param context
160      *            The request server context, such as associated principal.
161      * @param request
162      *            The patch request.
163      * @return A {@code Promise} containing the result of the operation.
164      */
165     Promise<ResourceResponse, ResourceException> handlePatch(Context context, PatchRequest request);
166 
167     /**
168      * Searches for all JSON resources matching a user specified set of
169      * criteria, returning a {@code Promise} that will be completed when the
170      * search has completed.
171      * <p>
172      * Implementations must invoke
173      * {@link QueryResourceHandler#handleResource(ResourceResponse)} for each resource
174      * which matches the query criteria. Once all matching resources have been
175      * returned implementations are required to return either a
176      * {@link QueryResponse} if the query has completed successfully, or
177      * {@link ResourceException} if the query did not complete successfully
178      * (even if some matching resources were returned).
179      * <p>
180      * Query expects failure exceptions as follows:
181      * <ul>
182      * <li>{@code ForbiddenException} if access to the resource is forbidden
183      * <li>{@code NotSupportedException} if the requested functionality is not
184      * implemented/supported
185      * <li>{@code BadRequestException} if the passed identifier, parameters or
186      * filter is invalid
187      * <li>{@code NotFoundException} if the specified resource could not be
188      * found
189      * </ul>
190      *
191      * @param context
192      *            The request server context, such as associated principal.
193      * @param request
194      *            The query request.
195      * @param handler
196      *            The query resource handler to be notified for each matching
197      *            resource.
198      * @return A {@code Promise} containing the result of the operation.
199      */
200     Promise<QueryResponse, ResourceException> handleQuery(Context context, QueryRequest request,
201             QueryResourceHandler handler);
202 
203     /**
204      * Reads a JSON resource, returning a {@code Promise} that will be
205      * completed when the resource has been read.
206      * <p>
207      * Read expects failure exceptions as follows:
208      * <ul>
209      * <li>{@code ForbiddenException} if access to the resource is forbidden.
210      * <li>{@code NotSupportedException} if the requested functionality is not
211      * implemented/supported
212      * <li>{@code BadRequestException} if the passed identifier or filter is
213      * invalid
214      * <li>{@code NotFoundException} if the specified resource could not be
215      * found.
216      * </ul>
217      *
218      * @param context
219      *            The request server context, such as associated principal.
220      * @param request
221      *            The read request.
222      * @return A {@code Promise} containing the result of the operation.
223      */
224     Promise<ResourceResponse, ResourceException> handleRead(Context context, ReadRequest request);
225 
226     /**
227      * Updates a JSON resource by replacing its existing content with new
228      * content, returning a {@code Promise} that will be completed when the
229      * resource has been updated.
230      * <p>
231      * Update expects failure the following failure exceptions:
232      * <ul>
233      * <li>{@code ForbiddenException} if access to the resource is forbidden
234      * <li>{@code NotSupportedException} if the requested functionality is not
235      * implemented/supported
236      * <li>{@code PreconditionRequiredException} if version is required, but is
237      * {@code null}
238      * <li>{@code PreconditionFailedException} if version did not match the
239      * existing resource
240      * <li>{@code BadRequestException} if the passed identifier or filter is
241      * invalid
242      * <li>{@code NotFoundException} if the specified resource could not be
243      * found.
244      * </ul>
245      *
246      * @param context
247      *            The request server context, such as associated principal.
248      * @param request
249      *            The update request.
250      * @return A {@code Promise} containing the result of the operation.
251      */
252     Promise<ResourceResponse, ResourceException> handleUpdate(Context context, UpdateRequest request);
253 }