[OLINGO-557] better server dispatching for functions

Change-Id: I4581fb226870672d2b2ff10617a97a40dd9543e3

Signed-off-by: Christian Amend <chrisam@apache.org>
This commit is contained in:
Klaus Straubinger 2015-03-06 09:56:31 +01:00 committed by Christian Amend
parent a3789c7cce
commit 33c1f02c07
2 changed files with 316 additions and 259 deletions

View File

@ -28,6 +28,8 @@ import org.apache.olingo.commons.api.edm.EdmFunction;
import org.apache.olingo.commons.api.edm.EdmFunctionImport;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.EdmReturnType;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
@ -328,7 +330,6 @@ public class ODataHandler {
handleOperationDispatching(request, response, true, returnType);
}
private void handleOperationDispatching(final ODataRequest request, final ODataResponse response,
final boolean isAction, final EdmReturnType edmReturnTypeKind)
throws ODataHandlerException, SerializerException, ContentNegotiatorException,
@ -350,7 +351,6 @@ public class ODataHandler {
}
}
private void handleReferenceDispatching(final ODataRequest request, final ODataResponse response,
final int lastPathSegmentIndex)
throws ContentNegotiatorException, ODataApplicationException, SerializerException, ODataHandlerException,
@ -397,10 +397,13 @@ public class ODataHandler {
DeserializerException {
final HttpMethod method = request.getMethod();
final UriResource resource = uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1);
if (resource instanceof UriResourceProperty) {
if (resource instanceof UriResourceProperty
|| resource instanceof UriResourceFunction
&& ((UriResourceFunction) resource).getType().getKind() == EdmTypeKind.PRIMITIVE) {
final EdmType type = resource instanceof UriResourceProperty ?
((UriResourceProperty) resource).getType() : ((UriResourceFunction) resource).getType();
final RepresentationType valueRepresentationType =
((UriResourceProperty) resource).getType() ==
EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary) ?
type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary) ?
RepresentationType.BINARY : RepresentationType.VALUE;
if (method == HttpMethod.GET) {
final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
@ -408,14 +411,14 @@ public class ODataHandler {
selectProcessor(PrimitiveValueProcessor.class)
.readPrimitiveValue(request, response, uriInfo, requestedContentType);
} else if (method == HttpMethod.PUT) {
} else if (method == HttpMethod.PUT && resource instanceof UriResourceProperty) {
final ContentType requestFormat = ContentType.parse(request.getHeader(HttpHeader.CONTENT_TYPE));
checkContentTypeSupport(requestFormat, valueRepresentationType);
final ContentType responseFormat = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
request, customContentTypeSupport, valueRepresentationType);
selectProcessor(PrimitiveValueProcessor.class)
.updatePrimitive(request, response, uriInfo, requestFormat, responseFormat);
} else if (method == HttpMethod.DELETE) {
} else if (method == HttpMethod.DELETE && resource instanceof UriResourceProperty) {
selectProcessor(PrimitiveValueProcessor.class).deletePrimitive(request, response, uriInfo);
} else {
throw new ODataHandlerException("HTTP method " + method + " is not allowed.",
@ -427,13 +430,13 @@ public class ODataHandler {
request, customContentTypeSupport, RepresentationType.MEDIA);
selectProcessor(MediaEntityProcessor.class)
.readMediaEntity(request, response, uriInfo, requestedContentType);
} else if (method == HttpMethod.PUT) {
} else if (method == HttpMethod.PUT && resource instanceof UriResourceEntitySet) {
final ContentType requestFormat = ContentType.parse(request.getHeader(HttpHeader.CONTENT_TYPE));
final ContentType responseFormat = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
request, customContentTypeSupport, RepresentationType.ENTITY);
selectProcessor(MediaEntityProcessor.class)
.updateMediaEntity(request, response, uriInfo, requestFormat, responseFormat);
} else if (method == HttpMethod.DELETE) {
} else if (method == HttpMethod.DELETE && resource instanceof UriResourceEntitySet) {
selectProcessor(MediaEntityProcessor.class).deleteEntity(request, response, uriInfo);
} else {
throw new ODataHandlerException("HTTP method " + method + " is not allowed.",
@ -556,10 +559,15 @@ public class ODataHandler {
final HttpMethod method = request.getMethod();
if (method == HttpMethod.GET) {
final UriResource resource = uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1);
if (resource instanceof UriResourceEntitySet || resource instanceof UriResourceNavigation) {
if (resource instanceof UriResourceEntitySet
|| resource instanceof UriResourceNavigation
|| resource instanceof UriResourceFunction
&& ((UriResourceFunction) resource).getType().getKind() == EdmTypeKind.ENTITY) {
selectProcessor(CountEntityCollectionProcessor.class)
.countEntityCollection(request, response, uriInfo);
} else if (resource instanceof UriResourcePrimitiveProperty) {
} else if (resource instanceof UriResourcePrimitiveProperty
|| resource instanceof UriResourceFunction
&& ((UriResourceFunction) resource).getType().getKind() == EdmTypeKind.PRIMITIVE) {
selectProcessor(CountPrimitiveCollectionProcessor.class)
.countPrimitiveCollection(request, response, uriInfo);
} else {

View File

@ -97,8 +97,8 @@ public class ODataHandlerTest {
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
dispatchMethodNotAllowed(HttpMethod.POST, "/", processor);
dispatchMethodNotAllowed(HttpMethod.PUT, "/", processor);
dispatchMethodNotAllowed(HttpMethod.PATCH, "/", processor);
dispatchMethodNotAllowed(HttpMethod.PUT, "/", processor);
dispatchMethodNotAllowed(HttpMethod.DELETE, "/", processor);
}
@ -135,8 +135,8 @@ public class ODataHandlerTest {
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
dispatchMethodNotAllowed(HttpMethod.POST, "$metadata", processor);
dispatchMethodNotAllowed(HttpMethod.PUT, "$metadata", processor);
dispatchMethodNotAllowed(HttpMethod.PATCH, "$metadata", processor);
dispatchMethodNotAllowed(HttpMethod.PUT, "$metadata", processor);
dispatchMethodNotAllowed(HttpMethod.DELETE, "$metadata", processor);
}
@ -303,15 +303,50 @@ public class ODataHandlerTest {
verify(entityCollectionProcessor).readEntityCollection(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
final String entityCountUri = "FICRTCollESTwoKeyNavParam(ParameterInt16=123)/$count";
final CountEntityCollectionProcessor entityCountProcessor = mock(CountEntityCollectionProcessor.class);
dispatch(HttpMethod.GET, entityCountUri, entityCountProcessor);
verify(entityCountProcessor).countEntityCollection(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));
dispatchMethodNotAllowed(HttpMethod.POST, entityCountUri, entityCountProcessor);
dispatchMethodNotAllowed(HttpMethod.PATCH, entityCountUri, entityCountProcessor);
dispatchMethodNotAllowed(HttpMethod.PUT, entityCountUri, entityCountProcessor);
dispatchMethodNotAllowed(HttpMethod.DELETE, entityCountUri, entityCountProcessor);
PrimitiveProcessor primitiveProcessor = mock(PrimitiveProcessor.class);
dispatch(HttpMethod.GET, "FICRTString()", primitiveProcessor);
verify(primitiveProcessor).readPrimitive(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
final String valueUri = "FINRTInt16()/$value";
final PrimitiveValueProcessor primitiveValueProcessor = mock(PrimitiveValueProcessor.class);
dispatch(HttpMethod.GET, valueUri, primitiveValueProcessor);
verify(primitiveValueProcessor).readPrimitiveValue(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
dispatchMethodNotAllowed(HttpMethod.POST, valueUri, primitiveValueProcessor);
dispatchMethodNotAllowed(HttpMethod.PATCH, valueUri, primitiveValueProcessor);
dispatchMethodNotAllowed(HttpMethod.PUT, valueUri, primitiveValueProcessor);
dispatchMethodNotAllowed(HttpMethod.DELETE, valueUri, primitiveValueProcessor);
final String primitiveCollectionUri = "FICRTCollString()";
PrimitiveCollectionProcessor primitiveCollectionProcessor = mock(PrimitiveCollectionProcessor.class);
dispatch(HttpMethod.GET, "FICRTCollString()", primitiveCollectionProcessor);
dispatch(HttpMethod.GET, primitiveCollectionUri, primitiveCollectionProcessor);
verify(primitiveCollectionProcessor).readPrimitiveCollection(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
dispatchMethodNotAllowed(HttpMethod.POST, primitiveCollectionUri, primitiveCollectionProcessor);
dispatchMethodNotAllowed(HttpMethod.PATCH, primitiveCollectionUri, primitiveCollectionProcessor);
dispatchMethodNotAllowed(HttpMethod.PUT, primitiveCollectionUri, primitiveCollectionProcessor);
dispatchMethodNotAllowed(HttpMethod.DELETE, primitiveCollectionUri, primitiveCollectionProcessor);
final String primitiveCountUri = "FICRTCollString()/$count";
final CountPrimitiveCollectionProcessor primitiveCountProcessor = mock(CountPrimitiveCollectionProcessor.class);
dispatch(HttpMethod.GET, primitiveCountUri, primitiveCountProcessor);
verify(primitiveCountProcessor).countPrimitiveCollection(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));
dispatchMethodNotAllowed(HttpMethod.POST, primitiveCountUri, primitiveCountProcessor);
dispatchMethodNotAllowed(HttpMethod.PATCH, primitiveCountUri, primitiveCountProcessor);
dispatchMethodNotAllowed(HttpMethod.PUT, primitiveCountUri, primitiveCountProcessor);
dispatchMethodNotAllowed(HttpMethod.DELETE, primitiveCountUri, primitiveCountProcessor);
ComplexProcessor complexProcessor = mock(ComplexProcessor.class);
dispatch(HttpMethod.GET, "FICRTCTTwoPrim()", complexProcessor);
@ -323,11 +358,26 @@ public class ODataHandlerTest {
verify(complexCollectionProcessor).readComplexCollection(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
dispatchMethodNotAllowed(HttpMethod.POST, "FICRTCollString()", mock(Processor.class));
dispatchMethodNotAllowed(HttpMethod.PUT, "FICRTCollString()", mock(Processor.class));
dispatchMethodNotAllowed(HttpMethod.DELETE, "FICRTCollString()", mock(Processor.class));
}
final String complexCountUri = "FICRTCollCTTwoPrim()/$count";
final CountComplexCollectionProcessor complexCountProcessor = mock(CountComplexCollectionProcessor.class);
dispatch(HttpMethod.GET, complexCountUri, complexCountProcessor);
verify(complexCountProcessor).countComplexCollection(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));
dispatchMethodNotAllowed(HttpMethod.POST, complexCountUri, complexCountProcessor);
dispatchMethodNotAllowed(HttpMethod.PATCH, complexCountUri, complexCountProcessor);
dispatchMethodNotAllowed(HttpMethod.PUT, complexCountUri, complexCountProcessor);
dispatchMethodNotAllowed(HttpMethod.DELETE, complexCountUri, complexCountProcessor);
final String mediaUri = "FICRTESMedia()/$value";
final MediaEntityProcessor mediaProcessor = mock(MediaEntityProcessor.class);
dispatch(HttpMethod.GET, mediaUri, mediaProcessor);
verify(mediaProcessor).readMediaEntity(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
dispatchMethodNotAllowed(HttpMethod.POST, mediaUri, mediaProcessor);
dispatchMethodNotAllowed(HttpMethod.PATCH, mediaUri, mediaProcessor);
dispatchMethodNotAllowed(HttpMethod.PUT, mediaUri, mediaProcessor);
dispatchMethodNotAllowed(HttpMethod.DELETE, mediaUri, mediaProcessor);
}
@Test
public void dispatchAction() throws Exception {
@ -391,12 +441,12 @@ public class ODataHandlerTest {
verify(processor).readEntity(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
dispatch(HttpMethod.PUT, uri, processor);
dispatch(HttpMethod.PATCH, uri, processor);
verify(processor).updateEntity(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class),
any(ContentType.class));
dispatch(HttpMethod.PATCH, uri, processor);
dispatch(HttpMethod.PUT, uri, processor);
verify(processor, times(2)).updateEntity(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class),
any(ContentType.class));
@ -452,12 +502,12 @@ public class ODataHandlerTest {
verify(processor).readPrimitive(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
dispatch(HttpMethod.PUT, uri, processor);
dispatch(HttpMethod.PATCH, uri, processor);
verify(processor).updatePrimitive(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class),
any(ContentType.class));
dispatch(HttpMethod.PATCH, uri, processor);
dispatch(HttpMethod.PUT, uri, processor);
verify(processor, times(2)).updatePrimitive(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class),
any(ContentType.class));
@ -519,8 +569,8 @@ public class ODataHandlerTest {
verify(processor).countPrimitiveCollection(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));
dispatchMethodNotAllowed(HttpMethod.POST, uri, processor);
dispatchMethodNotAllowed(HttpMethod.PUT, uri, processor);
dispatchMethodNotAllowed(HttpMethod.PATCH, uri, processor);
dispatchMethodNotAllowed(HttpMethod.PUT, uri, processor);
dispatchMethodNotAllowed(HttpMethod.DELETE, uri, processor);
}
@ -533,12 +583,12 @@ public class ODataHandlerTest {
verify(processor).readComplex(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
dispatch(HttpMethod.PUT, uri, processor);
dispatch(HttpMethod.PATCH, uri, processor);
verify(processor).updateComplex(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class),
any(ContentType.class));
dispatch(HttpMethod.PATCH, uri, processor);
dispatch(HttpMethod.PUT, uri, processor);
verify(processor, times(2)).updateComplex(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class),
any(ContentType.class));
@ -578,8 +628,8 @@ public class ODataHandlerTest {
verify(processor).countComplexCollection(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));
dispatchMethodNotAllowed(HttpMethod.POST, uri, processor);
dispatchMethodNotAllowed(HttpMethod.PUT, uri, processor);
dispatchMethodNotAllowed(HttpMethod.PATCH, uri, processor);
dispatchMethodNotAllowed(HttpMethod.PUT, uri, processor);
dispatchMethodNotAllowed(HttpMethod.DELETE, uri, processor);
}
@ -592,11 +642,11 @@ public class ODataHandlerTest {
verify(processor).readReference(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
any(ContentType.class));
dispatch(HttpMethod.PUT, uri, processor);
dispatch(HttpMethod.PATCH, uri, processor);
verify(processor).updateReference(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
any(ContentType.class));
dispatch(HttpMethod.PATCH, uri, processor);
dispatch(HttpMethod.PUT, uri, processor);
verify(processor, times(2)).updateReference(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
any(ContentType.class));
@ -619,8 +669,8 @@ public class ODataHandlerTest {
verify(processor).readReferenceCollection(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
any(ContentType.class));
dispatchMethodNotAllowed(HttpMethod.PUT, uri, processor);
dispatchMethodNotAllowed(HttpMethod.PATCH, uri, processor);
dispatchMethodNotAllowed(HttpMethod.PUT, uri, processor);
dispatchMethodNotAllowed(HttpMethod.DELETE, uri, processor);
}
@ -647,7 +697,6 @@ public class ODataHandlerTest {
return dispatch(method, path, query, headers, processors);
}
private ODataResponse dispatch(final HttpMethod method, final String path, final String query,
final Map<String, List<String>> headers, final List<Processor> processors) {
ODataRequest request = new ODataRequest();