use of com.linkedin.restli.common.ResourceMethod in project rest.li by linkedin.
the class TestFilterRequestContextInternalImpl method testFilterRequestContextAdapter.
@Test
@SuppressWarnings("unchecked")
public void testFilterRequestContextAdapter() throws Exception {
final String resourceName = "resourceName";
final String resourceNamespace = "resourceNamespace";
final ResourceMethod methodType = ResourceMethod.GET;
final DataMap customAnnotations = new DataMap();
customAnnotations.put("foo", "Bar");
final ProjectionMode projectionMode = ProjectionMode.AUTOMATIC;
final MaskTree maskTree = new MaskTree();
final MaskTree metadataMaskTree = new MaskTree();
final MaskTree pagingMaskTree = new MaskTree();
final MutablePathKeys pathKeys = new PathKeysImpl();
final Map<String, String> requestHeaders = new HashMap<>();
requestHeaders.put("Key1", "Value1");
final URI requestUri = new URI("foo.bar.com");
final ProtocolVersion protoVersion = AllProtocolVersions.BASELINE_PROTOCOL_VERSION;
final DataMap queryParams = new DataMap();
queryParams.put("Param1", "Val1");
final Map<String, Object> localAttrs = new HashMap<>();
localAttrs.put("Key1", "Val1");
final RequestContext r2RequestContext = new RequestContext();
r2RequestContext.putLocalAttr("Key1", "Val1");
final String finderName = UUID.randomUUID().toString();
final String batchFinderName = UUID.randomUUID().toString();
final String actionName = UUID.randomUUID().toString();
final List<ServiceError> methodServiceErrors = Collections.singletonList(TestServiceError.METHOD_LEVEL_ERROR);
final List<ServiceError> resourceServiceErrors = Collections.singletonList(TestServiceError.RESOURCE_LEVEL_ERROR);
final List<Parameter<?>> methodParameters = Collections.singletonList(Mockito.mock(Parameter.class));
when(resourceModel.getName()).thenReturn(resourceName);
when(resourceModel.getNamespace()).thenReturn(resourceNamespace);
when(filterResourceModel.getServiceErrors()).thenReturn(resourceServiceErrors);
when(resourceMethod.getResourceModel()).thenReturn(resourceModel);
when(resourceMethod.getMethodType()).thenReturn(methodType);
when(resourceMethod.getFinderName()).thenReturn(finderName);
when(resourceMethod.getBatchFinderName()).thenReturn(batchFinderName);
when(resourceMethod.getActionName()).thenReturn(actionName);
when(resourceMethod.getCustomAnnotationData()).thenReturn(customAnnotations);
when(resourceMethod.getMethod()).thenReturn(null);
when(resourceMethod.getParameters()).thenReturn(methodParameters);
when(resourceMethod.getServiceErrors()).thenReturn(methodServiceErrors);
when(context.getProjectionMode()).thenReturn(projectionMode);
when(context.getProjectionMask()).thenReturn(maskTree);
when(context.getMetadataProjectionMask()).thenReturn(metadataMaskTree);
when(context.getPagingProjectionMask()).thenReturn(pagingMaskTree);
when(context.getPathKeys()).thenReturn(pathKeys);
when(context.getRequestHeaders()).thenReturn(requestHeaders);
when(context.getRequestURI()).thenReturn(requestUri);
when(context.getRestliProtocolVersion()).thenReturn(protoVersion);
when(context.getParameters()).thenReturn(queryParams);
when(context.getRawRequestContext()).thenReturn(r2RequestContext);
FilterRequestContext filterContext = new FilterRequestContextInternalImpl(context, resourceMethod, null);
filterContext.setProjectionMask(maskTree);
filterContext.setMetadataProjectionMask(metadataMaskTree);
filterContext.setPagingProjectionMask(pagingMaskTree);
assertEquals(filterContext.getFilterResourceModel().getResourceName(), resourceName);
assertEquals(filterContext.getFilterResourceModel().getResourceNamespace(), resourceNamespace);
assertEquals(filterContext.getMethodType(), methodType);
assertEquals(filterContext.getCustomAnnotations(), customAnnotations);
assertEquals(filterContext.getProjectionMode(), projectionMode);
assertEquals(filterContext.getProjectionMask(), maskTree);
assertEquals(filterContext.getMetadataProjectionMask(), metadataMaskTree);
assertEquals(filterContext.getPagingProjectionMask(), pagingMaskTree);
assertEquals(filterContext.getPathKeys(), pathKeys);
assertEquals(filterContext.getRequestHeaders(), requestHeaders);
assertEquals(filterContext.getRequestURI(), requestUri);
assertEquals(filterContext.getRestliProtocolVersion(), protoVersion);
assertEquals(filterContext.getQueryParameters(), queryParams);
assertEquals(filterContext.getActionName(), actionName);
assertEquals(filterContext.getFinderName(), finderName);
assertEquals(filterContext.getBatchFinderName(), batchFinderName);
assertEquals(filterContext.getRequestContextLocalAttrs(), localAttrs);
assertNull(filterContext.getMethod());
assertEquals(filterContext.getMethodParameters(), methodParameters);
assertNotSame(filterContext.getMethodParameters(), methodParameters);
assertEquals(filterContext.getMethodServiceErrors(), methodServiceErrors);
filterContext.getRequestHeaders().put("header2", "value2");
assertEquals(requestHeaders.get("header2"), "value2");
verify(resourceModel).getName();
verify(resourceModel).getNamespace();
verify(resourceMethod).getMethodType();
verify(resourceMethod).getResourceModel();
verify(resourceMethod).getCustomAnnotationData();
verify(resourceMethod).getFinderName();
verify(resourceMethod).getBatchFinderName();
verify(resourceMethod).getActionName();
verify(resourceMethod).getMethod();
verify(resourceMethod, times(2)).getParameters();
verify(resourceMethod).getServiceErrors();
verify(context).getProjectionMode();
verify(context).setProjectionMask(maskTree);
verify(context).getProjectionMask();
verify(context).setMetadataProjectionMask(metadataMaskTree);
verify(context).getMetadataProjectionMask();
verify(context).setPagingProjectionMask(pagingMaskTree);
verify(context).getPagingProjectionMask();
verify(context).getPathKeys();
verify(context, times(2)).getRequestHeaders();
verify(context).getRequestURI();
verify(context).getRestliProtocolVersion();
verify(context).getParameters();
verify(context).getRawRequestContext();
verify(resourceMethod).getCollectionCustomMetadataType();
verifyNoMoreInteractions(context, resourceMethod, resourceModel);
}
use of com.linkedin.restli.common.ResourceMethod in project rest.li by linkedin.
the class RestLiValidationFilter method onResponse.
@SuppressWarnings("unchecked")
public CompletableFuture<Void> onResponse(final FilterRequestContext requestContext, final FilterResponseContext responseContext) {
RestLiResponseData<?> responseData = responseContext.getResponseData();
if (responseData.getResponseEnvelope().isErrorResponse()) {
return CompletableFuture.completedFuture(null);
}
if (shouldValidateOnResponse(requestContext)) {
ResourceMethod method = requestContext.getMethodType();
RestLiDataValidator validator = createResponseRestLiDataValidator(requestContext);
switch(method) {
case GET:
validateSingleResponse(validator, ((GetResponseEnvelope) responseData.getResponseEnvelope()).getRecord());
break;
case CREATE:
if (requestContext.isReturnEntityMethod() && requestContext.isReturnEntityRequested()) {
validateSingleResponse(validator, ((CreateResponseEnvelope) responseData.getResponseEnvelope()).getRecord());
}
break;
case PARTIAL_UPDATE:
if (requestContext.isReturnEntityMethod() && requestContext.isReturnEntityRequested()) {
validateSingleResponse(validator, ((PartialUpdateResponseEnvelope) responseData.getResponseEnvelope()).getRecord());
}
break;
case GET_ALL:
validateCollectionResponse(validator, ((GetAllResponseEnvelope) responseData.getResponseEnvelope()).getCollectionResponse());
break;
case FINDER:
validateCollectionResponse(validator, ((FinderResponseEnvelope) responseData.getResponseEnvelope()).getCollectionResponse());
break;
case BATCH_FINDER:
validateBatchCollectionResponse(validator, ((BatchFinderResponseEnvelope) responseData.getResponseEnvelope()).getItems());
break;
case BATCH_GET:
validateBatchResponse(validator, ((BatchGetResponseEnvelope) responseData.getResponseEnvelope()).getBatchResponseMap());
break;
case BATCH_CREATE:
if (requestContext.isReturnEntityMethod() && requestContext.isReturnEntityRequested()) {
validateCreateCollectionResponse(validator, ((BatchCreateResponseEnvelope) responseData.getResponseEnvelope()).getCreateResponses());
}
break;
case BATCH_PARTIAL_UPDATE:
if (requestContext.isReturnEntityMethod() && requestContext.isReturnEntityRequested()) {
validateBatchResponse(validator, ((BatchPartialUpdateResponseEnvelope) responseData.getResponseEnvelope()).getBatchResponseMap());
}
break;
}
}
return CompletableFuture.completedFuture(null);
}
use of com.linkedin.restli.common.ResourceMethod 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);
}
use of com.linkedin.restli.common.ResourceMethod in project rest.li by linkedin.
the class ResourceMethodConfigElement method parse.
static ResourceMethodConfigElement parse(RestLiMethodConfig.ConfigType configType, String key, Object value) throws ResourceMethodConfigParsingException {
ParsingErrorListener errorListener = new ParsingErrorListener();
ANTLRInputStream input = new ANTLRInputStream(key);
ResourceMethodKeyLexer lexer = new ResourceMethodKeyLexer(input);
lexer.removeErrorListeners();
lexer.addErrorListener(errorListener);
CommonTokenStream tokens = new CommonTokenStream(lexer);
ResourceMethodKeyParser parser = new ResourceMethodKeyParser(tokens);
parser.removeErrorListeners();
parser.addErrorListener(errorListener);
ResourceMethodKeyParser.KeyContext keyTree = parser.key();
if (!errorListener.hasErrors()) {
Optional<String> resourceName = handlingWildcard(keyTree.restResource());
Optional<ResourceMethod> opType = getOpType(keyTree.operation());
Optional<String> opName = opType.flatMap(method -> getOpName(method, keyTree.operation()));
return new ResourceMethodConfigElement(key, coerceValue(configType, value), configType, resourceName, opType, opName);
} else {
throw new ResourceMethodConfigParsingException("Error" + ((errorListener.errorsSize() > 1) ? "s" : "") + " parsing key: " + key + "\n" + errorListener);
}
}
use of com.linkedin.restli.common.ResourceMethod in project rest.li by linkedin.
the class TestBatchUpdateResponseBuilder method dataProvider.
@DataProvider(name = "testData")
public Object[][] dataProvider() {
CompoundKey c1 = new CompoundKey().append("a", "a1").append("b", 1);
CompoundKey c2 = new CompoundKey().append("a", "a2").append("b", 2);
CompoundKey c3 = new CompoundKey().append("a", "a3").append("b", 3);
Map<CompoundKey, UpdateResponse> results = new HashMap<>();
results.put(c1, new UpdateResponse(HttpStatus.S_202_ACCEPTED));
results.put(c2, new UpdateResponse(HttpStatus.S_202_ACCEPTED));
RestLiServiceException restLiServiceException = new RestLiServiceException(HttpStatus.S_404_NOT_FOUND);
Map<CompoundKey, RestLiServiceException> errors = Collections.singletonMap(c3, restLiServiceException);
BatchUpdateResult<CompoundKey, Foo> batchUpdateResult = new BatchUpdateResult<>(results, errors);
Map<CompoundKey, UpdateResponse> keyOverlapResults = new HashMap<>();
keyOverlapResults.put(c1, new UpdateResponse(HttpStatus.S_202_ACCEPTED));
keyOverlapResults.put(c2, new UpdateResponse(HttpStatus.S_202_ACCEPTED));
keyOverlapResults.put(c3, new UpdateResponse(HttpStatus.S_404_NOT_FOUND));
BatchUpdateResult<CompoundKey, Foo> keyOverlapBatchUpdateResult = new BatchUpdateResult<>(keyOverlapResults, errors);
UpdateStatus updateStatus = new UpdateStatus().setStatus(202);
ErrorResponse errorResponse = new ErrorResponse().setStatus(404);
Map<String, UpdateStatus> expectedProtocol1Results = new HashMap<>();
expectedProtocol1Results.put("a=a1&b=1", updateStatus);
expectedProtocol1Results.put("a=a2&b=2", updateStatus);
Map<String, ErrorResponse> expectedProtocol1Errors = new HashMap<>();
expectedProtocol1Errors.put("a=a3&b=3", errorResponse);
Map<String, UpdateStatus> expectedProtocol2Results = new HashMap<>();
expectedProtocol2Results.put("(a:a1,b:1)", updateStatus);
expectedProtocol2Results.put("(a:a2,b:2)", updateStatus);
Map<String, ErrorResponse> expectedProtocol2Errors = new HashMap<>();
expectedProtocol2Errors.put("(a:a3,b:3)", errorResponse);
Map<String, UpdateStatus> expectedAltKeyResults = new HashMap<>();
expectedAltKeyResults.put("aa1xb1", updateStatus);
expectedAltKeyResults.put("aa2xb2", updateStatus);
Map<String, ErrorResponse> expectedAltKeyErrors = new HashMap<>();
expectedAltKeyErrors.put("aa3xb3", errorResponse);
Map<String, AlternativeKey<?, ?>> alternativeKeyMap = new HashMap<>();
alternativeKeyMap.put("alt", new AlternativeKey<>(new TestKeyCoercer(), String.class, new StringDataSchema()));
List<Object[]> data = new ArrayList<>();
for (ResourceMethod resourceMethod : BUILDERS.keySet()) {
data.add(new Object[] { batchUpdateResult, null, null, expectedProtocol1Results, expectedProtocol1Errors, AllProtocolVersions.RESTLI_PROTOCOL_1_0_0.getProtocolVersion(), resourceMethod });
data.add(new Object[] { batchUpdateResult, null, null, expectedProtocol2Results, expectedProtocol2Errors, AllProtocolVersions.RESTLI_PROTOCOL_2_0_0.getProtocolVersion(), resourceMethod });
data.add(new Object[] { batchUpdateResult, "alt", alternativeKeyMap, expectedAltKeyResults, expectedAltKeyErrors, AllProtocolVersions.RESTLI_PROTOCOL_1_0_0.getProtocolVersion(), resourceMethod });
data.add(new Object[] { batchUpdateResult, "alt", alternativeKeyMap, expectedAltKeyResults, expectedAltKeyErrors, AllProtocolVersions.RESTLI_PROTOCOL_2_0_0.getProtocolVersion(), resourceMethod });
data.add(new Object[] { keyOverlapBatchUpdateResult, null, null, expectedProtocol2Results, expectedProtocol2Errors, AllProtocolVersions.RESTLI_PROTOCOL_2_0_0.getProtocolVersion(), resourceMethod });
}
return data.toArray(new Object[data.size()][]);
}
Aggregations