[OLINGO-616] Fix: BatchReferenceRewriter
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/97a01784 Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/97a01784 Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/97a01784 Branch: refs/heads/OLINGO-573 Commit: 97a017843249093d4c71838ea59d5a1d472140c5 Parents: 189de7b Author: Christian Holzer <[email protected]> Authored: Thu Apr 2 13:41:07 2015 +0200 Committer: Christian Holzer <[email protected]> Committed: Fri Apr 3 12:42:03 2015 +0200 ---------------------------------------------------------------------- .../fit/tecsvc/client/BatchClientITCase.java | 74 ++++++++++++++++++-- .../BatchReferenceRewriter.java | 3 +- 2 files changed, 69 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/97a01784/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java ---------------------------------------------------------------------- diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java index ed249fd..a46644c 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java @@ -20,8 +20,8 @@ package org.apache.olingo.fit.tecsvc.client; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.net.URI; @@ -30,6 +30,7 @@ import java.util.HashMap; import java.util.Iterator; import org.apache.olingo.client.api.ODataBatchConstants; +import org.apache.olingo.client.api.ODataClient; import org.apache.olingo.client.api.communication.request.batch.BatchManager; import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest; import org.apache.olingo.client.api.communication.request.batch.ODataBatchResponseItem; @@ -48,6 +49,7 @@ import org.apache.olingo.client.core.communication.request.batch.ODataChangesetR import org.apache.olingo.client.core.uri.URIUtils; import org.apache.olingo.commons.api.domain.ODataEntity; import org.apache.olingo.commons.api.domain.ODataEntitySet; +import org.apache.olingo.commons.api.domain.ODataObjectFactory; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.format.ContentType; @@ -62,6 +64,11 @@ import org.junit.Test; public class BatchClientITCase extends AbstractTestITCase { private final static String ACCEPT = ContentType.APPLICATION_OCTET_STREAM.toContentTypeString(); private static final String SERVICE_URI = TecSvcConst.BASE_URI; + private static final String SERVICE_NAMESPACE = "olingo.odata.test1"; + private static final String ES_NOT_AVAILABLE_NAME = "ESNotAvailable"; + private static final FullQualifiedName ES_NOT_AVAILABLE = new FullQualifiedName(SERVICE_NAMESPACE, + ES_NOT_AVAILABLE_NAME); + private static final String PROPERTY_STRING = "PropertyString"; @Before public void setup() { @@ -69,6 +76,59 @@ public class BatchClientITCase extends AbstractTestITCase { } @Test + public void testBadRequestInChangeSet() { + /* + * A bad request (status code >= 400) without "continue on error prefer header" in a changeset + * should return a single response with Content-Type: application/http + * + * See: + * OData Version 4.0 Part 1: Protocol Plus Errata 01 + * 11.7.4 Responding to a Batch Request + * + * When a request within a change set fails, the change set response is not represented using + * the multipart/mixed media type. Instead, a single response, using the application/http media type + * and a Content-Transfer-Encoding header with a value of binary, is returned that applies to all requests + * in the change set and MUST be formatted according to the Error Handling defined + * for the particular response format. + */ + + final ODataClient client = getClient(); + final ODataObjectFactory of = client.getObjectFactory(); + + // Try to create entity, with invalid type + final ODataEntity entity = of.newEntity(ES_NOT_AVAILABLE); + entity.getProperties().add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder() + .buildString("1"))); + final ODataBatchRequest batchRequest = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI); + batchRequest.setAccept(ACCEPT); + final BatchManager payloadManager = batchRequest.payloadManager(); + final ODataChangeset changeset = payloadManager.addChangeset(); + final URI targetURI = client.newURIBuilder(SERVICE_URI) + .appendEntitySetSegment(ES_NOT_AVAILABLE_NAME) + .build(); + final ODataEntityCreateRequest<ODataEntity> createRequest = client.getCUDRequestFactory() + .getEntityCreateRequest(targetURI, entity); + changeset.addRequest(createRequest); + + final ODataBatchResponse response = payloadManager.getResponse(); + assertEquals(HttpStatusCode.ACCEPTED.getStatusCode(), response.getStatusCode()); + + // Check response items + final Iterator<ODataBatchResponseItem> responseBodyIter = response.getBody(); + assertTrue(responseBodyIter.hasNext()); + + final ODataBatchResponseItem changeSetResponse = responseBodyIter.next(); + assertTrue(changeSetResponse.isChangeset()); + assertTrue(changeSetResponse.hasNext()); + + final ODataResponse updateResponse = changeSetResponse.next(); + assertTrue(changeSetResponse.isBreaking()); + + assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), updateResponse.getStatusCode()); + assertEquals(ODataFormat.JSON.toString(), updateResponse.getContentType()); + } + + @Test public void emptyBatchRequest() { // create your request final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI); @@ -191,7 +251,7 @@ public class BatchClientITCase extends AbstractTestITCase { // Check if third request is available assertFalse(iter.hasNext()); } - + @Test public void testInvalidAbsoluteUri() throws URISyntaxException { final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI); @@ -209,14 +269,14 @@ public class BatchClientITCase extends AbstractTestITCase { final Iterator<ODataBatchResponseItem> bodyIterator = response.getBody(); assertTrue(bodyIterator.hasNext()); - + ODataBatchResponseItem item = bodyIterator.next(); assertFalse(item.isChangeset()); - + final ODataResponse oDataResponse = item.next(); assertEquals(400, oDataResponse.getStatusCode()); } - + @Test @Ignore public void testInvalidHost() throws URISyntaxException { @@ -233,7 +293,7 @@ public class BatchClientITCase extends AbstractTestITCase { final ODataBatchResponse response = payload.getResponse(); assertEquals(400, response.getStatusCode()); } - + @Test @Ignore public void testInvalidAbsoluteRequest() throws URISyntaxException { @@ -250,7 +310,7 @@ public class BatchClientITCase extends AbstractTestITCase { final ODataBatchResponse response = payload.getResponse(); assertEquals(400, response.getStatusCode()); } - + @Test public void testErrorWithContinueOnErrorPreferHeader() throws URISyntaxException { client.getConfiguration().setContinueOnError(true); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/97a01784/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/referenceRewriting/BatchReferenceRewriter.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/referenceRewriting/BatchReferenceRewriter.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/referenceRewriting/BatchReferenceRewriter.java index 772fd9d..9f0429a 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/referenceRewriting/BatchReferenceRewriter.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/referenceRewriting/BatchReferenceRewriter.java @@ -78,7 +78,8 @@ public class BatchReferenceRewriter { if (request.getMethod() == HttpMethod.POST) { // Create entity // The URI of the new resource will be generated by the server and published in the location header - resourceUri = parseODataPath(response.getHeaders().get(HttpHeader.LOCATION), request.getRawBaseUri()); + final String locationHeader = response.getHeaders().get(HttpHeader.LOCATION); + resourceUri = locationHeader == null ? null : parseODataPath(locationHeader, request.getRawBaseUri()); } else { // Update, Upsert (PUT, PATCH, Delete) // These methods still addresses a given resource, so we use the URI given by the request
