use of com.linkedin.restli.common.CollectionMetadata in project rest.li by linkedin.
the class TestRestLiResponseHandler method testCollections.
@Test(dataProvider = TestConstants.RESTLI_PROTOCOL_1_2_PREFIX + "basicData")
public void testCollections(AcceptTypeData acceptTypeData, ProtocolVersion protocolVersion, String errorResponseHeaderName) throws Exception {
ResourceModel resourceModel = buildResourceModel(StatusCollectionResource.class);
ResourceMethodDescriptor methodDescriptor = resourceModel.findFinderMethod("search");
RestLiResponse response;
// #1 check datamap/entity structure
ServerResourceContext context = new ResourceContextImpl();
RestUtils.validateRequestHeadersAndUpdateResourceContext(acceptTypeData.acceptHeaders, Collections.emptySet(), context);
RoutingResult routingResult = new RoutingResult(context, methodDescriptor);
response = buildPartialRestResponse(buildRequest(acceptTypeData.acceptHeaders, protocolVersion), routingResult, buildStatusList(3));
checkResponse(response, 200, 1, true, errorResponseHeaderName);
String baseUri = "/test?someParam=foo";
// #1.1 using CollectionResult
response = invokeResponseHandler(baseUri + "&start=0&count=5", methodDescriptor, new BasicCollectionResult<>(buildStatusList(5)), acceptTypeData.acceptHeaders, protocolVersion);
checkCollectionResponse(response, 5, 0, 5, 1, null, null, null, acceptTypeData);
// #1.1 using CollectionResult (with total)
response = invokeResponseHandler(baseUri + "&start=0&count=5", methodDescriptor, new BasicCollectionResult<>(buildStatusList(5), 10), acceptTypeData.acceptHeaders, protocolVersion);
checkCollectionResponse(response, 5, 0, 5, 1, 10, null, null, acceptTypeData);
// using CollectionResult with metadata RecordTemplate
CollectionMetadata metadata = new CollectionMetadata();
metadata.setCount(42);
response = invokeResponseHandler(baseUri + "&start=0&count=5", methodDescriptor, new CollectionResult<>(buildStatusList(5), 10, metadata), acceptTypeData.acceptHeaders, protocolVersion);
checkCollectionResponse(response, 5, 0, 5, 1, 10, null, null, acceptTypeData);
DataMap dataMap = response.getDataMap();
CollectionResponse<Status> collectionResponse = new CollectionResponse<>(dataMap, Status.class);
assertEquals(new CollectionMetadata(collectionResponse.getMetadataRaw()), metadata);
// #2 pagination: first page, no next
response = invokeResponseHandler(baseUri + "&start=0&count=5", methodDescriptor, buildStatusList(3), acceptTypeData.acceptHeaders, protocolVersion);
checkCollectionResponse(response, 3, 0, 5, 0, null, null, null, acceptTypeData);
// #3 pagination: first page, has next (boundary case)
response = invokeResponseHandler(baseUri + "&start=0&count=5", methodDescriptor, buildStatusList(5), acceptTypeData.acceptHeaders, protocolVersion);
// "/test?count=5&start=5&someParam=foo"
final Map<String, String> queryParamsMap3next = new HashMap<>();
queryParamsMap3next.put("count", "5");
queryParamsMap3next.put("start", "5");
queryParamsMap3next.put("someParam", "foo");
final URIDetails expectedURIDetails3next = new URIDetails(protocolVersion, "/test", null, queryParamsMap3next, null);
checkCollectionResponse(response, 5, 0, 5, 1, null, null, expectedURIDetails3next, acceptTypeData);
// #4 pagination: second page, has prev/ext
response = invokeResponseHandler(baseUri + "&start=5&count=5", methodDescriptor, buildStatusList(5), acceptTypeData.acceptHeaders, protocolVersion);
// "/test?count=5&start=0&someParam=foo", "/test?count=5&start=10&someParam=foo",
final Map<String, String> queryParamsMap4prev = new HashMap<>();
queryParamsMap4prev.put("count", "5");
queryParamsMap4prev.put("start", "0");
queryParamsMap4prev.put("someParam", "foo");
final URIDetails expectedURIDetails4prev = new URIDetails(protocolVersion, "/test", null, queryParamsMap4prev, null);
final Map<String, String> queryParamsMap4next = new HashMap<>();
queryParamsMap4next.put("count", "5");
queryParamsMap4next.put("start", "10");
queryParamsMap4next.put("someParam", "foo");
final URIDetails expectedURIDetails4next = new URIDetails(protocolVersion, "/test", null, queryParamsMap4next, null);
checkCollectionResponse(response, 5, 5, 5, 2, null, expectedURIDetails4prev, expectedURIDetails4next, acceptTypeData);
// #5 pagination:last page, has prev
response = invokeResponseHandler(baseUri + "&start=10&count=5", methodDescriptor, buildStatusList(4), acceptTypeData.acceptHeaders, protocolVersion);
// "/test?count=5&start=5&someParam=foo"
final Map<String, String> queryParamsMap5prev = new HashMap<>();
queryParamsMap5prev.put("count", "5");
queryParamsMap5prev.put("start", "5");
queryParamsMap5prev.put("someParam", "foo");
final URIDetails expectedURIDetails5prev = new URIDetails(protocolVersion, "/test", null, queryParamsMap5prev, null);
checkCollectionResponse(response, 4, 10, 5, 1, null, expectedURIDetails5prev, null, acceptTypeData);
response = invokeResponseHandler(baseUri + "&start=10&count=5", methodDescriptor, new BasicCollectionResult<>(buildStatusList(4), 15), acceptTypeData.acceptHeaders, protocolVersion);
// "/test?count=5&start=5&someParam=foo", "/test?count=5&start=14&someParam=foo"
final Map<String, String> queryParamsMap6prev = new HashMap<>();
queryParamsMap6prev.put("count", "5");
queryParamsMap6prev.put("start", "5");
queryParamsMap6prev.put("someParam", "foo");
final URIDetails expectedURIDetails6prev = new URIDetails(protocolVersion, "/test", null, queryParamsMap6prev, null);
final Map<String, String> queryParamsMap6next = new HashMap<>();
queryParamsMap6next.put("count", "5");
queryParamsMap6next.put("start", "14");
queryParamsMap6next.put("someParam", "foo");
final URIDetails expectedURIDetails6next = new URIDetails(protocolVersion, "/test", null, queryParamsMap6next, null);
checkCollectionResponse(response, 4, 10, 5, 2, 15, expectedURIDetails6prev, expectedURIDetails6next, acceptTypeData);
response = invokeResponseHandler(baseUri + "&start=10&count=5", methodDescriptor, new BasicCollectionResult<>(buildStatusList(4), 14), acceptTypeData.acceptHeaders, protocolVersion);
// "/test?count=5&start=5&someParam=foo"
final Map<String, String> queryParamsMap7prev = new HashMap<>();
queryParamsMap7prev.put("count", "5");
queryParamsMap7prev.put("start", "5");
queryParamsMap7prev.put("someParam", "foo");
final URIDetails expectedURIDetails7prev = new URIDetails(protocolVersion, "/test", null, queryParamsMap7prev, null);
checkCollectionResponse(response, 4, 10, 5, 1, 14, expectedURIDetails7prev, null, acceptTypeData);
}
use of com.linkedin.restli.common.CollectionMetadata in project rest.li by linkedin.
the class TestDataMapConverter method createTestDataMap.
private DataMap createTestDataMap() {
CollectionMetadata someRecord = new CollectionMetadata();
someRecord.setCount(1);
someRecord.setStart(0);
someRecord.setTotal(10);
LinkArray links = new LinkArray();
Link link = new Link();
link.setHref("prevUri");
link.setRel("prev");
link.setType("en");
links.add(link);
someRecord.setLinks(links);
return someRecord.data();
}
use of com.linkedin.restli.common.CollectionMetadata in project rest.li by linkedin.
the class TestRestLiCallback method testOnErrorWithFiltersExceptionFromFirstFilterSecondFilterHandles.
@SuppressWarnings({ "unchecked", "deprecation" })
@Test(dataProvider = "provideResponseEntities")
public void testOnErrorWithFiltersExceptionFromFirstFilterSecondFilterHandles(final ResourceMethod resourceMethod, final RestLiResponseData<?> responseAppData, final Object entityFromFilter2) throws Exception {
// App stuff.
RestLiServiceException exFromApp = new RestLiServiceException(HttpStatus.S_404_NOT_FOUND, "App failure");
// Filter stuff.
final Exception exFromFirstFilter = new RuntimeException("Runtime exception from first filter");
final Map<String, String> headersFromFilter = Maps.newHashMap();
headersFromFilter.put(RestConstants.HEADER_RESTLI_PROTOCOL_VERSION, AllProtocolVersions.LATEST_PROTOCOL_VERSION.toString());
String errorResponseHeaderName = HeaderUtil.getErrorResponseHeaderName(AllProtocolVersions.LATEST_PROTOCOL_VERSION);
headersFromFilter.put(errorResponseHeaderName, RestConstants.HEADER_VALUE_ERROR);
RestLiResponse partialResponse = new RestLiResponse.Builder().build();
ArgumentCaptor<RestLiServiceException> wrappedExCapture = ArgumentCaptor.forClass(RestLiServiceException.class);
final String customHeader = "Custom-Header";
final String customHeaderValue = "CustomValue";
// Setup.
when(_responseHandler.buildExceptionResponseData(eq(_routingResult), wrappedExCapture.capture(), anyMap(), anyList())).thenReturn(responseAppData);
when(_responseHandler.buildPartialResponse(_routingResult, responseAppData)).thenReturn(partialResponse);
when(_restRequest.getHeaders()).thenReturn(null);
// Mock filter behavior.
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
FilterRequestContext requestContext = (FilterRequestContext) args[1];
FilterResponseContext responseContext = (FilterResponseContext) args[2];
responseContext.getResponseData().getHeaders().putAll(headersFromFilter);
return completedFutureWithError(exFromFirstFilter);
}
}).doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
FilterRequestContext requestContext = (FilterRequestContext) args[1];
FilterResponseContext responseContext = (FilterResponseContext) args[2];
// The second filter should be invoked with details of the exception thrown by the first
// filter. Verify incoming data.
assertEquals(responseContext.getResponseData().getStatus(), HttpStatus.S_500_INTERNAL_SERVER_ERROR);
switch(ResponseTypeUtil.fromMethodType(resourceMethod)) {
case SINGLE_ENTITY:
assertNull(responseContext.getResponseData().getRecordResponseEnvelope().getRecord());
break;
case GET_COLLECTION:
assertNull(responseContext.getResponseData().getCollectionResponseEnvelope().getCollectionResponse());
break;
case CREATE_COLLECTION:
assertNull(responseContext.getResponseData().getBatchCreateResponseEnvelope().getCreateResponses());
break;
case BATCH_ENTITIES:
assertNull(responseContext.getResponseData().getBatchResponseEnvelope().getBatchResponseMap());
break;
case STATUS_ONLY:
break;
}
assertEquals(responseContext.getResponseData().getHeaders(), headersFromFilter);
assertTrue(responseContext.getResponseData().isErrorResponse());
// Modify data.
responseContext.getResponseData().getHeaders().put(customHeader, customHeaderValue);
setStatus(responseContext, HttpStatus.S_402_PAYMENT_REQUIRED);
// filter.
if (entityFromFilter2 instanceof RecordTemplate) {
responseContext.getResponseData().getRecordResponseEnvelope().setRecord((RecordTemplate) entityFromFilter2, HttpStatus.S_402_PAYMENT_REQUIRED);
} else if (entityFromFilter2 instanceof List) {
responseContext.getResponseData().getCollectionResponseEnvelope().setCollectionResponse((List<? extends RecordTemplate>) entityFromFilter2, new CollectionMetadata(), null, HttpStatus.S_402_PAYMENT_REQUIRED);
} else {
Map<Object, BatchResponseEnvelope.BatchResponseEntry> responseMap = new HashMap<>();
for (Map.Entry<?, RecordTemplate> entry : ((Map<?, RecordTemplate>) entityFromFilter2).entrySet()) {
responseMap.put(entry.getKey(), new BatchResponseEnvelope.BatchResponseEntry(HttpStatus.S_200_OK, entry.getValue()));
}
responseContext.getResponseData().getBatchResponseEnvelope().setBatchResponseMap(responseMap, HttpStatus.S_402_PAYMENT_REQUIRED);
}
return CompletableFuture.completedFuture(null);
}
}).when(_filter).onError(any(Throwable.class), eq(_filterRequestContext), any(FilterResponseContext.class));
// invoke request filters so cursor is in correct place
when(_filter.onRequest(any(FilterRequestContext.class))).thenReturn(CompletableFuture.completedFuture(null));
_twoFilterChain.onRequest(_filterRequestContext, _filterResponseContextFactory);
// Invoke.
_twoFilterRestLiCallback.onError(exFromApp);
// Verify.
verify(_responseHandler).buildExceptionResponseData(eq(_routingResult), wrappedExCapture.capture(), anyMap(), anyList());
verify(_responseHandler).buildPartialResponse(_routingResult, responseAppData);
verify(_callback).onSuccess(partialResponse);
verify(_restRequest).getHeaders();
verifyNoMoreInteractions(_restRequest, _responseHandler, _callback);
assertNotNull(responseAppData);
assertEquals(HttpStatus.S_402_PAYMENT_REQUIRED, responseAppData.getResponseEnvelope().getStatus());
// Only the error header should have been cleared.
assertFalse(responseAppData.getHeaders().containsKey(errorResponseHeaderName));
assertEquals(responseAppData.getHeaders().get(customHeader), customHeaderValue);
if (entityFromFilter2 instanceof RecordTemplate) {
assertTrue(responseAppData.getResponseType() == ResponseType.SINGLE_ENTITY);
assertEquals(responseAppData.getRecordResponseEnvelope().getRecord(), entityFromFilter2);
} else if (entityFromFilter2 instanceof List) {
if (responseAppData.getResponseType() == ResponseType.GET_COLLECTION) {
assertEquals(responseAppData.getCollectionResponseEnvelope().getCollectionResponse(), entityFromFilter2);
} else {
fail();
}
} else {
assertTrue(responseAppData.getResponseType() == ResponseType.BATCH_ENTITIES);
Map<Object, RecordTemplate> values = new HashMap<>();
for (Map.Entry<?, BatchResponseEnvelope.BatchResponseEntry> entry : responseAppData.getBatchResponseEnvelope().getBatchResponseMap().entrySet()) {
values.put(entry.getKey(), entry.getValue().getRecord());
}
assertEquals(values, entityFromFilter2);
}
assertFalse(responseAppData.getResponseEnvelope().isErrorResponse());
RestLiServiceException restliEx = wrappedExCapture.getAllValues().get(0);
assertNotNull(restliEx);
assertEquals(exFromApp.getStatus(), restliEx.getStatus());
assertEquals(exFromApp.getMessage(), restliEx.getMessage());
}
use of com.linkedin.restli.common.CollectionMetadata in project rest.li by linkedin.
the class TestBatchFinderResponseBuilder method testItemsOrder.
@Test(dataProvider = TestConstants.RESTLI_PROTOCOL_1_2_PREFIX + "testData")
@SuppressWarnings({ "unchecked", "deprecation" })
public void testItemsOrder(List<Criteria> criteria, RestRequest request, Object results, ProtocolVersion protocolVersion, String label) {
RoutingResult routingResult = getMockRoutingResult(criteria, protocolVersion);
Map<String, String> headers = ResponseBuilderUtil.getHeaders();
BatchFinderResponseBuilder responseBuilder = new BatchFinderResponseBuilder(new ErrorResponseBuilder());
RestLiResponseData<BatchFinderResponseEnvelope> responseData = responseBuilder.buildRestLiResponseData(request, routingResult, results, headers, Collections.emptyList());
RestLiResponse restResponse = responseBuilder.buildResponse(routingResult, responseData);
Assert.assertNotNull(restResponse.getEntity());
Assert.assertEquals(restResponse.getStatus(), HttpStatus.S_200_OK);
List<BatchFinderResponseEnvelope.BatchFinderEntry> entries = responseData.getResponseEnvelope().getItems();
assertEquals(entries.size(), criteria.size());
// check the order is maintained
for (int i = 0; i < criteria.size(); i++) {
Foo currentCriteria = criteria.get(i).criteria;
BatchFinderResponseEnvelope.BatchFinderEntry entry = entries.get(i);
// If on error, the criteria i should have an exception with the serviceError i
if (entry.getElements() == null) {
Assert.assertNotNull(entry.getException());
Assert.assertEquals(entry.getException().getServiceErrorCode(), currentCriteria.getIntField());
} else // otherwise, at least the StringField of the first element should be equal to the criteria
{
Foo t = new Foo(entry.getElements().get(0).data());
Assert.assertEquals(t.getStringField(), currentCriteria.getStringField());
// Check paging
CollectionMetadata paging = entry.getPaging();
// If we have less or more elements that the number we asked for, we should not have links
if (currentCriteria.getIntField() != PAGE_COUNT) {
Assert.assertTrue(paging.getLinks().size() == 0);
} else // Check the pagination format and contain only the current criteria
{
Assert.assertTrue(paging.getLinks().size() == 1);
// Only 1 criteria and the criteria that match
Assert.assertTrue(criteria.get(i).validateLink(paging.getLinks().get(0).getHref(), protocolVersion));
}
}
}
}
use of com.linkedin.restli.common.CollectionMetadata in project rest.li by linkedin.
the class TestMockCollectionResponseFactory method testCreate.
@Test
public void testCreate() {
Greeting g1 = new Greeting().setId(1L).setMessage("g1");
Greeting g2 = new Greeting().setId(2L).setMessage("g2");
List<Greeting> greetings = Arrays.asList(g1, g2);
CollectionMetadata pagingMetadata = new CollectionMetadata().setCount(2).setStart(0).setTotal(2);
DataMap customMetadata = new DataMap();
customMetadata.put("foo", "bar");
CollectionResponse<Greeting> collectionResponse = MockCollectionResponseFactory.create(Greeting.class, greetings, pagingMetadata, customMetadata);
Assert.assertEquals(collectionResponse.getElements(), greetings);
Assert.assertEquals(collectionResponse.getPaging(), pagingMetadata);
Assert.assertEquals(collectionResponse.getMetadataRaw(), customMetadata);
}
Aggregations