From 189de7b2d70f84260d76ed323e22d85bf9cd6d57 Mon Sep 17 00:00:00 2001 From: Christian Holzer Date: Thu, 2 Apr 2015 15:04:00 +0200 Subject: [PATCH] [OLINGO-545] Fix: Bind operations are applyed before creating deep insert entities --- .../fit/tecsvc/client/BindingITCase.java | 47 +++++++++++++++++++ .../server/tecsvc/data/DataProvider.java | 15 +++--- 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java index d0435b27f..75cadd00b 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java @@ -25,6 +25,7 @@ import java.net.URI; import java.util.HashMap; import java.util.Iterator; +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.UpdateType; @@ -34,6 +35,7 @@ import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResp import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; import org.apache.olingo.client.core.ODataClientFactory; import org.apache.olingo.commons.api.domain.ODataEntity; +import org.apache.olingo.commons.api.domain.ODataInlineEntity; import org.apache.olingo.commons.api.domain.ODataLink; import org.apache.olingo.commons.api.domain.ODataObjectFactory; import org.apache.olingo.commons.api.domain.ODataProperty; @@ -310,6 +312,51 @@ public class BindingITCase extends AbstractBaseTestITCase { } } + @Test + public void testDeepInsertWithBindingSameNavigationProperty() { + final EdmEnabledODataClient client = ODataClientFactory.getEdmEnabledClient(SERVICE_URI); + client.getConfiguration().setDefaultPubFormat(ODataFormat.JSON); + final ODataObjectFactory of = client.getObjectFactory(); + + final ODataEntity entity = of.newEntity(ET_KEY_NAV); + entity.getProperties().add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder() + .buildString("1"))); + entity.getProperties().add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM) + .add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short)1))) + .add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("1"))))); + + final ODataEntity innerEntity = of.newEntity(ET_KEY_NAV); + innerEntity.getProperties().add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder() + .buildString("2"))); + innerEntity.getProperties().add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM) + .add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 1))) + .add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("2"))))); + + final ODataInlineEntity inlineLink = of.newDeepInsertEntity(NAV_PROPERTY_ET_KEY_NAV_ONE, innerEntity); + entity.addLink(inlineLink); + + final URI bindingURI = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV) + .appendKeySegment(3) + .build(); + + entity.addLink(of.newEntityNavigationLink(NAV_PROPERTY_ET_KEY_NAV_ONE, bindingURI)); + + final URI targetURI = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).build(); + final ODataEntityCreateResponse response = + client.getCUDRequestFactory().getEntityCreateRequest(targetURI, entity).execute(); + + assertEquals(HttpStatusCode.CREATED.getStatusCode(), response.getStatusCode()); + + assertEquals(1, response.getBody().getNavigationLink(NAV_PROPERTY_ET_KEY_NAV_ONE) + .asInlineEntity() + .getEntity() + .getProperty(PROPERTY_COMP_TWO_PRIM) + .getComplexValue() + .get(PROPERTY_INT16) + .getPrimitiveValue() + .toValue()); + } + @Override protected ODataClient getClient() { ODataClient odata = ODataClientFactory.getClient(); diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java index e4bb0a2ff..96f0cd7a2 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java @@ -243,18 +243,21 @@ public class DataProvider { patch); } } - + + // For insert operations collection navigation property bind operations and deep insert operations can be combined. + // In this case, the bind operations MUST appear before the deep insert operations in the payload. + // => Apply bindings first + final boolean navigationBindingsAvailable = !changedEntity.getNavigationBindings().isEmpty(); + if (navigationBindingsAvailable) { + applyNavigationBinding(rawBaseUri, edmEntitySet, entity, changedEntity.getNavigationBindings()); + } + // Deep insert (only if not an update) if (isInsert) { handleDeepInsert(rawBaseUri, edmEntitySet, entity, changedEntity); } else { handleDeleteSingleNavigationProperties(edmEntitySet, entity, changedEntity); } - - final boolean navigationBindingsAvailable = !changedEntity.getNavigationBindings().isEmpty(); - if (navigationBindingsAvailable) { - applyNavigationBinding(rawBaseUri, edmEntitySet, entity, changedEntity.getNavigationBindings()); - } } private void handleDeleteSingleNavigationProperties(EdmEntitySet edmEntitySet, Entity entity, Entity changedEntity)