use of com.linkedin.restli.server.annotations.BatchFinder in project rest.li by linkedin.
the class PhotoResource method searchPhotos.
@BatchFinder(value = "searchPhotos", batchParam = "criteria")
public BatchFinderResult<PhotoCriteria, Photo, NoMetadata> searchPhotos(@PagingContextParam PagingContext pagingContext, @QueryParam("criteria") PhotoCriteria[] criteria, @QueryParam("exif") @Optional EXIF exif) {
BatchFinderResult<PhotoCriteria, Photo, NoMetadata> batchFinderResult = new BatchFinderResult<>();
for (PhotoCriteria currentCriteria : criteria) {
if (currentCriteria.getTitle() != null) {
// on success
final List<Photo> photos = new ArrayList<>();
int index = 0;
final int begin = pagingContext.getStart();
final int end = begin + pagingContext.getCount();
final Collection<Photo> dbPhotos = _db.getData().values();
for (Photo p : dbPhotos) {
if (index == end) {
break;
} else if (index >= begin) {
if (p.getTitle().equalsIgnoreCase(currentCriteria.getTitle())) {
if (currentCriteria.getFormat() == null || currentCriteria.getFormat() == p.getFormat()) {
photos.add(p);
}
}
}
index++;
}
CollectionResult<Photo, NoMetadata> cr = new CollectionResult<>(photos, photos.size());
batchFinderResult.putResult(currentCriteria, cr);
} else {
// on error: to construct error response for test
batchFinderResult.putError(currentCriteria, new RestLiServiceException(HttpStatus.S_404_NOT_FOUND, "Failed to find Photo!"));
}
}
return batchFinderResult;
}
use of com.linkedin.restli.server.annotations.BatchFinder in project rest.li by linkedin.
the class RestLiAnnotationReader method validateBatchFinderMethod.
private static void validateBatchFinderMethod(final ResourceMethodDescriptor batchFinderMethodDescriptor, final ResourceModel resourceModel) {
Method method = batchFinderMethodDescriptor.getMethod();
BatchFinder finderAnno = batchFinderMethodDescriptor.getMethod().getAnnotation(BatchFinder.class);
if (finderAnno.batchParam().length() == 0) {
throw new ResourceConfigException("The batchParam annotation is required and can't be empty" + " on the @BatchFinder method '" + method.getName() + "' on class '" + resourceModel.getResourceClass().getName());
}
if (batchFinderMethodDescriptor.getBatchFinderCriteriaParamIndex() == BATCH_FINDER_MISSING_PARAMETER_INDEX) {
throw new ResourceConfigException("The batchParam annotation doesn't match any parameter name" + " on the @BatchFinder method '" + method.getName() + "' on class '" + resourceModel.getResourceClass().getName());
}
Parameter<?> batchParam = batchFinderMethodDescriptor.getParameter(finderAnno.batchParam());
if (!batchParam.isArray() || !DataTemplate.class.isAssignableFrom(batchParam.getItemType())) {
throw new ResourceConfigException("The batchParam '" + finderAnno.batchParam() + "' on the @BatchFinder method '" + method.getName() + "' on class '" + resourceModel.getResourceClass().getName() + "' must be a array of RecordTemplate");
}
Class<?> valueClass = resourceModel.getValueClass();
Class<?> returnType, elementType, criteriaType, metadataType;
try {
returnType = getLogicalReturnClass(method);
final List<Class<?>> typeArguments;
if (!BatchFinderResult.class.isAssignableFrom(returnType)) {
throw new ResourceConfigException("@BatchFinder method '" + method.getName() + "' on class '" + resourceModel.getResourceClass().getName() + "' has an unsupported return type");
}
final ParameterizedType collectionType = (ParameterizedType) getLogicalReturnType(method);
criteriaType = (Class<?>) collectionType.getActualTypeArguments()[0];
elementType = (Class<?>) collectionType.getActualTypeArguments()[1];
metadataType = (Class<?>) collectionType.getActualTypeArguments()[2];
} catch (ClassCastException e) {
throw new ResourceConfigException("@BatchFinder method '" + method.getName() + "' on class '" + resourceModel.getResourceClass().getName() + "' has an invalid return or a data template type", e);
}
if (!RecordTemplate.class.isAssignableFrom(elementType) || !valueClass.equals(elementType)) {
String collectionClassName = returnType.getSimpleName();
throw new ResourceConfigException("@BatchFinder method '" + method.getName() + "' on class '" + resourceModel.getResourceClass().getName() + "' has an invalid return type. Expected " + collectionClassName + "<" + valueClass.getName() + ">, but found " + collectionClassName + "<" + elementType + '>');
}
if (!RecordTemplate.class.isAssignableFrom(metadataType) || !RecordTemplate.class.isAssignableFrom(criteriaType)) {
String collectionClassName = returnType.getSimpleName();
throw new ResourceConfigException("@BatchFinder method '" + method.getName() + "' on class '" + resourceModel.getResourceClass().getName() + "' has an invalid return type. The criteria and the metadata parameterized types " + "must be a RecordTemplate");
}
ResourceMethodDescriptor existingBatchFinder = resourceModel.findBatchFinderMethod(batchFinderMethodDescriptor.getBatchFinderName());
if (existingBatchFinder != null) {
throw new ResourceConfigException("Found duplicate @BatchFinder method named '" + batchFinderMethodDescriptor.getFinderName() + "' on class '" + resourceModel.getResourceClass().getName() + '\'');
}
}
use of com.linkedin.restli.server.annotations.BatchFinder in project rest.li by linkedin.
the class RestLiAnnotationReader method addBatchFinderResourceMethod.
private static void addBatchFinderResourceMethod(final ResourceModel model, final Method method) {
BatchFinder finderAnno = method.getAnnotation(BatchFinder.class);
if (finderAnno == null) {
return;
}
String queryType = finderAnno.value();
if (queryType != null) {
if (!Modifier.isPublic(method.getModifiers())) {
throw new ResourceConfigException(String.format("Resource '%s' contains non-public batch finder method '%s'.", model.getName(), method.getName()));
}
List<Parameter<?>> queryParameters = getParameters(model, method, ResourceMethod.BATCH_FINDER);
Class<? extends RecordTemplate> metadataType = getCustomCollectionMetadata(method, BATCH_FINDER_METADATA_PARAMETER_INDEX);
DataMap annotationsMap = ResourceModelAnnotation.getAnnotationsMap(method.getAnnotations());
addDeprecatedAnnotation(annotationsMap, method);
Integer criteriaIndex = getCriteriaParametersIndex(finderAnno, queryParameters);
ResourceMethodDescriptor batchFinderMethodDescriptor = ResourceMethodDescriptor.createForBatchFinder(method, queryParameters, queryType, criteriaIndex, metadataType, getInterfaceType(method), annotationsMap);
validateBatchFinderMethod(batchFinderMethodDescriptor, model);
addServiceErrors(batchFinderMethodDescriptor, method);
addSuccessStatuses(batchFinderMethodDescriptor, method);
addMaxBatchSize(batchFinderMethodDescriptor, method, ResourceMethod.BATCH_FINDER);
model.addResourceMethodDescriptor(batchFinderMethodDescriptor);
}
}
use of com.linkedin.restli.server.annotations.BatchFinder in project rest.li by linkedin.
the class ValidationDemoResource method searchValidationDemos.
@BatchFinder(value = "searchValidationDemos", batchParam = "criteria")
public BatchFinderResult<ValidationDemoCriteria, ValidationDemo, Empty> searchValidationDemos(@PagingContextParam PagingContext context, @QueryParam("criteria") ValidationDemoCriteria[] criteria, @ValidatorParam RestLiDataValidator validator) {
BatchFinderResult<ValidationDemoCriteria, ValidationDemo, Empty> batchFinderResult = new BatchFinderResult<>();
for (ValidationDemoCriteria currentCriteria : criteria) {
List<ValidationDemo> validationDemos = new ArrayList<>();
// Generate entities that are missing stringB fields
for (int i = 0; i < 3; i++) {
ValidationDemo.UnionFieldWithInlineRecord union = new ValidationDemo.UnionFieldWithInlineRecord();
union.setMyEnum(myEnum.FOOFOO);
validationDemos.add(new ValidationDemo().setStringA("valueA").setIntA(currentCriteria.getIntA()).setUnionFieldWithInlineRecord(union));
}
// Validate outgoing data
for (ValidationDemo entity : validationDemos) {
ValidationResult result = validator.validateOutput(entity);
check(!result.isValid());
check(result.getMessages().toString().contains("/stringB :: field is required but not found"));
}
// Fix entities
for (ValidationDemo validationDemo : validationDemos) {
validationDemo.setStringB("valueB");
}
// Validate again
for (ValidationDemo entity : validationDemos) {
ValidationResult result = validator.validateOutput(entity);
check(result.isValid());
}
CollectionResult<ValidationDemo, Empty> cr = new CollectionResult<>(validationDemos, validationDemos.size());
batchFinderResult.putResult(currentCriteria, cr);
}
return batchFinderResult;
}
use of com.linkedin.restli.server.annotations.BatchFinder in project rest.li by linkedin.
the class AutomaticValidationDemoResource method searchValidationDemos.
@BatchFinder(value = "searchValidationDemos", batchParam = "criteria")
public BatchFinderResult<ValidationDemoCriteria, ValidationDemo, Empty> searchValidationDemos(@PagingContextParam PagingContext context, @QueryParam("criteria") ValidationDemoCriteria[] criteria) {
BatchFinderResult<ValidationDemoCriteria, ValidationDemo, Empty> batchFinderResult = new BatchFinderResult<>();
for (ValidationDemoCriteria currentCriteria : criteria) {
List<ValidationDemo> validationDemos = new ArrayList<>();
if (currentCriteria.getIntA() == 1111) {
// Generate entities that are missing stringB fields
for (int i = 0; i < 3; i++) {
ValidationDemo.UnionFieldWithInlineRecord union = new ValidationDemo.UnionFieldWithInlineRecord();
union.setMyEnum(myEnum.FOOFOO);
validationDemos.add(new ValidationDemo().setStringA("valueA").setIntA(currentCriteria.getIntA()).setUnionFieldWithInlineRecord(union));
}
} else if (currentCriteria.getIntA() == 2222) {
// Generate entities that their stringA field has a value over the length limitation
for (int i = 0; i < 3; i++) {
ValidationDemo.UnionFieldWithInlineRecord union = new ValidationDemo.UnionFieldWithInlineRecord();
union.setMyEnum(myEnum.FOOFOO);
validationDemos.add(new ValidationDemo().setStringA("longLengthValueA").setIntA(currentCriteria.getIntA()).setStringB("valueB").setUnionFieldWithInlineRecord(union));
}
} else if (currentCriteria.getIntA() == 3333) {
// the stringA field has a value over the length limitation and miss stringB fields
for (int i = 0; i < 3; i++) {
ValidationDemo.UnionFieldWithInlineRecord union = new ValidationDemo.UnionFieldWithInlineRecord();
union.setMyEnum(myEnum.FOOFOO);
validationDemos.add(new ValidationDemo().setStringA("longLengthValueA").setIntA(currentCriteria.getIntA()).setUnionFieldWithInlineRecord(union));
}
} else if (currentCriteria.getIntA() == 4444) {
// entities without errors
for (int i = 0; i < 3; i++) {
ValidationDemo.UnionFieldWithInlineRecord union = new ValidationDemo.UnionFieldWithInlineRecord();
union.setMyEnum(myEnum.FOOFOO);
validationDemos.add(new ValidationDemo().setStringA("valueA").setIntA(currentCriteria.getIntA()).setStringB("valueB").setUnionFieldWithInlineRecord(union));
}
} else {
// on errorResponse
batchFinderResult.putError(currentCriteria, new RestLiServiceException(HttpStatus.S_404_NOT_FOUND, "Fail to find Validation Demo!"));
continue;
}
CollectionResult<ValidationDemo, Empty> cr = new CollectionResult<>(validationDemos, validationDemos.size());
batchFinderResult.putResult(currentCriteria, cr);
}
return batchFinderResult;
}
Aggregations