use of com.linkedin.data.template.RecordTemplate in project rest.li by linkedin.
the class TestRestClientRequestBuilder method clientGeneratedRestRequest.
@SuppressWarnings({ "unchecked", "rawtypes", "deprecation" })
private <T extends Request> RestRequest clientGeneratedRestRequest(Class<T> requestClass, ResourceMethod method, DataMap entityBody, RestClient.ContentType contentType, List<RestClient.AcceptType> acceptTypes, boolean acceptContentTypePerClient) throws URISyntaxException {
// massive setup...
Client mockClient = EasyMock.createMock(Client.class);
@SuppressWarnings({ "rawtypes" }) Request<?> mockRequest = EasyMock.createMock(requestClass);
RecordTemplate mockRecordTemplate = EasyMock.createMock(RecordTemplate.class);
@SuppressWarnings({ "rawtypes" }) RestResponseDecoder mockResponseDecoder = EasyMock.createMock(RestResponseDecoder.class);
RestliRequestOptions requestOptions = RestliRequestOptions.DEFAULT_OPTIONS;
if (!acceptContentTypePerClient) {
requestOptions = new RestliRequestOptions(ProtocolVersionOption.USE_LATEST_IF_AVAILABLE, null, null, contentType, acceptTypes, false);
}
setCommonExpectations(mockRequest, method, mockResponseDecoder, requestOptions);
EasyMock.expect(mockRequest.getStreamingAttachments()).andReturn(null).times(2);
setResourceMethodExpectations(method, mockRequest, mockRecordTemplate, entityBody);
Capture<RestRequest> restRequestCapture = new Capture<RestRequest>();
EasyMock.expect(mockClient.getMetadata(new URI(HOST + SERVICE_NAME))).andReturn(Collections.<String, Object>emptyMap()).once();
mockClient.restRequest(EasyMock.capture(restRequestCapture), (RequestContext) EasyMock.anyObject(), (Callback<RestResponse>) EasyMock.anyObject());
EasyMock.expectLastCall().once();
EasyMock.replay(mockClient, mockRequest, mockRecordTemplate);
// do work!
RestClient restClient;
if (acceptContentTypePerClient) {
// configuration per client
restClient = new RestClient(mockClient, HOST, contentType, acceptTypes);
} else {
// configuration per request
restClient = new RestClient(mockClient, HOST);
}
restClient.sendRequest(mockRequest);
return restRequestCapture.getValue();
}
use of com.linkedin.data.template.RecordTemplate in project rest.li by linkedin.
the class BatchCreateResponseBuilder method buildRestLiResponseData.
@Override
public RestLiResponseData buildRestLiResponseData(RestRequest request, RoutingResult routingResult, Object result, Map<String, String> headers, List<HttpCookie> cookies) {
if (result instanceof BatchCreateKVResult) {
BatchCreateKVResult<?, ?> list = (BatchCreateKVResult<?, ?>) result;
if (list.getResults() == null) {
throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, "Unexpected null encountered. Null List inside of a BatchCreateKVResult returned by the resource method: " + routingResult.getResourceMethod());
}
List<BatchCreateResponseEnvelope.CollectionCreateResponseItem> collectionCreateList = new ArrayList<BatchCreateResponseEnvelope.CollectionCreateResponseItem>(list.getResults().size());
for (CreateKVResponse e : list.getResults()) {
if (e == null) {
throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, "Unexpected null encountered. Null element inside of List inside of a BatchCreateResult returned by the resource method: " + routingResult.getResourceMethod());
} else {
Object id = ResponseUtils.translateCanonicalKeyToAlternativeKeyIfNeeded(e.getId(), routingResult);
if (e.getError() == null) {
final ResourceContext resourceContext = routingResult.getContext();
DataMap entityData = e.getEntity() != null ? e.getEntity().data() : null;
final DataMap data = RestUtils.projectFields(entityData, resourceContext.getProjectionMode(), resourceContext.getProjectionMask());
CreateIdEntityStatus<Object, RecordTemplate> entry = new CreateIdEntityStatus<Object, RecordTemplate>(e.getStatus().getCode(), id, new AnyRecord(data), null, ProtocolVersionUtil.extractProtocolVersion(headers));
collectionCreateList.add(new BatchCreateResponseEnvelope.CollectionCreateResponseItem(entry));
} else {
collectionCreateList.add(new BatchCreateResponseEnvelope.CollectionCreateResponseItem(e.getError(), id));
}
}
}
RestLiResponseDataImpl responseData = new RestLiResponseDataImpl(HttpStatus.S_200_OK, headers, cookies);
responseData.setResponseEnvelope(new BatchCreateResponseEnvelope(collectionCreateList, true, responseData));
return responseData;
} else {
BatchCreateResult<?, ?> list = (BatchCreateResult<?, ?>) result;
//Verify that a null list was not passed into the BatchCreateResult. If so, this is a developer error.
if (list.getResults() == null) {
throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, "Unexpected null encountered. Null List inside of a BatchCreateResult returned by the resource method: " + routingResult.getResourceMethod());
}
List<BatchCreateResponseEnvelope.CollectionCreateResponseItem> collectionCreateList = new ArrayList<BatchCreateResponseEnvelope.CollectionCreateResponseItem>(list.getResults().size());
for (CreateResponse e : list.getResults()) {
//Verify that a null element was not passed into the BatchCreateResult list. If so, this is a developer error.
if (e == null) {
throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, "Unexpected null encountered. Null element inside of List inside of a BatchCreateResult returned by the resource method: " + routingResult.getResourceMethod());
} else {
Object id = ResponseUtils.translateCanonicalKeyToAlternativeKeyIfNeeded(e.getId(), routingResult);
if (e.getError() == null) {
CreateIdStatus<Object> entry = new CreateIdStatus<Object>(e.getStatus().getCode(), id, null, ProtocolVersionUtil.extractProtocolVersion(headers));
collectionCreateList.add(new BatchCreateResponseEnvelope.CollectionCreateResponseItem(entry));
} else {
collectionCreateList.add(new BatchCreateResponseEnvelope.CollectionCreateResponseItem(e.getError(), id));
}
}
}
RestLiResponseDataImpl responseData = new RestLiResponseDataImpl(HttpStatus.S_200_OK, headers, cookies);
responseData.setResponseEnvelope(new BatchCreateResponseEnvelope(collectionCreateList, responseData));
return responseData;
}
}
use of com.linkedin.data.template.RecordTemplate in project rest.li by linkedin.
the class BatchGetResponseBuilder method buildRestLiResponseData.
@Override
public RestLiResponseData buildRestLiResponseData(RestRequest request, RoutingResult routingResult, Object result, Map<String, String> headers, List<HttpCookie> cookies) {
@SuppressWarnings({ "unchecked" }) final Map<Object, RecordTemplate> /** constrained by signature of {@link com.linkedin.restli.server.resources.CollectionResource#batchGet(java.util.Set)} */
entities = (Map<Object, RecordTemplate>) result;
Map<Object, HttpStatus> statuses = Collections.emptyMap();
Map<Object, RestLiServiceException> serviceErrors = Collections.emptyMap();
if (result instanceof BatchResult) {
@SuppressWarnings({ "unchecked" }) final BatchResult<Object, RecordTemplate> /** constrained by signature of {@link com.linkedin.restli.server.resources.CollectionResource#batchGet(java.util.Set)} */
batchResult = (BatchResult<Object, RecordTemplate>) result;
statuses = batchResult.getStatuses();
serviceErrors = batchResult.getErrors();
}
try {
if (statuses.containsKey(null)) {
throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, "Unexpected null encountered. Null key inside of a Map returned by the resource method: " + routingResult.getResourceMethod());
}
} catch (NullPointerException e) {
// Some map implementations will throw an NPE if they do not support null keys.
// In this case it is OK to swallow this exception and proceed.
}
Map<Object, BatchResponseEntry> batchResult = new HashMap<Object, BatchResponseEntry>(entities.size() + serviceErrors.size());
for (Map.Entry<Object, RecordTemplate> entity : entities.entrySet()) {
if (entity.getKey() == null) {
throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, "Unexpected null encountered. Null key inside of a Map returned by the resource method: " + routingResult.getResourceMethod());
}
Object finalKey = ResponseUtils.translateCanonicalKeyToAlternativeKeyIfNeeded(entity.getKey(), routingResult);
final DataMap projectedData = RestUtils.projectFields(entity.getValue().data(), routingResult.getContext().getProjectionMode(), routingResult.getContext().getProjectionMask());
AnyRecord anyRecord = new AnyRecord(projectedData);
batchResult.put(finalKey, new BatchResponseEntry(statuses.get(entity.getKey()), anyRecord));
}
for (Map.Entry<Object, RestLiServiceException> entity : serviceErrors.entrySet()) {
if (entity.getKey() == null || entity.getValue() == null) {
throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, "Unexpected null encountered. Null key inside of a Map returned by the resource method: " + routingResult.getResourceMethod());
}
Object finalKey = ResponseUtils.translateCanonicalKeyToAlternativeKeyIfNeeded(entity.getKey(), routingResult);
batchResult.put(finalKey, new BatchResponseEntry(statuses.get(entity.getKey()), entity.getValue()));
}
final Map<Object, RestLiServiceException> contextErrors = ((ServerResourceContext) routingResult.getContext()).getBatchKeyErrors();
for (Map.Entry<Object, RestLiServiceException> entry : contextErrors.entrySet()) {
Object finalKey = ResponseUtils.translateCanonicalKeyToAlternativeKeyIfNeeded(entry.getKey(), routingResult);
batchResult.put(finalKey, new BatchResponseEntry(statuses.get(entry.getKey()), entry.getValue()));
}
RestLiResponseDataImpl responseData = new RestLiResponseDataImpl(HttpStatus.S_200_OK, headers, cookies);
responseData.setResponseEnvelope(new BatchGetResponseEnvelope(batchResult, responseData));
return responseData;
}
use of com.linkedin.data.template.RecordTemplate in project rest.li by linkedin.
the class CollectionResponseBuilder method buildRestLiResponseData.
private static RestLiResponseData buildRestLiResponseData(final RestRequest request, final RoutingResult routingResult, final List<? extends RecordTemplate> elements, final PageIncrement pageIncrement, final RecordTemplate customMetadata, final Integer totalResults, final Map<String, String> headers, final List<HttpCookie> cookies) {
//Extract the resource context that contains projection information for root object entities, metadata and paging.
final ResourceContext resourceContext = routingResult.getContext();
//Calculate paging metadata and apply projection
final CollectionMetadata paging = RestUtils.buildMetadata(request.getURI(), resourceContext, routingResult.getResourceMethod(), elements, pageIncrement, totalResults);
//PagingMetadata cannot be null at this point so we skip the null check. Notice here that we are using automatic
//intentionally since resource methods cannot explicitly project paging. However, it should be noted that client
//resource methods have the option of selectively setting the total to null. This happens if a client decides
//that they want the total in the paging response, which the resource method will see in their paging path spec,
//and then specify total when they create CollectionResult. Restli will then also subsequently separately project
//paging using this same path spec.
//Note that there is no chance of potential data loss here:
//If the client decides they don't want total in their paging response, then the resource method will
//see the lack of total in their paging path spec and then decide to set total to null. We will then also exclude it
//when we project paging.
//If the client decides they want total in their paging response, then the resource method will see total in their
//paging path spec and then decide to set total to a non null value. We will then also include it when we project
//paging.
final CollectionMetadata projectedPaging = new CollectionMetadata(RestUtils.projectFields(paging.data(), ProjectionMode.AUTOMATIC, resourceContext.getPagingProjectionMask()));
//For root object entities
List<AnyRecord> processedElements = new ArrayList<AnyRecord>(elements.size());
for (RecordTemplate entry : elements) {
//We don't permit null elements in our lists. If so, this is a developer error.
if (entry == null) {
throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR, "Unexpected null encountered. Null element inside of a List returned by the resource method: " + routingResult.getResourceMethod());
}
processedElements.add(new AnyRecord(RestUtils.projectFields(entry.data(), resourceContext.getProjectionMode(), resourceContext.getProjectionMask())));
}
//Now for custom metadata
final AnyRecord projectedCustomMetadata;
if (customMetadata != null) {
projectedCustomMetadata = new AnyRecord(RestUtils.projectFields(customMetadata.data(), resourceContext.getMetadataProjectionMode(), resourceContext.getMetadataProjectionMask()));
} else {
projectedCustomMetadata = null;
}
RestLiResponseDataImpl responseData = new RestLiResponseDataImpl(HttpStatus.S_200_OK, headers, cookies);
RestLiResponseEnvelope responseEnvelope;
switch(routingResult.getResourceMethod().getType()) {
case GET_ALL:
responseEnvelope = new GetAllResponseEnvelope(processedElements, projectedPaging, projectedCustomMetadata, responseData);
break;
case FINDER:
responseEnvelope = new FinderResponseEnvelope(processedElements, projectedPaging, projectedCustomMetadata, responseData);
break;
default:
throw new IllegalStateException("Resource method is invalid for CollectionResponseBuilder");
}
responseData.setResponseEnvelope(responseEnvelope);
return responseData;
}
use of com.linkedin.data.template.RecordTemplate in project rest.li by linkedin.
the class RestLiValidationFilter method onRequest.
@Override
public CompletableFuture<Void> onRequest(final FilterRequestContext requestContext) {
Class<?> resourceClass = requestContext.getFilterResourceModel().getResourceClass();
ResourceMethod method = requestContext.getMethodType();
RestLiDataValidator validator = new RestLiDataValidator(resourceClass.getAnnotations(), requestContext.getFilterResourceModel().getValueClass(), method);
RestLiRequestData requestData = requestContext.getRequestData();
if (method == ResourceMethod.CREATE || method == ResourceMethod.UPDATE) {
ValidationResult result = validator.validateInput(requestData.getEntity());
if (!result.isValid()) {
throw new RestLiServiceException(HttpStatus.S_422_UNPROCESSABLE_ENTITY, result.getMessages().toString());
}
} else if (method == ResourceMethod.PARTIAL_UPDATE) {
ValidationResult result = validator.validateInput((PatchRequest) requestData.getEntity());
if (!result.isValid()) {
throw new RestLiServiceException(HttpStatus.S_422_UNPROCESSABLE_ENTITY, result.getMessages().toString());
}
} else if (method == ResourceMethod.BATCH_CREATE) {
StringBuilder sb = new StringBuilder();
for (RecordTemplate entity : requestData.getBatchEntities()) {
ValidationResult result = validator.validateInput(entity);
if (!result.isValid()) {
sb.append(result.getMessages().toString());
}
}
if (sb.length() > 0) {
throw new RestLiServiceException(HttpStatus.S_422_UNPROCESSABLE_ENTITY, sb.toString());
}
} else if (method == ResourceMethod.BATCH_UPDATE || method == ResourceMethod.BATCH_PARTIAL_UPDATE) {
StringBuilder sb = new StringBuilder();
for (Map.Entry<?, ? extends RecordTemplate> entry : requestData.getBatchKeyEntityMap().entrySet()) {
ValidationResult result;
if (method == ResourceMethod.BATCH_UPDATE) {
result = validator.validateInput(entry.getValue());
} else {
result = validator.validateInput((PatchRequest) entry.getValue());
}
if (!result.isValid()) {
sb.append("Key: ");
sb.append(entry.getKey());
sb.append(", ");
sb.append(result.getMessages().toString());
}
}
if (sb.length() > 0) {
throw new RestLiServiceException(HttpStatus.S_422_UNPROCESSABLE_ENTITY, sb.toString());
}
}
return CompletableFuture.completedFuture(null);
}
Aggregations