Repository: olingo-odata2 Updated Branches: refs/heads/master 4bab6aab0 -> 14c534ee3
[OLINGO-521] Fix BatchResponseWriter Signed-off-by: Christian Amend <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/14c534ee Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/14c534ee Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/14c534ee Branch: refs/heads/master Commit: 14c534ee3bc265f6a9bc5b32ca87ad199371d627 Parents: 4bab6aa Author: Christian Holzer <[email protected]> Authored: Thu Dec 11 14:27:36 2014 +0100 Committer: Christian Amend <[email protected]> Committed: Mon Dec 15 14:55:08 2014 +0100 ---------------------------------------------------------------------- .../odata2/core/batch/BatchResponseWriter.java | 31 +-- .../core/batch/BatchRequestWriterITTest.java | 243 +++++++++++++++++++ .../core/batch/BatchResponseParserTest.java | 57 ++++- .../odata2/core/batch/BatchResponseTest.java | 2 +- .../core/batch/BatchResponseWriterITTest.java | 179 ++++++++++++++ 5 files changed, 496 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/14c534ee/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchResponseWriter.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchResponseWriter.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchResponseWriter.java index be189d3..3840cdf 100644 --- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchResponseWriter.java +++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/BatchResponseWriter.java @@ -33,7 +33,7 @@ import org.apache.olingo.odata2.api.processor.ODataResponse; public class BatchResponseWriter { private static final String COLON = ":"; private static final String SP = " "; - private static final String LF = "\r\n"; + private static final String CRLF = "\r\n"; private ResponseWriter writer = new ResponseWriter(); public ODataResponse writeResponse(final List<BatchResponsePart> batchResponseParts) throws BatchException { @@ -49,18 +49,18 @@ public class BatchResponseWriter { private void appendChangeSet(final BatchResponsePart batchResponsePart) throws BatchException { String boundary = BatchHelper.generateBoundary("changeset"); writer.append(HttpHeaders.CONTENT_TYPE).append(COLON).append(SP) - .append("multipart/mixed; boundary=" + boundary).append(LF).append(LF); + .append("multipart/mixed; boundary=" + boundary).append(CRLF).append(CRLF); for (ODataResponse response : batchResponsePart.getResponses()) { - writer.append("--").append(boundary).append(LF); + writer.append("--").append(boundary).append(CRLF); appendResponsePartBody(response); } - writer.append("--").append(boundary).append("--").append(LF).append(LF); + writer.append("--").append(boundary).append("--").append(CRLF); } private void appendResponsePart(final List<BatchResponsePart> batchResponseParts, final String boundary) throws BatchException { for (BatchResponsePart batchResponsePart : batchResponseParts) { - writer.append("--").append(boundary).append(LF); + writer.append("--").append(boundary).append(CRLF); if (batchResponsePart.isChangeSet()) { appendChangeSet(batchResponsePart); } else { @@ -73,16 +73,16 @@ public class BatchResponseWriter { private void appendResponsePartBody(final ODataResponse response) throws BatchException { writer.append(HttpHeaders.CONTENT_TYPE).append(COLON).append(SP) - .append(HttpContentType.APPLICATION_HTTP).append(LF); + .append(HttpContentType.APPLICATION_HTTP).append(CRLF); writer.append(BatchHelper.HTTP_CONTENT_TRANSFER_ENCODING).append(COLON).append(SP) - .append(BatchHelper.BINARY_ENCODING).append(LF); + .append(BatchHelper.BINARY_ENCODING).append(CRLF); if (response.getHeader(BatchHelper.MIME_HEADER_CONTENT_ID) != null) { writer.append(BatchHelper.HTTP_CONTENT_ID).append(COLON).append(SP) - .append(response.getHeader(BatchHelper.MIME_HEADER_CONTENT_ID)).append(LF); + .append(response.getHeader(BatchHelper.MIME_HEADER_CONTENT_ID)).append(CRLF); } - writer.append(LF); + writer.append(CRLF); writer.append("HTTP/1.1").append(SP).append(String.valueOf(response.getStatus().getStatusCode())).append(SP) - .append(response.getStatus().getInfo()).append(LF); + .append(response.getStatus().getInfo()).append(CRLF); appendHeader(response); if (!HttpStatusCodes.NO_CONTENT.equals(response.getStatus())) { String body; @@ -93,20 +93,23 @@ public class BatchResponseWriter { body = response.getEntity().toString(); } writer.append(HttpHeaders.CONTENT_LENGTH).append(COLON).append(SP) - .append(String.valueOf(BatchHelper.getBytes(body).length)).append(LF).append(LF); + .append(String.valueOf(BatchHelper.getBytes(body).length)).append(CRLF).append(CRLF); writer.append(body); + } else { + // No header if status code equals to 204 (No content) + writer.append(CRLF); } - writer.append(LF).append(LF); + writer.append(CRLF); } private void appendHeader(final ODataResponse response) { for (String name : response.getHeaderNames()) { if (!BatchHelper.MIME_HEADER_CONTENT_ID.equalsIgnoreCase(name) && !BatchHelper.REQUEST_HEADER_CONTENT_ID.equalsIgnoreCase(name)) { - writer.append(name).append(COLON).append(SP).append(response.getHeader(name)).append(LF); + writer.append(name).append(COLON).append(SP).append(response.getHeader(name)).append(CRLF); } else if (BatchHelper.REQUEST_HEADER_CONTENT_ID.equalsIgnoreCase(name)) { writer.append(BatchHelper.HTTP_CONTENT_ID).append(COLON).append(SP) - .append(response.getHeader(name)).append(LF); + .append(response.getHeader(name)).append(CRLF); } } } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/14c534ee/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestWriterITTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestWriterITTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestWriterITTest.java new file mode 100644 index 0000000..b153596 --- /dev/null +++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestWriterITTest.java @@ -0,0 +1,243 @@ +/******************************************************************************* + * 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.odata2.core.batch; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.olingo.odata2.api.batch.BatchException; +import org.apache.olingo.odata2.api.batch.BatchRequestPart; +import org.apache.olingo.odata2.api.client.batch.BatchChangeSet; +import org.apache.olingo.odata2.api.client.batch.BatchChangeSetPart; +import org.apache.olingo.odata2.api.client.batch.BatchPart; +import org.apache.olingo.odata2.api.client.batch.BatchQueryPart; +import org.apache.olingo.odata2.api.commons.HttpHeaders; +import org.apache.olingo.odata2.api.ep.EntityProviderBatchProperties; +import org.apache.olingo.odata2.api.processor.ODataRequest; +import org.apache.olingo.odata2.core.PathInfoImpl; +import org.apache.olingo.odata2.core.batch.v2.BatchParser; +import org.apache.olingo.odata2.core.batch.v2.BufferedReaderIncludingLineEndings; +import org.junit.BeforeClass; +import org.junit.Test; + +public class BatchRequestWriterITTest { + private static final String POST = "POST"; + private static final String GET = "GET"; + private static final String BOUNDARY = "batch_123"; + private static final String CONTENT_TYPE = "multipart/mixed ;boundary=" + BOUNDARY; + private static final String SERVICE_ROOT = "http://localhost/odata/"; + private static EntityProviderBatchProperties batchProperties; + + @BeforeClass + public static void setProperties() throws URISyntaxException { + PathInfoImpl pathInfo = new PathInfoImpl(); + pathInfo.setServiceRoot(new URI(SERVICE_ROOT)); + batchProperties = EntityProviderBatchProperties.init().pathInfo(pathInfo).build(); + } + + @Test + public void testQueryPart() throws Exception { + List<BatchPart> batch = new ArrayList<BatchPart>(); + Map<String, String> headers = new HashMap<String, String>(); + headers.put("Accept", "application/json"); + BatchPart request = BatchQueryPart.method(GET).uri("Employees").headers(headers).build(); + batch.add(request); + + BatchRequestWriter writer = new BatchRequestWriter(); + InputStream stream = writer.writeBatchRequest(batch, BOUNDARY); + + List<BatchRequestPart> parsedRequestParts = parseBatchRequest(stream); + assertEquals(1, parsedRequestParts.size()); + BatchRequestPart part = parsedRequestParts.get(0); + + assertFalse(part.isChangeSet()); + assertEquals(1, part.getRequests().size()); + ODataRequest oDataRequest = part.getRequests().get(0); + assertEquals("Employees", oDataRequest.getPathInfo().getODataSegments().get(0).getPath()); + assertEquals("application/json", oDataRequest.getAcceptHeaders().get(0)); + } + + @Test + public void testChangeSet() throws Exception { + List<BatchPart> batch = new ArrayList<BatchPart>(); + Map<String, String> headers = new HashMap<String, String>(); + headers.put("Accept", "application/json"); + BatchPart request = BatchQueryPart.method(GET).uri("Employees").headers(headers).contentId("000").build(); + batch.add(request); + + Map<String, String> changeSetHeaders = new HashMap<String, String>(); + changeSetHeaders.put("content-type", "application/json"); + String body = "/9j/4AAQSkZJRgABAQEBLAEsAAD/4RM0RXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEA"; + BatchChangeSetPart changeRequest = BatchChangeSetPart.method(POST) + .uri("Employees") + .body(body) + .headers(changeSetHeaders) + .contentId("111") + .build(); + BatchChangeSet changeSet = BatchChangeSet.newBuilder().build(); + changeSet.add(changeRequest); + batch.add(changeSet); + BatchRequestWriter writer = new BatchRequestWriter(); + InputStream stream = writer.writeBatchRequest(batch, BOUNDARY); + + final List<BatchRequestPart> parsedRequestParts = parseBatchRequest(stream); + assertEquals(2, parsedRequestParts.size()); + + // Get Request + final BatchRequestPart partGet = parsedRequestParts.get(0); + assertFalse(partGet.isChangeSet()); + assertEquals(1, partGet.getRequests().size()); + final ODataRequest oDataRequestGet = partGet.getRequests().get(0); + assertEquals("Employees", oDataRequestGet.getPathInfo().getODataSegments().get(0).getPath()); + assertEquals("application/json", oDataRequestGet.getAcceptHeaders().get(0)); + + // Change set + final BatchRequestPart partChangeSet = parsedRequestParts.get(1); + assertTrue(partChangeSet.isChangeSet()); + assertEquals(1, partChangeSet.getRequests().size()); + final ODataRequest oDataRequestPost = partChangeSet.getRequests().get(0); + assertEquals("Employees", oDataRequestGet.getPathInfo().getODataSegments().get(0).getPath()); + assertEquals("111", oDataRequestPost.getRequestHeaderValue(BatchHelper.MIME_HEADER_CONTENT_ID)); + assertEquals(body, streamToString(oDataRequestPost.getBody())); + assertEquals("application/json", oDataRequestPost.getRequestHeaderValue(HttpHeaders.CONTENT_TYPE)); + } + + @Test + public void testTwoChangeSets() throws Exception { + List<BatchPart> batch = new ArrayList<BatchPart>(); + + // Get request + Map<String, String> headers = new HashMap<String, String>(); + headers.put("Accept", "application/json"); + BatchPart request = BatchQueryPart.method(GET).uri("Employees").headers(headers).contentId("000").build(); + batch.add(request); + + Map<String, String> headerPostRequest = new HashMap<String, String>(); + headerPostRequest.put("content-type", "application/json"); + + // Changeset 1 + String bodyEmployee = "/9j/4AAQSkZJRgABAQEBLAEsAAD/4RM0RXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEA"; + BatchChangeSetPart postRequest = BatchChangeSetPart.method(POST) + .uri("Employees") + .body(bodyEmployee) + .headers(headerPostRequest) + .contentId("111") + .build(); + + String bodyEmployee2 = "TestString\r\n"; + BatchChangeSetPart postRequest2 = BatchChangeSetPart.method(POST) + .uri("Employees") + .body(bodyEmployee2) + .headers(headerPostRequest) + .contentId("222") + .build(); + BatchChangeSet changeSet = BatchChangeSet.newBuilder().build(); + changeSet.add(postRequest); + changeSet.add(postRequest2); + batch.add(changeSet); + + // Changeset 2 + BatchChangeSet changeSet2 = BatchChangeSet.newBuilder().build(); + postRequest2 = BatchChangeSetPart.method(POST) + .uri("Employees") + .body(bodyEmployee2) + .headers(headerPostRequest) + .contentId("222") + .build(); + changeSet2.add(postRequest2); + postRequest = BatchChangeSetPart.method(POST) + .uri("Employees") + .body(bodyEmployee) + .headers(headerPostRequest) + .contentId("111") + .build(); + changeSet2.add(postRequest); + batch.add(changeSet2); + + // Write requests + BatchRequestWriter writer = new BatchRequestWriter(); + InputStream stream = writer.writeBatchRequest(batch, BOUNDARY); + // Read requests + final List<BatchRequestPart> parsedRequestParts = parseBatchRequest(stream); + assertEquals(3, parsedRequestParts.size()); + + // Get request + final BatchRequestPart partGet = parsedRequestParts.get(0); + assertFalse(partGet.isChangeSet()); + assertEquals(1, partGet.getRequests().size()); + final ODataRequest oDataRequestGet = partGet.getRequests().get(0); + assertEquals("Employees", oDataRequestGet.getPathInfo().getODataSegments().get(0).getPath()); + assertEquals("application/json", oDataRequestGet.getAcceptHeaders().get(0)); + + // Changeset 1 + BatchRequestPart parsedChangeSet1 = parsedRequestParts.get(1); + assertTrue(parsedChangeSet1.isChangeSet()); + assertEquals(2, parsedChangeSet1.getRequests().size()); + ODataRequest oDataRequestPost1 = parsedChangeSet1.getRequests().get(0); + assertEquals("111", oDataRequestPost1.getRequestHeaderValue(BatchHelper.MIME_HEADER_CONTENT_ID)); + assertEquals(bodyEmployee, streamToString(oDataRequestPost1.getBody())); + assertEquals("application/json", oDataRequestPost1.getRequestHeaderValue(HttpHeaders.CONTENT_TYPE)); + + ODataRequest oDataRequestPost12 = parsedChangeSet1.getRequests().get(1); + assertEquals("222", oDataRequestPost12.getRequestHeaderValue(BatchHelper.MIME_HEADER_CONTENT_ID)); + assertEquals(bodyEmployee2, streamToString(oDataRequestPost12.getBody())); + assertEquals("application/json", oDataRequestPost12.getRequestHeaderValue(HttpHeaders.CONTENT_TYPE)); + + // Changeset 2 + BatchRequestPart parsedChangeSet2 = parsedRequestParts.get(2); + assertTrue(parsedChangeSet2.isChangeSet()); + assertEquals(2, parsedChangeSet2.getRequests().size()); + ODataRequest oDataRequestPost21 = parsedChangeSet2.getRequests().get(0); + assertEquals("222", oDataRequestPost21.getRequestHeaderValue(BatchHelper.MIME_HEADER_CONTENT_ID)); + assertEquals(bodyEmployee2, streamToString(oDataRequestPost21.getBody())); + assertEquals("application/json", oDataRequestPost21.getRequestHeaderValue(HttpHeaders.CONTENT_TYPE)); + + ODataRequest oDataRequestPost22 = parsedChangeSet2.getRequests().get(1); + assertEquals("111", oDataRequestPost22.getRequestHeaderValue(BatchHelper.MIME_HEADER_CONTENT_ID)); + assertEquals(bodyEmployee, streamToString(oDataRequestPost22.getBody())); + assertEquals("application/json", oDataRequestPost22.getRequestHeaderValue(HttpHeaders.CONTENT_TYPE)); + } + + private List<BatchRequestPart> parseBatchRequest(InputStream batchRequest) throws BatchException { + final BatchParser parser = new BatchParser(CONTENT_TYPE, batchProperties, true); + return parser.parseBatchRequest(batchRequest); + } + + private String streamToString(final InputStream in) throws IOException { + final BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(new InputStreamReader(in)); + final StringBuilder builder = new StringBuilder(); + String line; + + while ((line = reader.readLine()) != null) { + builder.append(line); + } + + reader.close(); + return builder.toString(); + } +} http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/14c534ee/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseParserTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseParserTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseParserTest.java index feaa50d..e107db5 100644 --- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseParserTest.java +++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseParserTest.java @@ -64,6 +64,61 @@ public class BatchResponseParserTest { assertEquals("text/plain;charset=utf-8", response.getHeaders().get(HttpHeaders.CONTENT_TYPE)); assertEquals("22", response.getHeaders().get("Content-length")); assertEquals("1", response.getContentId()); + assertEquals("Frederic Fall MODIFIED", response.getBody()); + } + } + + @Test + public void testSimpleBatchResponseWithLinebreak() throws BatchException { + String getResponse = "--batch_123" + CRLF + + "Content-Type: application/http" + CRLF + + "Content-Transfer-Encoding: binary" + CRLF + + "Content-ID: 1" + CRLF + + CRLF + + "HTTP/1.1 200 OK" + CRLF + + "DataServiceVersion: 2.0" + CRLF + + "Content-Type: text/plain;charset=utf-8" + CRLF + + "Content-length: 24" + CRLF + + CRLF + + "Frederic Fall MODIFIED" + CRLF + + CRLF + + "--batch_123--"; + + InputStream in = new ByteArrayInputStream(getResponse.getBytes()); + BatchParser parser = new BatchParser("multipart/mixed;boundary=batch_123", true); + List<BatchSingleResponse> responses = parser.parseBatchResponse(in); + for (BatchSingleResponse response : responses) { + assertEquals("200", response.getStatusCode()); + assertEquals("OK", response.getStatusInfo()); + assertEquals("text/plain;charset=utf-8", response.getHeaders().get(HttpHeaders.CONTENT_TYPE)); + assertEquals("24", response.getHeaders().get("Content-length")); + assertEquals("1", response.getContentId()); + assertEquals("Frederic Fall MODIFIED\r\n", response.getBody()); + } + } + + @Test + public void testNoContentResponse() throws Exception { + String responseContent = + "--ejjeeffe1\r\n" + + "Content-Type: application/http\r\n" + + "Content-Length: 96\r\n" + + "content-transfer-encoding: binary\r\n" + + "\r\n" + + "HTTP/1.1 204 No Content\r\n" + + "Content-Type: text/html\r\n" + + "dataserviceversion: 2.0\r\n" + + "\r\n" + + "\r\n" + + "--ejjeeffe1--\r\n"; + + InputStream in = new ByteArrayInputStream(responseContent.getBytes()); + BatchParser parser = new BatchParser("multipart/mixed;boundary=ejjeeffe1", true); + List<BatchSingleResponse> responses = parser.parseBatchResponse(in); + for (BatchSingleResponse response : responses) { + assertEquals("204", response.getStatusCode()); + assertEquals("No Content", response.getStatusInfo()); + assertEquals("text/html", response.getHeaders().get(HttpHeaders.CONTENT_TYPE)); } } @@ -119,7 +174,7 @@ public class BatchResponseParserTest { @Test public void testResponseToChangeSetNoContentButContentLength() throws BatchException { String putResponse = - "--batch_123" + CRLF + "--batch_123" + CRLF + "Content-Type: " + HttpContentType.MULTIPART_MIXED + ";boundary=changeset_12ks93js84d" + CRLF + CRLF + "--changeset_12ks93js84d" + CRLF http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/14c534ee/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseTest.java index 2f8b7f8..4076a25 100644 --- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseTest.java +++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseTest.java @@ -140,6 +140,6 @@ public class BatchResponseTest { StringHelper.Stream content = StringHelper.toStream(body); List<BatchSingleResponse> result = parser.parseBatchResponse(content.asStream()); assertEquals(2, result.size()); - assertEquals("Failing content:\n" + content.asString(), 20, content.linesCount()); + assertEquals("Failing content:\n" + content.asString(), 19, content.linesCount()); } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/14c534ee/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseWriterITTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseWriterITTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseWriterITTest.java new file mode 100644 index 0000000..df84f39 --- /dev/null +++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseWriterITTest.java @@ -0,0 +1,179 @@ +/******************************************************************************* + * 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.odata2.core.batch; + +import static org.junit.Assert.*; + +import java.io.ByteArrayInputStream; +import java.util.ArrayList; +import java.util.List; + +import org.apache.olingo.odata2.api.batch.BatchResponsePart; +import org.apache.olingo.odata2.api.client.batch.BatchSingleResponse; +import org.apache.olingo.odata2.api.commons.HttpHeaders; +import org.apache.olingo.odata2.api.commons.HttpStatusCodes; +import org.apache.olingo.odata2.api.processor.ODataResponse; +import org.apache.olingo.odata2.core.batch.v2.BatchParser; +import org.apache.olingo.odata2.core.commons.ContentType; +import org.junit.Test; + +public class BatchResponseWriterITTest { + + @Test + public void testSimpleRequest() throws Exception { + // Create batch response + List<BatchResponsePart> parts = new ArrayList<BatchResponsePart>(); + ODataResponse response = + ODataResponse.entity("Walter Winter").status(HttpStatusCodes.OK).contentHeader("application/json").build(); + List<ODataResponse> responses = new ArrayList<ODataResponse>(1); + responses.add(response); + parts.add(BatchResponsePart.responses(responses).changeSet(false).build()); + BatchResponseWriter writer = new BatchResponseWriter(); + ODataResponse batchResponse = writer.writeResponse(parts); + + assertEquals(202, batchResponse.getStatus().getStatusCode()); + assertNotNull(batchResponse.getEntity()); + String body = (String) batchResponse.getEntity(); + // Get boundary + int lineEndingIndex = body.indexOf("\r\n"); + String boundary = body.substring(2, lineEndingIndex); + + // Parse response and test outputs + final BatchParser parser = new BatchParser("multipart/mixed;boundary=" + boundary, true); + List<BatchSingleResponse> parserResponses = parser.parseBatchResponse(new ByteArrayInputStream(body.getBytes())); + for (BatchSingleResponse parserResponse : parserResponses) { + assertEquals("200", parserResponse.getStatusCode()); + assertEquals("OK", parserResponse.getStatusInfo()); + assertEquals("application/json", parserResponse.getHeaders().get(HttpHeaders.CONTENT_TYPE)); + assertEquals("13", parserResponse.getHeaders().get(HttpHeaders.CONTENT_LENGTH)); + assertEquals("Walter Winter", parserResponse.getBody()); + } + } + + @Test + public void testNoContent() throws Exception { + // Create batch response + List<BatchResponsePart> parts = new ArrayList<BatchResponsePart>(); + ODataResponse response = + ODataResponse.status(HttpStatusCodes.NO_CONTENT).build(); + List<ODataResponse> responses = new ArrayList<ODataResponse>(1); + responses.add(response); + parts.add(BatchResponsePart.responses(responses).changeSet(false).build()); + BatchResponseWriter writer = new BatchResponseWriter(); + ODataResponse batchResponse = writer.writeResponse(parts); + + assertEquals(202, batchResponse.getStatus().getStatusCode()); + assertNotNull(batchResponse.getEntity()); + String body = (String) batchResponse.getEntity(); + // Get boundary + int lineEndingIndex = body.indexOf("\r\n"); + String boundary = body.substring(2, lineEndingIndex); + + // Parse response and test outputs + final BatchParser parser = new BatchParser("multipart/mixed;boundary=" + boundary, true); + List<BatchSingleResponse> parserResponses = parser.parseBatchResponse(new ByteArrayInputStream(body.getBytes())); + for (BatchSingleResponse parserResponse : parserResponses) { + assertEquals("204", parserResponse.getStatusCode()); + assertEquals("No Content", parserResponse.getStatusInfo()); + } + } + + @Test + public void testChangeSet() throws Exception { + List<BatchResponsePart> parts = new ArrayList<BatchResponsePart>(); + ODataResponse response = ODataResponse.entity("Walter Winter") + .status(HttpStatusCodes.OK) + .contentHeader("application/json") + .build(); + List<ODataResponse> responses = new ArrayList<ODataResponse>(1); + responses.add(response); + parts.add(BatchResponsePart.responses(responses).changeSet(false).build()); + + ODataResponse changeSetResponse = + ODataResponse.status(HttpStatusCodes.NO_CONTENT).header(BatchHelper.MIME_HEADER_CONTENT_ID, "1").build(); + responses = new ArrayList<ODataResponse>(2); + ODataResponse changeSetResponseEntity = + ODataResponse.status(HttpStatusCodes.OK).contentHeader(ContentType.APPLICATION_JSON.toContentTypeString()) + .header(BatchHelper.MIME_HEADER_CONTENT_ID, "2") + .entity("Test\r\n").build(); + ODataResponse changeSetResponseEntity2 = + ODataResponse.status(HttpStatusCodes.OK).contentHeader(ContentType.APPLICATION_JSON.toContentTypeString()) + .header(BatchHelper.MIME_HEADER_CONTENT_ID, "2") + .entity("Test\n").build(); + ODataResponse changeSetResponseEntity3 = + ODataResponse.status(HttpStatusCodes.OK).contentHeader(ContentType.APPLICATION_JSON.toContentTypeString()) + .header(BatchHelper.MIME_HEADER_CONTENT_ID, "2") + .entity("Test").build(); + responses.add(changeSetResponse); + responses.add(changeSetResponseEntity); + responses.add(changeSetResponseEntity2); + responses.add(changeSetResponseEntity3); + + parts.add(BatchResponsePart.responses(responses).changeSet(true).build()); + + BatchResponseWriter writer = new BatchResponseWriter(); + ODataResponse batchResponse = writer.writeResponse(parts); + + assertEquals(202, batchResponse.getStatus().getStatusCode()); + assertNotNull(batchResponse.getEntity()); + String body = (String) batchResponse.getEntity(); + + // Get boundary + int lineEndingIndex = body.indexOf("\r\n"); + String boundary = body.substring(2, lineEndingIndex); + + // Parse response and test outputs + final BatchParser parser = new BatchParser("multipart/mixed;boundary=" + boundary, true); + List<BatchSingleResponse> parserResponses = parser.parseBatchResponse(new ByteArrayInputStream(body.getBytes())); + assertEquals(5, parserResponses.size()); + + BatchSingleResponse parserResponse = parserResponses.get(0); + assertEquals("200", parserResponse.getStatusCode()); + assertEquals("OK", parserResponse.getStatusInfo()); + assertEquals("application/json", parserResponse.getHeaders().get(HttpHeaders.CONTENT_TYPE)); + assertEquals("13", parserResponse.getHeaders().get(HttpHeaders.CONTENT_LENGTH)); + assertEquals("Walter Winter", parserResponse.getBody()); + + parserResponse = parserResponses.get(1); + assertEquals("204", parserResponse.getStatusCode()); + assertEquals("1", parserResponse.getContentId()); + assertEquals("No Content", parserResponse.getStatusInfo()); + + parserResponse = parserResponses.get(2); + assertEquals("200", parserResponse.getStatusCode()); + assertEquals("OK", parserResponse.getStatusInfo()); + assertEquals("application/json", parserResponse.getHeaders().get(HttpHeaders.CONTENT_TYPE)); + assertEquals("6", parserResponse.getHeaders().get(HttpHeaders.CONTENT_LENGTH)); + assertEquals("Test\r\n", parserResponse.getBody()); + + parserResponse = parserResponses.get(3); + assertEquals("200", parserResponse.getStatusCode()); + assertEquals("OK", parserResponse.getStatusInfo()); + assertEquals("application/json", parserResponse.getHeaders().get(HttpHeaders.CONTENT_TYPE)); + assertEquals("5", parserResponse.getHeaders().get(HttpHeaders.CONTENT_LENGTH)); + assertEquals("Test\n", parserResponse.getBody()); + + parserResponse = parserResponses.get(4); + assertEquals("200", parserResponse.getStatusCode()); + assertEquals("OK", parserResponse.getStatusInfo()); + assertEquals("application/json", parserResponse.getHeaders().get(HttpHeaders.CONTENT_TYPE)); + assertEquals("4", parserResponse.getHeaders().get(HttpHeaders.CONTENT_LENGTH)); + assertEquals("Test", parserResponse.getBody()); + } +}
