You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ra...@apache.org on 2015/04/20 16:28:34 UTC

[14/22] olingo-odata4 git commit: [OLINGO-545] Tests for batch changesets, update and insert requests added

[OLINGO-545] Tests for batch changesets, update and insert requests added


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/9e232a2d
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/9e232a2d
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/9e232a2d

Branch: refs/heads/OLINGO-573
Commit: 9e232a2d748b74ae12ee9fb64b87665d53124e99
Parents: 62214d2
Author: Christian Holzer <c....@sap.com>
Authored: Tue Apr 7 12:22:02 2015 +0200
Committer: Christian Holzer <c....@sap.com>
Committed: Tue Apr 7 17:20:52 2015 +0200

----------------------------------------------------------------------
 .../olingo/fit/tecsvc/client/BasicITCase.java   | 324 ++++++++++++++++++-
 .../fit/tecsvc/client/BatchClientITCase.java    | 262 ++++++++-------
 .../fit/tecsvc/client/DeepInsertITCase.java     | 203 +++++++++++-
 .../olingo/server/tecsvc/data/DataCreator.java  |   5 +
 .../server/tecsvc/data/RequestValidator.java    |  27 +-
 .../processor/TechnicalEntityProcessor.java     |   4 +-
 6 files changed, 668 insertions(+), 157 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/9e232a2d/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java
----------------------------------------------------------------------
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 5b8949a..5beec7b 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());
-    
-    ODataComplexValue complexProperty = entityResponse.getBody()
-                                                      .getProperty("CollPropertyComp")
-                                                      .getCollectionValue()
-                                                      .iterator()
-                                                      .next()
-                                                      .asComplex();
+    assertEquals(2, entityResponse.getBody().getProperty("CollPropertyComp").getCollectionValue().size());
+    
+    final Iterator<ODataValue> 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<ODataEntity> 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<ODataEntity> entityRequest = client.getRetrieveRequestFactory()
+                                                                .getEntityRequest(client.newURIBuilder()
+                                                                    .appendEntitySetSegment("ESTwoPrim")
+                                                                    .appendKeySegment(key)
+                                                                    .build());
+    entityRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
+    final ODataRetrieveResponse<ODataEntity> 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<ODataEntity> 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<ODataEntity> entityRequest = client.getRetrieveRequestFactory()
+                                                                .getEntityRequest(targetURI);
+    entityRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
+    final ODataRetrieveResponse<ODataEntity> 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<ODataEntity> 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<ODataEntity> entityRequest = client.getRetrieveRequestFactory()
+                                                      .getEntityRequest(
+                                                          client.newURIBuilder()
+                                                          .appendEntitySetSegment("ESKeyNav")
+                                                          .appendKeySegment(1)
+                                                          .expand("NavPropertyETKeyNavOne", "NavPropertyETKeyNavMany")
+                                                          .build());
+    entityRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
+    final ODataRetrieveResponse<ODataEntity> 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<ODataValue> 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<ODataEntity> 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<ODataEntity> entityRequest = client.getRetrieveRequestFactory()
+                                                      .getEntityRequest(
+                                                          client.newURIBuilder()
+                                                          .appendEntitySetSegment("ESKeyNav")
+                                                          .appendKeySegment(1)
+                                                          .expand("NavPropertyETKeyNavOne", "NavPropertyETKeyNavMany")
+                                                          .build());
+    entityRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
+    final ODataRetrieveResponse<ODataEntity> 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<ODataValue> 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();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/9e232a2d/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 a46644c..55fa57f 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<ODataEntity> 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<ODataEntity> 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<String, Object>() {
-              private static final long serialVersionUID = 3109256773218160485L;
-
-              {
-                put("PropertyInt16", 4242);
-                put("PropertyString", "Test");
-              }
-            }).build()));
+        client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESTwoPrim").appendKeySegment(32767).build()));
 
     final ODataEntityUpdateRequest<ODataEntity> 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<ODataBatchResponseItem> iter = response.getBody();
+    final Iterator<ODataBatchResponseItem> 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<ODataEntity>) res).getBody();
-    final ODataEntitySetRequest<ODataEntitySet> 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<ODataEntity> createResponse = ((ODataEntityCreateResponse<ODataEntity>) res);
+    
     res = chgitem.next();
-    assertEquals(204, res.getStatusCode());
+    assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), res.getStatusCode());
     assertTrue(res instanceof ODataEntityUpdateResponse);
+    
+    final ODataEntitySetRequest<ODataEntitySet> req = client.getRetrieveRequestFactory().getEntitySetRequest(
+        new URI(createResponse.getHeader(HttpHeader.LOCATION).iterator().next() + "/NavPropertyETTwoPrimMany"));
+    req.setFormat(ODataFormat.JSON);
+    req.addCustomHeader(HttpHeader.COOKIE, cookie);
+    final ODataRetrieveResponse<ODataEntitySet> 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<ODataEntity> 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<ODataEntity> 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<ODataEntity>)response0).getBody()
+                                                                    .getProperty("PropertyDecimal")
+                                                                    .getPrimitiveValue()
+                                                                    .toValue());
+    
     // Check change set
     assertTrue(bodyIterator.hasNext());
     item = bodyIterator.next();
     assertTrue(item.isChangeset());
-
-    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());
-
+    
+    // Insert
+    assertTrue(item.hasNext());
+    final ODataResponse response1 = item.next();
+    assertEquals(HttpStatusCode.CREATED.getStatusCode(), response1.getStatusCode());
+    assertTrue(response1 instanceof ODataEntityCreateResponse);
+    assertEquals(3.1415, ((ODataEntityCreateResponse<ODataEntity>) 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);
+
+    // Upsert
+    assertTrue(item.hasNext());
+    final ODataResponse response3 = item.next();
+    assertEquals(HttpStatusCode.CREATED.getStatusCode(),response3.getStatusCode());
+    assertTrue(response3 instanceof ODataEntityUpdateResponse);
+    assertEquals(3.1415, ((ODataEntityUpdateResponse<ODataEntity>) 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<ODataEntity>)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);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/9e232a2d/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/DeepInsertITCase.java
----------------------------------------------------------------------
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 22f56f5..b043a02 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<ODataEntity> 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<ODataEntity> esKeyNavRequest = client.getRetrieveRequestFactory()
+        .getEntityRequest(esKeyNavURI);
+    esKeyNavRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
+    final ODataRetrieveResponse<ODataEntity> 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<ODataValue> 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<String, Object> composedKey = new HashMap<String, Object>();
+    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<ODataEntity> esTwoKeyNavSingleRequest = client.getRetrieveRequestFactory()
+        .getEntityRequest(esTwoKeyNavEntitySingleURI);
+    esTwoKeyNavSingleRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
+    final ODataRetrieveResponse<ODataEntity> 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<ODataEntity> esTwoKeyNavManyOneRequest =
+        client.getRetrieveRequestFactory().getEntityRequest(esTwoKeyNavEntityManyOneURI);
+    esTwoKeyNavManyOneRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
+    final ODataRetrieveResponse<ODataEntity> 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<ODataEntity> esTwoKeyNavManyTwoRequest =
+        client.getRetrieveRequestFactory().getEntityRequest(esTwoKeyNavEntityManyTwoURI);
+    esTwoKeyNavManyTwoRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
+    final ODataRetrieveResponse<ODataEntity> 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<ODataEntitySet> response = client.getRetrieveRequestFactory()

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/9e232a2d/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
----------------------------------------------------------------------
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 b48d051..3cef7e6 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<String, EntityCollection> data) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/9e232a2d/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/RequestValidator.java
----------------------------------------------------------------------
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 c2e9da4..92bb5ce 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<String> path = new ArrayList<String>();
@@ -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);
           }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/9e232a2d/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
----------------------------------------------------------------------
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 623d22d..6d7d928 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()