001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2012-2015 ForgeRock AS. 015 */ 016 017package org.forgerock.json.resource; 018 019import org.forgerock.services.context.Context; 020import org.forgerock.util.promise.Promise; 021 022/** 023 * Represents the contract with a set of resources. 024 * <p> 025 * The structure and depth of the (potentially nested) resource set it deals 026 * with is up to the implementation. It can choose to just deal with one level, 027 * and hand off to another resource implementation, or it can choose to handle 028 * multiple levels. 029 * <p> 030 * As an example, taking an id of level1/level2/leaf, and assuming that the 031 * resource implementation registers to handle level1 with the router; the 032 * implementation could choose to hand off processing to other implementations 033 * for level2 (or leaf) or it could handle all operations down to leaf. 034 * <p> 035 * Supports either synchronous or asynchronous internal processing, i.e. it does 036 * not have to block the request thread until a response becomes available. 037 * <p> 038 * For synchronous internal processing, immediately return a completed 039 * {@code Promise}, e.g. 040 * 041 * <pre> 042 * return Promises.newResultPromise(result); 043 * </pre> 044 * 045 * <p> 046 * <b>NOTE:</b> field filtering alters the structure of a JSON resource and MUST 047 * only be performed once while processing a request. It is therefore the 048 * responsibility of front-end implementations (e.g. HTTP listeners, Servlets, 049 * etc) to perform field filtering. Request handler and resource provider 050 * implementations SHOULD NOT filter fields, but MAY choose to optimise their 051 * processing in order to return a resource containing only the fields targeted 052 * by the field filters. 053 */ 054public interface RequestHandler { 055 056 /** 057 * Handles performing an action on a resource, and optionally returns an 058 * associated result. The execution of an action is allowed to incur side 059 * effects. 060 * <p> 061 * Actions are parametric; a set of named parameters is provided as input to 062 * the action. The action result is a JSON object structure composed of 063 * basic Java types; its overall structure is defined by a specific 064 * implementation. 065 * <p> 066 * On completion, the action result (or null) must be used to complete the 067 * returned {@code Promise}. On failure, the returned {@code Promise} must 068 * be completed with the exception. 069 * <p> 070 * Action expects failure exceptions as follows: {@code ForbiddenException} 071 * if access to the resource is forbidden. {@code NotSupportedException} if 072 * the requested functionality is not implemented/supported 073 * {@code BadRequestException} if the passed identifier, parameters or 074 * filter is invalid {@code NotFoundException} if the specified resource 075 * could not be found. 076 * 077 * @param context 078 * The request server context, such as associated principal. 079 * @param request 080 * The action request. 081 * @return A {@code Promise} containing the result of the operation. 082 */ 083 Promise<ActionResponse, ResourceException> handleAction(Context context, ActionRequest request); 084 085 /** 086 * Adds a new JSON resource, returning a {@code Promise} that will be 087 * completed when the resource has been added. 088 * <p> 089 * Create expects failure exceptions as follows: 090 * <ul> 091 * <li>{@code ForbiddenException} if access to the resource is forbidden. 092 * <li>{@code NotSupportedException} if the requested functionality is not 093 * implemented/supported 094 * <li>{@code PreconditionFailedException} if a resource with the same ID 095 * already exists 096 * <li>{@code BadRequestException} if the passed identifier or value is 097 * invalid 098 * <li>{@code NotFoundException} if the specified id could not be resolved, 099 * 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}