Search in sources :

Example 1 with ParamError

use of com.linkedin.restli.server.annotations.ParamError in project rest.li by linkedin.

the class AlbumEntryResource method update.

/**
 * Add the specified photo to the specified album.
 * If a matching pair of IDs already exists, this changes the add date.
 */
@Override
@SuccessResponse(statuses = { HttpStatus.S_204_NO_CONTENT })
@ServiceErrors(INVALID_PERMISSIONS)
@ParamError(code = INVALID_ID, parameterNames = { "albumEntryId" })
public UpdateResponse update(CompoundKey key, AlbumEntry entity) {
    long photoId = (Long) key.getPart("photoId");
    long albumId = (Long) key.getPart("albumId");
    // make sure photo and album exist
    if (!_photoDb.getData().containsKey(photoId))
        throw new RestLiServiceException(HttpStatus.S_400_BAD_REQUEST, "Nonexistent photo ID: " + photoId);
    if (!_albumDb.getData().containsKey(albumId))
        throw new RestLiServiceException(HttpStatus.S_400_BAD_REQUEST, "Nonexistent album ID: " + albumId);
    // disallow changing entity ID
    if (entity.hasAlbumId() || entity.hasPhotoId())
        throw new RestLiServiceException(HttpStatus.S_400_BAD_REQUEST, "Photo/album ID are not acceptable in request");
    // make sure the ID in the entity is consistent with the key in the database
    entity.setPhotoId(photoId);
    entity.setAlbumId(albumId);
    _db.getData().put(key, entity);
    return new UpdateResponse(HttpStatus.S_204_NO_CONTENT);
}
Also used : UpdateResponse(com.linkedin.restli.server.UpdateResponse) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) SuccessResponse(com.linkedin.restli.server.annotations.SuccessResponse) ServiceErrors(com.linkedin.restli.server.annotations.ServiceErrors) ParamError(com.linkedin.restli.server.annotations.ParamError)

Example 2 with ParamError

use of com.linkedin.restli.server.annotations.ParamError in project rest.li by linkedin.

the class RestLiAnnotationReader method buildServiceErrorParameters.

/**
 * Given an array of {@link ParamError} annotations, build a mapping from service error code to parameter names.
 * Uses the resource class and method to construct exception messages.
 *
 * @param paramErrorAnnotations parameter error annotations
 * @param resourceClass resource class
 * @param method resource method
 * @return mapping from service error code to parameter names
 */
private static LinkedHashMap<String, String[]> buildServiceErrorParameters(final ParamError[] paramErrorAnnotations, final Class<?> resourceClass, final Method method) {
    // Create a mapping of service error codes to their parameters (if any)
    final LinkedHashMap<String, String[]> paramsMapping = new LinkedHashMap<>();
    if (paramErrorAnnotations != null) {
        for (ParamError paramErrorAnnotation : paramErrorAnnotations) {
            final String serviceErrorCode = paramErrorAnnotation.code();
            // Check for redundant parameter error annotations
            if (paramsMapping.containsKey(serviceErrorCode)) {
                throw new ResourceConfigException(String.format("Redundant @%s annotations for service error code '%s' used in %s", ParamError.class.getSimpleName(), serviceErrorCode, buildExceptionLocationString(resourceClass, method)));
            }
            final String[] parameterNames = paramErrorAnnotation.parameterNames();
            // Ensure the parameter names array is non-empty
            if (parameterNames.length == 0) {
                throw new ResourceConfigException(String.format("@%s annotation on %s specifies no parameter names for service error code '%s'", ParamError.class.getSimpleName(), buildExceptionLocationString(resourceClass, method), serviceErrorCode));
            }
            // Ensure that there are no duplicate parameter names
            if (parameterNames.length != new HashSet<>(Arrays.asList(parameterNames)).size()) {
                throw new ResourceConfigException(String.format("Duplicate parameter specified for service error code '%s' in %s", serviceErrorCode, buildExceptionLocationString(resourceClass, method)));
            }
            paramsMapping.put(serviceErrorCode, paramErrorAnnotation.parameterNames());
        }
    }
    return paramsMapping;
}
Also used : ResourceConfigException(com.linkedin.restli.server.ResourceConfigException) ParamError(com.linkedin.restli.server.annotations.ParamError) LinkedHashMap(java.util.LinkedHashMap) HashSet(java.util.HashSet)

Example 3 with ParamError

use of com.linkedin.restli.server.annotations.ParamError in project rest.li by linkedin.

the class AlbumEntryResource method search.

/**
 * Find all entries matching the given album and photo IDs. <code>null</code> is treated
 * as a wildcard.
 *
 * @param albumId provides the id to match for albums to match, if not provided, it is treated as a wildcard
 * @param photoId provides the id to match for photos to match, if not provided, it is treated as a wildcard
 * @return a list of {@link AlbumEntry} matching the  given parameters
 */
@Finder("search")
@SuccessResponse(statuses = { HttpStatus.S_200_OK })
@ParamError(code = INVALID_ID, parameterNames = { "albumId", "photoId" })
@ParamError(code = UNSEARCHABLE_ALBUM_ID, parameterNames = { "albumId" })
public List<AlbumEntry> search(@Optional @QueryParam("albumId") Long albumId, @Optional @QueryParam("photoId") Long photoId) {
    List<AlbumEntry> result = new ArrayList<>();
    for (Map.Entry<CompoundKey, AlbumEntry> entry : _db.getData().entrySet()) {
        CompoundKey key = entry.getKey();
        // (treat all values as a match)
        if (albumId != null && !key.getPart("albumId").equals(albumId))
            continue;
        if (photoId != null && !key.getPart("photoId").equals(photoId))
            continue;
        result.add(entry.getValue());
    }
    return result;
}
Also used : AlbumEntry(com.linkedin.restli.example.AlbumEntry) CompoundKey(com.linkedin.restli.common.CompoundKey) ArrayList(java.util.ArrayList) HashMap(java.util.HashMap) Map(java.util.Map) SuccessResponse(com.linkedin.restli.server.annotations.SuccessResponse) Finder(com.linkedin.restli.server.annotations.Finder) ParamError(com.linkedin.restli.server.annotations.ParamError)

Example 4 with ParamError

use of com.linkedin.restli.server.annotations.ParamError in project rest.li by linkedin.

the class RestLiAnnotationReader method addServiceErrors.

/**
 * Reads annotations on a given method in order to build service errors, which are then added to
 * a given resource method descriptor.
 *
 * @param resourceMethodDescriptor resource method descriptor to add service errors to
 * @param method method annotated with service errors
 */
private static void addServiceErrors(final ResourceMethodDescriptor resourceMethodDescriptor, final Method method) {
    final Class<?> resourceClass = method.getDeclaringClass();
    final ServiceErrorDef serviceErrorDefAnnotation = resourceClass.getAnnotation(ServiceErrorDef.class);
    final ServiceErrors serviceErrorsAnnotation = method.getAnnotation(ServiceErrors.class);
    final ParamError[] paramErrorAnnotations = method.getAnnotationsByType(ParamError.class);
    final List<ServiceError> serviceErrors = buildServiceErrors(serviceErrorDefAnnotation, serviceErrorsAnnotation, paramErrorAnnotations, resourceClass, method);
    if (serviceErrors == null) {
        return;
    }
    // Form a set of parameter names which exist on this method
    final Set<String> acceptableParameterNames = resourceMethodDescriptor.getParameters().stream().map(Parameter::getName).collect(Collectors.toSet());
    // Validate that all parameter names are valid
    for (ServiceError serviceError : serviceErrors) {
        if (serviceError instanceof ParametersServiceError) {
            final String[] parameterNames = ((ParametersServiceError) serviceError).parameterNames();
            if (parameterNames != null) {
                for (String parameterName : parameterNames) {
                    if (!acceptableParameterNames.contains(parameterName)) {
                        throw new ResourceConfigException(String.format("Nonexistent parameter '%s' specified for method-level service error '%s' in %s (valid parameters: %s)", parameterName, serviceError.code(), buildExceptionLocationString(resourceClass, method), acceptableParameterNames.toString()));
                    }
                }
            }
        }
    }
    resourceMethodDescriptor.setServiceErrors(serviceErrors);
}
Also used : ParametersServiceError(com.linkedin.restli.server.errors.ParametersServiceError) ServiceErrorDef(com.linkedin.restli.server.annotations.ServiceErrorDef) ParametersServiceError(com.linkedin.restli.server.errors.ParametersServiceError) ServiceError(com.linkedin.restli.server.errors.ServiceError) ServiceErrors(com.linkedin.restli.server.annotations.ServiceErrors) ResourceConfigException(com.linkedin.restli.server.ResourceConfigException) ParamError(com.linkedin.restli.server.annotations.ParamError)

Aggregations

ParamError (com.linkedin.restli.server.annotations.ParamError)4 ResourceConfigException (com.linkedin.restli.server.ResourceConfigException)2 ServiceErrors (com.linkedin.restli.server.annotations.ServiceErrors)2 SuccessResponse (com.linkedin.restli.server.annotations.SuccessResponse)2 CompoundKey (com.linkedin.restli.common.CompoundKey)1 AlbumEntry (com.linkedin.restli.example.AlbumEntry)1 RestLiServiceException (com.linkedin.restli.server.RestLiServiceException)1 UpdateResponse (com.linkedin.restli.server.UpdateResponse)1 Finder (com.linkedin.restli.server.annotations.Finder)1 ServiceErrorDef (com.linkedin.restli.server.annotations.ServiceErrorDef)1 ParametersServiceError (com.linkedin.restli.server.errors.ParametersServiceError)1 ServiceError (com.linkedin.restli.server.errors.ServiceError)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1