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 }