use of com.linkedin.restli.internal.server.methods.AnyRecord 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.restli.internal.server.methods.AnyRecord in project rest.li by linkedin.
the class CollectionResponseBuilder method buildResponse.
@Override
public PartialRestResponse buildResponse(RoutingResult routingResult, RestLiResponseData responseData) {
CollectionResponseEnvelope response = responseData.getCollectionResponseEnvelope();
PartialRestResponse.Builder builder = new PartialRestResponse.Builder();
CollectionResponse<AnyRecord> collectionResponse = new CollectionResponse<AnyRecord>(AnyRecord.class);
collectionResponse.setPaging(response.getCollectionResponsePaging());
DataList elementsMap = (DataList) collectionResponse.data().get(CollectionResponse.ELEMENTS);
for (RecordTemplate entry : response.getCollectionResponse()) {
CheckedUtil.addWithoutChecking(elementsMap, entry.data());
}
if (response.getCollectionResponseCustomMetadata() != null) {
collectionResponse.setMetadataRaw(response.getCollectionResponseCustomMetadata().data());
}
builder.entity(collectionResponse);
return builder.headers(responseData.getHeaders()).cookies(responseData.getCookies()).build();
}
use of com.linkedin.restli.internal.server.methods.AnyRecord 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.restli.internal.server.methods.AnyRecord 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.restli.internal.server.methods.AnyRecord in project rest.li by linkedin.
the class TestRestLiValidationFromClient method testInvalidInputEntityValidation.
@Test
public void testInvalidInputEntityValidation() {
try {
ValidationDemosCreateRequestBuilder.validateInput(null);
Assert.fail("Expected IllegalArgumentException.");
} catch (IllegalArgumentException e) {
Assert.assertEquals(e.getMessage(), "Record template is null.");
}
try {
ValidationDemosCreateRequestBuilder.validateInput(new ValidationDemo(null));
Assert.fail("Expected IllegalArgumentException.");
} catch (IllegalArgumentException e) {
Assert.assertEquals(e.getMessage(), "Record template does not have data.");
}
try {
RestLiDataValidator anyRecordValidator = new RestLiDataValidator(Collections.<String, List<String>>emptyMap(), AnyRecord.class, ResourceMethod.CREATE);
anyRecordValidator.validateInput(new AnyRecord(new DataMap()));
Assert.fail("Expected IllegalArgumentException.");
} catch (IllegalArgumentException e) {
Assert.assertEquals(e.getMessage(), "Record template does not have a schema.");
}
}
Aggregations