From 9e232a2d748b74ae12ee9fb64b87665d53124e99 Mon Sep 17 00:00:00 2001 From: Christian Holzer Date: Tue, 7 Apr 2015 12:22:02 +0200 Subject: [PATCH] [OLINGO-545] Tests for batch changesets, update and insert requests added --- .../olingo/fit/tecsvc/client/BasicITCase.java | 322 +++++++++++++++++- .../fit/tecsvc/client/BatchClientITCase.java | 260 +++++++------- .../fit/tecsvc/client/DeepInsertITCase.java | 203 ++++++++++- .../server/tecsvc/data/DataCreator.java | 5 + .../server/tecsvc/data/RequestValidator.java | 27 +- .../processor/TechnicalEntityProcessor.java | 4 +- 6 files changed, 666 insertions(+), 155 deletions(-) diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java index 5b8949a44..5beec7b5f 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java @@ -21,6 +21,7 @@ package org.apache.olingo.fit.tecsvc.client; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.hasItem; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; @@ -64,6 +65,7 @@ import org.apache.olingo.commons.api.domain.ODataProperty; import org.apache.olingo.commons.api.domain.ODataServiceDocument; import org.apache.olingo.commons.api.domain.ODataValue; import org.apache.olingo.commons.api.edm.Edm; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.format.ContentType; import org.apache.olingo.commons.api.format.ODataFormat; @@ -461,7 +463,11 @@ public class BasicITCase extends AbstractBaseTestITCase { .add(of.newComplexValue("CTPrimComp") .add(of.newPrimitiveProperty("PropertyInt16", of.newPrimitiveValueBuilder().buildInt16((short)42))) .add(of.newComplexProperty("PropertyComp", of.newComplexValue("CTAllPrim") - .add(of.newPrimitiveProperty("PropertyString", of.newPrimitiveValueBuilder().buildString("42")))))))); + .add(of.newPrimitiveProperty("PropertyString", of.newPrimitiveValueBuilder().buildString("42")))))) + .add(of.newComplexValue("CTPrimComp") + .add(of.newPrimitiveProperty("PropertyInt16", of.newPrimitiveValueBuilder().buildInt16((short)43))) + .add(of.newComplexProperty("PropertyComp", of.newComplexValue("CTAllPrim") + .add(of.newPrimitiveProperty("PropertyString", of.newPrimitiveValueBuilder().buildString("43")))))))); final URI uri = getClient().newURIBuilder(SERVICE_URI) .appendEntitySetSegment("ESKeyNav") @@ -484,19 +490,26 @@ public class BasicITCase extends AbstractBaseTestITCase { assertEquals(HttpStatusCode.OK.getStatusCode(), entityResponse.getStatusCode()); assertNotNull(entityResponse.getBody().getProperty("CollPropertyComp")); - assertEquals(1, entityResponse.getBody().getProperty("CollPropertyComp").getCollectionValue().size()); + assertEquals(2, entityResponse.getBody().getProperty("CollPropertyComp").getCollectionValue().size()); - ODataComplexValue complexProperty = entityResponse.getBody() - .getProperty("CollPropertyComp") - .getCollectionValue() - .iterator() - .next() - .asComplex(); + final Iterator collectionIterator = entityResponse.getBody() + .getProperty("CollPropertyComp") + .getCollectionValue() + .iterator(); + + ODataComplexValue complexProperty = collectionIterator.next().asComplex(); assertEquals(42, complexProperty.get("PropertyInt16").getPrimitiveValue().toValue()); assertNotNull(complexProperty.get("PropertyComp")); - final ODataComplexValue innerComplexProperty = complexProperty.get("PropertyComp").getComplexValue(); + ODataComplexValue innerComplexProperty = complexProperty.get("PropertyComp").getComplexValue(); assertEquals("42", innerComplexProperty.get("PropertyString").getPrimitiveValue().toValue()); + + complexProperty = collectionIterator.next().asComplex(); + assertEquals(43, complexProperty.get("PropertyInt16").getPrimitiveValue().toValue()); + assertNotNull(complexProperty.get("PropertyComp")); + + innerComplexProperty = complexProperty.get("PropertyComp").getComplexValue(); + assertEquals("43", innerComplexProperty.get("PropertyString").getPrimitiveValue().toValue()); } @Test @@ -614,6 +627,297 @@ public class BasicITCase extends AbstractBaseTestITCase { } } + @Test + public void testUpsert() throws EdmPrimitiveTypeException { + final EdmEnabledODataClient client = ODataClientFactory.getEdmEnabledClient(SERVICE_URI); + final ODataObjectFactory of = client.getObjectFactory(); + + final ODataEntity entity = of.newEntity(new FullQualifiedName("olingo.odata.test1", "ETTwoPrim")); + entity.getProperties().add(of.newPrimitiveProperty("PropertyString", of.newPrimitiveValueBuilder() + .buildString("Test"))); + + final URI uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESTwoPrim").appendKeySegment(33).build(); + final ODataEntityUpdateResponse updateResponse = + client.getCUDRequestFactory().getEntityUpdateRequest(uri, UpdateType.PATCH, entity).execute(); + + assertEquals(HttpStatusCode.CREATED.getStatusCode(), updateResponse.getStatusCode()); + assertEquals("Test", updateResponse.getBody().getProperty("PropertyString").getPrimitiveValue().toValue()); + + final String cookie = updateResponse.getHeader(HttpHeader.SET_COOKIE).iterator().next(); + final Short key = updateResponse.getBody().getProperty("PropertyInt16") + .getPrimitiveValue() + .toCastValue(Short.class); + + final ODataEntityRequest entityRequest = client.getRetrieveRequestFactory() + .getEntityRequest(client.newURIBuilder() + .appendEntitySetSegment("ESTwoPrim") + .appendKeySegment(key) + .build()); + entityRequest.addCustomHeader(HttpHeader.COOKIE, cookie); + final ODataRetrieveResponse responseEntityRequest = entityRequest.execute(); + assertEquals(HttpStatusCode.OK.getStatusCode(), responseEntityRequest.getStatusCode()); + assertEquals("Test", responseEntityRequest.getBody().getProperty("PropertyString").getPrimitiveValue().toValue()); + } + + @Test + public void testUpdatePropertyWithNull() { + final EdmEnabledODataClient client = ODataClientFactory.getEdmEnabledClient(SERVICE_URI); + final ODataObjectFactory of = client.getObjectFactory(); + + final URI targetURI = client.newURIBuilder(SERVICE_URI) + .appendEntitySetSegment("ESAllPrim") + .appendKeySegment(32767) + .build(); + + final ODataEntity entity = of.newEntity(new FullQualifiedName("olingo.odata.test1", "ETAllPrim")); + entity.getProperties().add(of.newPrimitiveProperty("PropertyString", of.newPrimitiveValueBuilder() + .buildString(null))); + + final ODataEntityUpdateResponse updateResponse = client.getCUDRequestFactory() + .getEntityUpdateRequest(targetURI, UpdateType.PATCH, entity) + .execute(); + + assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), updateResponse.getStatusCode()); + final String cookie = updateResponse.getHeader(HttpHeader.SET_COOKIE).iterator().next(); + + final ODataEntityRequest entityRequest = client.getRetrieveRequestFactory() + .getEntityRequest(targetURI); + entityRequest.addCustomHeader(HttpHeader.COOKIE, cookie); + final ODataRetrieveResponse entityResponse = entityRequest.execute(); + assertEquals(HttpStatusCode.OK.getStatusCode(), entityResponse.getStatusCode()); + + assertTrue(entityResponse.getBody().getProperty("PropertyString").hasNullValue()); + assertEquals(34, entityResponse.getBody().getProperty("PropertyDecimal").getPrimitiveValue().toValue()); + } + + @Test(expected=ODataClientErrorException.class) + public void testUpdatePropertyWithNullNotAllowed() { + final EdmEnabledODataClient client = ODataClientFactory.getEdmEnabledClient(SERVICE_URI); + final ODataObjectFactory of = client.getObjectFactory(); + + final URI targetURI = client.newURIBuilder(SERVICE_URI) + .appendEntitySetSegment("ESKeyNav") + .appendKeySegment(32767) + .build(); + + final ODataEntity entity = of.newEntity(new FullQualifiedName("olingo.odata.test1", "ETKeyNav")); + entity.getProperties().add(of.newPrimitiveProperty("PropertyString", of.newPrimitiveValueBuilder() + .buildString(null))); + + client.getCUDRequestFactory().getEntityUpdateRequest(targetURI, UpdateType.PATCH, entity).execute(); + } + + @Test + public void testUpdateMerge() { + final EdmEnabledODataClient client = ODataClientFactory.getEdmEnabledClient(SERVICE_URI); + final ODataObjectFactory of = client.getObjectFactory(); + + final URI targetURI = client.newURIBuilder(SERVICE_URI) + .appendEntitySetSegment("ESKeyNav") + .appendKeySegment(1) + .build(); + + final ODataEntity entity = of.newEntity(new FullQualifiedName("olingo.odata.test1", "ETKeyNav")); + entity.addLink(of.newEntityNavigationLink("NavPropertyETKeyNavOne", targetURI)); + entity.addLink(of.newEntitySetNavigationLink("NavPropertyETKeyNavMany", client.newURIBuilder(SERVICE_URI) + .appendEntitySetSegment("ESKeyNav").appendKeySegment(3).build())); + entity.getProperties().add(of.newCollectionProperty("CollPropertyString", of.newCollectionValue("Edm.String") + .add(of.newPrimitiveValueBuilder().buildString("Single entry!")))); + entity.getProperties().add(of.newComplexProperty("PropertyCompAllPrim", + of.newComplexValue("CTAllPrim") + .add(of.newPrimitiveProperty("PropertyString", + of.newPrimitiveValueBuilder().buildString("Changed"))))); + + final ODataEntityUpdateResponse response = client.getCUDRequestFactory() + .getEntityUpdateRequest(targetURI,UpdateType.PATCH, entity) + .execute(); + + assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode()); + final String cookie = response.getHeader(HttpHeader.SET_COOKIE).iterator().next(); + + final ODataEntityRequest entityRequest = client.getRetrieveRequestFactory() + .getEntityRequest( + client.newURIBuilder() + .appendEntitySetSegment("ESKeyNav") + .appendKeySegment(1) + .expand("NavPropertyETKeyNavOne", "NavPropertyETKeyNavMany") + .build()); + entityRequest.addCustomHeader(HttpHeader.COOKIE, cookie); + final ODataRetrieveResponse entitytResponse = entityRequest.execute(); + + assertEquals(HttpStatusCode.OK.getStatusCode(), entitytResponse.getStatusCode()); + assertEquals(1, entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavOne") + .asInlineEntity() + .getEntity() + .getProperty("PropertyInt16") + .getPrimitiveValue() + .toValue()); + + assertEquals(3, entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") + .asInlineEntitySet() + .getEntitySet() + .getEntities() + .size()); + + assertEquals(1, entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") + .asInlineEntitySet() + .getEntitySet() + .getEntities() + .get(0) + .getProperty("PropertyInt16") + .getPrimitiveValue() + .toValue()); + + assertEquals(2, entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") + .asInlineEntitySet() + .getEntitySet() + .getEntities() + .get(1) + .getProperty("PropertyInt16") + .getPrimitiveValue() + .toValue()); + + assertEquals(3, entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") + .asInlineEntitySet() + .getEntitySet() + .getEntities() + .get(2) + .getProperty("PropertyInt16") + .getPrimitiveValue() + .toValue()); + + final Iterator collectionIterator = entitytResponse.getBody() + .getProperty("CollPropertyString") + .getCollectionValue() + .iterator(); + assertTrue(collectionIterator.hasNext()); + assertEquals("Single entry!", collectionIterator.next().asPrimitive().toValue()); + assertFalse(collectionIterator.hasNext()); + + final ODataComplexValue complexValue = entitytResponse.getBody() + .getProperty("PropertyCompAllPrim") + .getComplexValue(); + + assertEquals("Changed", complexValue.get("PropertyString").getPrimitiveValue().toValue()); + } + + @Test + public void testUpdateReplace() { + final EdmEnabledODataClient client = ODataClientFactory.getEdmEnabledClient(SERVICE_URI); + final ODataObjectFactory of = client.getObjectFactory(); + + final URI targetURI = client.newURIBuilder(SERVICE_URI) + .appendEntitySetSegment("ESKeyNav") + .appendKeySegment(1) + .build(); + + final ODataEntity entity = of.newEntity(new FullQualifiedName("olingo.odata.test1", "ETKeyNav")); + entity.addLink(of.newEntityNavigationLink("NavPropertyETKeyNavOne", targetURI)); + entity.addLink(of.newEntitySetNavigationLink("NavPropertyETKeyNavMany", client.newURIBuilder(SERVICE_URI) + .appendEntitySetSegment("ESKeyNav").appendKeySegment(3).build())); + entity.getProperties().add(of.newPrimitiveProperty("PropertyString", of.newPrimitiveValueBuilder() + .buildString("Must not be null"))); + entity.getProperties().add(of.newComplexProperty("PropertyCompTwoPrim", of.newComplexValue("CTTwoPrim") + .add(of.newPrimitiveProperty("PropertyString", of.newPrimitiveValueBuilder() + .buildString("Must not be null"))) + .add(of.newPrimitiveProperty("PropertyInt16", of.newPrimitiveValueBuilder().buildInt16((short) 42))))); + entity.getProperties().add(of.newCollectionProperty("CollPropertyString", of.newCollectionValue("Edm.String") + .add(of.newPrimitiveValueBuilder().buildString("Single entry!")))); + entity.getProperties().add(of.newComplexProperty("PropertyCompAllPrim", + of.newComplexValue("CTAllPrim") + .add(of.newPrimitiveProperty("PropertyString", + of.newPrimitiveValueBuilder().buildString("Changed"))))); + + final ODataEntityUpdateResponse response = client.getCUDRequestFactory() + .getEntityUpdateRequest(targetURI,UpdateType.REPLACE, entity) + .execute(); + + assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode()); + final String cookie = response.getHeader(HttpHeader.SET_COOKIE).iterator().next(); + + final ODataEntityRequest entityRequest = client.getRetrieveRequestFactory() + .getEntityRequest( + client.newURIBuilder() + .appendEntitySetSegment("ESKeyNav") + .appendKeySegment(1) + .expand("NavPropertyETKeyNavOne", "NavPropertyETKeyNavMany") + .build()); + entityRequest.addCustomHeader(HttpHeader.COOKIE, cookie); + final ODataRetrieveResponse entitytResponse = entityRequest.execute(); + + assertEquals(HttpStatusCode.OK.getStatusCode(), entitytResponse.getStatusCode()); + assertEquals(1, entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavOne") + .asInlineEntity() + .getEntity() + .getProperty("PropertyInt16") + .getPrimitiveValue() + .toValue()); + + assertEquals(3, entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") + .asInlineEntitySet() + .getEntitySet() + .getEntities() + .size()); + + assertEquals(1, entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") + .asInlineEntitySet() + .getEntitySet() + .getEntities() + .get(0) + .getProperty("PropertyInt16") + .getPrimitiveValue() + .toValue()); + + assertEquals(2, entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") + .asInlineEntitySet() + .getEntitySet() + .getEntities() + .get(1) + .getProperty("PropertyInt16") + .getPrimitiveValue() + .toValue()); + + assertEquals(3, entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany") + .asInlineEntitySet() + .getEntitySet() + .getEntities() + .get(2) + .getProperty("PropertyInt16") + .getPrimitiveValue() + .toValue()); + + final Iterator collectionIterator = entitytResponse.getBody() + .getProperty("CollPropertyString") + .getCollectionValue() + .iterator(); + assertTrue(collectionIterator.hasNext()); + assertEquals("Single entry!", collectionIterator.next().asPrimitive().toValue()); + assertFalse(collectionIterator.hasNext()); + + final ODataComplexValue propCompAllPrim = entitytResponse.getBody() + .getProperty("PropertyCompAllPrim") + .getComplexValue(); + + assertEquals("Changed", propCompAllPrim.get("PropertyString").getPrimitiveValue().toValue()); + assertTrue(propCompAllPrim.get("PropertyInt16").hasNullValue()); + assertTrue(propCompAllPrim.get("PropertyDate").hasNullValue()); + + final ODataComplexValue propCompTwoPrim = entitytResponse.getBody() + .getProperty("PropertyCompTwoPrim") + .getComplexValue(); + + assertEquals("Must not be null", propCompTwoPrim.get("PropertyString").getPrimitiveValue().toValue()); + assertEquals(42, propCompTwoPrim.get("PropertyInt16").getPrimitiveValue().toValue()); + + assertNotNull(entitytResponse.getBody().getProperty("PropertyCompNav").getComplexValue()); + assertTrue(entitytResponse.getBody() + .getProperty("PropertyCompNav") + .getComplexValue() + .get("PropertyInt16") + .hasNullValue()); + } + + @Override protected ODataClient getClient() { ODataClient odata = ODataClientFactory.getClient(); 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 a46644cd4..55fa57f99 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 @@ -22,14 +22,11 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import java.net.URI; import java.net.URISyntaxException; -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; @@ -44,9 +41,10 @@ import org.apache.olingo.client.api.communication.response.ODataBatchResponse; import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse; import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse; import org.apache.olingo.client.api.communication.response.ODataResponse; +import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; +import org.apache.olingo.client.api.http.HttpClientException; import org.apache.olingo.client.api.uri.URIBuilder; import org.apache.olingo.client.core.communication.request.batch.ODataChangesetResponseItem; -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; @@ -54,11 +52,11 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.format.ContentType; import org.apache.olingo.commons.api.format.ODataFormat; +import org.apache.olingo.commons.api.http.HttpHeader; import org.apache.olingo.commons.api.http.HttpStatusCode; import org.apache.olingo.fit.tecsvc.TecSvcConst; import org.apache.olingo.fit.v4.AbstractTestITCase; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; public class BatchClientITCase extends AbstractTestITCase { @@ -66,8 +64,8 @@ public class BatchClientITCase extends AbstractTestITCase { 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 FullQualifiedName ES_NOT_AVAILABLE = new FullQualifiedName(SERVICE_NAMESPACE, + ES_NOT_AVAILABLE_NAME); private static final String PROPERTY_STRING = "PropertyString"; @Before @@ -107,7 +105,7 @@ public class BatchClientITCase extends AbstractTestITCase { .appendEntitySetSegment(ES_NOT_AVAILABLE_NAME) .build(); final ODataEntityCreateRequest createRequest = client.getCUDRequestFactory() - .getEntityCreateRequest(targetURI, entity); + .getEntityCreateRequest(targetURI, entity); changeset.addRequest(createRequest); final ODataBatchResponse response = payloadManager.getResponse(); @@ -277,8 +275,7 @@ public class BatchClientITCase extends AbstractTestITCase { assertEquals(400, oDataResponse.getStatusCode()); } - @Test - @Ignore + @Test(expected = HttpClientException.class) public void testInvalidHost() throws URISyntaxException { final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI); request.setAccept(ACCEPT); @@ -290,12 +287,10 @@ public class BatchClientITCase extends AbstractTestITCase { payload.addRequest(queryReq); // Fetch result - final ODataBatchResponse response = payload.getResponse(); - assertEquals(400, response.getStatusCode()); + payload.getResponse(); } - @Test - @Ignore + @Test(expected = HttpClientException.class) public void testInvalidAbsoluteRequest() throws URISyntaxException { final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI); request.setAccept(ACCEPT); @@ -307,8 +302,7 @@ public class BatchClientITCase extends AbstractTestITCase { payload.addRequest(queryReq); // Fetch result - final ODataBatchResponse response = payload.getResponse(); - assertEquals(400, response.getStatusCode()); + payload.getResponse(); } @Test @@ -367,111 +361,92 @@ public class BatchClientITCase extends AbstractTestITCase { assertEquals("application/json;odata.metadata=minimal", oDataResonse.getContentType()); } - @SuppressWarnings("unchecked") @Test - @Ignore("Not implemented") - public void changesetWithReferences() throws EdmPrimitiveTypeException { + @SuppressWarnings("unchecked") + public void changesetWithReferences() throws EdmPrimitiveTypeException, URISyntaxException { // create your request final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI); + final ODataObjectFactory of = client.getObjectFactory(); request.setAccept(ACCEPT); final BatchManager streamManager = request.payloadManager(); final ODataChangeset changeset = streamManager.addChangeset(); - ODataEntity esAllPrim = newESAllPrim((short) 23); + final ODataEntity entityESAllPrim = getClient().getObjectFactory(). + newEntity(new FullQualifiedName("olingo.odata.test1.ESAllPrim")); + entityESAllPrim.getProperties().add(client.getObjectFactory().newPrimitiveProperty( + "PropertyDouble", + client.getObjectFactory().newPrimitiveValueBuilder().buildDouble(3.1415))); + + entityESAllPrim.addLink( + of.newEntityNavigationLink("NavPropertyETTwoPrimOne", client.newURIBuilder(SERVICE_URI) + .appendEntitySetSegment("ESTwoPrim") + .appendKeySegment(-365) + .build())); + + final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim"); // add create request final ODataEntityCreateRequest createReq = - client.getCUDRequestFactory().getEntityCreateRequest(uriBuilder.build(), esAllPrim); - + client.getCUDRequestFactory().getEntityCreateRequest(uriBuilder.build(), entityESAllPrim); + createReq.setFormat(ODataFormat.JSON); changeset.addRequest(createReq); // retrieve request reference int createRequestRef = changeset.getLastContentId(); // add update request - final ODataEntity customerChanges = client.getObjectFactory().newEntity(esAllPrim.getTypeName()); - customerChanges.addLink(client.getObjectFactory().newEntitySetNavigationLink( + final ODataEntity entityUpdate = client.getObjectFactory().newEntity(entityESAllPrim.getTypeName()); + entityUpdate.addLink(client.getObjectFactory().newEntitySetNavigationLink( "NavPropertyETTwoPrimMany", - client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("NavPropertyETTwoPrimMany"). - appendKeySegment(new HashMap() { - private static final long serialVersionUID = 3109256773218160485L; - - { - put("PropertyInt16", 4242); - put("PropertyString", "Test"); - } - }).build())); + client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESTwoPrim").appendKeySegment(32767).build())); final ODataEntityUpdateRequest updateReq = client.getCUDRequestFactory().getEntityUpdateRequest( - URI.create("$" + createRequestRef), UpdateType.PATCH, customerChanges); - + URI.create("$" + createRequestRef), UpdateType.PATCH, entityUpdate); + updateReq.setFormat(ODataFormat.JSON); + changeset.addRequest(updateReq); final ODataBatchResponse response = streamManager.getResponse(); - assertEquals(200, response.getStatusCode()); - assertEquals("OK", response.getStatusMessage()); - + assertEquals(HttpStatusCode.ACCEPTED.getStatusCode(), response.getStatusCode()); + final String cookie = response.getHeader(HttpHeader.SET_COOKIE).iterator().next(); + // verify response payload ... - final Iterator iter = response.getBody(); + final Iterator bodyIterator = response.getBody(); + final ODataBatchResponseItem item = bodyIterator.next(); - final ODataBatchResponseItem item = iter.next(); assertTrue(item instanceof ODataChangesetResponseItem); - final ODataChangesetResponseItem chgitem = (ODataChangesetResponseItem) item; - + assertTrue(chgitem.hasNext()); ODataResponse res = chgitem.next(); - assertEquals(201, res.getStatusCode()); + assertEquals(HttpStatusCode.CREATED.getStatusCode(), res.getStatusCode()); assertTrue(res instanceof ODataEntityCreateResponse); - - esAllPrim = ((ODataEntityCreateResponse) res).getBody(); - final ODataEntitySetRequest req = client.getRetrieveRequestFactory().getEntitySetRequest( - URIUtils.getURI(SERVICE_URI, esAllPrim.getEditLink().toASCIIString() + "/NavPropertyETTwoPrimMany")); - - assertEquals(Integer.valueOf(4242), - req.execute().getBody().getEntities().get(0).getProperty("PropertyInt16").getPrimitiveValue(). - toCastValue(Integer.class)); - + final ODataEntityCreateResponse createResponse = ((ODataEntityCreateResponse) res); + res = chgitem.next(); - assertEquals(204, res.getStatusCode()); + assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), res.getStatusCode()); assertTrue(res instanceof ODataEntityUpdateResponse); + + final ODataEntitySetRequest req = client.getRetrieveRequestFactory().getEntitySetRequest( + new URI(createResponse.getHeader(HttpHeader.LOCATION).iterator().next() + "/NavPropertyETTwoPrimMany")); + req.setFormat(ODataFormat.JSON); + req.addCustomHeader(HttpHeader.COOKIE, cookie); + final ODataRetrieveResponse getResponse = req.execute(); + + assertEquals(32767, getResponse.getBody() + .getEntities() + .get(0) + .getProperty("PropertyInt16") + .getPrimitiveValue() + .toValue()); + } - // clean ... - assertEquals(204, client.getCUDRequestFactory().getDeleteRequest( - URIUtils.getURI(SERVICE_URI, esAllPrim.getEditLink().toASCIIString())).execute(). - getStatusCode()); - - try { - client.getRetrieveRequestFactory().getEntityRequest( - URIUtils.getURI(SERVICE_URI, esAllPrim.getEditLink().toASCIIString())). - execute().getBody(); - fail("Entity not deleted"); - } catch (Exception e) { - // ignore - } - } - - private ODataEntity newESAllPrim(short id) { - final ODataEntity entity = getClient().getObjectFactory(). - newEntity(new FullQualifiedName("olingo.odata.test1.ESAllPrim")); - - entity.getProperties().add(client.getObjectFactory().newPrimitiveProperty( - "PropertyInt16", - client.getObjectFactory().newPrimitiveValueBuilder().buildInt16(id))); - - entity.getProperties().add(client.getObjectFactory().newPrimitiveProperty( - "PropertyDouble", - client.getObjectFactory().newPrimitiveValueBuilder().buildDouble(3.1415))); - - return entity; - } - - // TODO If write support is implemented, remove ignore tag @Test - @Ignore("Not implemented") + @SuppressWarnings("unchecked") public void changesetBatchRequest() throws URISyntaxException { final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI); + final ODataObjectFactory of = client.getObjectFactory(); request.setAccept(ACCEPT); final BatchManager payload = request.payloadManager(); @@ -491,21 +466,20 @@ public class BatchClientITCase extends AbstractTestITCase { client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim"); URI editLink = targetURI.build(); - ODataEntity post = client.getObjectFactory().newEntity( + ODataEntity postEntity = client.getObjectFactory().newEntity( new FullQualifiedName("olingo.odata.test1.ESAllPrim")); + postEntity.addLink(of.newEntityNavigationLink("NavPropertyETTwoPrimOne", client.newURIBuilder(SERVICE_URI) + .appendEntitySetSegment("ESTwoPrim") + .appendKeySegment(32766) + .build())); - post.getProperties().add(client.getObjectFactory().newPrimitiveProperty( - "PropertyInt16", - client.getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 15))); - - post.getProperties().add(client.getObjectFactory().newPrimitiveProperty( + postEntity.getProperties().add(client.getObjectFactory().newPrimitiveProperty( "PropertyDouble", client.getObjectFactory().newPrimitiveValueBuilder().buildDouble(3.1415))); final ODataEntityCreateRequest createRequest = - client.getCUDRequestFactory().getEntityCreateRequest(editLink, post); - createRequest.setFormat(ODataFormat.JSON_FULL_METADATA); - createRequest.setContentType("1"); + client.getCUDRequestFactory().getEntityCreateRequest(editLink, postEntity); + createRequest.setFormat(ODataFormat.JSON); changeset.addRequest(createRequest); @@ -514,40 +488,44 @@ public class BatchClientITCase extends AbstractTestITCase { targetURI = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim").appendKeySegment(0); editLink = targetURI.build(); - ODataEntity patch = client.getObjectFactory().newEntity(new FullQualifiedName("olingo.odata.test1.ESAllPrim")); - patch.setEditLink(editLink); + ODataEntity patchEntity = client.getObjectFactory() + .newEntity(new FullQualifiedName("olingo.odata.test1.ESAllPrim")); + patchEntity.setEditLink(editLink); - patch.getProperties().add(client.getObjectFactory().newPrimitiveProperty( + patchEntity.getProperties().add(client.getObjectFactory().newPrimitiveProperty( "PropertyDouble", client.getObjectFactory().newPrimitiveValueBuilder().buildDouble(3.1415))); ODataEntityUpdateRequest changeReq = - client.getCUDRequestFactory().getEntityUpdateRequest(UpdateType.PATCH, patch); - changeReq.setFormat(ODataFormat.JSON_FULL_METADATA); - changeReq.setContentType("2"); + client.getCUDRequestFactory().getEntityUpdateRequest(UpdateType.PATCH, patchEntity); + changeReq.setFormat(ODataFormat.JSON); changeset.addRequest(changeReq); // ------------------------ // Patch request (Upsert) - targetURI = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim").appendKeySegment(35); + targetURI = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim").appendKeySegment(15); editLink = targetURI.build(); - patch = client.getObjectFactory().newEntity(new FullQualifiedName("olingo.odata.test1.ESAllPrim")); - patch.setEditLink(editLink); + patchEntity = client.getObjectFactory().newEntity(new FullQualifiedName("olingo.odata.test1.ESAllPrim")); + patchEntity.setEditLink(editLink); - patch.getProperties().add(client.getObjectFactory().newPrimitiveProperty( + patchEntity.getProperties().add(client.getObjectFactory().newPrimitiveProperty( "PropertyDouble", client.getObjectFactory().newPrimitiveValueBuilder().buildDouble(3.1415))); - - changeReq = client.getCUDRequestFactory().getEntityUpdateRequest(UpdateType.PATCH, patch); - changeReq.setFormat(ODataFormat.JSON_FULL_METADATA); - changeReq.setContentType("3"); + + patchEntity.addLink(of.newEntityNavigationLink("NavPropertyETTwoPrimOne", client.newURIBuilder(SERVICE_URI) + .appendEntitySetSegment("ESTwoPrim") + .appendKeySegment(32766) + .build())); + + changeReq = client.getCUDRequestFactory().getEntityUpdateRequest(UpdateType.PATCH, patchEntity); + changeReq.setFormat(ODataFormat.JSON); changeset.addRequest(changeReq); // ----------------------------- // - Append get request // ----------------------------- - appendGetRequest(payload, "ESAllPrim", 32767, false); // Without error + appendGetRequest(payload, "ESAllPrim", 0, false); // Without error // ----------------------------- // - Fetch result @@ -560,42 +538,54 @@ public class BatchClientITCase extends AbstractTestITCase { assertTrue(bodyIterator.hasNext()); ODataBatchResponseItem item = bodyIterator.next(); assertFalse(item.isChangeset()); - + assertTrue(item.hasNext()); + final ODataResponse response0 = item.next(); + assertTrue(response0 instanceof ODataRetrieveResponse); + assertEquals(34, ((ODataRetrieveResponse)response0).getBody() + .getProperty("PropertyDecimal") + .getPrimitiveValue() + .toValue()); + // Check change set assertTrue(bodyIterator.hasNext()); item = bodyIterator.next(); assertTrue(item.isChangeset()); + + // Insert + assertTrue(item.hasNext()); + final ODataResponse response1 = item.next(); + assertEquals(HttpStatusCode.CREATED.getStatusCode(), response1.getStatusCode()); + assertTrue(response1 instanceof ODataEntityCreateResponse); + assertEquals(3.1415, ((ODataEntityCreateResponse) response1).getBody().getProperty("PropertyDouble") + .getPrimitiveValue() + .toValue()); + // Update + assertTrue(item.hasNext()); + final ODataResponse response2 = item.next(); + assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response2.getStatusCode()); + assertTrue(response2 instanceof ODataEntityUpdateResponse); - for (int i = 0; i < 3; i++) { - assertTrue(item.hasNext()); - assertTrue(item instanceof ODataChangesetResponseItem); - ODataChangesetResponseItem changeSetResponseItem = (ODataChangesetResponseItem) item.next(); - assertNotNull(changeSetResponseItem); - - ODataResponse chgRequest = changeSetResponseItem.next(); - final String contentId = chgRequest.getHeader(ODataBatchConstants.CHANGESET_CONTENT_ID_NAME).iterator().next(); - - if (contentId == "1") { - // Insert - assertEquals(HttpStatusCode.CREATED.getStatusCode(), chgRequest.getStatusCode()); - } else if (contentId == "2") { - // Update - assertEquals(HttpStatusCode.OK.getStatusCode(), chgRequest.getStatusCode()); - } else if (contentId == "3") { - // Upsert - assertEquals(HttpStatusCode.CREATED.getStatusCode(), chgRequest.getStatusCode()); - } else { - fail("Unkonwn content id " + contentId); - } - } - assertFalse(item.hasNext()); - + // Upsert + assertTrue(item.hasNext()); + final ODataResponse response3 = item.next(); + assertEquals(HttpStatusCode.CREATED.getStatusCode(),response3.getStatusCode()); + assertTrue(response3 instanceof ODataEntityUpdateResponse); + assertEquals(3.1415, ((ODataEntityUpdateResponse) response3).getBody().getProperty("PropertyDouble") + .getPrimitiveValue() + .toValue()); + // Check second get request assertTrue(bodyIterator.hasNext()); item = bodyIterator.next(); assertFalse(item.isChangeset()); + assertTrue(item.hasNext()); + final ODataResponse response4 = item.next(); + assertTrue(response4 instanceof ODataRetrieveResponse); + assertEquals(3.1415, ((ODataRetrieveResponse)response4).getBody() + .getProperty("PropertyDouble") + .getPrimitiveValue() + .toValue()); } - private void appendGetRequest(final BatchManager manager, final String segment, final Object key, boolean isRelative) throws URISyntaxException { final URIBuilder targetURI = client.newURIBuilder(SERVICE_URI); diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/DeepInsertITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/DeepInsertITCase.java index 22f56f599..b043a02d7 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/DeepInsertITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/DeepInsertITCase.java @@ -33,9 +33,11 @@ import org.apache.olingo.client.api.EdmEnabledODataClient; import org.apache.olingo.client.api.ODataClient; import org.apache.olingo.client.api.communication.ODataClientErrorException; import org.apache.olingo.client.api.communication.request.cud.ODataEntityCreateRequest; +import org.apache.olingo.client.api.communication.request.cud.UpdateType; import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest; import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest; import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse; +import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse; import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; import org.apache.olingo.client.core.ODataClientFactory; import org.apache.olingo.commons.api.domain.ODataComplexValue; @@ -54,6 +56,7 @@ import org.apache.olingo.commons.api.http.HttpHeader; import org.apache.olingo.commons.api.http.HttpStatusCode; import org.apache.olingo.fit.AbstractBaseTestITCase; import org.apache.olingo.fit.tecsvc.TecSvcConst; +import org.junit.Ignore; import org.junit.Test; public class DeepInsertITCase extends AbstractBaseTestITCase { @@ -567,7 +570,7 @@ public class DeepInsertITCase extends AbstractBaseTestITCase { // Entity must not be created validateSet(targetURI, cookie, (short) 1, (short) 2, (short) 3); } - + @Test public void testInvalidType() throws EdmPrimitiveTypeException { final EdmEnabledODataClient client = ODataClientFactory.getEdmEnabledClient(SERVICE_URI); @@ -607,7 +610,7 @@ public class DeepInsertITCase extends AbstractBaseTestITCase { } @Test - @org.junit.Ignore + @Ignore public void testDeepInsertOnNavigationPropertyInComplexProperty() { final EdmEnabledODataClient client = ODataClientFactory.getEdmEnabledClient(SERVICE_URI); final ODataObjectFactory of = client.getObjectFactory(); @@ -662,6 +665,202 @@ public class DeepInsertITCase extends AbstractBaseTestITCase { .toValue()); } + @Test + public void testDeepUpsert() { + final ODataClient client = getClient(); + final URI updateURI = client.newURIBuilder(SERVICE_URI) + .appendEntitySetSegment(ES_KEY_NAV) + .appendKeySegment(815) + .build(); + final ODataObjectFactory of = client.getObjectFactory(); + final ODataEntity entity = client.getObjectFactory().newEntity(ET_KEY_NAV); + + // Prepare entity(EntitySet: ESKeyNav, Type: ETKeyNav) + entity.getProperties() + .add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42))); + entity.getProperties() + .add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42"))); + entity.getProperties() + .add(of.newComplexProperty(PROPERTY_COMP_NAV, of.newComplexValue(CT_NAV_FIVE_PROP) + .add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42))))); + entity.getProperties() + .add(of.newComplexProperty(PROPERTY_COMP_ALL_PRIM, of.newComplexValue(CT_ALL_PRIM) + .add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42"))))); + entity.getProperties() + .add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM) + .add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42))) + .add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42"))))); + entity.getProperties() + .add(of.newComplexProperty(PROPERTY_COMP_COMP_NAV, of.newComplexValue(CT_PRIM_COMP) + .add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42"))) + .add(of.newComplexProperty(PROPERTY_COMP_NAV, of.newComplexValue(CT_NAV_FIVE_PROP) + .add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42))))))); + + // Non collection navigation property + // Create related entity(EntitySet: ESTwoKeyNav, Type: ETTwoKeyNav, Nav. Property: NavPropertyETTwoKeyNavOne) + final ODataEntity inlineEntitySingle = client.getObjectFactory().newEntity(ET_TWO_KEY_NAV); + inlineEntitySingle.getProperties() + .add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 43))); + inlineEntitySingle.getProperties() + .add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("43"))); + inlineEntitySingle.getProperties().add( + of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_PRIM_COMP))); + inlineEntitySingle.getProperties() + .add(of.newComplexProperty(PROPERTY_COMP_NAV, of.newComplexValue(CT_PRIM_COMP) + .add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 431))))); + inlineEntitySingle.getProperties() + .add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM) + .add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 432))) + .add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("432"))))); + + // Collection navigation property + // The navigation property has a partner navigation property named "NavPropertyETKeyNavOne" + // Create related entity(EntitySet: ESTwoKeyNav, Type: NavPropertyETTwoKeyNavMany + final ODataEntity inlineEntityCol1 = client.getObjectFactory().newEntity(ET_TWO_KEY_NAV); + inlineEntityCol1.getProperties() + .add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 44))); + inlineEntityCol1.getProperties() + .add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("44"))); + inlineEntityCol1.getProperties() + .add(of.newComplexProperty(PROPERTY_COMP_NAV, of.newComplexValue(CT_PRIM_COMP) + .add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 441))))); + inlineEntityCol1.getProperties().add( + of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_PRIM_COMP))); + inlineEntityCol1.getProperties() + .add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM) + .add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 442))) + .add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("442"))))); + + final ODataEntity inlineEntityCol2 = client.getObjectFactory().newEntity(ET_TWO_KEY_NAV); + inlineEntityCol2.getProperties() + .add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 45))); + inlineEntityCol2.getProperties() + .add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("45"))); + inlineEntityCol2.getProperties() + .add(of.newComplexProperty(PROPERTY_COMP_NAV, of.newComplexValue(CT_PRIM_COMP) + .add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 451))))); + inlineEntityCol2.getProperties().add( + of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_PRIM_COMP))); + inlineEntityCol2.getProperties() + .add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM) + .add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 452))) + .add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("452"))))); + + final ODataInlineEntity newDeepInsertEntityLink = + of.newDeepInsertEntity(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE, inlineEntitySingle); + final ODataEntitySet newDeepInsertEntitySet = of.newEntitySet(); + newDeepInsertEntitySet.getEntities().add(inlineEntityCol1); + newDeepInsertEntitySet.getEntities().add(inlineEntityCol2); + final ODataInlineEntitySet newDeepInsertEntitySetLink = + of.newDeepInsertEntitySet(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, newDeepInsertEntitySet); + + entity.addLink(newDeepInsertEntityLink); + entity.addLink(newDeepInsertEntitySetLink); + + // Perform update request (upsert) + final ODataEntityUpdateResponse responseCreate = client.getCUDRequestFactory() + .getEntityUpdateRequest(updateURI, UpdateType.PATCH, entity) + .execute(); + assertEquals(HttpStatusCode.CREATED.getStatusCode(), responseCreate.getStatusCode()); + + final String cookie = responseCreate.getHeader(HttpHeader.SET_COOKIE).toString(); + + // Fetch ESKeyNav entity with expand of NavPropertyETTwoKeyNavOne nav. property + ODataProperty propertyInt16 = responseCreate.getBody().getProperty(PROPERTY_INT16); + final URI esKeyNavURI = + client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).appendKeySegment( + propertyInt16.getPrimitiveValue().toValue()).expand(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE, + NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).build(); + + final ODataEntityRequest esKeyNavRequest = client.getRetrieveRequestFactory() + .getEntityRequest(esKeyNavURI); + esKeyNavRequest.addCustomHeader(HttpHeader.COOKIE, cookie); + final ODataRetrieveResponse esKeyNavResponse = esKeyNavRequest.execute(); + + // Check nav. property NavPropertyETTwoKeyNavOne + assertNotNull(esKeyNavResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE)); + assertEquals(431, esKeyNavResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE).getComplexValue().get( + PROPERTY_COMP_NAV).getComplexValue().get(PROPERTY_INT16).getPrimitiveValue().toValue()); + + // Check nav. property NavPropertyETTwoKeyNavMany + assertNotNull(esKeyNavResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY)); + assertEquals(2, esKeyNavResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).getCollectionValue() + .size()); + Iterator twoKeyNavManyIterator = + esKeyNavResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).getCollectionValue().iterator(); + final ODataValue firstTwoKeyNavEnity = twoKeyNavManyIterator.next(); // First entity + assertEquals(441, firstTwoKeyNavEnity.asComplex().get(PROPERTY_COMP_NAV).getValue().asComplex().get( + PROPERTY_INT16).getPrimitiveValue().toValue()); + final ODataValue secondTwoKeyNavEnity = twoKeyNavManyIterator.next(); // Second entity + assertEquals(451, secondTwoKeyNavEnity.asComplex().get(PROPERTY_COMP_NAV).getValue().asComplex().get( + PROPERTY_INT16).getPrimitiveValue().toValue()); + + // Fetch ESTwoKeyNav entities and check if available and the partner relation have been set up + // Check ESTwoKeyNav(Created via NavPropertyETTwoKeyNavOne) + Map composedKey = new HashMap(); + composedKey.put(PROPERTY_INT16, esKeyNavResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE) + .getComplexValue().get(PROPERTY_INT16) + .getPrimitiveValue().toValue()); + composedKey.put(PROPERTY_STRING, esKeyNavResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE) + .getComplexValue().get(PROPERTY_STRING) + .getPrimitiveValue().toValue()); + + final URI esTwoKeyNavEntitySingleURI = client.newURIBuilder(SERVICE_URI) + .appendEntitySetSegment(ES_TWO_KEY_NAV) + .appendKeySegment(composedKey) + .build(); + + final ODataEntityRequest esTwoKeyNavSingleRequest = client.getRetrieveRequestFactory() + .getEntityRequest(esTwoKeyNavEntitySingleURI); + esTwoKeyNavSingleRequest.addCustomHeader(HttpHeader.COOKIE, cookie); + final ODataRetrieveResponse esTwoKeyNavSingleResponse = esTwoKeyNavSingleRequest.execute(); + assertEquals(431, esTwoKeyNavSingleResponse.getBody().getProperty(PROPERTY_COMP_NAV).getComplexValue().get( + PROPERTY_INT16).getPrimitiveValue().toValue()); + + // Check ESTwoKeyNav(Created via NavPropertyETTwoKeyNavMany(0)) + composedKey.clear(); + composedKey.put(PROPERTY_INT16, firstTwoKeyNavEnity.asComplex().get(PROPERTY_INT16).getPrimitiveValue().toValue()); + composedKey.put(PROPERTY_STRING, firstTwoKeyNavEnity.asComplex().get(PROPERTY_STRING).getPrimitiveValue() + .toValue()); + + URI esTwoKeyNavEntityManyOneURI = + client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_TWO_KEY_NAV).appendKeySegment(composedKey) + .expand(NAV_PROPERTY_ET_KEY_NAV_ONE).build(); + + final ODataEntityRequest esTwoKeyNavManyOneRequest = + client.getRetrieveRequestFactory().getEntityRequest(esTwoKeyNavEntityManyOneURI); + esTwoKeyNavManyOneRequest.addCustomHeader(HttpHeader.COOKIE, cookie); + final ODataRetrieveResponse esTwoKeyNavManyOneResponse = esTwoKeyNavManyOneRequest.execute(); + + assertEquals(441, esTwoKeyNavManyOneResponse.getBody().getProperty(PROPERTY_COMP_NAV).getComplexValue().get( + PROPERTY_INT16).getPrimitiveValue().toValue()); + assertNotNull(esTwoKeyNavManyOneResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_ONE).getComplexValue()); + assertEquals(propertyInt16.getPrimitiveValue().toValue(), esTwoKeyNavManyOneResponse.getBody().getProperty( + NAV_PROPERTY_ET_KEY_NAV_ONE).getComplexValue().get(PROPERTY_INT16).getPrimitiveValue().toValue()); + + // Check ESTwoKeyNav(Created via NavPropertyETTwoKeyNavMany(1)) + composedKey.clear(); + composedKey.put(PROPERTY_INT16, secondTwoKeyNavEnity.asComplex().get(PROPERTY_INT16).getPrimitiveValue().toValue()); + composedKey.put(PROPERTY_STRING, secondTwoKeyNavEnity.asComplex().get(PROPERTY_STRING).getPrimitiveValue() + .toValue()); + + URI esTwoKeyNavEntityManyTwoURI = + client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_TWO_KEY_NAV).appendKeySegment(composedKey) + .expand(NAV_PROPERTY_ET_KEY_NAV_ONE).build(); + + final ODataEntityRequest esTwoKeyNavManyTwoRequest = + client.getRetrieveRequestFactory().getEntityRequest(esTwoKeyNavEntityManyTwoURI); + esTwoKeyNavManyTwoRequest.addCustomHeader(HttpHeader.COOKIE, cookie); + final ODataRetrieveResponse esTwoKeyNavManyTwoResponse = esTwoKeyNavManyTwoRequest.execute(); + + assertEquals(451, esTwoKeyNavManyTwoResponse.getBody().getProperty(PROPERTY_COMP_NAV).getComplexValue().get( + PROPERTY_INT16).getPrimitiveValue().toValue()); + assertNotNull(esTwoKeyNavManyTwoResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_ONE).getComplexValue()); + assertEquals(propertyInt16.getPrimitiveValue().toValue(), esTwoKeyNavManyTwoResponse.getBody().getProperty( + NAV_PROPERTY_ET_KEY_NAV_ONE).getComplexValue().get(PROPERTY_INT16).getPrimitiveValue().toValue()); + + } + private String getCookie() { final EdmEnabledODataClient client = ODataClientFactory.getEdmEnabledClient(SERVICE_URI); final ODataRetrieveResponse response = client.getRetrieveRequestFactory() diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java index b48d05173..3cef7e621 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java @@ -522,6 +522,11 @@ public class DataCreator { setLink(entitySet.getEntities().get(0), "NavPropertyETMediaOne", esMediaTargets.get(0)); setLink(entitySet.getEntities().get(1), "NavPropertyETMediaOne", esMediaTargets.get(1)); setLink(entitySet.getEntities().get(2), "NavPropertyETMediaOne", esMediaTargets.get(2)); + + // NavPropertyETMediaMany + setLinks(entitySet.getEntities().get(0), "NavPropertyETMediaMany", esMediaTargets.get(0), esMediaTargets.get(2)); + setLinks(entitySet.getEntities().get(1), "NavPropertyETMediaMany", esMediaTargets.get(2)); + setLinks(entitySet.getEntities().get(2), "NavPropertyETMediaMany", esMediaTargets.get(0), esMediaTargets.get(1)); } private void linkESTwoKeyNav(Map data) { diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/RequestValidator.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/RequestValidator.java index c2e9da4a6..92bb5ce4e 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/RequestValidator.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/RequestValidator.java @@ -44,19 +44,30 @@ import org.apache.olingo.server.tecsvc.data.DataProvider.DataProviderException; public class RequestValidator { private DataProvider provider; private boolean isInsert; + private boolean isPatch; private UriHelper uriHelper; private Edm edm; private String rawServiceRoot; - public RequestValidator(final DataProvider provider, final boolean isInsert, final UriHelper uriHelper, + public RequestValidator(final DataProvider provider, final UriHelper uriHelper, final Edm edm, final String rawServiceRoot) { this.provider = provider; - this.isInsert = isInsert; + this.isInsert = true; this.uriHelper = uriHelper; this.edm = edm; this.rawServiceRoot = rawServiceRoot; } + public RequestValidator(final DataProvider provider, final boolean isUpdate, final boolean isPatch, + final UriHelper uriHelper, final Edm edm, final String rawServiceRoot) { + this.provider = provider; + this.isInsert = !isUpdate; + this.isPatch = isPatch; + this.uriHelper = uriHelper; + this.edm = edm; + this.rawServiceRoot = rawServiceRoot; + } + public void validate(final EdmBindingTarget edmBindingTarget, final Entity entity) throws DataProviderException { final List path = new ArrayList(); @@ -84,9 +95,10 @@ public class RequestValidator { edmProperty, target); - if (( isInsert && !edmProperty.isNullable() && (bindingResult != ValidatioResult.FOUND - && linkResult != ValidatioResult.FOUND)) - || (!isInsert && !edmProperty.isNullable() && linkResult == ValidatioResult.EMPTY)) { + if (( isInsert && !edmProperty.isNullable() + && (bindingResult != ValidatioResult.FOUND + && linkResult != ValidatioResult.FOUND)) + || (!(isInsert && isPatch) && !edmProperty.isNullable() && linkResult == ValidatioResult.EMPTY)) { throw new DataProviderException("Navigation property " + navPropertyName + " must not be null", HttpStatusCode.BAD_REQUEST); } @@ -192,8 +204,9 @@ public class RequestValidator { // Check if all "not nullable" properties are set if(!edmProperty.isNullable()) { - if((property != null && property.isNull()) // Update,insert; Property is explicit set to null - || (isInsert && property == null) ) { // Insert; Property not provided + if((property != null && property.isNull()) // Update,insert; Property is explicit set to null + || (isInsert && property == null) // Insert; Property not provided + || (!isInsert && !isPatch && property == null)) { // Insert(Put); Property not provided throw new DataProviderException("Property " + propertyName + " must not be null", HttpStatusCode.BAD_REQUEST); } diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java index 623d22d5a..6d7d92817 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java @@ -241,7 +241,6 @@ public class TechnicalEntityProcessor extends TechnicalProcessor final DeserializerResult deserializerResult = odata.createDeserializer(ODataFormat.fromContentType(requestFormat)) .entity(request.getBody(), edmEntityType); new RequestValidator(dataProvider, - true, // Insert odata.createUriHelper(), serviceMetadata.getEdm(), request.getRawBaseUri() @@ -289,7 +288,8 @@ public class TechnicalEntityProcessor extends TechnicalProcessor final Entity changedEntity = deserializer.entity(request.getBody(), edmEntitySet.getEntityType()).getEntity(); new RequestValidator(dataProvider, - false, // Update + true, // Update + request.getMethod() == HttpMethod.PATCH, odata.createUriHelper(), serviceMetadata.getEdm(), request.getRawBaseUri()