[OLINGO-482] split server processor interfaces + improved dispatching

Change-Id: Ie57a469299e73662838307f1b96b558d3beb723d

Signed-off-by: Christian Amend <chrisam@apache.org>
This commit is contained in:
Klaus Straubinger 2014-11-06 13:19:20 +01:00 committed by Christian Amend
parent 3e11738125
commit a405e5b4b5
15 changed files with 965 additions and 861 deletions

View File

@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.olingo.server.api.processor;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriInfo;
/**
* Processor interface for handling a collection of complex-type instances, e.g.,
* a property of an entity defined as collection of complex-type instances.
*/
public interface ComplexTypeCollectionProcessor extends Processor {
/**
* Reads complex-type collection.
* If it is not available, for example due to permissions, the service responds with 404 Not Found.
* @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
* @param format requested content type after content negotiation
* @throws ODataApplicationException if the service implementation encounters a failure
* @throws SerializerException if serialization failed
*/
void readComplexTypeCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
throws ODataApplicationException, SerializerException;
}

View File

@ -0,0 +1,45 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.olingo.server.api.processor;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriInfo;
/**
* Processor interface for handling a complex type, e.g., a complex property of an entity.
*/
public interface ComplexTypeProcessor extends Processor {
/**
* Reads complex type.
* If it is not available, for example due to permissions, the service responds with 404 Not Found.
* @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
* @param format requested content type after content negotiation
* @throws ODataApplicationException if the service implementation encounters a failure
* @throws SerializerException if serialization failed
*/
void readComplexType(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
throws ODataApplicationException, SerializerException;
}

View File

@ -0,0 +1,44 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.olingo.server.api.processor;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriInfo;
/**
* Processor interface for handling counting a collection of entities, e.g., an Entity Set.
*/
public interface CountEntityTypeCollectionProcessor extends Processor {
/**
* Counts entities from persistence and puts serialized content and status into the response.
* Response content type is <code>text/plain</code> by default.
*
* @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
* @throws ODataApplicationException
* @throws SerializerException
*/
void countEntityTypeCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo)
throws ODataApplicationException, SerializerException;
}

View File

@ -26,9 +26,9 @@ import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriInfo; import org.apache.olingo.server.api.uri.UriInfo;
/** /**
* Processor interface for handling EntitySets (i.e. collection of entities). * Processor interface for handling a collection of entities, e.g., an Entity Set.
*/ */
public interface EntitySetProcessor extends Processor { public interface EntityTypeCollectionProcessor extends Processor {
/** /**
* Reads entities data from persistence and puts serialized content and status into the response. * Reads entities data from persistence and puts serialized content and status into the response.
@ -40,19 +40,6 @@ public interface EntitySetProcessor extends Processor {
* @throws ODataApplicationException * @throws ODataApplicationException
* @throws SerializerException * @throws SerializerException
*/ */
void readEntitySet(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestedContentType) void readEntityTypeCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo,
throws ODataApplicationException, SerializerException; ContentType requestedContentType) throws ODataApplicationException, SerializerException;
/**
* Count entities from persistence and puts serialized content and status into the response.
* Response content type is <code>text/plain</code> by default.
*
* @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
* @throws ODataApplicationException
* @throws SerializerException
*/
void countEntitySet(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException,
SerializerException;
} }

View File

@ -26,9 +26,9 @@ import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriInfo; import org.apache.olingo.server.api.uri.UriInfo;
/** /**
* Processor interface for handling a single Entity. * Processor interface for handling a single instance of an Entity Type.
*/ */
public interface EntityProcessor extends Processor { public interface EntityTypeProcessor extends Processor {
/** /**
* Reads entity data from persistence and puts serialized content and status into the response. * Reads entity data from persistence and puts serialized content and status into the response.
@ -39,6 +39,6 @@ public interface EntityProcessor extends Processor {
* @throws ODataApplicationException * @throws ODataApplicationException
* @throws SerializerException * @throws SerializerException
*/ */
void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestedContentType) void readEntityType(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestedContentType)
throws ODataApplicationException, SerializerException; throws ODataApplicationException, SerializerException;
} }

View File

@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.olingo.server.api.processor;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriInfo;
/**
* Processor interface for handling a collection of primitive-type instances, e.g.,
* a property of an entity defined as collection of primitive-type instances.
*/
public interface PrimitiveTypeCollectionProcessor extends Processor {
/**
* Reads primitive-type collection.
* If it is not available, for example due to permissions, the service responds with 404 Not Found.
* @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
* @param format requested content type after content negotiation
* @throws ODataApplicationException if the service implementation encounters a failure
* @throws SerializerException if serialization failed
*/
void readPrimitiveTypeCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
throws ODataApplicationException, SerializerException;
}

View File

@ -0,0 +1,60 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.olingo.server.api.processor;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriInfo;
/**
* Processor interface for handling a primitive type, e.g., a primitive property of an entity.
*/
public interface PrimitiveTypeProcessor extends Processor {
/**
* Reads primitive type.
* If its value is <code>null</code>, the service responds with 204 No Content.
* If it is not available, for example due to permissions, the service responds with 404 Not Found.
* @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
* @param format requested content type after content negotiation
* @throws ODataApplicationException if the service implementation encounters a failure
* @throws SerializerException if serialization failed
*/
void readPrimitiveType(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
throws ODataApplicationException, SerializerException;
/**
* Reads raw value of a primitive type, e.g., of a primitive property of an entity.
* If the value is <code>null</code>, the service responds with 204 No Content.
* If it is not available, for example due to permissions, the service responds with 404 Not Found.
* @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
* @param format requested content type after content negotiation
* @throws ODataApplicationException if the service implementation encounters a failure
* @throws SerializerException if serialization failed
*/
void readPrimitiveTypeAsValue(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
throws ODataApplicationException, SerializerException;
}

View File

@ -1,62 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.olingo.server.api.processor;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriInfo;
/**
* Processor interface for handling a property of an entity.
*/
public interface PropertyProcessor extends Processor {
/**
* Reads primitive or complex property from entity.
* If the property is single-valued and has the null value, the service responds with 204 No Content.
* If the property is not available, for example due to permissions, the service responds with 404 Not Found
*
* @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
* @param format - requested content type after content negotiation
* @throws ODataApplicationException if service implementation encounters a failure
* @throws SerializerException if serialization failed
*/
void readProperty(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
throws ODataApplicationException, SerializerException;
/**
* Reads value for primitive property from entity.
* If the property is single-valued and has the null value, the service responds with 204 No Content.
* If the property is not available, for example due to permissions, the service responds with 404 Not Found
*
* @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
* @param format - requested content type after content negotiation
* @throws ODataApplicationException if service implementation encounters a failure
* @throws SerializerException if serialization failed
*/
void readPropertyValue(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
throws ODataApplicationException, SerializerException;
}

View File

@ -35,20 +35,24 @@ 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.ODataServerError; import org.apache.olingo.server.api.ODataServerError;
import org.apache.olingo.server.api.ServiceMetadata; import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.processor.ComplexTypeCollectionProcessor;
import org.apache.olingo.server.api.processor.ComplexTypeProcessor;
import org.apache.olingo.server.api.processor.CountEntityTypeCollectionProcessor;
import org.apache.olingo.server.api.processor.DefaultProcessor; import org.apache.olingo.server.api.processor.DefaultProcessor;
import org.apache.olingo.server.api.processor.EntitySetProcessor; import org.apache.olingo.server.api.processor.EntityTypeCollectionProcessor;
import org.apache.olingo.server.api.processor.EntityProcessor; import org.apache.olingo.server.api.processor.EntityTypeProcessor;
import org.apache.olingo.server.api.processor.ExceptionProcessor; import org.apache.olingo.server.api.processor.ExceptionProcessor;
import org.apache.olingo.server.api.processor.MetadataProcessor; import org.apache.olingo.server.api.processor.MetadataProcessor;
import org.apache.olingo.server.api.processor.PrimitiveTypeCollectionProcessor;
import org.apache.olingo.server.api.processor.PrimitiveTypeProcessor;
import org.apache.olingo.server.api.processor.Processor; import org.apache.olingo.server.api.processor.Processor;
import org.apache.olingo.server.api.processor.PropertyProcessor;
import org.apache.olingo.server.api.processor.ServiceDocumentProcessor; import org.apache.olingo.server.api.processor.ServiceDocumentProcessor;
import org.apache.olingo.server.api.serializer.CustomContentTypeSupport; import org.apache.olingo.server.api.serializer.CustomContentTypeSupport;
import org.apache.olingo.server.api.serializer.RepresentationType; import org.apache.olingo.server.api.serializer.RepresentationType;
import org.apache.olingo.server.api.serializer.SerializerException; import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriInfo; import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriResource; import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceKind; import org.apache.olingo.server.api.uri.UriResourceEntitySet;
import org.apache.olingo.server.api.uri.UriResourceNavigation; import org.apache.olingo.server.api.uri.UriResourceNavigation;
import org.apache.olingo.server.api.uri.UriResourcePartTyped; import org.apache.olingo.server.api.uri.UriResourcePartTyped;
import org.apache.olingo.server.api.uri.UriResourceProperty; import org.apache.olingo.server.api.uri.UriResourceProperty;
@ -127,11 +131,10 @@ public class ODataHandler {
switch (uriInfo.getKind()) { switch (uriInfo.getKind()) {
case metadata: case metadata:
if (method.equals(HttpMethod.GET)) { if (method.equals(HttpMethod.GET)) {
MetadataProcessor mp = selectProcessor(MetadataProcessor.class); final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
request, customContentTypeSupport, RepresentationType.METADATA);
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request, selectProcessor(MetadataProcessor.class)
customContentTypeSupport, RepresentationType.METADATA); .readMetadata(request, response, uriInfo, requestedContentType);
mp.readMetadata(request, response, uriInfo, requestedContentType);
} else { } else {
throw new ODataHandlerException("HttpMethod " + method + " not allowed for metadata document", throw new ODataHandlerException("HttpMethod " + method + " not allowed for metadata document",
ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_ALLOWED, method.toString()); ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_ALLOWED, method.toString());
@ -140,15 +143,13 @@ public class ODataHandler {
case service: case service:
if (method.equals(HttpMethod.GET)) { if (method.equals(HttpMethod.GET)) {
if ("".equals(request.getRawODataPath())) { if ("".equals(request.getRawODataPath())) {
RedirectProcessor rdp = selectProcessor(RedirectProcessor.class); selectProcessor(RedirectProcessor.class).redirect(request, response);
rdp.redirect(request, response);
} else { } else {
ServiceDocumentProcessor sdp = selectProcessor(ServiceDocumentProcessor.class); final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
request, customContentTypeSupport, RepresentationType.SERVICE);
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request, selectProcessor(ServiceDocumentProcessor.class)
customContentTypeSupport, RepresentationType.SERVICE); .readServiceDocument(request, response, uriInfo, requestedContentType);
sdp.readServiceDocument(request, response, uriInfo, requestedContentType);
} }
} else { } else {
throw new ODataHandlerException("HttpMethod " + method + " not allowed for service document", throw new ODataHandlerException("HttpMethod " + method + " not allowed for service document",
@ -185,113 +186,118 @@ public class ODataHandler {
private void handleResourceDispatching(final ODataRequest request, final ODataResponse response) private void handleResourceDispatching(final ODataRequest request, final ODataResponse response)
throws ODataHandlerException, ContentNegotiatorException, ODataApplicationException, SerializerException { throws ODataHandlerException, ContentNegotiatorException, ODataApplicationException, SerializerException {
final HttpMethod method = request.getMethod();
final int lastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 1; final int lastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 1;
UriResource lastPathSegment = uriInfo.getUriResourceParts().get(lastPathSegmentIndex); final UriResource lastPathSegment = uriInfo.getUriResourceParts().get(lastPathSegmentIndex);
switch (lastPathSegment.getKind()) { switch (lastPathSegment.getKind()) {
case entitySet: case entitySet:
if (((UriResourcePartTyped) lastPathSegment).isCollection()) {
if (request.getMethod().equals(HttpMethod.GET)) {
EntitySetProcessor cp = selectProcessor(EntitySetProcessor.class);
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
customContentTypeSupport, RepresentationType.COLLECTION_ENTITY);
cp.readEntitySet(request, response, uriInfo, requestedContentType);
} else {
throw new ODataHandlerException("not implemented",
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
}
} else {
if (request.getMethod().equals(HttpMethod.GET)) {
EntityProcessor ep = selectProcessor(EntityProcessor.class);
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
customContentTypeSupport, RepresentationType.ENTITY);
ep.readEntity(request, response, uriInfo, requestedContentType);
} else {
throw new ODataHandlerException("not implemented",
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
}
}
break;
case navigationProperty: case navigationProperty:
if (((UriResourceNavigation) lastPathSegment).isCollection()) { if (((UriResourcePartTyped) lastPathSegment).isCollection()) {
if (request.getMethod().equals(HttpMethod.GET)) { if (method.equals(HttpMethod.GET)) {
EntitySetProcessor cp = selectProcessor(EntitySetProcessor.class); final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
request, customContentTypeSupport, RepresentationType.COLLECTION_ENTITY);
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request, selectProcessor(EntityTypeCollectionProcessor.class)
customContentTypeSupport, RepresentationType.COLLECTION_ENTITY); .readEntityTypeCollection(request, response, uriInfo, requestedContentType);
cp.readEntitySet(request, response, uriInfo, requestedContentType);
} else { } else {
throw new ODataHandlerException("not implemented", throw new ODataHandlerException("not implemented",
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED); ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
} }
} else { } else {
if (request.getMethod().equals(HttpMethod.GET)) { if (method.equals(HttpMethod.GET)) {
EntityProcessor ep = selectProcessor(EntityProcessor.class); final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
request, customContentTypeSupport, RepresentationType.ENTITY);
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request, selectProcessor(EntityTypeProcessor.class)
customContentTypeSupport, RepresentationType.ENTITY); .readEntityType(request, response, uriInfo, requestedContentType);
ep.readEntity(request, response, uriInfo, requestedContentType);
} else { } else {
throw new ODataHandlerException("not implemented", throw new ODataHandlerException("not implemented",
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED); ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
} }
} }
break; break;
case count: case count:
if (request.getMethod().equals(HttpMethod.GET)) { if (method.equals(HttpMethod.GET)) {
EntitySetProcessor cp = selectProcessor(EntitySetProcessor.class); final UriResource resource = uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1);
cp.countEntitySet(request, response, uriInfo); if (resource instanceof UriResourceEntitySet || resource instanceof UriResourceNavigation) {
selectProcessor(CountEntityTypeCollectionProcessor.class)
.countEntityTypeCollection(request, response, uriInfo);
} else {
throw new ODataHandlerException(
"Count of collections of primitive-type or complex-type instances is not implemented.",
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
}
} else { } else {
throw new ODataHandlerException("not implemented", throw new ODataHandlerException("HTTP method " + method + " is not allowed for count.",
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED); ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_ALLOWED, method.toString());
} }
break; break;
case primitiveProperty: case primitiveProperty:
case complexProperty: if (method.equals(HttpMethod.GET)) {
if (request.getMethod().equals(HttpMethod.GET)) {
PropertyProcessor ep = selectProcessor(PropertyProcessor.class);
final UriResourceProperty propertyResource = (UriResourceProperty) lastPathSegment; final UriResourceProperty propertyResource = (UriResourceProperty) lastPathSegment;
final boolean isCollection = propertyResource.isCollection(); final RepresentationType representationType = propertyResource.isCollection() ?
final boolean isComplex = propertyResource.getKind() == UriResourceKind.complexProperty; RepresentationType.COLLECTION_PRIMITIVE : RepresentationType.PRIMITIVE;
final RepresentationType representationType = final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
isComplex ? isCollection ? RepresentationType.COLLECTION_COMPLEX : RepresentationType.COMPLEX : request, customContentTypeSupport, representationType);
isCollection ? RepresentationType.COLLECTION_PRIMITIVE : RepresentationType.PRIMITIVE; if (representationType == RepresentationType.PRIMITIVE) {
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request, selectProcessor(PrimitiveTypeProcessor.class)
customContentTypeSupport, representationType); .readPrimitiveType(request, response, uriInfo, requestedContentType);
} else {
ep.readProperty(request, response, uriInfo, requestedContentType); selectProcessor(PrimitiveTypeCollectionProcessor.class)
.readPrimitiveTypeCollection(request, response, uriInfo, requestedContentType);
}
} else { } else {
throw new ODataHandlerException("not implemented", throw new ODataHandlerException("not implemented",
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED); ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
} }
break; break;
case complexProperty:
if (method.equals(HttpMethod.GET)) {
final UriResourceProperty propertyResource = (UriResourceProperty) lastPathSegment;
final RepresentationType representationType = propertyResource.isCollection() ?
RepresentationType.COLLECTION_COMPLEX : RepresentationType.COMPLEX;
final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
request, customContentTypeSupport, representationType);
if (representationType == RepresentationType.COMPLEX) {
selectProcessor(ComplexTypeProcessor.class)
.readComplexType(request, response, uriInfo, requestedContentType);
} else {
selectProcessor(ComplexTypeCollectionProcessor.class)
.readComplexTypeCollection(request, response, uriInfo, requestedContentType);
}
} else {
throw new ODataHandlerException("not implemented",
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
}
break;
case value: case value:
if (request.getMethod().equals(HttpMethod.GET)) { if (method.equals(HttpMethod.GET)) {
PropertyProcessor ep = selectProcessor(PropertyProcessor.class); final UriResource resource = uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1);
if (resource instanceof UriResourceProperty) {
final RepresentationType representationType =
(EdmPrimitiveType) ((UriResourceProperty) resource).getType() ==
EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary) ?
RepresentationType.BINARY : RepresentationType.VALUE;
final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
request, customContentTypeSupport, representationType);
final UriResourceProperty propertyResource = selectProcessor(PrimitiveTypeProcessor.class)
(UriResourceProperty) uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1); .readPrimitiveTypeAsValue(request, response, uriInfo, requestedContentType);
final RepresentationType representationType = } else {
(EdmPrimitiveType) propertyResource.getType() == throw new ODataHandlerException("Media Entity is not implemented.",
EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary) ? ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
RepresentationType.BINARY : }
RepresentationType.VALUE;
ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(), request,
customContentTypeSupport, representationType);
ep.readPropertyValue(request, response, uriInfo, requestedContentType);
} else { } else {
throw new ODataHandlerException("not implemented", throw new ODataHandlerException("not implemented",
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED); ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
} }
break; break;
default: default:
throw new ODataHandlerException("not implemented", throw new ODataHandlerException("not implemented",
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED); ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);

View File

@ -24,7 +24,8 @@ import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.edmx.EdmxReference; import org.apache.olingo.server.api.edmx.EdmxReference;
import org.apache.olingo.server.api.edmx.EdmxReferenceInclude; import org.apache.olingo.server.api.edmx.EdmxReferenceInclude;
import org.apache.olingo.server.tecsvc.data.DataProvider; import org.apache.olingo.server.tecsvc.data.DataProvider;
import org.apache.olingo.server.tecsvc.processor.TechnicalProcessor; import org.apache.olingo.server.tecsvc.processor.TechnicalEntityProcessor;
import org.apache.olingo.server.tecsvc.processor.TechnicalPrimitiveComplexProcessor;
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider; import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -64,7 +65,8 @@ public class TechnicalServlet extends HttpServlet {
} }
ODataHttpHandler handler = odata.createHandler(serviceMetadata); ODataHttpHandler handler = odata.createHandler(serviceMetadata);
handler.register(new TechnicalProcessor(dataProvider)); handler.register(new TechnicalEntityProcessor(dataProvider));
handler.register(new TechnicalPrimitiveComplexProcessor(dataProvider));
handler.process(req, resp); handler.process(req, resp);
} catch (RuntimeException e) { } catch (RuntimeException e) {
LOG.error("Server Error", e); LOG.error("Server Error", e);

View File

@ -0,0 +1,163 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.olingo.server.tecsvc.processor;
import java.io.ByteArrayInputStream;
import java.util.List;
import java.util.Locale;
import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.ContextURL.Suffix;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntitySet;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.processor.CountEntityTypeCollectionProcessor;
import org.apache.olingo.server.api.processor.EntityTypeCollectionProcessor;
import org.apache.olingo.server.api.processor.EntityTypeProcessor;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriResource;
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.SelectOption;
import org.apache.olingo.server.tecsvc.data.DataProvider;
/**
* Technical Processor for entity-related functionality.
*/
public class TechnicalEntityProcessor extends TechnicalProcessor
implements EntityTypeCollectionProcessor, CountEntityTypeCollectionProcessor, EntityTypeProcessor {
public TechnicalEntityProcessor(final DataProvider dataProvider) {
super(dataProvider);
}
@Override
public void readEntityTypeCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
validateOptions(uriInfo.asUriInfoResource());
if (uriInfo.asUriInfoResource().getUriResourceParts().size() > 1) {
throw new ODataApplicationException("Invalid resource type.",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
final EntitySet entitySet = readEntitySetInternal(edmEntitySet,
uriInfo.getCountOption() != null && uriInfo.getCountOption().getValue());
if (entitySet == null) {
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
} else {
final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
ODataSerializer serializer = odata.createSerializer(format);
final ExpandOption expand = uriInfo.getExpandOption();
final SelectOption select = uriInfo.getSelectOption();
response.setContent(serializer.entitySet(edmEntitySet, entitySet,
ODataSerializerOptions.with()
.contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
getContextUrl(serializer, edmEntitySet, false, expand, select))
.count(uriInfo.getCountOption())
.expand(expand).select(select)
.build()));
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
}
}
@Override
public void countEntityTypeCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
throws ODataApplicationException, SerializerException {
validateOptions(uriInfo.asUriInfoResource());
final List<UriResource> resourceParts = uriInfo.asUriInfoResource().getUriResourceParts();
final int pos = resourceParts.size() - 2;
if (pos > 0) {
throw new ODataApplicationException("Invalid resource type.",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
final EntitySet entitySet =
readEntitySetInternal(((UriResourceEntitySet) resourceParts.get(pos)).getEntitySet(), true);
if (entitySet == null) {
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
} else {
response.setContent(new ByteArrayInputStream(entitySet.getCount().toString().getBytes()));
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, HttpContentType.TEXT_PLAIN);
}
}
@Override
public void readEntityType(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType requestedContentType) throws ODataApplicationException, SerializerException {
validateOptions(uriInfo.asUriInfoResource());
if (uriInfo.asUriInfoResource().getUriResourceParts().size() > 1) {
throw new ODataApplicationException("Invalid resource type.",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0);
final Entity entity = dataProvider.read(edmEntitySet, resourceEntitySet.getKeyPredicates());
if (entity == null) {
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
} else {
final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
ODataSerializer serializer = odata.createSerializer(format);
final ExpandOption expand = uriInfo.getExpandOption();
final SelectOption select = uriInfo.getSelectOption();
response.setContent(serializer.entity(edmEntitySet, entity,
ODataSerializerOptions.with()
.contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
getContextUrl(serializer, edmEntitySet, true, expand, select))
.count(uriInfo.getCountOption())
.expand(expand).select(select)
.build()));
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
}
}
private EntitySet readEntitySetInternal(final EdmEntitySet edmEntitySet, final boolean withCount)
throws DataProvider.DataProviderException {
EntitySet entitySet = dataProvider.readAll(edmEntitySet);
// TODO: set count (correctly) and next link
if (withCount && entitySet.getCount() == null) {
entitySet.setCount(entitySet.getEntities().size());
}
return entitySet;
}
private ContextURL getContextUrl(final ODataSerializer serializer,
final EdmEntitySet entitySet, final boolean isSingleEntity,
final ExpandOption expand, final SelectOption select) throws SerializerException {
return ContextURL.with().entitySet(entitySet)
.selectList(serializer.buildContextURLSelectList(entitySet, expand, select))
.suffix(isSingleEntity ? Suffix.ENTITY : null)
.build();
}
}

View File

@ -0,0 +1,224 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.olingo.server.tecsvc.processor;
import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.processor.ComplexTypeCollectionProcessor;
import org.apache.olingo.server.api.processor.ComplexTypeProcessor;
import org.apache.olingo.server.api.processor.PrimitiveTypeCollectionProcessor;
import org.apache.olingo.server.api.processor.PrimitiveTypeProcessor;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriInfoResource;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
import org.apache.olingo.server.api.uri.UriResourceKind;
import org.apache.olingo.server.api.uri.UriResourceProperty;
import org.apache.olingo.server.tecsvc.data.DataProvider;
/**
* Technical Processor which provides functionality related to primitive and complex types and collections thereof.
*/
public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
implements PrimitiveTypeProcessor, PrimitiveTypeCollectionProcessor,
ComplexTypeProcessor, ComplexTypeCollectionProcessor {
public TechnicalPrimitiveComplexProcessor(final DataProvider dataProvider) {
super(dataProvider);
}
@Override
public void readPrimitiveType(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType contentType) throws ODataApplicationException, SerializerException {
readProperty(response, uriInfo, contentType);
}
@Override
public void readPrimitiveTypeCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType contentType) throws ODataApplicationException, SerializerException {
readProperty(response, uriInfo, contentType);
}
@Override
public void readComplexType(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType contentType) throws ODataApplicationException, SerializerException {
readProperty(response, uriInfo, contentType);
}
@Override
public void readComplexTypeCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType contentType) throws ODataApplicationException, SerializerException {
readProperty(response, uriInfo, contentType);
}
private void readProperty(ODataResponse response, final UriInfo uriInfo, final ContentType contentType)
throws ODataApplicationException, SerializerException {
final UriInfoResource resource = uriInfo.asUriInfoResource();
validateOptions(resource);
validatePath(resource);
final List<UriResource> resourceParts = resource.getUriResourceParts();
final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) resourceParts.get(0);
final List<String> path = getPropertyPath(resourceParts);
final Property property = getPropertyData(resourceEntitySet, path);
if (property == null) {
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
} else {
if (property.getValue() == null) {
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
} else {
final EdmEntitySet edmEntitySet = getEdmEntitySet(resource);
final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(path.size())).getProperty();
final ODataFormat format = ODataFormat.fromContentType(contentType);
ODataSerializer serializer = odata.createSerializer(format);
response.setContent(serializer.entityProperty(edmProperty, property,
ODataSerializerOptions.with().contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
ContextURL.with().entitySet(edmEntitySet)
.keyPath(serializer.buildContextURLKeyPredicate(
((UriResourceEntitySet) resourceParts.get(0)).getKeyPredicates()))
.navOrPropertyPath(buildPropertyPath(path))
.build())
.build()));
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
}
}
}
private Property getPropertyData(final UriResourceEntitySet resourceEntitySet, final List<String> path)
throws ODataApplicationException {
final Entity entity = dataProvider.read(resourceEntitySet.getEntitySet(), resourceEntitySet.getKeyPredicates());
if (entity == null) {
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
} else {
Property property = entity.getProperty(path.get(0));
for (final String name : path.subList(1, path.size())) {
if (property != null && (property.isLinkedComplex() || property.isComplex())) {
final List<Property> complex = property.isLinkedComplex() ?
property.asLinkedComplex().getValue() : property.asComplex();
property = null;
for (final Property innerProperty : complex) {
if (innerProperty.getName().equals(name)) {
property = innerProperty;
break;
}
}
}
}
return property;
}
}
private List<String> getPropertyPath(final List<UriResource> path) {
List<String> result = new LinkedList<String>();
int index = 1;
while (index < path.size() && path.get(index) instanceof UriResourceProperty) {
result.add(((UriResourceProperty) path.get(index)).getProperty().getName());
index++;
}
return result;
}
private String buildPropertyPath(final List<String> path) {
StringBuilder result = new StringBuilder();
for (final String segment : path) {
result.append(result.length() == 0 ? "" : '/').append(segment);
}
return result.toString();
}
@Override
public void readPrimitiveTypeAsValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType contentType) throws ODataApplicationException, SerializerException {
final UriInfoResource resource = uriInfo.asUriInfoResource();
validateOptions(resource);
validatePath(resource);
final List<UriResource> resourceParts = resource.getUriResourceParts();
final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) resourceParts.get(0);
final List<String> path = getPropertyPath(resourceParts);
final Property property = getPropertyData(resourceEntitySet, path);
if (property == null || property.getValue() == null) {
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
} else {
final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(path.size())).getProperty();
final EdmPrimitiveType type = (EdmPrimitiveType) edmProperty.getType();
if (type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary)) {
response.setContent(new ByteArrayInputStream((byte[]) property.getValue()));
} else {
try {
final String value = type.valueToString(property.getValue(),
edmProperty.isNullable(), edmProperty.getMaxLength(),
edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode());
response.setContent(new ByteArrayInputStream(value.getBytes("UTF-8")));
} catch (final EdmPrimitiveTypeException e) {
throw new ODataApplicationException("Error in value formatting.",
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT, e);
} catch (final UnsupportedEncodingException e) {
throw new ODataApplicationException("Encoding exception.",
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT, e);
}
}
response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
}
}
private void validatePath(final UriInfoResource uriInfo) throws ODataApplicationException {
final List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
for (final UriResource segment : resourcePaths.subList(1, resourcePaths.size())) {
final UriResourceKind kind = segment.getKind();
if (kind != UriResourceKind.primitiveProperty
&& kind != UriResourceKind.complexProperty
&& kind != UriResourceKind.count
&& kind != UriResourceKind.value) {
throw new ODataApplicationException("Invalid resource type.",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
}
}
}

View File

@ -18,60 +18,29 @@
*/ */
package org.apache.olingo.server.tecsvc.processor; package org.apache.olingo.server.tecsvc.processor;
import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.ContextURL.Suffix;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntitySet;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntitySet; import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode; import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
import org.apache.olingo.server.api.OData; import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException; import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ServiceMetadata; import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.processor.EntityProcessor; import org.apache.olingo.server.api.processor.Processor;
import org.apache.olingo.server.api.processor.EntitySetProcessor;
import org.apache.olingo.server.api.processor.PropertyProcessor;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriInfoResource; import org.apache.olingo.server.api.uri.UriInfoResource;
import org.apache.olingo.server.api.uri.UriParameter;
import org.apache.olingo.server.api.uri.UriResource; 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.UriResourceKind;
import org.apache.olingo.server.api.uri.UriResourceProperty;
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
import org.apache.olingo.server.tecsvc.data.DataProvider; import org.apache.olingo.server.tecsvc.data.DataProvider;
/** /**
* Technical Processor which provides currently implemented processor functionality. * Technical Processor base.
*/ */
public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor, PropertyProcessor { public abstract class TechnicalProcessor implements Processor {
private OData odata; protected OData odata;
private DataProvider dataProvider; protected DataProvider dataProvider;
public TechnicalProcessor(final DataProvider dataProvider) { protected TechnicalProcessor(final DataProvider dataProvider) {
this.dataProvider = dataProvider; this.dataProvider = dataProvider;
} }
@ -80,92 +49,23 @@ public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor,
this.odata = odata; this.odata = odata;
} }
@Override protected EdmEntitySet getEdmEntitySet(final UriInfoResource uriInfo) throws ODataApplicationException {
public void readEntitySet(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, final List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
final ContentType requestedContentType) throws ODataApplicationException, SerializerException { // first must be entity set
validateOptions(uriInfo.asUriInfoResource()); if (!(resourcePaths.get(0) instanceof UriResourceEntitySet)) {
throw new ODataApplicationException("Invalid resource type.",
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource()); HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
final EntitySet entitySet = readEntitySetInternal(edmEntitySet,
uriInfo.getCountOption() != null && uriInfo.getCountOption().getValue());
if (entitySet == null) {
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
} else {
final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
ODataSerializer serializer = odata.createSerializer(format);
final ExpandOption expand = uriInfo.getExpandOption();
final SelectOption select = uriInfo.getSelectOption();
response.setContent(serializer.entitySet(edmEntitySet, entitySet,
ODataSerializerOptions.with()
.contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
getContextUrl(serializer, edmEntitySet, false, expand, select, null, null))
.count(uriInfo.getCountOption())
.expand(expand).select(select)
.build()));
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
} }
}
@Override final UriResourceEntitySet uriResource = (UriResourceEntitySet) resourcePaths.get(0);
public void readEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, if (uriResource.getTypeFilterOnCollection() != null || uriResource.getTypeFilterOnEntry() != null) {
final ContentType requestedContentType) throws ODataApplicationException, SerializerException { throw new ODataApplicationException("Type filters are not supported.",
validateOptions(uriInfo.asUriInfoResource()); HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
final Entity entity = readEntityInternal(uriInfo.asUriInfoResource(), edmEntitySet);
if (entity == null) {
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
} else {
final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
ODataSerializer serializer = odata.createSerializer(format);
final ExpandOption expand = uriInfo.getExpandOption();
final SelectOption select = uriInfo.getSelectOption();
response.setContent(serializer.entity(edmEntitySet, entity,
ODataSerializerOptions.with()
.contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
getContextUrl(serializer, edmEntitySet, true, expand, select, null, null))
.count(uriInfo.getCountOption())
.expand(expand).select(select)
.build()));
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
} }
return uriResource.getEntitySet();
} }
@Override protected void validateOptions(final UriInfoResource uriInfo) throws ODataApplicationException {
public void countEntitySet(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
throws ODataApplicationException, SerializerException {
final List<UriResource> resourceParts = uriInfo.asUriInfoResource().getUriResourceParts();
final int pos = resourceParts.size() - 2;
final EntitySet entitySet =
readEntitySetInternal(((UriResourceEntitySet) resourceParts.get(pos)).getEntitySet(), true);
if (entitySet == null) {
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
} else {
response.setContent(new ByteArrayInputStream(entitySet.getCount().toString().getBytes()));
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, HttpContentType.TEXT_PLAIN);
}
}
private EntitySet readEntitySetInternal(final EdmEntitySet edmEntitySet,
final boolean withCount) throws DataProvider.DataProviderException {
EntitySet entitySet = dataProvider.readAll(edmEntitySet);
// TODO: set count (correctly) and next link
if (withCount && entitySet.getCount() == null) {
entitySet.setCount(entitySet.getEntities().size());
}
return entitySet;
}
private Entity readEntityInternal(final UriInfoResource uriInfo, final EdmEntitySet entitySet)
throws DataProvider.DataProviderException {
final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0);
return dataProvider.read(entitySet, resourceEntitySet.getKeyPredicates());
}
private void validateOptions(final UriInfoResource uriInfo) throws ODataApplicationException {
if (uriInfo.getCountOption() != null if (uriInfo.getCountOption() != null
|| !uriInfo.getCustomQueryOptions().isEmpty() || !uriInfo.getCustomQueryOptions().isEmpty()
|| uriInfo.getFilterOption() != null || uriInfo.getFilterOption() != null
@ -179,151 +79,4 @@ public class TechnicalProcessor implements EntitySetProcessor, EntityProcessor,
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
} }
} }
private EdmEntitySet getEdmEntitySet(final UriInfoResource uriInfo) throws ODataApplicationException {
final List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
// first must be entity set
if (!(resourcePaths.get(0) instanceof UriResourceEntitySet)) {
throw new ODataApplicationException("Invalid resource type.",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
List<UriResource> subResPaths = resourcePaths.subList(1, resourcePaths.size());
for (UriResource subResPath : subResPaths) {
UriResourceKind kind = subResPath.getKind();
if(kind != UriResourceKind.primitiveProperty
&& kind != UriResourceKind.complexProperty
&& kind != UriResourceKind.count
&& kind != UriResourceKind.value) {
throw new ODataApplicationException("Invalid resource type.",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
}
final UriResourceEntitySet uriResource = (UriResourceEntitySet) resourcePaths.get(0);
if (uriResource.getTypeFilterOnCollection() != null || uriResource.getTypeFilterOnEntry() != null) {
throw new ODataApplicationException("Type filters are not supported.",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
return uriResource.getEntitySet();
}
private ContextURL getContextUrl(final ODataSerializer serializer,
final EdmEntitySet entitySet, final boolean isSingleEntity,
final ExpandOption expand, final SelectOption select,
final List<UriParameter> keys, final String propertyPath) throws SerializerException {
return ContextURL.with().entitySet(entitySet)
.selectList(serializer.buildContextURLSelectList(entitySet, expand, select))
.suffix(isSingleEntity && propertyPath == null ? Suffix.ENTITY : null)
.keyPath(serializer.buildContextURLKeyPredicate(keys))
.navOrPropertyPath(propertyPath)
.build();
}
@Override
public void readProperty(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType contentType) throws ODataApplicationException, SerializerException {
validateOptions(uriInfo.asUriInfoResource());
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
final List<UriResource> resourceParts = uriInfo.getUriResourceParts();
final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) resourceParts.get(0);
final Entity entity = readEntityInternal(uriInfo.asUriInfoResource(), edmEntitySet);
if (entity == null) {
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
} else {
final List<String> path = getPropertyPath(resourceParts);
EdmProperty edmProperty = edmEntitySet.getEntityType().getStructuralProperty(path.get(0));
Property property = entity.getProperty(path.get(0));
for (final String name : path.subList(1, path.size())) {
if (property != null && (property.isLinkedComplex() || property.isComplex())) {
edmProperty = ((EdmComplexType) edmProperty.getType()).getStructuralProperty(name);
final List<Property> complex = property.isLinkedComplex() ?
property.asLinkedComplex().getValue() :
property.asComplex();
property = null;
for (final Property innerProperty : complex) {
if (innerProperty.getName().equals(name)) {
property = innerProperty;
break;
}
}
}
}
if (property == null) {
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
} else {
if (property.getValue() == null) {
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
} else {
final ODataFormat format = ODataFormat.fromContentType(contentType);
ODataSerializer serializer = odata.createSerializer(format);
response.setContent(serializer.entityProperty(edmProperty, property,
ODataSerializerOptions.with().contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
getContextUrl(serializer, edmEntitySet, true, null, null,
resourceEntitySet.getKeyPredicates(), buildPropertyPath(path)))
.build()));
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
}
}
}
}
private List<String> getPropertyPath(final List<UriResource> path) {
List<String> result = new LinkedList<String>();
int index = path.size();
while (path.get(--index) instanceof UriResourceProperty) {
result.add(0, ((UriResourceProperty) path.get(index)).getProperty().getName());
}
return result;
}
private String buildPropertyPath(final List<String> path) {
StringBuilder result = new StringBuilder();
for (final String segment : path) {
result.append(result.length() == 0 ? "" : '/').append(segment);
}
return result.toString();
}
@Override
public void readPropertyValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType contentType) throws ODataApplicationException, SerializerException {
validateOptions(uriInfo.asUriInfoResource());
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
final Entity entity = readEntityInternal(uriInfo.asUriInfoResource(), edmEntitySet);
if (entity == null) {
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
} else {
final UriResourceProperty uriProperty =
(UriResourceProperty) uriInfo.getUriResourceParts().get(uriInfo.getUriResourceParts().size() - 2);
final EdmProperty edmProperty = uriProperty.getProperty();
final Property property = entity.getProperty(edmProperty.getName());
if (property == null || property.getValue() == null) {
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
} else {
final EdmPrimitiveType type = (EdmPrimitiveType) edmProperty.getType();
if (type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary)) {
response.setContent(new ByteArrayInputStream((byte[]) property.getValue()));
} else {
try {
final String value = type.valueToString(property.getValue(),
edmProperty.isNullable(), edmProperty.getMaxLength(),
edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode());
response.setContent(new ByteArrayInputStream(value.getBytes("UTF-8")));
} catch (final EdmPrimitiveTypeException e) {
throw new ODataApplicationException("Error in value formatting.",
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT, e);
} catch (final UnsupportedEncodingException e) {
throw new ODataApplicationException("Encoding exception.",
HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT, e);
}
}
response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
}
}
}
} }

View File

@ -1,210 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.olingo.server.core;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import java.util.Collections;
import java.util.Locale;
import org.apache.olingo.commons.api.ODataException;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.edm.provider.EdmProvider;
import org.apache.olingo.server.api.edm.provider.EntitySet;
import org.apache.olingo.server.api.edmx.EdmxReference;
import org.apache.olingo.server.api.processor.MetadataProcessor;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
import org.junit.Before;
import org.junit.Test;
public class ODataHandlerExceptionHandlingTest {
private ODataHandler handler;
@Before
public void before() {
OData odata = OData.newInstance();
ServiceMetadata metadata = odata.createServiceMetadata(
new EdmTechProvider(), Collections.<EdmxReference>emptyList());
handler = new ODataHandler(odata, metadata);
}
@Test
public void wrongHttpMethodForMetadataDocument() throws Exception {
ODataRequest request = new ODataRequest();
request.setMethod(HttpMethod.POST);
request.setRawODataPath("$metadata");
ODataResponse response = handler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
assertNotNull(response.getContent());
request = new ODataRequest();
request.setMethod(HttpMethod.PUT);
request.setRawODataPath("$metadata");
response = handler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
assertNotNull(response.getContent());
request = new ODataRequest();
request.setMethod(HttpMethod.PATCH);
request.setRawODataPath("$metadata");
response = handler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
assertNotNull(response.getContent());
request = new ODataRequest();
request.setMethod(HttpMethod.MERGE);
request.setRawODataPath("$metadata");
response = handler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
assertNotNull(response.getContent());
request = new ODataRequest();
request.setMethod(HttpMethod.DELETE);
request.setRawODataPath("$metadata");
response = handler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
assertNotNull(response.getContent());
}
@Test
public void wrongHttpMethodForServiceDocument() throws Exception {
ODataRequest request = new ODataRequest();
request.setMethod(HttpMethod.POST);
request.setRawODataPath("");
ODataResponse response = handler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
assertNotNull(response.getContent());
request = new ODataRequest();
request.setMethod(HttpMethod.PUT);
request.setRawODataPath("");
response = handler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
assertNotNull(response.getContent());
request = new ODataRequest();
request.setMethod(HttpMethod.PATCH);
request.setRawODataPath("");
response = handler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
assertNotNull(response.getContent());
request = new ODataRequest();
request.setMethod(HttpMethod.MERGE);
request.setRawODataPath("");
response = handler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
assertNotNull(response.getContent());
request = new ODataRequest();
request.setMethod(HttpMethod.DELETE);
request.setRawODataPath("");
response = handler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
assertNotNull(response.getContent());
}
@Test
public void testUriParserExceptionResultsInRightResponseNotFound() throws Exception {
ODataRequest request = new ODataRequest();
request.setMethod(HttpMethod.GET);
request.setRawODataPath("NotFound");
ODataResponse response = handler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), response.getStatusCode());
}
@Test
public void testUriParserExceptionResultsInRightResponseBadRequest() throws Exception {
ODataRequest request = new ODataRequest();
request.setMethod(HttpMethod.GET);
request.setRawODataPath("ESAllPrim('122')");
ODataResponse response = handler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), response.getStatusCode());
}
@Test
public void testUriParserExceptionResultsInRightResponseEdmCause() throws Exception {
ODataRequest request = new ODataRequest();
request.setMethod(HttpMethod.GET);
request.setRawODataPath("EdmException");
OData odata = OData.newInstance();
ServiceMetadata serviceMetadata = odata.createServiceMetadata(new EdmProvider() {
public EntitySet getEntitySet(final FullQualifiedName entityContainer, final String entitySetName)
throws ODataException {
throw new ODataException("msg");
}
}, Collections.<EdmxReference>emptyList());
ODataHandler localHandler = new ODataHandler(odata, serviceMetadata);
ODataResponse response = localHandler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatusCode());
}
@Test
public void testWithApplicationExceptionInProcessor() throws Exception {
ODataRequest request = new ODataRequest();
request.setMethod(HttpMethod.GET);
request.setRawODataPath("$metadata");
MetadataProcessor metadataProcessor = mock(MetadataProcessor.class);
doThrow(new ODataApplicationException("msg", 425, Locale.ENGLISH)).when(metadataProcessor).readMetadata(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
handler.register(metadataProcessor);
ODataResponse response = handler.process(request);
assertNotNull(response);
assertEquals(425, response.getStatusCode());
}
}

View File

@ -18,15 +18,21 @@
*/ */
package org.apache.olingo.server.core; package org.apache.olingo.server.core;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Locale;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.olingo.commons.api.ODataException;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion; import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.apache.olingo.commons.api.format.ContentType; import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpContentType; import org.apache.olingo.commons.api.http.HttpContentType;
@ -34,311 +40,305 @@ import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpMethod; import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.commons.api.http.HttpStatusCode; 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.ODataApplicationException;
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.ServiceMetadata; import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.edm.provider.EdmProvider;
import org.apache.olingo.server.api.edm.provider.EntitySet;
import org.apache.olingo.server.api.edmx.EdmxReference; import org.apache.olingo.server.api.edmx.EdmxReference;
import org.apache.olingo.server.api.processor.EntitySetProcessor; import org.apache.olingo.server.api.processor.ComplexTypeCollectionProcessor;
import org.apache.olingo.server.api.processor.ComplexTypeProcessor;
import org.apache.olingo.server.api.processor.CountEntityTypeCollectionProcessor;
import org.apache.olingo.server.api.processor.EntityTypeCollectionProcessor;
import org.apache.olingo.server.api.processor.EntityTypeProcessor;
import org.apache.olingo.server.api.processor.MetadataProcessor; import org.apache.olingo.server.api.processor.MetadataProcessor;
import org.apache.olingo.server.api.processor.PropertyProcessor; import org.apache.olingo.server.api.processor.PrimitiveTypeCollectionProcessor;
import org.apache.olingo.server.api.processor.PrimitiveTypeProcessor;
import org.apache.olingo.server.api.processor.Processor;
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.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.Test; import org.junit.Test;
import org.mockito.Mockito;
public class ODataHandlerTest { public class ODataHandlerTest {
private ODataHandler handler; private static final String BASE_URI = "http://localhost/odata";
@Before
public void before() {
OData odata = OData.newInstance();
ServiceMetadata metadata = odata.createServiceMetadata(
new EdmTechProvider(), Collections.<EdmxReference>emptyList());
handler = new ODataHandler(odata, metadata);
}
@Test @Test
public void testServiceDocumentNonDefault() throws Exception { public void serviceDocumentNonDefault() throws Exception {
ODataRequest request = new ODataRequest(); final ServiceDocumentProcessor processor = mock(ServiceDocumentProcessor.class);
final ODataResponse response = dispatch(HttpMethod.GET, "/", processor);
request.setMethod(HttpMethod.GET);
request.setRawBaseUri("http://localhost/odata");
request.setRawODataPath("/");
ServiceDocumentProcessor processor = mock(ServiceDocumentProcessor.class);
handler.register(processor);
ODataResponse response = handler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatusCode()); assertEquals(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatusCode());
verify(processor).readServiceDocument(
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.MERGE, "/", processor);
dispatchMethodNotAllowed(HttpMethod.DELETE, "/", processor);
} }
@Test @Test
public void testServiceDocumentDefault() throws Exception { public void serviceDocumentDefault() throws Exception {
ODataRequest request = new ODataRequest(); final ODataResponse response = dispatch(HttpMethod.GET, "/", null);
request.setMethod(HttpMethod.GET);
request.setRawBaseUri("http://localhost/odata");
request.setRawODataPath("/");
ODataResponse response = handler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
String ct = response.getHeaders().get(HttpHeader.CONTENT_TYPE); String ct = response.getHeaders().get(HttpHeader.CONTENT_TYPE);
assertTrue(ct.contains("application/json")); assertThat(ct, containsString("application/json"));
assertTrue(ct.contains("odata.metadata=minimal")); assertThat(ct, containsString("odata.metadata=minimal"));
assertNotNull(response.getContent()); assertNotNull(response.getContent());
String doc = IOUtils.toString(response.getContent()); String doc = IOUtils.toString(response.getContent());
assertTrue(doc.contains("\"@odata.context\" : \"http://localhost/odata/$metadata\"")); assertThat(doc, containsString("\"@odata.context\" : \"" + BASE_URI + "/$metadata\""));
assertTrue(doc.contains("\"value\" :")); assertThat(doc, containsString("\"value\" :"));
} }
@Test @Test
public void testServiceDocumentRedirect() throws Exception { public void serviceDocumentRedirect() throws Exception {
ODataRequest request = new ODataRequest(); final ODataResponse response = dispatch(HttpMethod.GET, "", null);
request.setMethod(HttpMethod.GET);
request.setRawBaseUri("http://localhost/odata");
request.setRawRequestUri("http://localhost/odata");
request.setRawODataPath("");
ODataResponse response = handler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.TEMPORARY_REDIRECT.getStatusCode(), response.getStatusCode()); assertEquals(HttpStatusCode.TEMPORARY_REDIRECT.getStatusCode(), response.getStatusCode());
assertEquals("http://localhost/odata/", response.getHeaders().get(HttpHeader.LOCATION)); assertEquals(BASE_URI + "/", response.getHeaders().get(HttpHeader.LOCATION));
} }
@Test @Test
public void testMetadataNonDefault() throws Exception { public void metadataNonDefault() throws Exception {
ODataRequest request = new ODataRequest(); final MetadataProcessor processor = mock(MetadataProcessor.class);
final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", processor);
request.setMethod(HttpMethod.GET);
request.setRawODataPath("$metadata");
MetadataProcessor processor = mock(MetadataProcessor.class);
handler.register(processor);
ODataResponse response = handler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatusCode()); assertEquals(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatusCode());
verify(processor).readMetadata(
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.MERGE, "$metadata", processor);
dispatchMethodNotAllowed(HttpMethod.DELETE, "$metadata", processor);
} }
@Test @Test
public void testMetadataDefault() throws Exception { public void metadataDefault() throws Exception {
ODataRequest request = new ODataRequest(); final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", null);
request.setMethod(HttpMethod.GET);
request.setRawODataPath("$metadata");
ODataResponse response = handler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
assertEquals(HttpContentType.APPLICATION_XML, response.getHeaders().get(HttpHeader.CONTENT_TYPE)); assertEquals(HttpContentType.APPLICATION_XML, response.getHeaders().get(HttpHeader.CONTENT_TYPE));
assertNotNull(response.getContent()); assertNotNull(response.getContent());
String doc = IOUtils.toString(response.getContent()); assertThat(IOUtils.toString(response.getContent()),
containsString("<edmx:Edmx Version=\"4.0\""));
assertTrue(doc.contains("<edmx:Edmx Version=\"4.0\""));
} }
@Test @Test
public void testMaxVersionNone() { public void maxVersionNone() {
ODataRequest request = new ODataRequest(); final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", null);
request.setMethod(HttpMethod.GET);
request.setRawODataPath("$metadata");
ODataResponse response = handler.process(request);
assertNotNull(response);
assertEquals(ODataServiceVersion.V40.toString(), response.getHeaders().get(HttpHeader.ODATA_VERSION)); assertEquals(ODataServiceVersion.V40.toString(), response.getHeaders().get(HttpHeader.ODATA_VERSION));
} }
@Test @Test
public void testMaxVersionSupported() { public void maxVersionSupported() {
ODataRequest request = new ODataRequest(); final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", null,
HttpHeader.ODATA_MAX_VERSION, ODataServiceVersion.V40.toString(), null);
request.setMethod(HttpMethod.GET);
request.setRawODataPath("$metadata");
request.addHeader(HttpHeader.ODATA_MAX_VERSION, Arrays.asList(ODataServiceVersion.V40.toString()));
ODataResponse response = handler.process(request);
assertNotNull(response);
assertEquals(ODataServiceVersion.V40.toString(), response.getHeaders().get(HttpHeader.ODATA_VERSION)); assertEquals(ODataServiceVersion.V40.toString(), response.getHeaders().get(HttpHeader.ODATA_VERSION));
} }
@Test @Test
public void testMaxVersionNotSupported() { public void maxVersionNotSupported() {
ODataRequest request = new ODataRequest(); final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", null,
HttpHeader.ODATA_MAX_VERSION, ODataServiceVersion.V30.toString(), null);
request.setMethod(HttpMethod.GET);
request.setRawODataPath("$metadata");
request.addHeader(HttpHeader.ODATA_MAX_VERSION, Arrays.asList(ODataServiceVersion.V30.toString()));
ODataResponse response = handler.process(request);
assertNotNull(response);
assertEquals(ODataServiceVersion.V40.toString(), response.getHeaders().get(HttpHeader.ODATA_VERSION)); assertEquals(ODataServiceVersion.V40.toString(), response.getHeaders().get(HttpHeader.ODATA_VERSION));
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), response.getStatusCode()); assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), response.getStatusCode());
} }
@Test @Test
public void testContentNegotiationSupported() { public void contentNegotiationSupported() {
ODataRequest request = new ODataRequest(); final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", "$format=xml", null, null, null);
request.setMethod(HttpMethod.GET);
request.setRawODataPath("$metadata");
request.setRawQueryPath("$format=xml");
ODataResponse response = handler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode()); assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
} }
@Test @Test
public void testContentNegotiationNotSupported() { public void contentNegotiationNotSupported() {
ODataRequest request = new ODataRequest(); final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", "$format=not/Supported", null, null, null);
request.setMethod(HttpMethod.GET);
request.setRawODataPath("$metadata");
request.setRawQueryPath("$format=not/Supported");
ODataResponse response = handler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.NOT_ACCEPTABLE.getStatusCode(), response.getStatusCode()); assertEquals(HttpStatusCode.NOT_ACCEPTABLE.getStatusCode(), response.getStatusCode());
} }
@Test @Test
public void testContentNegotiationNotSupported2() { public void contentNegotiationNotSupported2() {
ODataRequest request = new ODataRequest(); final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", "$format=notSupported", null, null, null);
request.setMethod(HttpMethod.GET);
request.setRawODataPath("$metadata");
request.setRawQueryPath("$format=notSupported");
ODataResponse response = handler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.NOT_ACCEPTABLE.getStatusCode(), response.getStatusCode()); assertEquals(HttpStatusCode.NOT_ACCEPTABLE.getStatusCode(), response.getStatusCode());
} }
@Test @Test
public void testUnregisteredProcessor() { public void unregisteredProcessor() {
ODataRequest request = new ODataRequest(); final ODataResponse response = dispatch(HttpMethod.GET, "ESAllPrim", null);
request.setMethod(HttpMethod.GET);
request.setRawODataPath("ESAllPrim");
ODataResponse response = handler.process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), response.getStatusCode()); assertEquals(HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), response.getStatusCode());
} }
@Test @Test
public void testCount() throws Exception { public void uriParserExceptionResultsInRightResponseNotFound() throws Exception {
final ODataResponse response = dispatch(HttpMethod.GET, "NotFound", null);
assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), response.getStatusCode());
}
@Test
public void uriParserExceptionResultsInRightResponseBadRequest() throws Exception {
final ODataResponse response = dispatch(HttpMethod.GET, "ESAllPrim('122')", null);
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), response.getStatusCode());
}
@Test
public void applicationExceptionInProcessor() throws Exception {
MetadataProcessor processor = mock(MetadataProcessor.class);
doThrow(new ODataApplicationException("msg", 425, Locale.ENGLISH)).when(processor).readMetadata(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", processor);
assertEquals(425, response.getStatusCode());
}
@Test
public void uriParserExceptionResultsInRightResponseEdmCause() throws Exception {
final OData odata = OData.newInstance();
final ServiceMetadata serviceMetadata = odata.createServiceMetadata(
new EdmProvider() {
public EntitySet getEntitySet(final FullQualifiedName entityContainer, final String entitySetName)
throws ODataException {
throw new ODataException("msg");
}
},
Collections.<EdmxReference> emptyList());
ODataRequest request = new ODataRequest(); ODataRequest request = new ODataRequest();
request.setMethod(HttpMethod.GET); request.setMethod(HttpMethod.GET);
request.setRawODataPath("ESAllPrim/$count"); request.setRawODataPath("EdmException");
EntitySetProcessor processor = mock(EntitySetProcessor.class); final ODataResponse response = new ODataHandler(odata, serviceMetadata).process(request);
handler.register(processor);
ODataResponse response = handler.process(request);
assertNotNull(response); assertNotNull(response);
Mockito.verify(processor).countEntitySet( assertEquals(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatusCode());
Mockito.eq(request), }
Mockito.any(ODataResponse.class),
Mockito.any(UriInfo.class)); @Test
public void dispatchEntitySet() throws Exception {
final EntityTypeCollectionProcessor processor = mock(EntityTypeCollectionProcessor.class);
dispatch(HttpMethod.GET, "ESAllPrim", processor);
verify(processor).readEntityTypeCollection(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
}
@Test
public void dispatchEntitySetCount() throws Exception {
final CountEntityTypeCollectionProcessor processor = mock(CountEntityTypeCollectionProcessor.class);
dispatch(HttpMethod.GET, "ESAllPrim/$count", processor);
verify(processor).countEntityTypeCollection(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));
dispatchMethodNotAllowed(HttpMethod.POST, "ESAllPrim/$count", processor);
} }
@Test @Test
public void dispatchCountWithNavigation() throws Exception { public void dispatchCountWithNavigation() throws Exception {
ODataRequest request = new ODataRequest(); final CountEntityTypeCollectionProcessor processor = mock(CountEntityTypeCollectionProcessor.class);
dispatch(HttpMethod.GET, "ESAllPrim(0)/NavPropertyETTwoPrimMany/$count", processor);
request.setMethod(HttpMethod.GET); verify(processor).countEntityTypeCollection(
request.setRawODataPath("ESAllPrim(0)/NavPropertyETTwoPrimMany/$count"); any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));
EntitySetProcessor processor = mock(EntitySetProcessor.class);
handler.register(processor);
ODataResponse response = handler.process(request);
assertNotNull(response);
Mockito.verify(processor).countEntitySet(
Mockito.eq(request),
Mockito.any(ODataResponse.class),
Mockito.any(UriInfo.class));
} }
@Test @Test
public void dispatchAddressPrimitiveProperty() throws Exception { public void dispatchEntity() throws Exception {
ODataRequest request = new ODataRequest(); final EntityTypeProcessor processor = mock(EntityTypeProcessor.class);
dispatch(HttpMethod.GET, "ESAllPrim(0)", processor);
request.setMethod(HttpMethod.GET); verify(processor).readEntityType(
request.setRawODataPath("ESAllPrim(0)/PropertyInt16"); any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
PropertyProcessor processor = mock(PropertyProcessor.class);
handler.register(processor);
ODataResponse response = handler.process(request);
assertNotNull(response);
Mockito.verify(processor).readProperty(
Mockito.any(ODataRequest.class),
Mockito.any(ODataResponse.class),
Mockito.any(UriInfo.class),
Mockito.any(ContentType.class));
} }
@Test @Test
public void dispatchAddressPrimitivePropertyValue() throws Exception { public void dispatchPrimitiveProperty() throws Exception {
ODataRequest request = new ODataRequest(); final PrimitiveTypeProcessor processor = mock(PrimitiveTypeProcessor.class);
dispatch(HttpMethod.GET, "ESAllPrim(0)/PropertyInt16", processor);
request.setMethod(HttpMethod.GET); verify(processor).readPrimitiveType(
request.setRawODataPath("ESAllPrim(0)/PropertyInt16/$value"); any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
PropertyProcessor processor = mock(PropertyProcessor.class);
handler.register(processor);
ODataResponse response = handler.process(request);
assertNotNull(response);
Mockito.verify(processor).readPropertyValue(
Mockito.any(ODataRequest.class),
Mockito.any(ODataResponse.class),
Mockito.any(UriInfo.class),
Mockito.any(ContentType.class));
} }
@Test @Test
public void dispatchAddressComplexProperty() throws Exception { public void dispatchPrimitivePropertyValue() throws Exception {
ODataRequest request = new ODataRequest(); final PrimitiveTypeProcessor processor = mock(PrimitiveTypeProcessor.class);
dispatch(HttpMethod.GET, "ESAllPrim(0)/PropertyInt16/$value", processor);
request.setMethod(HttpMethod.GET); verify(processor).readPrimitiveTypeAsValue(
request.setRawODataPath("ESMixPrimCollComp(7)/PropertyComp"); any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
PropertyProcessor processor = mock(PropertyProcessor.class);
handler.register(processor);
ODataResponse response = handler.process(request);
assertNotNull(response);
Mockito.verify(processor).readProperty(
Mockito.any(ODataRequest.class),
Mockito.any(ODataResponse.class),
Mockito.any(UriInfo.class),
Mockito.any(ContentType.class));
} }
}
@Test
public void dispatchPrimitiveCollectionProperty() throws Exception {
final PrimitiveTypeCollectionProcessor processor = mock(PrimitiveTypeCollectionProcessor.class);
dispatch(HttpMethod.GET, "ESMixPrimCollComp(7)/CollPropertyString", processor);
verify(processor).readPrimitiveTypeCollection(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
}
@Test
public void dispatchComplexProperty() throws Exception {
final ComplexTypeProcessor processor = mock(ComplexTypeProcessor.class);
dispatch(HttpMethod.GET, "ESMixPrimCollComp(7)/PropertyComp", processor);
verify(processor).readComplexType(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
}
@Test
public void dispatchComplexCollectionProperty() throws Exception {
final ComplexTypeCollectionProcessor processor = mock(ComplexTypeCollectionProcessor.class);
dispatch(HttpMethod.GET, "ESMixPrimCollComp(7)/CollPropertyComp", processor);
verify(processor).readComplexTypeCollection(
any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
}
private ODataResponse dispatch(final HttpMethod method, final String path, final String query,
final String headerName, final String headerValue, final Processor processor) {
ODataRequest request = new ODataRequest();
request.setMethod(method);
request.setRawBaseUri(BASE_URI);
if (path.isEmpty()) {
request.setRawRequestUri(BASE_URI);
}
request.setRawODataPath(path);
request.setRawQueryPath(query);
if (headerName != null) {
request.addHeader(headerName, Collections.singletonList(headerValue));
}
final OData odata = OData.newInstance();
final ServiceMetadata metadata = odata.createServiceMetadata(
new EdmTechProvider(), Collections.<EdmxReference> emptyList());
ODataHandler handler = new ODataHandler(odata, metadata);
if (processor != null) {
handler.register(processor);
}
final ODataResponse response = handler.process(request);
assertNotNull(response);
return response;
}
private ODataResponse dispatch(final HttpMethod method, final String path, final Processor processor) {
return dispatch(method, path, null, null, null, processor);
}
private void dispatchMethodNotAllowed(final HttpMethod method, final String path, final Processor processor) {
final ODataResponse response = dispatch(method, path, processor);
assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
assertNotNull(response.getContent());
}
}