Search in sources :

Example 1 with BatchFinder

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;
}
Also used : CollectionResult(com.linkedin.restli.server.CollectionResult) NoMetadata(com.linkedin.restli.server.NoMetadata) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) ArrayList(java.util.ArrayList) Photo(com.linkedin.restli.example.Photo) BatchFinderResult(com.linkedin.restli.server.BatchFinderResult) PhotoCriteria(com.linkedin.restli.example.PhotoCriteria) BatchFinder(com.linkedin.restli.server.annotations.BatchFinder)

Example 2 with BatchFinder

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() + '\'');
    }
}
Also used : ParameterizedType(java.lang.reflect.ParameterizedType) BatchFinder(com.linkedin.restli.server.annotations.BatchFinder) RestMethod(com.linkedin.restli.server.annotations.RestMethod) ResourceMethod(com.linkedin.restli.common.ResourceMethod) Method(java.lang.reflect.Method) BatchFinderResult(com.linkedin.restli.server.BatchFinderResult) ResourceConfigException(com.linkedin.restli.server.ResourceConfigException)

Example 3 with BatchFinder

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);
    }
}
Also used : BatchFinder(com.linkedin.restli.server.annotations.BatchFinder) ResourceConfigException(com.linkedin.restli.server.ResourceConfigException) DataMap(com.linkedin.data.DataMap)

Example 4 with BatchFinder

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;
}
Also used : ArrayList(java.util.ArrayList) BatchFinderResult(com.linkedin.restli.server.BatchFinderResult) ValidationResult(com.linkedin.data.schema.validation.ValidationResult) ValidationDemo(com.linkedin.restli.examples.greetings.api.ValidationDemo) CollectionResult(com.linkedin.restli.server.CollectionResult) Empty(com.linkedin.restli.examples.greetings.api.Empty) ValidationDemoCriteria(com.linkedin.restli.examples.greetings.api.ValidationDemoCriteria) BatchFinder(com.linkedin.restli.server.annotations.BatchFinder)

Example 5 with BatchFinder

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;
}
Also used : ArrayList(java.util.ArrayList) BatchFinderResult(com.linkedin.restli.server.BatchFinderResult) ValidationDemo(com.linkedin.restli.examples.greetings.api.ValidationDemo) CollectionResult(com.linkedin.restli.server.CollectionResult) Empty(com.linkedin.restli.examples.greetings.api.Empty) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) ValidationDemoCriteria(com.linkedin.restli.examples.greetings.api.ValidationDemoCriteria) BatchFinder(com.linkedin.restli.server.annotations.BatchFinder)

Aggregations

BatchFinder (com.linkedin.restli.server.annotations.BatchFinder)9 BatchFinderResult (com.linkedin.restli.server.BatchFinderResult)7 CollectionResult (com.linkedin.restli.server.CollectionResult)6 Empty (com.linkedin.restli.examples.greetings.api.Empty)5 RestLiServiceException (com.linkedin.restli.server.RestLiServiceException)4 ArrayList (java.util.ArrayList)3 DataMap (com.linkedin.data.DataMap)2 Greeting (com.linkedin.restli.examples.greetings.api.Greeting)2 GreetingCriteria (com.linkedin.restli.examples.greetings.api.GreetingCriteria)2 ValidationDemo (com.linkedin.restli.examples.greetings.api.ValidationDemo)2 ValidationDemoCriteria (com.linkedin.restli.examples.greetings.api.ValidationDemoCriteria)2 ResourceConfigException (com.linkedin.restli.server.ResourceConfigException)2 ValidationResult (com.linkedin.data.schema.validation.ValidationResult)1 StringArray (com.linkedin.data.template.StringArray)1 ResourceMethod (com.linkedin.restli.common.ResourceMethod)1 Photo (com.linkedin.restli.example.Photo)1 PhotoCriteria (com.linkedin.restli.example.PhotoCriteria)1 Message (com.linkedin.restli.examples.greetings.api.Message)1 MessageCriteria (com.linkedin.restli.examples.greetings.api.MessageCriteria)1 BatchFinderSchema (com.linkedin.restli.restspec.BatchFinderSchema)1