Search in sources :

Example 1 with InvalidProjectionException

use of com.linkedin.restli.common.util.ProjectionMaskApplier.InvalidProjectionException in project rest.li by linkedin.

the class RestLiValidationFilter method onRequest.

@Override
public CompletableFuture<Void> onRequest(final FilterRequestContext requestContext) {
    // are spotted early
    if (shouldValidateOnResponse(requestContext)) {
        MaskTree projectionMask = requestContext.getProjectionMask();
        if (projectionMask != null) {
            try {
                // Value class from resource model is the only source of truth for record schema.
                // Schema from the record template itself should not be used.
                DataSchema originalSchema = DataTemplateUtil.getSchema(requestContext.getFilterResourceModel().getValueClass());
                DataSchema validatingSchema = constructValidatingSchema(requestContext, originalSchema, projectionMask.getDataMap(), _nonSchemaFieldsToAllowInProjectionMask);
                // Put validating schema in scratchpad for use in onResponse
                requestContext.getFilterScratchpad().put(VALIDATING_SCHEMA_KEY, validatingSchema);
            } catch (InvalidProjectionException e) {
                throw new RestLiServiceException(HttpStatus.S_400_BAD_REQUEST, e.getMessage());
            } catch (TemplateRuntimeException e) {
                throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, TEMPLATE_RUNTIME_EXCEPTION_MESSAGE);
            }
        }
    }
    if (!shouldValidateOnRequest(requestContext)) {
        return CompletableFuture.completedFuture(null);
    }
    Class<?> resourceClass = requestContext.getFilterResourceModel().getResourceClass();
    if (UnstructuredDataUtil.isUnstructuredDataClass(resourceClass)) {
        return CompletableFuture.completedFuture(null);
    }
    ResourceMethod method = requestContext.getMethodType();
    RestLiDataValidator validator = createRequestRestLiDataValidator(requestContext);
    RestLiRequestData requestData = requestContext.getRequestData();
    ValidationResult result;
    switch(method) {
        case CREATE:
        case UPDATE:
            result = validator.validateInput(requestData.getEntity());
            if (!result.isValid()) {
                throw constructRestLiServiceException(result.getMessages(), result.getMessages().toString());
            }
            break;
        case PARTIAL_UPDATE:
            result = validator.validateInput((PatchRequest<?>) requestData.getEntity());
            if (!result.isValid()) {
                throw constructRestLiServiceException(result.getMessages(), result.getMessages().toString());
            }
            break;
        case BATCH_CREATE:
            StringBuilder errorMessage = new StringBuilder();
            Map<String, Collection<Message>> messages = new HashMap<>();
            int index = 0;
            for (RecordTemplate entity : requestData.getBatchEntities()) {
                result = validator.validateInput(entity);
                if (!result.isValid()) {
                    errorMessage.append("Index: ").append(index).append(", ").append(result.getMessages().toString());
                    messages.put(String.valueOf(index), result.getMessages());
                }
                ++index;
            }
            if (errorMessage.length() > 0) {
                throw constructRestLiServiceException(messages, errorMessage.toString());
            }
            break;
        case BATCH_UPDATE:
        case BATCH_PARTIAL_UPDATE:
            ProtocolVersion protocolVersion = requestContext.getRestliProtocolVersion();
            StringBuilder stringBuilder = new StringBuilder();
            Map<String, Collection<Message>> errorMessages = new HashMap<>();
            for (Map.Entry<?, ? extends RecordTemplate> entry : requestData.getBatchKeyEntityMap().entrySet()) {
                if (method == ResourceMethod.BATCH_UPDATE) {
                    result = validator.validateInput(entry.getValue());
                } else {
                    result = validator.validateInput((PatchRequest<?>) entry.getValue());
                }
                if (!result.isValid()) {
                    stringBuilder.append("Key: ").append(entry.getKey()).append(", ").append(result.getMessages().toString());
                    errorMessages.put(URIParamUtils.encodeKeyForBody(entry.getKey(), false, protocolVersion), result.getMessages());
                }
            }
            if (stringBuilder.length() > 0) {
                throw constructRestLiServiceException(errorMessages, stringBuilder.toString());
            }
            break;
        default:
            break;
    }
    return CompletableFuture.completedFuture(null);
}
Also used : InvalidProjectionException(com.linkedin.restli.common.util.ProjectionMaskApplier.InvalidProjectionException) HashMap(java.util.HashMap) ValidationResult(com.linkedin.data.schema.validation.ValidationResult) PatchRequest(com.linkedin.restli.common.PatchRequest) ProtocolVersion(com.linkedin.restli.common.ProtocolVersion) DataSchema(com.linkedin.data.schema.DataSchema) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) MaskTree(com.linkedin.data.transform.filter.request.MaskTree) RestLiDataValidator(com.linkedin.restli.common.validation.RestLiDataValidator) RecordTemplate(com.linkedin.data.template.RecordTemplate) TemplateRuntimeException(com.linkedin.data.template.TemplateRuntimeException) Collection(java.util.Collection) HashMap(java.util.HashMap) DataMap(com.linkedin.data.DataMap) Map(java.util.Map) ResourceMethod(com.linkedin.restli.common.ResourceMethod) RestLiRequestData(com.linkedin.restli.server.RestLiRequestData)

Aggregations

DataMap (com.linkedin.data.DataMap)1 DataSchema (com.linkedin.data.schema.DataSchema)1 ValidationResult (com.linkedin.data.schema.validation.ValidationResult)1 RecordTemplate (com.linkedin.data.template.RecordTemplate)1 TemplateRuntimeException (com.linkedin.data.template.TemplateRuntimeException)1 MaskTree (com.linkedin.data.transform.filter.request.MaskTree)1 PatchRequest (com.linkedin.restli.common.PatchRequest)1 ProtocolVersion (com.linkedin.restli.common.ProtocolVersion)1 ResourceMethod (com.linkedin.restli.common.ResourceMethod)1 InvalidProjectionException (com.linkedin.restli.common.util.ProjectionMaskApplier.InvalidProjectionException)1 RestLiDataValidator (com.linkedin.restli.common.validation.RestLiDataValidator)1 RestLiRequestData (com.linkedin.restli.server.RestLiRequestData)1 RestLiServiceException (com.linkedin.restli.server.RestLiServiceException)1 Collection (java.util.Collection)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1