[OLINGO-1238]Handling Prefer header with values being minimal and representation for GET and DELETE requests
This commit is contained in:
parent
f3919036ae
commit
03a02d2d69
|
@ -0,0 +1,355 @@
|
|||
/*
|
||||
* 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.fit.tecsvc.http;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.olingo.client.api.ODataClient;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||
import org.apache.olingo.commons.api.http.HttpMethod;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.fit.AbstractBaseTestITCase;
|
||||
import org.apache.olingo.fit.tecsvc.TecSvcConst;
|
||||
import org.apache.olingo.fit.util.StringHelper;
|
||||
import org.apache.olingo.server.tecsvc.async.TechnicalAsyncService;
|
||||
import org.junit.Test;
|
||||
|
||||
public class PreferHeaderForGetAndDeleteITCase extends AbstractBaseTestITCase {
|
||||
|
||||
private static final String SERVICE_URI = TecSvcConst.BASE_URI + "/";
|
||||
|
||||
@Test
|
||||
public void preferHeaderMinimal_GetEntitySet() throws Exception {
|
||||
URL url = new URL(SERVICE_URI + "ESAllPrim");
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.GET.name());
|
||||
connection.setRequestProperty(HttpHeader.PREFER, "return=minimal");
|
||||
connection.connect();
|
||||
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
|
||||
final String content = IOUtils.toString(connection.getErrorStream());
|
||||
assertTrue(content.contains("The Prefer header 'return=minimal' is not supported for this HTTP Method."));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preferHeaderRepresentation_GetEntitySet() throws Exception {
|
||||
URL url = new URL(SERVICE_URI + "ESAllPrim");
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.GET.name());
|
||||
connection.setRequestProperty(HttpHeader.PREFER, "return=representation");
|
||||
connection.connect();
|
||||
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
|
||||
final String content = IOUtils.toString(connection.getErrorStream());
|
||||
assertTrue(content.contains("The Prefer header 'return=representation' is not supported for this HTTP Method."));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preferHeaderMinimal_GetEntity() throws Exception {
|
||||
URL url = new URL(SERVICE_URI + "ESAllPrim(32767)");
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.GET.name());
|
||||
connection.setRequestProperty(HttpHeader.PREFER, "return=minimal");
|
||||
connection.connect();
|
||||
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
|
||||
final String content = IOUtils.toString(connection.getErrorStream());
|
||||
assertTrue(content.contains("The Prefer header 'return=minimal' is not supported for this HTTP Method."));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preferHeaderRepresentation_GetEntity() throws Exception {
|
||||
URL url = new URL(SERVICE_URI + "ESAllPrim(32767)");
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.GET.name());
|
||||
connection.setRequestProperty(HttpHeader.PREFER, "return=representation");
|
||||
connection.connect();
|
||||
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
|
||||
final String content = IOUtils.toString(connection.getErrorStream());
|
||||
assertTrue(content.contains("The Prefer header 'return=representation' is not supported for this HTTP Method."));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preferHeaderRepresentation_DeleteEntity() throws Exception {
|
||||
URL url = new URL(SERVICE_URI + "ESAllPrim(32767)");
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.DELETE.name());
|
||||
connection.setRequestProperty(HttpHeader.PREFER, "return=representation");
|
||||
connection.connect();
|
||||
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
|
||||
final String content = IOUtils.toString(connection.getErrorStream());
|
||||
assertTrue(content.contains("The Prefer header 'return=representation' is not supported for this HTTP Method."));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preferHeaderMinimal_DeleteEntity() throws Exception {
|
||||
URL url = new URL(SERVICE_URI + "ESAllPrim(32767)");
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.DELETE.name());
|
||||
connection.setRequestProperty(HttpHeader.PREFER, "return=minimal");
|
||||
connection.connect();
|
||||
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
|
||||
final String content = IOUtils.toString(connection.getErrorStream());
|
||||
assertTrue(content.contains("The Prefer header 'return=minimal' is not supported for this HTTP Method."));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preferHeaderRepresentation_GetComplexProperty() throws Exception {
|
||||
URL url = new URL(SERVICE_URI + "ESCompCollDerived(12345)/PropertyCompAno");
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.GET.name());
|
||||
connection.setRequestProperty(HttpHeader.PREFER, "return=representation");
|
||||
connection.connect();
|
||||
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
|
||||
final String content = IOUtils.toString(connection.getErrorStream());
|
||||
assertTrue(content.contains("The Prefer header 'return=representation' is not supported for this HTTP Method."));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preferHeaderMinimal_GetSimpleProperty() throws Exception {
|
||||
URL url = new URL(SERVICE_URI + "ESAllPrim(32767)/PropertyString");
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.GET.name());
|
||||
connection.setRequestProperty(HttpHeader.PREFER, "return=minimal");
|
||||
connection.connect();
|
||||
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
|
||||
final String content = IOUtils.toString(connection.getErrorStream());
|
||||
assertTrue(content.contains("The Prefer header 'return=minimal' is not supported for this HTTP Method."));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preferHeaderMinimal_GetNavigationProperty() throws Exception {
|
||||
URL url = new URL(SERVICE_URI + "ESAllPrim(32767)/NavPropertyETTwoPrimOne");
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.GET.name());
|
||||
connection.setRequestProperty(HttpHeader.PREFER, "return=minimal");
|
||||
connection.connect();
|
||||
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
|
||||
final String content = IOUtils.toString(connection.getErrorStream());
|
||||
assertTrue(content.contains("The Prefer header 'return=minimal' is not supported for this HTTP Method."));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preferHeaderRepresentation_GetReference() throws Exception {
|
||||
URL url = new URL(SERVICE_URI + "ESAllPrim(32767)/NavPropertyETTwoPrimOne/$ref");
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.GET.name());
|
||||
connection.setRequestProperty(HttpHeader.PREFER, "return=representation");
|
||||
connection.connect();
|
||||
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
|
||||
final String content = IOUtils.toString(connection.getErrorStream());
|
||||
assertTrue(content.contains("The Prefer header 'return=representation' is not supported for this HTTP Method."));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preferHeaderRepresentation_GetMediaEntitySet() throws Exception {
|
||||
URL url = new URL(SERVICE_URI + "ESMedia");
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.GET.name());
|
||||
connection.setRequestProperty(HttpHeader.PREFER, "return=representation");
|
||||
connection.connect();
|
||||
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
|
||||
final String content = IOUtils.toString(connection.getErrorStream());
|
||||
assertTrue(content.contains("The Prefer header 'return=representation' is not supported for this HTTP Method."));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preferHeaderMinimal_GetMediaEntity() throws Exception {
|
||||
URL url = new URL(SERVICE_URI + "ESMedia(1)");
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.GET.name());
|
||||
connection.setRequestProperty(HttpHeader.PREFER, "return=minimal");
|
||||
connection.connect();
|
||||
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
|
||||
final String content = IOUtils.toString(connection.getErrorStream());
|
||||
assertTrue(content.contains("The Prefer header 'return=minimal' is not supported for this HTTP Method."));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preferHeaderMinimal_PostMediaEntity() throws Exception {
|
||||
URL url = new URL(SERVICE_URI + "ESMedia");
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.POST.name());
|
||||
connection.setRequestProperty(HttpHeader.PREFER, "return=minimal");
|
||||
connection.setRequestProperty(HttpHeader.CONTENT_TYPE, "application/json");
|
||||
connection.setRequestProperty(HttpHeader.ACCEPT, "application/json");
|
||||
connection.connect();
|
||||
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
|
||||
final String content = IOUtils.toString(connection.getErrorStream());
|
||||
assertTrue(content.contains("The Prefer header 'return=minimal' is not supported for this HTTP Method."));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preferHeaderRepresentation_PutMediaEntity() throws Exception {
|
||||
URL url = new URL(SERVICE_URI + "ESMedia(1)");
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.PUT.name());
|
||||
connection.setRequestProperty(HttpHeader.PREFER, "return=representation");
|
||||
connection.connect();
|
||||
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
|
||||
final String content = IOUtils.toString(connection.getErrorStream());
|
||||
assertTrue(content.contains("The Prefer header 'return=representation' is not supported for this HTTP Method."));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preferHeaderRepresentation_Count() throws Exception {
|
||||
URL url = new URL(SERVICE_URI + "ESAllPrim/$count");
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.GET.name());
|
||||
connection.setRequestProperty(HttpHeader.PREFER, "return=representation");
|
||||
connection.connect();
|
||||
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
|
||||
final String content = IOUtils.toString(connection.getErrorStream());
|
||||
assertTrue(content.contains("The Prefer header 'return=representation' is not supported for this HTTP Method."));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preferHeaderMinimal_UnboundFunction() throws Exception {
|
||||
URL url = new URL(SERVICE_URI + "FICRTETKeyNav()");
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.GET.name());
|
||||
connection.setRequestProperty(HttpHeader.PREFER, "return=minimal");
|
||||
connection.connect();
|
||||
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
|
||||
final String content = IOUtils.toString(connection.getErrorStream());
|
||||
assertTrue(content.contains("The Prefer header 'return=minimal' is not supported for this HTTP Method."));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preferHeaderMinimal_Batch() throws Exception {
|
||||
InputStream content = Thread.currentThread().getContextClassLoader().getResourceAsStream("basicBatchPost.batch");
|
||||
final HttpURLConnection connection = postBatch(content, "batch_8194-cf13-1f56", 1, true);
|
||||
|
||||
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), connection.getResponseCode());
|
||||
final String response = IOUtils.toString(connection.getErrorStream());
|
||||
assertTrue(response.contains("The Prefer header 'return=minimal' is not supported for this HTTP Method."));
|
||||
|
||||
}
|
||||
|
||||
private HttpURLConnection postBatch(final InputStream content, String batchBoundary,
|
||||
int sleepTime, boolean preferHeader)
|
||||
throws IOException {
|
||||
|
||||
Map<String, String> headers = new HashMap<String, String>();
|
||||
String contentTypeValue = ContentType.create(
|
||||
ContentType.MULTIPART_MIXED, "boundary", batchBoundary).toContentTypeString();
|
||||
headers.put(HttpHeader.CONTENT_TYPE, contentTypeValue);
|
||||
headers.put(HttpHeader.ACCEPT, "application/json");
|
||||
if(sleepTime >= 0 && preferHeader) {
|
||||
headers.put(HttpHeader.PREFER, "respond-async; " +
|
||||
TechnicalAsyncService.TEC_ASYNC_SLEEP + "=" + String.valueOf(sleepTime));
|
||||
}
|
||||
if (preferHeader) {
|
||||
headers.put(HttpHeader.PREFER, "return=minimal");
|
||||
}
|
||||
StringHelper.Stream s = StringHelper.toStream(content);
|
||||
final URL url = new URL(SERVICE_URI + "$batch");
|
||||
return postRequest(url, s.asString("utf-8"), headers);
|
||||
}
|
||||
|
||||
private HttpURLConnection postRequest(final URL url, final String content, final Map<String, String> headers)
|
||||
throws IOException {
|
||||
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(HttpMethod.POST.toString());
|
||||
|
||||
for (Map.Entry<String, String> header : headers.entrySet()) {
|
||||
connection.setRequestProperty(header.getKey(), header.getValue());
|
||||
}
|
||||
|
||||
connection.setDoOutput(true);
|
||||
final OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
|
||||
writer.append(content);
|
||||
writer.close();
|
||||
connection.connect();
|
||||
return connection;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preferHeaderMinimal_InBatchPayload() throws Exception {
|
||||
InputStream content = Thread.currentThread().getContextClassLoader().
|
||||
getResourceAsStream("basicBatchPostWithPreferHeader.batch");
|
||||
final HttpURLConnection connection = postBatch(content, "batch_8194-cf13-1f56", 1, false);
|
||||
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
|
||||
StringHelper.Stream resultBody = StringHelper.toStream(connection.getInputStream());
|
||||
String resBody = resultBody.asString();
|
||||
assertTrue(resBody.contains("The Prefer header 'return=minimal' is not supported for this HTTP Method."));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ODataClient getClient() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
--batch_8194-cf13-1f56
|
||||
Content-Type: application/http
|
||||
Content-Transfer-Encoding: binary
|
||||
|
||||
GET ESAllPrim(32767) HTTP/1.1
|
||||
Accept: application/json
|
||||
|
||||
|
||||
--batch_8194-cf13-1f56
|
||||
Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd
|
||||
|
||||
--changeset_f980-1cb6-94dd
|
||||
Content-Type: application/http
|
||||
Content-Transfer-Encoding: binary
|
||||
Content-ID: changeRequest1
|
||||
|
||||
PUT ESAllPrim(32767) HTTP/1.1
|
||||
Accept: application/json
|
||||
Content-Type: application/json
|
||||
|
||||
{"PropertyString":"MODIFIED"}
|
||||
|
||||
--changeset_f980-1cb6-94dd--
|
||||
|
||||
--batch_8194-cf13-1f56
|
||||
Content-Type: application/http
|
||||
Content-Transfer-Encoding: binary
|
||||
|
||||
GET ESAllPrim(32767)/PropertyString HTTP/1.1
|
||||
Accept: application/json
|
||||
Prefer: return=minimal
|
||||
|
||||
|
||||
--batch_8194-cf13-1f56--
|
|
@ -18,14 +18,16 @@
|
|||
*/
|
||||
package org.apache.olingo.server.core;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.EdmAction;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.apache.olingo.commons.api.edm.EdmFunction;
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
||||
import org.apache.olingo.commons.api.edm.EdmReturnType;
|
||||
import org.apache.olingo.commons.api.edm.EdmSingleton;
|
||||
import org.apache.olingo.commons.api.edm.EdmType;
|
||||
import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
|
||||
import org.apache.olingo.commons.api.edm.EdmSingleton;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||
import org.apache.olingo.commons.api.http.HttpMethod;
|
||||
|
@ -69,15 +71,17 @@ import org.apache.olingo.server.api.uri.UriResourceNavigation;
|
|||
import org.apache.olingo.server.api.uri.UriResourcePartTyped;
|
||||
import org.apache.olingo.server.api.uri.UriResourcePrimitiveProperty;
|
||||
import org.apache.olingo.server.api.uri.UriResourceProperty;
|
||||
import org.apache.olingo.server.api.uri.UriResourceSingleton;
|
||||
import org.apache.olingo.server.core.batchhandler.BatchHandler;
|
||||
import org.apache.olingo.server.core.etag.PreconditionsValidator;
|
||||
import org.apache.olingo.server.api.uri.UriResourceSingleton;
|
||||
|
||||
public class ODataDispatcher {
|
||||
|
||||
private static final String NOT_IMPLEMENTED_MESSAGE = "not implemented";
|
||||
private final UriInfo uriInfo;
|
||||
private final ODataHandlerImpl handler;
|
||||
private static final String RETURN_MINIMAL = "return=minimal";
|
||||
private static final String RETURN_REPRESENTATION = "return=representation";
|
||||
|
||||
public ODataDispatcher(final UriInfo uriInfo, final ODataHandlerImpl handler) {
|
||||
this.uriInfo = uriInfo;
|
||||
|
@ -277,6 +281,7 @@ public class ODataDispatcher {
|
|||
.isCollection();
|
||||
|
||||
if (isCollection && httpMethod == HttpMethod.GET) {
|
||||
validatePreferHeader(request);
|
||||
final ContentType responseFormat = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, handler.getCustomContentTypeSupport(), RepresentationType.COLLECTION_REFERENCE);
|
||||
handler.selectProcessor(ReferenceCollectionProcessor.class)
|
||||
|
@ -289,6 +294,7 @@ public class ODataDispatcher {
|
|||
.createReference(request, response, uriInfo, requestFormat);
|
||||
|
||||
} else if (!isCollection && httpMethod == HttpMethod.GET) {
|
||||
validatePreferHeader(request);
|
||||
final ContentType responseFormat = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, handler.getCustomContentTypeSupport(), RepresentationType.REFERENCE);
|
||||
handler.selectProcessor(ReferenceProcessor.class).readReference(request, response, uriInfo, responseFormat);
|
||||
|
@ -300,6 +306,7 @@ public class ODataDispatcher {
|
|||
.updateReference(request, response, uriInfo, requestFormat);
|
||||
|
||||
} else if (httpMethod == HttpMethod.DELETE) {
|
||||
validatePreferHeader(request);
|
||||
handler.selectProcessor(ReferenceProcessor.class)
|
||||
.deleteReference(request, response, uriInfo);
|
||||
|
||||
|
@ -326,6 +333,7 @@ public class ODataDispatcher {
|
|||
ODataApplicationException, ODataLibraryException,
|
||||
ODataHandlerException, PreconditionException {
|
||||
final HttpMethod method = request.getMethod();
|
||||
validatePreferHeader(request);
|
||||
if (method == HttpMethod.GET) {
|
||||
// This can be a GET on an EntitySet, Navigation or Function
|
||||
final ContentType requestedContentType = ContentNegotiator.
|
||||
|
@ -362,6 +370,7 @@ public class ODataDispatcher {
|
|||
type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary) ?
|
||||
RepresentationType.BINARY : RepresentationType.VALUE;
|
||||
if (method == HttpMethod.GET) {
|
||||
validatePreferHeader(request);
|
||||
final ContentType requestedContentType = ContentNegotiator.
|
||||
doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, handler.getCustomContentTypeSupport(), valueRepresentationType);
|
||||
|
@ -377,6 +386,7 @@ public class ODataDispatcher {
|
|||
handler.selectProcessor(PrimitiveValueProcessor.class)
|
||||
.updatePrimitiveValue(request, response, uriInfo, requestFormat, responseFormat);
|
||||
} else if (method == HttpMethod.DELETE && resource instanceof UriResourceProperty) {
|
||||
validatePreferHeader(request);
|
||||
validatePreconditions(request, false);
|
||||
handler.selectProcessor(PrimitiveValueProcessor.class)
|
||||
.deletePrimitiveValue(request, response, uriInfo);
|
||||
|
@ -391,6 +401,7 @@ public class ODataDispatcher {
|
|||
final RepresentationType complexRepresentationType = isCollection ? RepresentationType.COLLECTION_COMPLEX
|
||||
: RepresentationType.COMPLEX;
|
||||
if (method == HttpMethod.GET) {
|
||||
validatePreferHeader(request);
|
||||
final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, handler.getCustomContentTypeSupport(), complexRepresentationType);
|
||||
if (isCollection) {
|
||||
|
@ -414,6 +425,7 @@ public class ODataDispatcher {
|
|||
.updateComplex(request, response, uriInfo, requestFormat, responseFormat);
|
||||
}
|
||||
} else if (method == HttpMethod.DELETE) {
|
||||
validatePreferHeader(request);
|
||||
validatePreconditions(request, false);
|
||||
if (isCollection) {
|
||||
handler.selectProcessor(ComplexCollectionProcessor.class)
|
||||
|
@ -433,6 +445,7 @@ public class ODataDispatcher {
|
|||
final RepresentationType representationType = isCollection ? RepresentationType.COLLECTION_PRIMITIVE
|
||||
: RepresentationType.PRIMITIVE;
|
||||
if (method == HttpMethod.GET) {
|
||||
validatePreferHeader(request);
|
||||
final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, handler.getCustomContentTypeSupport(), representationType);
|
||||
if (isCollection) {
|
||||
|
@ -456,6 +469,7 @@ public class ODataDispatcher {
|
|||
.updatePrimitive(request, response, uriInfo, requestFormat, responseFormat);
|
||||
}
|
||||
} else if (method == HttpMethod.DELETE) {
|
||||
validatePreferHeader(request);
|
||||
validatePreconditions(request, false);
|
||||
if (isCollection) {
|
||||
handler.selectProcessor(PrimitiveCollectionProcessor.class)
|
||||
|
@ -471,6 +485,7 @@ public class ODataDispatcher {
|
|||
|
||||
private void handleCountDispatching(final ODataRequest request, final ODataResponse response,
|
||||
final int lastPathSegmentIndex) throws ODataApplicationException, ODataLibraryException {
|
||||
validatePreferHeader(request);
|
||||
final UriResource resource = uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1);
|
||||
if (resource instanceof UriResourceEntitySet
|
||||
|| resource instanceof UriResourceNavigation
|
||||
|
@ -505,6 +520,7 @@ public class ODataDispatcher {
|
|||
ODataHandlerException {
|
||||
final HttpMethod method = request.getMethod();
|
||||
if (method == HttpMethod.GET) {
|
||||
validatePreferHeader(request);
|
||||
final ContentType requestedContentType = ContentNegotiator.
|
||||
doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, handler.getCustomContentTypeSupport(), RepresentationType.COLLECTION_ENTITY);
|
||||
|
@ -515,6 +531,7 @@ public class ODataDispatcher {
|
|||
doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, handler.getCustomContentTypeSupport(), RepresentationType.ENTITY);
|
||||
if (isMedia) {
|
||||
validatePreferHeader(request);
|
||||
final ContentType requestFormat = ContentType.parse(
|
||||
request.getHeader(HttpHeader.CONTENT_TYPE));
|
||||
handler.selectProcessor(MediaEntityProcessor.class)
|
||||
|
@ -530,6 +547,23 @@ public class ODataDispatcher {
|
|||
throwMethodNotAllowed(method);
|
||||
}
|
||||
}
|
||||
|
||||
/**Checks if Prefer header is set with return=minimal or
|
||||
* return=representation for GET and DELETE requests
|
||||
* @param request
|
||||
* @throws ODataHandlerException
|
||||
*/
|
||||
private void validatePreferHeader(final ODataRequest request) throws ODataHandlerException {
|
||||
final List<String> returnPreference = request.getHeaders(HttpHeader.PREFER);
|
||||
if (null != returnPreference) {
|
||||
for (String preference : returnPreference) {
|
||||
if (preference.equals(RETURN_MINIMAL) || preference.equals(RETURN_REPRESENTATION)) {
|
||||
throw new ODataHandlerException("Prefer Header not supported: " + preference,
|
||||
ODataHandlerException.MessageKeys.INVALID_PREFER_HEADER, preference);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSingletonMedia(final UriResource pathSegment) {
|
||||
return pathSegment instanceof UriResourceSingleton
|
||||
|
@ -544,12 +578,16 @@ public class ODataDispatcher {
|
|||
ODataLibraryException, ODataHandlerException, PreconditionException {
|
||||
final HttpMethod method = request.getMethod();
|
||||
if (method == HttpMethod.GET) {
|
||||
validatePreferHeader(request);
|
||||
final ContentType requestedContentType = ContentNegotiator.
|
||||
doContentNegotiation(uriInfo.getFormatOption(),
|
||||
request, handler.getCustomContentTypeSupport(), RepresentationType.ENTITY);
|
||||
handler.selectProcessor(EntityProcessor.class)
|
||||
.readEntity(request, response, uriInfo, requestedContentType);
|
||||
} else if (method == HttpMethod.PUT || method == HttpMethod.PATCH) {
|
||||
if (isMedia) {
|
||||
validatePreferHeader(request);
|
||||
}
|
||||
validatePreconditions(request, false);
|
||||
final ContentType requestFormat = getSupportedContentType(
|
||||
request.getHeader(HttpHeader.CONTENT_TYPE),
|
||||
|
@ -562,6 +600,7 @@ public class ODataDispatcher {
|
|||
} else if (method == HttpMethod.DELETE && !isSingleton) {
|
||||
validateIsSingleton(method);
|
||||
validatePreconditions(request, false);
|
||||
validatePreferHeader(request);
|
||||
handler.selectProcessor(isMedia ? MediaEntityProcessor.class : EntityProcessor.class)
|
||||
.deleteEntity(request, response, uriInfo);
|
||||
} else {
|
||||
|
|
|
@ -100,7 +100,8 @@ public class ODataExceptionHelper {
|
|||
|| ODataHandlerException.MessageKeys.AMBIGUOUS_XHTTP_METHOD.equals(e.getMessageKey())
|
||||
|| ODataHandlerException.MessageKeys.MISSING_CONTENT_TYPE.equals(e.getMessageKey())
|
||||
|| ODataHandlerException.MessageKeys.INVALID_CONTENT_TYPE.equals(e.getMessageKey())
|
||||
|| ODataHandlerException.MessageKeys.UNSUPPORTED_CONTENT_TYPE.equals(e.getMessageKey())) {
|
||||
|| ODataHandlerException.MessageKeys.UNSUPPORTED_CONTENT_TYPE.equals(e.getMessageKey())
|
||||
|| ODataHandlerException.MessageKeys.INVALID_PREFER_HEADER.equals(e.getMessageKey())) {
|
||||
serverError.setStatusCode(HttpStatusCode.BAD_REQUEST.getStatusCode());
|
||||
} else if (ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_ALLOWED.equals(e.getMessageKey())) {
|
||||
serverError.setStatusCode(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode());
|
||||
|
|
|
@ -42,7 +42,9 @@ public class ODataHandlerException extends ODataLibraryException {
|
|||
/** parameter: content type */
|
||||
INVALID_CONTENT_TYPE,
|
||||
/** parameter: version */
|
||||
ODATA_VERSION_NOT_SUPPORTED;
|
||||
ODATA_VERSION_NOT_SUPPORTED,
|
||||
/** parameter: prefer header */
|
||||
INVALID_PREFER_HEADER;
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
package org.apache.olingo.server.core.batchhandler;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||
import org.apache.olingo.commons.api.http.HttpMethod;
|
||||
|
@ -29,12 +31,15 @@ import org.apache.olingo.server.api.batch.BatchFacade;
|
|||
import org.apache.olingo.server.api.deserializer.batch.BatchDeserializerException;
|
||||
import org.apache.olingo.server.api.deserializer.batch.BatchDeserializerException.MessageKeys;
|
||||
import org.apache.olingo.server.api.processor.BatchProcessor;
|
||||
import org.apache.olingo.server.core.ODataHandlerException;
|
||||
import org.apache.olingo.server.core.ODataHandlerImpl;
|
||||
import org.apache.olingo.server.core.deserializer.batch.BatchParserCommon;
|
||||
|
||||
public class BatchHandler {
|
||||
private final BatchProcessor batchProcessor;
|
||||
private final ODataHandlerImpl oDataHandler;
|
||||
private static final String RETURN_MINIMAL = "return=minimal";
|
||||
private static final String RETURN_REPRESENTATION = "return=representation";
|
||||
|
||||
public BatchHandler(final ODataHandlerImpl oDataHandler, final BatchProcessor batchProcessor) {
|
||||
|
||||
|
@ -45,10 +50,28 @@ public class BatchHandler {
|
|||
public void process(final ODataRequest request, final ODataResponse response, final boolean isStrict)
|
||||
throws ODataApplicationException, ODataLibraryException {
|
||||
validateRequest(request);
|
||||
validatePreferHeader(request);
|
||||
|
||||
final BatchFacade operation = new BatchFacadeImpl(oDataHandler, batchProcessor, isStrict);
|
||||
batchProcessor.processBatch(operation, request, response);
|
||||
}
|
||||
|
||||
/** Checks if Prefer header is set with return=minimal or
|
||||
* return=representation for batch requests
|
||||
* @param request
|
||||
* @throws ODataHandlerException
|
||||
*/
|
||||
private void validatePreferHeader(final ODataRequest request) throws ODataHandlerException {
|
||||
final List<String> returnPreference = request.getHeaders(HttpHeader.PREFER);
|
||||
if (null != returnPreference) {
|
||||
for (String preference : returnPreference) {
|
||||
if (preference.equals(RETURN_MINIMAL) || preference.equals(RETURN_REPRESENTATION)) {
|
||||
throw new ODataHandlerException("Prefer Header not supported: " + preference,
|
||||
ODataHandlerException.MessageKeys.INVALID_PREFER_HEADER, preference);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validateRequest(final ODataRequest request) throws BatchDeserializerException {
|
||||
validateHttpMethod(request);
|
||||
|
|
|
@ -27,6 +27,7 @@ ODataHandlerException.ODATA_VERSION_NOT_SUPPORTED=OData version '%1$s' is not su
|
|||
ODataHandlerException.MISSING_CONTENT_TYPE=The Content-Type HTTP header must be specified for this request.
|
||||
ODataHandlerException.UNSUPPORTED_CONTENT_TYPE=The content type '%1$s' is not supported for this request.
|
||||
ODataHandlerException.INVALID_CONTENT_TYPE=The content type '%1$s' is not valid.
|
||||
ODataHandlerException.INVALID_PREFER_HEADER=The Prefer header '%1$s' is not supported for this HTTP Method.
|
||||
|
||||
UriParserSyntaxException.MUST_BE_LAST_SEGMENT=The segment '%1$s' must be the last segment.
|
||||
UriParserSyntaxException.UNKNOWN_SYSTEM_QUERY_OPTION=The system query option '%1$s' is not defined.
|
||||
|
|
Loading…
Reference in New Issue