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);
}
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;
}
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;
}
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);
}
Aggregations