[OLINGO-438] Added count support for entity set
This commit is contained in:
parent
ad3fbfb4cb
commit
aac77f05ae
|
@ -29,11 +29,19 @@ import org.apache.olingo.server.api.uri.UriInfo;
|
||||||
public interface EntityCollectionProcessor extends Processor {
|
public interface EntityCollectionProcessor extends Processor {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads entities data from persistency and puts serialized content and status into the response.
|
* Reads entities data from persistence and puts serialized content and status into the response.
|
||||||
* @param request - OData request object containing raw HTTP information
|
* @param request - OData request object containing raw HTTP information
|
||||||
* @param response - OData response object for collecting response data
|
* @param response - OData response object for collecting response data
|
||||||
* @param uriInfo - information of a parsed OData URI
|
* @param uriInfo - information of a parsed OData URI
|
||||||
* @param requestedContentType - requested content type after content negotiation
|
* @param requestedContentType - requested content type after content negotiation
|
||||||
*/
|
*/
|
||||||
void readCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestedContentType);
|
void readCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestedContentType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count entities from persistence and puts serialized content and status into the response.
|
||||||
|
* @param request - OData request object containing raw http information.
|
||||||
|
* @param response - OData response object for collecting response data
|
||||||
|
* @param uriInfo - information of a parsed OData uri
|
||||||
|
*/
|
||||||
|
void countCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,6 +227,15 @@ public class ODataHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case count:
|
||||||
|
if (request.getMethod().equals(HttpMethod.GET)) {
|
||||||
|
EntityCollectionProcessor cp = selectProcessor(EntityCollectionProcessor.class);
|
||||||
|
cp.countCollection(request, response, uriInfo);
|
||||||
|
} else {
|
||||||
|
throw new ODataHandlerException("not implemented",
|
||||||
|
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ODataHandlerException("not implemented",
|
throw new ODataHandlerException("not implemented",
|
||||||
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
|
||||||
|
|
|
@ -521,6 +521,7 @@ public class UriValidator {
|
||||||
UriResource secondLastPathSegment = uriInfo.getUriResourceParts().get(secondLastPathSegmentIndex);
|
UriResource secondLastPathSegment = uriInfo.getUriResourceParts().get(secondLastPathSegmentIndex);
|
||||||
switch (secondLastPathSegment.getKind()) {
|
switch (secondLastPathSegment.getKind()) {
|
||||||
case entitySet:
|
case entitySet:
|
||||||
|
case navigationProperty:
|
||||||
idx = RowIndexForUriType.entitySetCount;
|
idx = RowIndexForUriType.entitySetCount;
|
||||||
break;
|
break;
|
||||||
case complexProperty:
|
case complexProperty:
|
||||||
|
|
|
@ -230,5 +230,10 @@ public class ContentNegotiatorTest {
|
||||||
final ContentType requestedContentType) {
|
final ContentType requestedContentType) {
|
||||||
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
|
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void countCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo) {
|
||||||
|
response.setHeader(HttpHeader.CONTENT_TYPE, ContentType.TEXT_PLAIN.toContentTypeString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,8 +43,10 @@ import org.apache.olingo.server.api.uri.UriResource;
|
||||||
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
||||||
|
import org.apache.olingo.server.api.uri.queryoption.SystemQueryOptionKind;
|
||||||
import org.apache.olingo.server.tecsvc.data.DataProvider;
|
import org.apache.olingo.server.tecsvc.data.DataProvider;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
@ -134,9 +136,54 @@ public class TechnicalProcessor implements EntityCollectionProcessor, EntityProc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void countCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo) {
|
||||||
|
try {
|
||||||
|
EntitySet entitySet = null;
|
||||||
|
final UriInfoResource uriResource = uriInfo.asUriInfoResource();
|
||||||
|
final List<UriResource> resourceParts = uriResource.getUriResourceParts();
|
||||||
|
if(isCount(resourceParts)) {
|
||||||
|
int pos = resourceParts.size() - 2;
|
||||||
|
if(pos >= 0) {
|
||||||
|
final UriResourceEntitySet ur =
|
||||||
|
(UriResourceEntitySet) uriResource.getUriResourceParts().get(pos);
|
||||||
|
entitySet = readEntitySetInternal(ur.getEntitySet(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entitySet == null) {
|
||||||
|
response.setStatusCode(HttpStatusCode.NOT_FOUND.getStatusCode());
|
||||||
|
} else {
|
||||||
|
Integer count = entitySet.getCount();
|
||||||
|
response.setContent(new ByteArrayInputStream(count.toString().getBytes()));
|
||||||
|
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||||
|
response.setHeader(HttpHeader.CONTENT_TYPE, "text/plain");
|
||||||
|
}
|
||||||
|
} catch (final DataProvider.DataProviderException e) {
|
||||||
|
response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isCount(List<UriResource> resourceParts) {
|
||||||
|
if(resourceParts.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
UriResource part = resourceParts.get(resourceParts.size() - 1);
|
||||||
|
return SystemQueryOptionKind.COUNT.toString().equals(part.toString());
|
||||||
|
}
|
||||||
|
|
||||||
private EntitySet readEntitySetInternal(final EdmEntitySet edmEntitySet) throws DataProvider.DataProviderException {
|
private EntitySet readEntitySetInternal(final EdmEntitySet edmEntitySet) throws DataProvider.DataProviderException {
|
||||||
|
return readEntitySetInternal(edmEntitySet, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private EntitySet readEntitySetInternal(final EdmEntitySet edmEntitySet,
|
||||||
|
boolean withCount) throws DataProvider.DataProviderException {
|
||||||
EntitySet entitySet = dataProvider.readAll(edmEntitySet);
|
EntitySet entitySet = dataProvider.readAll(edmEntitySet);
|
||||||
// TODO: set count and next link
|
// TODO: set count (correctly) and next link
|
||||||
|
if(withCount && entitySet.getCount() == null) {
|
||||||
|
entitySet.setCount(entitySet.getEntities().size());
|
||||||
|
}
|
||||||
|
//
|
||||||
return entitySet;
|
return entitySet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,11 +35,14 @@ import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||||
import org.apache.olingo.server.api.OData;
|
import org.apache.olingo.server.api.OData;
|
||||||
import org.apache.olingo.server.api.ODataRequest;
|
import org.apache.olingo.server.api.ODataRequest;
|
||||||
import org.apache.olingo.server.api.ODataResponse;
|
import org.apache.olingo.server.api.ODataResponse;
|
||||||
|
import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
|
||||||
import org.apache.olingo.server.api.processor.MetadataProcessor;
|
import org.apache.olingo.server.api.processor.MetadataProcessor;
|
||||||
import org.apache.olingo.server.api.processor.ServiceDocumentProcessor;
|
import org.apache.olingo.server.api.processor.ServiceDocumentProcessor;
|
||||||
|
import org.apache.olingo.server.api.uri.UriInfo;
|
||||||
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
|
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
public class ODataHandlerTest {
|
public class ODataHandlerTest {
|
||||||
|
|
||||||
|
@ -238,4 +241,41 @@ public class ODataHandlerTest {
|
||||||
assertEquals(HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), response.getStatusCode());
|
assertEquals(HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), response.getStatusCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCount() throws Exception {
|
||||||
|
ODataRequest request = new ODataRequest();
|
||||||
|
|
||||||
|
request.setMethod(HttpMethod.GET);
|
||||||
|
request.setRawODataPath("ESAllPrim/$count");
|
||||||
|
|
||||||
|
EntityCollectionProcessor processor = mock(EntityCollectionProcessor.class);
|
||||||
|
handler.register(processor);
|
||||||
|
|
||||||
|
ODataResponse response = handler.process(request);
|
||||||
|
|
||||||
|
assertNotNull(response);
|
||||||
|
Mockito.verify(processor).countCollection(
|
||||||
|
Mockito.eq(request),
|
||||||
|
Mockito.any(ODataResponse.class),
|
||||||
|
Mockito.any(UriInfo.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCountWithNavigation() throws Exception {
|
||||||
|
ODataRequest request = new ODataRequest();
|
||||||
|
|
||||||
|
request.setMethod(HttpMethod.GET);
|
||||||
|
request.setRawODataPath("ESAllPrim/NavPropertyETTwoPrimMany/$count");
|
||||||
|
|
||||||
|
EntityCollectionProcessor processor = mock(EntityCollectionProcessor.class);
|
||||||
|
handler.register(processor);
|
||||||
|
|
||||||
|
ODataResponse response = handler.process(request);
|
||||||
|
|
||||||
|
assertNotNull(response);
|
||||||
|
Mockito.verify(processor).countCollection(
|
||||||
|
Mockito.eq(request),
|
||||||
|
Mockito.any(ODataResponse.class),
|
||||||
|
Mockito.any(UriInfo.class));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue