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 }