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