You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2013/09/04 11:00:07 UTC
git commit: Fix for incorrect Accept handling in case
Updated Branches:
refs/heads/master 7bbc14ed9 -> 33834d2be
Fix for incorrect Accept handling in case
Project: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/commit/33834d2b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/tree/33834d2b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/diff/33834d2b
Branch: refs/heads/master
Commit: 33834d2be75a3b2ebe552217d07e0dd0980be547
Parents: 7bbc14e
Author: Michael Bolz <mi...@apache.org>
Authored: Wed Sep 4 10:57:59 2013 +0200
Committer: Michael Bolz <mi...@apache.org>
Committed: Wed Sep 4 10:57:59 2013 +0200
----------------------------------------------------------------------
.../olingo/odata2/core/ContentNegotiator.java | 13 ++-
.../olingo/odata2/core/ODataRequestHandler.java | 26 +++++-
.../core/ODataRequestHandlerValidationTest.java | 93 +++++++++++++++++++-
3 files changed, 128 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/33834d2b/odata-core/src/main/java/org/apache/olingo/odata2/core/ContentNegotiator.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/ContentNegotiator.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/ContentNegotiator.java
index f9767c3..02bbd23 100644
--- a/odata-core/src/main/java/org/apache/olingo/odata2/core/ContentNegotiator.java
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/ContentNegotiator.java
@@ -26,6 +26,7 @@ import java.util.Set;
import org.apache.olingo.odata2.api.exception.ODataBadRequestException;
import org.apache.olingo.odata2.api.exception.ODataException;
import org.apache.olingo.odata2.api.exception.ODataNotAcceptableException;
+import org.apache.olingo.odata2.api.uri.UriInfo;
import org.apache.olingo.odata2.core.commons.ContentType;
import org.apache.olingo.odata2.core.commons.ContentType.ODataFormat;
import org.apache.olingo.odata2.core.uri.UriInfoImpl;
@@ -39,7 +40,17 @@ public class ContentNegotiator {
private static final String URI_INFO_FORMAT_ATOM = "atom";
private static final String URI_INFO_FORMAT_XML = "xml";
static final String DEFAULT_CHARSET = "utf-8";
-
+
+ /**
+ * Do the content negotiation based on requested content type (in <code>acceptHeaderContentTypes</code> list)
+ * and supported content types (in <code>supportedContentTypes</code> list).
+ *
+ * @param uriInfo additional uri informations especially <code>$format</code>
+ * @param acceptHeaderContentTypes list of requested content types
+ * @param supportedContentTypes list of supported content types
+ * @return best fitting content type or <code>NULL</code> if content type is not set and for given {@link UriInfo} is ignored
+ * @throws ODataException if no supported content type was found
+ */
public String doContentNegotiation(final UriInfoImpl uriInfo, final List<String> acceptHeaderContentTypes, final List<String> supportedContentTypes) throws ODataException {
ContentType contentType;
if (uriInfo.getFormat() == null) {
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/33834d2b/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestHandler.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestHandler.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestHandler.java
index 56b0fab..b61c6c2 100644
--- a/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestHandler.java
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestHandler.java
@@ -100,19 +100,19 @@ public class ODataRequestHandler {
context.stopRuntimeMeasurement(timingHandle2);
final ODataHttpMethod method = request.getMethod();
- final UriType uriType = uriInfo.getUriType();
validateMethodAndUri(method, uriInfo);
if (method == ODataHttpMethod.POST || method == ODataHttpMethod.PUT || method == ODataHttpMethod.PATCH || method == ODataHttpMethod.MERGE) {
checkRequestContentType(uriInfo, request.getContentType());
}
- final String acceptContentType = new ContentNegotiator().doContentNegotiation(uriInfo, request.getAcceptHeaders(), getSupportedContentTypes(uriInfo));
+ final String acceptContentType = doContentNegotiation(request, uriInfo);
timingHandle2 = context.startRuntimeMeasurement("Dispatcher", "dispatch");
odataResponse = dispatcher.dispatch(method, uriInfo, request.getBody(), request.getContentType(), acceptContentType);
context.stopRuntimeMeasurement(timingHandle2);
+ final UriType uriType = uriInfo.getUriType();
final String location = (method == ODataHttpMethod.POST && (uriType == UriType.URI1 || uriType == UriType.URI6B)) ? odataResponse.getIdLiteral() : null;
final HttpStatusCodes s = odataResponse.getStatus() == null ? method == ODataHttpMethod.POST ? uriType == UriType.URI9 ? HttpStatusCodes.OK : uriType == UriType.URI7B ? HttpStatusCodes.NO_CONTENT : HttpStatusCodes.CREATED : method == ODataHttpMethod.PUT || method == ODataHttpMethod.PATCH || method == ODataHttpMethod.MERGE || method == ODataHttpMethod.DELETE ? HttpStatusCodes.NO_CONTENT : HttpStatusCodes.OK : odataResponse.getStatus();
@@ -133,6 +133,23 @@ public class ODataRequestHandler {
return debugValue == null ? odataResponse : new ODataDebugResponseWrapper(context, odataResponse, uriInfo, exception, debugValue).wrapResponse();
}
+ /**
+ * Do the content negotiation based on requested content type (in HTTP accept header) and from {@link ODataService}
+ * supported content types (via {@link ODataService#getSupportedContentTypes(Class)}).
+ *
+ * @param request with requested content type
+ * @param uriInfo additional uri informations
+ * @return best fitting content type or <code>NULL</code> if content type is not set and for given {@link UriInfo} is ignored
+ * @throws ODataException if no supported content type was found
+ */
+ private String doContentNegotiation(final ODataRequest request, UriInfoImpl uriInfo) throws ODataException {
+ if(uriInfo.isCount() || uriInfo.isValue()) {
+ return request.getRequestHeaderValue("Accept");
+ } else {
+ return new ContentNegotiator().doContentNegotiation(uriInfo, request.getAcceptHeaders(), getSupportedContentTypes(uriInfo));
+ }
+ }
+
private String getServerDataServiceVersion() throws ODataException {
return service.getVersion() == null ? ODataServiceVersion.V20 : service.getVersion();
}
@@ -220,6 +237,11 @@ public class ODataRequestHandler {
case URI17:
if (method != ODataHttpMethod.GET && method != ODataHttpMethod.PUT && method != ODataHttpMethod.DELETE) {
throw new ODataMethodNotAllowedException(ODataMethodNotAllowedException.DISPATCH);
+ } else {
+ if(uriInfo.getFormat() != null) {
+// throw new ODataMethodNotAllowedException(ODataMethodNotAllowedException.DISPATCH);
+ throw new ODataBadRequestException(ODataBadRequestException.INVALID_SYNTAX);
+ }
}
break;
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/33834d2b/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataRequestHandlerValidationTest.java
----------------------------------------------------------------------
diff --git a/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataRequestHandlerValidationTest.java b/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataRequestHandlerValidationTest.java
index fe39c76..279bdd3 100644
--- a/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataRequestHandlerValidationTest.java
+++ b/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataRequestHandlerValidationTest.java
@@ -218,6 +218,7 @@ public class ODataRequestHandlerValidationTest extends BaseTest {
final ODataHttpMethod method,
final List<String> pathSegments,
final Map<String, String> queryParameters,
+ final List<String> acceptHeaders,
final String requestContentType) throws ODataException {
ODataRequest request = mock(ODataRequest.class);
when(request.getMethod()).thenReturn(method);
@@ -233,8 +234,20 @@ public class ODataRequestHandlerValidationTest extends BaseTest {
when(request.getQueryParameters())
.thenReturn(queryParameters == null ? new HashMap<String, String>() : queryParameters);
when(request.getContentType()).thenReturn(requestContentType);
+ when(request.getAcceptHeaders()).thenReturn(acceptHeaders);
return request;
}
+
+ private ODataRequest mockODataRequest(
+ final ODataHttpMethod method,
+ final List<String> pathSegments,
+ final Map<String, String> queryParameters,
+ final String requestContentType) throws ODataException {
+
+ List<String> acceptHeaders = new ArrayList<String>(0);
+ return mockODataRequest(method, pathSegments, queryParameters, acceptHeaders, requestContentType);
+ }
+
private ODataService mockODataService(final ODataServiceFactory serviceFactory) throws ODataException {
ODataService service = DispatcherTest.getMockService();
@@ -312,6 +325,36 @@ public class ODataRequestHandlerValidationTest extends BaseTest {
response.getStatus());
}
+ private void executeAndValidateGetRequest(
+ final List<String> pathSegments,
+ final Map<String, String> queryParameters,
+ final List<String> acceptHeaders,
+ final HttpStatusCodes expectedStatusCode) throws ODataException {
+
+ executeAndValidateRequest(ODataHttpMethod.GET, pathSegments, queryParameters, acceptHeaders, null, expectedStatusCode);
+ }
+
+ private void executeAndValidateRequest(final ODataHttpMethod method,
+ final List<String> pathSegments,
+ final Map<String, String> queryParameters,
+ final List<String> acceptHeaders,
+ final String requestContentType,
+ final HttpStatusCodes expectedStatusCode) throws ODataException {
+
+ ODataServiceFactory serviceFactory = mock(ODataServiceFactory.class);
+ final ODataService service = mockODataService(serviceFactory);
+ when(serviceFactory.createService(any(ODataContext.class))).thenReturn(service);
+
+ final ODataRequest request = mockODataRequest(method, pathSegments, queryParameters, acceptHeaders, requestContentType);
+ final ODataContextImpl context = new ODataContextImpl(request, serviceFactory);
+
+ final ODataResponse response = new ODataRequestHandler(serviceFactory, service, context).handle(request);
+ assertNotNull(response);
+ assertEquals(expectedStatusCode == null ? HttpStatusCodes.PAYMENT_REQUIRED : expectedStatusCode,
+ response.getStatus());
+ }
+
+
private void checkValueContentType(final ODataHttpMethod method, final UriType uriType, final String requestContentType) throws Exception {
executeAndValidateRequest(method, createPathSegments(uriType, false, true), null, requestContentType, null);
}
@@ -498,7 +541,15 @@ public class ODataRequestHandlerValidationTest extends BaseTest {
wrongOptions(ODataHttpMethod.POST, UriType.URI7B, false, false, false, false, false, false, true, false, false);
wrongOptions(ODataHttpMethod.PUT, UriType.URI17, false, true, false, false, false, false, false, false, false);
- wrongOptions(ODataHttpMethod.DELETE, UriType.URI17, true, false, false, false, false, false, false, false, false);
+ executeAndValidateRequest(ODataHttpMethod.PUT, createPathSegments(UriType.URI17, false, false),
+ createOptions(true, false, false, false, false, false, false, false, false),
+ null, HttpStatusCodes.BAD_REQUEST);
+
+ executeAndValidateRequest(ODataHttpMethod.DELETE, createPathSegments(UriType.URI17, false, false),
+ createOptions(true, false, false, false, false, false, false, false, false),
+ null, HttpStatusCodes.BAD_REQUEST);
+// wrongOptions(ODataHttpMethod.DELETE, UriType.URI17, true, false, false, false, false, false, false, false, false);
+
wrongOptions(ODataHttpMethod.DELETE, UriType.URI17, false, true, false, false, false, false, false, false, false);
}
@@ -547,6 +598,46 @@ public class ODataRequestHandlerValidationTest extends BaseTest {
wrongNavigationPath(ODataHttpMethod.DELETE, UriType.URI17, HttpStatusCodes.BAD_REQUEST);
}
+
+ @Test
+ public void requestAcceptHeader() throws Exception {
+ executeAndValidateGetRequest(createPathSegments(UriType.URI1, false, false), null,
+ Arrays.asList(HttpContentType.APPLICATION_JSON), null);
+ executeAndValidateGetRequest(createPathSegments(UriType.URI2, false, false), null,
+ Arrays.asList(HttpContentType.APPLICATION_JSON), null);
+ executeAndValidateGetRequest(createPathSegments(UriType.URI3, false, false), null,
+ Arrays.asList(HttpContentType.APPLICATION_JSON), null);
+ executeAndValidateGetRequest(createPathSegments(UriType.URI4, false, false), null,
+ Arrays.asList(HttpContentType.APPLICATION_JSON), null);
+ executeAndValidateGetRequest(createPathSegments(UriType.URI5, false, false), null,
+ Arrays.asList(HttpContentType.APPLICATION_JSON), null);
+ executeAndValidateGetRequest(createPathSegments(UriType.URI6A, false, false), null,
+ Arrays.asList(HttpContentType.APPLICATION_JSON), null);
+ executeAndValidateGetRequest(createPathSegments(UriType.URI6B, false, false), null,
+ Arrays.asList(HttpContentType.APPLICATION_JSON), null);
+ executeAndValidateGetRequest(createPathSegments(UriType.URI7A, false, false), null,
+ Arrays.asList(HttpContentType.APPLICATION_JSON), null);
+ executeAndValidateGetRequest(createPathSegments(UriType.URI7B, false, false), null,
+ Arrays.asList(HttpContentType.APPLICATION_JSON), null);
+ executeAndValidateGetRequest(createPathSegments(UriType.URI8, false, false), null,
+ Arrays.asList(HttpContentType.APPLICATION_XML), null);
+ // in discussion, hence currently not implemented (see ODataRequestHandler#doContentNegotiation(...))
+// executeAndValidateGetRequest(createPathSegments(UriType.URI8, false, false), null,
+// Arrays.asList(HttpContentType.TEXT_PLAIN), null);
+ executeAndValidateGetRequest(createPathSegments(UriType.URI9, false, false), null,
+ Arrays.asList(HttpContentType.APPLICATION_XML), HttpStatusCodes.METHOD_NOT_ALLOWED);
+ executeAndValidateGetRequest(createPathSegments(UriType.URI15, false, false), null,
+ Arrays.asList(HttpContentType.TEXT_PLAIN), null);
+ executeAndValidateGetRequest(createPathSegments(UriType.URI16, false, false), null,
+ Arrays.asList(HttpContentType.TEXT_PLAIN), null);
+ executeAndValidateGetRequest(createPathSegments(UriType.URI17, false, true), null,
+ Arrays.asList(HttpContentType.APPLICATION_OCTET_STREAM), null);
+ executeAndValidateGetRequest(createPathSegments(UriType.URI50A, false, false), null,
+ Arrays.asList(HttpContentType.APPLICATION_XML), null);
+ executeAndValidateGetRequest(createPathSegments(UriType.URI50B, false, false), null,
+ Arrays.asList(HttpContentType.APPLICATION_XML), null);
+ }
+
@Test
public void requestContentType() throws Exception {
executeAndValidateRequest(ODataHttpMethod.PUT, createPathSegments(UriType.URI2, false, false), null, HttpContentType.APPLICATION_XML, null);