You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ra...@apache.org on 2019/08/28 03:47:17 UTC
[olingo-odata2] branch master updated: [OLINGO-1388]Allow
Content-id referencing across changesets
This is an automated email from the ASF dual-hosted git repository.
ramyav pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/olingo-odata2.git
The following commit(s) were added to refs/heads/master by this push:
new 9631139 [OLINGO-1388]Allow Content-id referencing across changesets
9631139 is described below
commit 9631139c22564ce0a549a727ca673eab40f4c9e6
Author: ramya vasanth <ra...@sap.com>
AuthorDate: Wed Aug 28 09:17:06 2019 +0530
[OLINGO-1388]Allow Content-id referencing across changesets
---
.../olingo/odata2/core/batch/BatchHandlerImpl.java | 21 +++--
.../olingo/odata2/core/batch/BatchHandlerTest.java | 19 ++++
.../batchContentIdReferencingForGet.batch | 35 +++++++
.../olingo/odata2/fit/client/ClientBatchTest.java | 102 +++++++++++++++++++++
.../basicBatchWithContentIdReferencing.batch | 58 ++++++++++++
.../basicBatchWithContentIdReferencingFail.batch | 65 +++++++++++++
.../resources/basicBatchWithContentIdWithNav.batch | 37 ++++++++
.../basicBatchWithContentIdWithNavFail.batch | 52 +++++++++++
8 files changed, 383 insertions(+), 6 deletions(-)
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchHandlerImpl.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchHandlerImpl.java
index cfc5df6..2c0d31a 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchHandlerImpl.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchHandlerImpl.java
@@ -53,25 +53,31 @@ public class BatchHandlerImpl implements BatchHandler {
public BatchHandlerImpl(final ODataServiceFactory factory, final ODataService service) {
this.factory = factory;
this.service = service;
+ contentIdMap = new HashMap<String, String>();
}
@Override
public BatchResponsePart handleBatchPart(final BatchRequestPart batchPart) throws ODataException {
if (batchPart.isChangeSet()) {
List<ODataRequest> changeSetRequests = batchPart.getRequests();
- contentIdMap = new HashMap<String, String>();
return service.getBatchProcessor().executeChangeSet(this, changeSetRequests);
} else {
if (batchPart.getRequests().size() != 1) {
throw new ODataException("Query Operation should contain one request");
}
ODataRequest request = batchPart.getRequests().get(0);
- ODataRequestHandler handler = createHandler(request);
String mimeHeaderContentId =
request.getRequestHeaderValue(BatchHelper.MIME_HEADER_CONTENT_ID.toLowerCase(Locale.ENGLISH));
String requestHeaderContentId =
request.getRequestHeaderValue(BatchHelper.REQUEST_HEADER_CONTENT_ID.toLowerCase(Locale.ENGLISH));
- ODataResponse response = setContentIdHeader(handler.handle(request), mimeHeaderContentId, requestHeaderContentId);
+
+ List<PathSegment> odataSegments = request.getPathInfo().getODataSegments();
+ if (!odataSegments.isEmpty() && odataSegments.get(0).getPath().matches("\\$.*")) {
+ request = modifyRequest(request, odataSegments);
+ }
+ ODataRequestHandler handler = createHandler(request);
+ ODataResponse response = setContentIdHeader(request, handler.handle(request),
+ mimeHeaderContentId, requestHeaderContentId);
List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
responses.add(response);
return BatchResponsePart.responses(responses).changeSet(false).build();
@@ -95,7 +101,7 @@ public class BatchHandlerImpl implements BatchHandler {
ODataRequestHandler handler = createHandler(request);
ODataResponse response = handler.handle(request);
if (response.getStatus().getStatusCode() < BAD_REQUEST) {
- response = setContentIdHeader(response, mimeHeaderContentId, requestHeaderContentId);
+ response = setContentIdHeader(request, response, mimeHeaderContentId, requestHeaderContentId);
}
if (request.getMethod().equals(ODataHttpMethod.POST)) {
String baseUri = getBaseUri(request);
@@ -151,10 +157,13 @@ public class BatchHandlerImpl implements BatchHandler {
return modifiedRequest;
}
- private ODataResponse setContentIdHeader(final ODataResponse response, final String mimeHeaderContentId,
- final String requestHeaderContentId) {
+ private ODataResponse setContentIdHeader(ODataRequest request, final ODataResponse response,
+ final String mimeHeaderContentId, final String requestHeaderContentId) {
ODataResponse modifiedResponse;
if (requestHeaderContentId != null && mimeHeaderContentId != null) {
+ String baseUri = getBaseUri(request);
+ fillContentIdMap(response, requestHeaderContentId, baseUri);
+ fillContentIdMap(response, mimeHeaderContentId, baseUri);
modifiedResponse =
ODataResponse.fromResponse(response).header(BatchHelper.REQUEST_HEADER_CONTENT_ID, requestHeaderContentId)
.header(BatchHelper.MIME_HEADER_CONTENT_ID, mimeHeaderContentId).build();
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchHandlerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchHandlerTest.java
index d520c10..bafc003 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchHandlerTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchHandlerTest.java
@@ -108,6 +108,25 @@ public class BatchHandlerTest {
}
@Test
+ public void contentIdReferencingForGet() throws Exception {
+ SERVICE_ROOT = SERVICE_BASE;
+ PathInfoImpl pathInfo = new PathInfoImpl();
+ pathInfo.setServiceRoot(new URI(SERVICE_ROOT));
+ pathInfo.setODataPathSegment(Collections.<PathSegment> singletonList(
+ new ODataPathSegmentImpl("$batch", null)));
+ EntityProviderBatchProperties properties = EntityProviderBatchProperties.init().pathInfo(pathInfo).build();
+ InputStream content = readFile("/batchContentIdReferencingForGet.batch");
+ List<BatchRequestPart> parsedRequest = EntityProvider.parseBatchRequest(CONTENT_TYPE, content, properties);
+
+ PathInfo firstPathInfo = parsedRequest.get(0).getRequests().get(0).getPathInfo();
+ assertFirst(firstPathInfo);
+
+ handler.handleBatchPart(parsedRequest.get(0));
+ handler.handleBatchPart(parsedRequest.get(1));
+ }
+
+
+ @Test
public void contentIdReferencingWithAdditionalSegments() throws Exception {
SERVICE_ROOT = SERVICE_BASE + "seg1/seg2/";
PathInfoImpl pathInfo = new PathInfoImpl();
diff --git a/odata2-lib/odata-core/src/test/resources/batchContentIdReferencingForGet.batch b/odata2-lib/odata-core/src/test/resources/batchContentIdReferencingForGet.batch
new file mode 100644
index 0000000..bb8cf44
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/batchContentIdReferencingForGet.batch
@@ -0,0 +1,35 @@
+--batch_123
+Content-Type: multipart/mixed; boundary=changeset_b4d2651f-4c8e-4707-8ac3-5bdde1e25760
+
+--changeset_b4d2651f-4c8e-4707-8ac3-5bdde1e25760
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+Content-Id: 1
+
+POST Employees HTTP/1.1
+Content-Length: 23
+Accept: application/json
+content-type: application/json
+
+gAAAAgABwESAAMAAAABAAEA
+--changeset_b4d2651f-4c8e-4707-8ac3-5bdde1e25760
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+Content-Id: 2
+
+PUT $1/EmployeeName HTTP/1.1
+Content-Length: 41
+Accept: application/json
+content-type: application/json
+
+{"EmployeeName":"Frederic Fall MODIFIED"}
+--changeset_b4d2651f-4c8e-4707-8ac3-5bdde1e25760--
+
+--batch_123
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+GET $1 HTTP/1.1
+
+
+--batch_123--
\ No newline at end of file
diff --git a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/client/ClientBatchTest.java b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/client/ClientBatchTest.java
index 66be286..da5a302 100644
--- a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/client/ClientBatchTest.java
+++ b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/client/ClientBatchTest.java
@@ -351,4 +351,106 @@ public class ClientBatchTest extends AbstractRefTest {
+ "\"Could not find an entity set or function import for 'nonsense'.\"}}}", response.getBody());
}
}
+
+ @Test
+ public void testContentIDReferencing() throws Exception {
+ final HttpPost post = new HttpPost(URI.create(getEndpoint().toString() + "$batch"));
+ post.setHeader("Content-Type", "multipart/mixed;boundary=" + BOUNDARY);
+
+ String body = StringHelper.inputStreamToStringCRLFLineBreaks(
+ this.getClass().getResourceAsStream("/basicBatchWithContentIdReferencing.batch"));
+ HttpEntity entity = new StringEntity(body);
+ post.setEntity(entity);
+ HttpResponse batchResponse = getHttpClient().execute(post);
+
+ assertNotNull(batchResponse);
+ assertEquals(202, batchResponse.getStatusLine().getStatusCode());
+
+ InputStream responseBody = batchResponse.getEntity().getContent();
+ String contentType = batchResponse.getFirstHeader(HttpHeaders.CONTENT_TYPE).getValue();
+ List<BatchSingleResponse> responses = EntityProvider.parseBatchResponse(responseBody, contentType);
+ assertEquals("201", responses.get(0).getStatusCode());
+ assertEquals("Created", responses.get(0).getStatusInfo());
+ assertEquals("201", responses.get(1).getStatusCode());
+ assertEquals("Created", responses.get(1).getStatusInfo());
+ assertEquals("200", responses.get(2).getStatusCode());
+ assertEquals("OK", responses.get(2).getStatusInfo());
+ }
+
+ @Test
+ public void testContentIDReferencingfail() throws Exception {
+ final HttpPost post = new HttpPost(URI.create(getEndpoint().toString() + "$batch"));
+ post.setHeader("Content-Type", "multipart/mixed;boundary=" + BOUNDARY);
+
+ String body = StringHelper.inputStreamToStringCRLFLineBreaks(
+ this.getClass().getResourceAsStream("/basicBatchWithContentIdReferencingFail.batch"));
+ HttpEntity entity = new StringEntity(body);
+ post.setEntity(entity);
+ HttpResponse batchResponse = getHttpClient().execute(post);
+
+ assertNotNull(batchResponse);
+ assertEquals(202, batchResponse.getStatusLine().getStatusCode());
+
+ InputStream responseBody = batchResponse.getEntity().getContent();
+ String contentType = batchResponse.getFirstHeader(HttpHeaders.CONTENT_TYPE).getValue();
+ List<BatchSingleResponse> responses = EntityProvider.parseBatchResponse(responseBody, contentType);
+ assertEquals("400", responses.get(0).getStatusCode());
+ assertEquals("Bad Request", responses.get(0).getStatusInfo());
+ assertEquals("201", responses.get(1).getStatusCode());
+ assertEquals("Created", responses.get(1).getStatusInfo());
+ assertEquals("404", responses.get(2).getStatusCode());
+ assertEquals("Not Found", responses.get(2).getStatusInfo());
+ assertEquals("200", responses.get(3).getStatusCode());
+ assertEquals("OK", responses.get(3).getStatusInfo());
+ }
+
+ @Test
+ public void testContentIDReferencingWithNav() throws Exception {
+ final HttpPost post = new HttpPost(URI.create(getEndpoint().toString() + "$batch"));
+ post.setHeader("Content-Type", "multipart/mixed;boundary=" + BOUNDARY);
+
+ String body = StringHelper.inputStreamToStringCRLFLineBreaks(
+ this.getClass().getResourceAsStream("/basicBatchWithContentIdWithNav.batch"));
+ HttpEntity entity = new StringEntity(body);
+ post.setEntity(entity);
+ HttpResponse batchResponse = getHttpClient().execute(post);
+
+ assertNotNull(batchResponse);
+ assertEquals(202, batchResponse.getStatusLine().getStatusCode());
+
+ InputStream responseBody = batchResponse.getEntity().getContent();
+ String contentType = batchResponse.getFirstHeader(HttpHeaders.CONTENT_TYPE).getValue();
+ List<BatchSingleResponse> responses = EntityProvider.parseBatchResponse(responseBody, contentType);
+ assertEquals("201", responses.get(0).getStatusCode());
+ assertEquals("Created", responses.get(0).getStatusInfo());
+ assertEquals("200", responses.get(1).getStatusCode());
+ assertEquals("OK", responses.get(1).getStatusInfo());
+ assertTrue(responses.get(1).getBody().contains("Building 100"));
+ }
+
+ @Test
+ public void testContentIDReferencingWithNavFail() throws Exception {
+ final HttpPost post = new HttpPost(URI.create(getEndpoint().toString() + "$batch"));
+ post.setHeader("Content-Type", "multipart/mixed;boundary=" + BOUNDARY);
+
+ String body = StringHelper.inputStreamToStringCRLFLineBreaks(
+ this.getClass().getResourceAsStream("/basicBatchWithContentIdWithNavFail.batch"));
+ HttpEntity entity = new StringEntity(body);
+ post.setEntity(entity);
+ HttpResponse batchResponse = getHttpClient().execute(post);
+
+ assertNotNull(batchResponse);
+ assertEquals(202, batchResponse.getStatusLine().getStatusCode());
+
+ InputStream responseBody = batchResponse.getEntity().getContent();
+ String contentType = batchResponse.getFirstHeader(HttpHeaders.CONTENT_TYPE).getValue();
+ List<BatchSingleResponse> responses = EntityProvider.parseBatchResponse(responseBody, contentType);
+ assertEquals("400", responses.get(0).getStatusCode());
+ assertEquals("Bad Request", responses.get(0).getStatusInfo());
+ assertTrue(responses.get(0).getBody().contains("The request body is malformed."));
+ assertEquals("404", responses.get(1).getStatusCode());
+ assertEquals("Not Found", responses.get(1).getStatusInfo());
+ assertTrue(responses.get(1).getBody().contains(
+ "Could not find an entity set or function import for '$2'."));
+ }
}
diff --git a/odata2-lib/odata-fit/src/test/resources/basicBatchWithContentIdReferencing.batch b/odata2-lib/odata-fit/src/test/resources/basicBatchWithContentIdReferencing.batch
new file mode 100644
index 0000000..a3d5ac0
--- /dev/null
+++ b/odata2-lib/odata-fit/src/test/resources/basicBatchWithContentIdReferencing.batch
@@ -0,0 +1,58 @@
+--batch_123
+Content-Type: multipart/mixed; boundary=changeset_005056A5-09B1-1ED1-BF82-409B26A80301
+
+
+--changeset_005056A5-09B1-1ED1-BF82-409B26A80301
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+POST Rooms HTTP/1.1
+Content-Type: application/atom+xml
+Content-ID: 2
+
+<entry xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
+<content type="application/xml">
+<m:properties>
+<d:Id>100</d:Id>
+<d:Name>Room 1</d:Name>
+<d:Seats>1</d:Seats>
+<d:Version>1</d:Version>
+</m:properties>
+</content>
+</entry>
+
+--changeset_005056A5-09B1-1ED1-BF82-409B26A80301--
+
+
+--batch_123
+Content-Type: multipart/mixed; boundary=changeset_005056A5-09B1-1ED1-BF82-409B26A80302
+
+--changeset_005056A5-09B1-1ED1-BF82-409B26A80302
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+POST Rooms HTTP/1.1
+Content-Type: application/atom+xml
+Content-ID: 3
+
+<entry xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
+<content type="application/xml">
+<m:properties>
+<d:Id>300</d:Id>
+<d:Name>Room 1</d:Name>
+<d:Seats>1</d:Seats>
+<d:Version>1</d:Version>
+</m:properties>
+</content>
+</entry>
+
+--changeset_005056A5-09B1-1ED1-BF82-409B26A80302--
+
+--batch_123
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+GET $2 HTTP/1.1
+
+
+--batch_123--
\ No newline at end of file
diff --git a/odata2-lib/odata-fit/src/test/resources/basicBatchWithContentIdReferencingFail.batch b/odata2-lib/odata-fit/src/test/resources/basicBatchWithContentIdReferencingFail.batch
new file mode 100644
index 0000000..8f2c890
--- /dev/null
+++ b/odata2-lib/odata-fit/src/test/resources/basicBatchWithContentIdReferencingFail.batch
@@ -0,0 +1,65 @@
+--batch_123
+Content-Type: multipart/mixed; boundary=changeset_005056A5-09B1-1ED1-BF82-409B26A80301
+
+
+--changeset_005056A5-09B1-1ED1-BF82-409B26A80301
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+POST Rooms HTTP/1.1
+Content-Type: application/atom+xml
+Content-ID: 2
+
+<entry xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
+<content type="application/xml">
+<m:properties>
+<d:Id>100</d:Id>
+<d:Name>Room 1</d:Name>
+<d:Seats>10-12-2019</d:Seats>
+<d:Version>1</d:Version>
+</m:properties>
+</content>
+</entry>
+
+--changeset_005056A5-09B1-1ED1-BF82-409B26A80301--
+
+
+--batch_123
+Content-Type: multipart/mixed; boundary=changeset_005056A5-09B1-1ED1-BF82-409B26A80302
+
+--changeset_005056A5-09B1-1ED1-BF82-409B26A80302
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+POST Rooms HTTP/1.1
+Content-Type: application/atom+xml
+Content-ID: 3
+
+<entry xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
+<content type="application/xml">
+<m:properties>
+<d:Id>300</d:Id>
+<d:Name>Room 1</d:Name>
+<d:Seats>1</d:Seats>
+<d:Version>1</d:Version>
+</m:properties>
+</content>
+</entry>
+
+--changeset_005056A5-09B1-1ED1-BF82-409B26A80302--
+
+--batch_123
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+GET $2 HTTP/1.1
+
+
+--batch_123
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+GET $3 HTTP/1.1
+
+
+--batch_123--
\ No newline at end of file
diff --git a/odata2-lib/odata-fit/src/test/resources/basicBatchWithContentIdWithNav.batch b/odata2-lib/odata-fit/src/test/resources/basicBatchWithContentIdWithNav.batch
new file mode 100644
index 0000000..28f5237
--- /dev/null
+++ b/odata2-lib/odata-fit/src/test/resources/basicBatchWithContentIdWithNav.batch
@@ -0,0 +1,37 @@
+--batch_123
+Content-Type: multipart/mixed; boundary=changeset_005056A5-09B1-1ED1-BF82-409B26A80301
+
+
+--changeset_005056A5-09B1-1ED1-BF82-409B26A80301
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+POST Rooms HTTP/1.1
+Content-Type: application/json
+Content-ID: 2
+
+{
+ "d": {
+ "Id": "100",
+ "Name": "Room 100",
+ "Seats": 1,
+ "Version": 1,
+ "nr_Building": {
+ "Id": "100",
+ "Name": "Building 100",
+ "Image": null
+ }
+ }
+}
+
+--changeset_005056A5-09B1-1ED1-BF82-409B26A80301--
+
+--batch_123
+Content-Type: application/http
+Accept: application/json
+Content-Transfer-Encoding: binary
+
+GET $2/nr_Building HTTP/1.1
+
+
+--batch_123--
\ No newline at end of file
diff --git a/odata2-lib/odata-fit/src/test/resources/basicBatchWithContentIdWithNavFail.batch b/odata2-lib/odata-fit/src/test/resources/basicBatchWithContentIdWithNavFail.batch
new file mode 100644
index 0000000..cf38574
--- /dev/null
+++ b/odata2-lib/odata-fit/src/test/resources/basicBatchWithContentIdWithNavFail.batch
@@ -0,0 +1,52 @@
+--batch_123
+Content-Type: multipart/mixed; boundary=changeset_005056A5-09B1-1ED1-BF82-409B26A80301
+
+
+--changeset_005056A5-09B1-1ED1-BF82-409B26A80301
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+POST Rooms HTTP/1.1
+Content-Type: application/json
+Content-ID: 2
+
+{
+ "d": {,
+ "Id": "100",
+ "Name": "Room 100",
+ "Seats": 1,
+ "Version": 1,
+ "nr_Building": {
+ "Id": "100",
+ "Name": "Building 100",
+ "Image": null,
+ }
+ }
+}
+
+--changeset_005056A5-09B1-1ED1-BF82-409B26A80301
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+PUT $2/nr_Building HTTP/1.1
+Content-Type: application/json
+Content-ID: 3
+
+{
+ "d": {
+ "Name": Building,
+ "Image": null
+ }
+}
+
+--changeset_005056A5-09B1-1ED1-BF82-409B26A80301--
+
+--batch_123
+Content-Type: application/http
+Accept: application/json
+Content-Transfer-Encoding: binary
+
+GET $2/nr_Building HTTP/1.1
+
+
+--batch_123--
\ No newline at end of file