You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2013/09/18 14:05:59 UTC

git commit: Fix for OLINGO-19

Updated Branches:
  refs/heads/master 95a43b421 -> 61ab0780b


Fix for OLINGO-19


Project: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/commit/61ab0780
Tree: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/tree/61ab0780
Diff: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/diff/61ab0780

Branch: refs/heads/master
Commit: 61ab0780bad081ceab448f4c1781136028fd2e6d
Parents: 95a43b4
Author: Michael Bolz <mi...@apache.org>
Authored: Wed Sep 18 14:05:48 2013 +0200
Committer: Michael Bolz <mi...@apache.org>
Committed: Wed Sep 18 14:05:48 2013 +0200

----------------------------------------------------------------------
 .../olingo/odata2/core/ODataRequestHandler.java | 32 ++++++++--
 .../olingo/odata2/fit/basic/BasicBatchTest.java | 26 +++++++-
 .../olingo/odata2/fit/ref/AbstractRefTest.java  | 11 +++-
 .../apache/olingo/odata2/fit/ref/BatchTest.java | 63 +++++++++++++++++---
 .../odata2/fit/ref/PropertyJsonChangeTest.java  | 34 ++++++++++-
 .../resources/batchWithContentIdPart2.batch     | 50 ++++++++++++++++
 6 files changed, 197 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/61ab0780/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestHandler.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestHandler.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestHandler.java
index eed7a12..9d02912 100644
--- a/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestHandler.java
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/ODataRequestHandler.java
@@ -116,17 +116,18 @@ public class ODataRequestHandler {
 
 
       ODataResponseBuilder extendedResponse = ODataResponse.fromResponse(odataResponse);
+      final UriType uriType = uriInfo.getUriType();
+      final String location = (method == ODataHttpMethod.POST && (uriType == UriType.URI1 || uriType == UriType.URI6B)) ? odataResponse.getIdLiteral() : null;
+      final HttpStatusCodes s = getStatusCode(odataResponse, method, uriType);
+      extendedResponse = extendedResponse.idLiteral(location).status(s);
+      
       if (!odataResponse.containsHeader(ODataHttpHeaders.DATASERVICEVERSION)) {
         extendedResponse = extendedResponse.header(ODataHttpHeaders.DATASERVICEVERSION, serverDataServiceVersion);
       }
-      if(!odataResponse.containsHeader(HttpHeaders.CONTENT_TYPE)) {
+      if(!HttpStatusCodes.NO_CONTENT.equals(s) && !odataResponse.containsHeader(HttpHeaders.CONTENT_TYPE)) {
         extendedResponse.header(HttpHeaders.CONTENT_TYPE, acceptContentType.toContentTypeString());
       }
       
-      final UriType uriType = uriInfo.getUriType();
-      final String location = (method == ODataHttpMethod.POST && (uriType == UriType.URI1 || uriType == UriType.URI6B)) ? odataResponse.getIdLiteral() : null;
-      final HttpStatusCodes s = odataResponse.getStatus() == null ? method == ODataHttpMethod.POST ? uriType == UriType.URI9 ? HttpStatusCodes.OK : uriType == UriType.URI7B ? HttpStatusCodes.NO_CONTENT : HttpStatusCodes.CREATED : method == ODataHttpMethod.PUT || method == ODataHttpMethod.PATCH || method == ODataHttpMethod.MERGE || method == ODataHttpMethod.DELETE ? HttpStatusCodes.NO_CONTENT : HttpStatusCodes.OK : odataResponse.getStatus();
-      extendedResponse = extendedResponse.idLiteral(location).status(s);
       
       odataResponse = extendedResponse.build();
     } catch (final Exception e) {
@@ -139,6 +140,25 @@ public class ODataRequestHandler {
     return debugValue == null ? odataResponse : new ODataDebugResponseWrapper(context, odataResponse, uriInfo, exception, debugValue).wrapResponse();
   }
 
+  private HttpStatusCodes getStatusCode(ODataResponse odataResponse, final ODataHttpMethod method, final UriType uriType) {
+    if (odataResponse.getStatus() == null) {
+      if (method == ODataHttpMethod.POST) {
+        if (uriType == UriType.URI9) {
+          return HttpStatusCodes.OK;
+        } else if (uriType == UriType.URI7B) {
+          return HttpStatusCodes.NO_CONTENT;
+        }
+        return HttpStatusCodes.CREATED;
+      } else if (method == ODataHttpMethod.PUT
+          || method == ODataHttpMethod.PATCH
+          || method == ODataHttpMethod.MERGE
+          || method == ODataHttpMethod.DELETE) {
+        return HttpStatusCodes.NO_CONTENT;
+      }
+      return HttpStatusCodes.OK;
+    }
+    return odataResponse.getStatus();
+  }
   
   private String getServerDataServiceVersion() throws ODataException {
     return service.getVersion() == null ? ODataServiceVersion.V20 : service.getVersion();
@@ -430,4 +450,4 @@ public class ODataRequestHandler {
     final String debugValue = queryParameters.get(ODataDebugResponseWrapper.ODATA_DEBUG_QUERY_PARAMETER);
     return ODataDebugResponseWrapper.ODATA_DEBUG_JSON.equals(debugValue) ? debugValue : null;
   }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/61ab0780/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/BasicBatchTest.java
----------------------------------------------------------------------
diff --git a/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/BasicBatchTest.java b/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/BasicBatchTest.java
index 3cfcffb..ecf3351 100644
--- a/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/BasicBatchTest.java
+++ b/odata-fit/src/test/java/org/apache/olingo/odata2/fit/basic/BasicBatchTest.java
@@ -120,13 +120,37 @@ public class BasicBatchTest extends AbstractBasicTest {
     assertTrue(response.getEntity().getContentType().getValue().matches(REG_EX));
     assertNotNull(response.getEntity().getContent());
 
-    String body = StringHelper.inputStreamToString(response.getEntity().getContent());
+    String body = StringHelper.inputStreamToString(response.getEntity().getContent(), true);
     assertTrue(body.contains("Content-Id: mimeHeaderContentId1"));
     assertTrue(body.contains("Content-Id: requestHeaderContentId1"));
     assertTrue(body.contains("Content-Id: mimeHeaderContentId2"));
     assertTrue(body.contains("Content-Id: requestHeaderContentId2"));
   }
 
+  @Test
+  public void testBatchInvalidContentTypeForPut() throws Exception {
+    final HttpPost post = new HttpPost(URI.create(getEndpoint().toString() + "$batch"));
+    post.setHeader("Content-Type", "multipart/mixed;boundary=batch_98c1-8b13-36bb");
+    String replacedEntity = REQUEST_PAYLOAD.replace("Content-Type: application/json;odata=verbose" + LF, "");
+    HttpEntity entity = new StringEntity(replacedEntity);
+    post.setEntity(entity);
+    HttpResponse response = getHttpClient().execute(post);
+
+    assertNotNull(response);
+    assertEquals(202, response.getStatusLine().getStatusCode());
+    assertEquals("HTTP/1.1", response.getProtocolVersion().toString());
+    assertTrue(response.containsHeader("Content-Length"));
+    assertTrue(response.containsHeader("Content-Type"));
+    assertTrue(response.containsHeader("DataServiceVersion"));
+    assertTrue(response.getEntity().getContentType().getValue().matches(REG_EX));
+    assertNotNull(response.getEntity().getContent());
+
+    String body = StringHelper.inputStreamToString(response.getEntity().getContent(), true);
+    assertTrue(body.contains("Content-Id: mimeHeaderContentId1"));
+    assertTrue(body.contains("Content-Id: requestHeaderContentId1"));
+    assertTrue(body.contains("HTTP/1.1 415 Unsupported Media Type"));
+  }
+
   static class TestSingleProc extends ODataSingleProcessor {
     @Override
     public ODataResponse executeBatch(final BatchHandler handler, final String requestContentType, final InputStream content) {

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/61ab0780/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/AbstractRefTest.java
----------------------------------------------------------------------
diff --git a/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/AbstractRefTest.java b/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/AbstractRefTest.java
index 45d9e34..0e09fdc 100644
--- a/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/AbstractRefTest.java
+++ b/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/AbstractRefTest.java
@@ -35,7 +35,6 @@ import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.methods.HttpPut;
 import org.apache.http.client.methods.HttpRequestBase;
 import org.apache.http.entity.StringEntity;
-
 import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
 import org.apache.olingo.odata2.api.commons.ODataHttpMethod;
 import org.apache.olingo.odata2.api.edm.provider.EdmProvider;
@@ -184,6 +183,16 @@ public class AbstractRefTest extends AbstractFitTest {
     }
   }
 
+  protected void putUri(final String uri, final String acceptHeader,
+      final String requestBody, final String requestContentType,
+      final HttpStatusCodes expectedStatusCode) throws Exception {
+    final HttpResponse response = callUri(ODataHttpMethod.PUT, uri, 
+        org.apache.olingo.odata2.api.commons.HttpHeaders.ACCEPT, acceptHeader, requestBody, requestContentType, expectedStatusCode);
+    if (expectedStatusCode != HttpStatusCodes.NO_CONTENT) {
+      response.getEntity().getContent().close();
+    }
+  }
+
   protected String getBody(final HttpResponse response) throws Exception {
     assertNotNull(response);
     assertNotNull(response.getEntity());

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/61ab0780/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/BatchTest.java
----------------------------------------------------------------------
diff --git a/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/BatchTest.java b/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/BatchTest.java
index 845c4e5..6bcb8c5 100644
--- a/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/BatchTest.java
+++ b/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/BatchTest.java
@@ -23,15 +23,19 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
 import java.net.URI;
 
+import junit.framework.Assert;
+
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
+import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.entity.StringEntity;
-import org.junit.Test;
-
 import org.apache.olingo.odata2.testutil.helper.StringHelper;
+import org.junit.Test;
 
 /**
  * 
@@ -74,14 +78,60 @@ public class BatchTest extends AbstractRefTest {
   }
 
   @Test
+  public void testGPPG() throws Exception {
+    HttpResponse response = execute("/batchWithContentIdPart2.batch", "batch_cf90-46e5-1246");
+    String responseBody = StringHelper.inputStreamToString(response.getEntity().getContent(), true);
+
+    assertContentContainValues(responseBody, 
+      "{\"d\":{\"EmployeeName\":\"Frederic Fall\"}}",
+      "HTTP/1.1 201 Created",
+      "Content-Id: employee",
+      "Content-Type: application/json;odata=verbose",
+      "\"EmployeeId\":\"7\",\"EmployeeName\":\"Employee 7\",",
+      "HTTP/1.1 204 No Content",
+      "Content-Id: AAA",
+      "{\"d\":{\"EmployeeName\":\"Robert Fall\"}}"
+      );
+    
+    // validate that response for PUT does not contains a Content Type
+    int indexNoContent = responseBody.indexOf("HTTP/1.1 204 No Content");
+    int indexBoundary = responseBody.indexOf("--changeset_", indexNoContent);
+    
+    int indexContentType = responseBody.indexOf("Content-Type:", indexNoContent);
+    Assert.assertTrue(indexBoundary < indexContentType);
+  }
+  
+  @Test
   public void testErrorBatch() throws Exception {
     String responseBody = execute("/error.batch");
     assertTrue(responseBody.contains("HTTP/1.1 404 Not Found"));
   }
 
+  /**
+   * Validate that given <code>content</code> contains all <code>values</code> in the given order. 
+   * 
+   * @param content
+   * @param containingValues
+   */
+  private void assertContentContainValues(String content, String ... containingValues) {
+    int index = -1;
+    for (String value : containingValues) {
+      int newIndex = content.indexOf(value, index);
+      Assert.assertTrue("Value '" + value + "' not found after index position '" + index + "'.", newIndex >= 0);
+      index = newIndex;
+    }
+  }
+
   private String execute(final String batchResource) throws Exception {
+    HttpResponse response = execute(batchResource, "batch_123");
+
+    String responseBody = StringHelper.inputStreamToString(response.getEntity().getContent(), true);
+    return responseBody;
+  }
+
+  private HttpResponse execute(final String batchResource, String boundary) throws IOException, UnsupportedEncodingException, ClientProtocolException {
     final HttpPost post = new HttpPost(URI.create(getEndpoint().toString() + "$batch"));
-    post.setHeader("Content-Type", "multipart/mixed;boundary=batch_123");
+    post.setHeader("Content-Type", "multipart/mixed;boundary=" + boundary);
 
     String body = StringHelper.inputStreamToString(this.getClass().getResourceAsStream(batchResource), true);
     HttpEntity entity = new StringEntity(body);
@@ -90,9 +140,6 @@ public class BatchTest extends AbstractRefTest {
 
     assertNotNull(response);
     assertEquals(202, response.getStatusLine().getStatusCode());
-
-    String responseBody = StringHelper.inputStreamToString(response.getEntity().getContent(), true);
-    return responseBody;
+    return response;
   }
-
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/61ab0780/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/PropertyJsonChangeTest.java
----------------------------------------------------------------------
diff --git a/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/PropertyJsonChangeTest.java b/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/PropertyJsonChangeTest.java
index de119aa..b76f18c 100644
--- a/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/PropertyJsonChangeTest.java
+++ b/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/PropertyJsonChangeTest.java
@@ -21,10 +21,9 @@ package org.apache.olingo.odata2.fit.ref;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
-import org.junit.Test;
-
 import org.apache.olingo.odata2.api.commons.HttpContentType;
 import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
+import org.junit.Test;
 
 /**
  * Tests employing the reference scenario changing properties in JSON format.
@@ -33,15 +32,44 @@ import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
 public class PropertyJsonChangeTest extends AbstractRefTest {
 
   @Test
-  public void simpleProperty() throws Exception {
+  public void simplePropertyWithoutAcceptHeader() throws Exception {
     final String url = "Employees('2')/Age";
     putUri(url, "{\"Age\":17}", HttpContentType.APPLICATION_JSON, HttpStatusCodes.NO_CONTENT);
     assertEquals("{\"d\":{\"Age\":17}}", getBody(callUri(url + "?$format=json")));
+    putUri(url, "{\"Age\":\"17\"}", HttpContentType.APPLICATION_JSON, HttpStatusCodes.BAD_REQUEST);
 
+    final String urlForName = "Employees('2')/EmployeeName";
+    putUri(urlForName, "{\"EmployeeName\":\"NewName\"}", HttpContentType.APPLICATION_JSON, HttpStatusCodes.NO_CONTENT);
+    assertEquals("{\"d\":{\"EmployeeName\":\"NewName\"}}", getBody(callUri(urlForName + "?$format=json")));
+    putUri(urlForName, "{\"EmployeeName\":NewName}", HttpContentType.APPLICATION_JSON, HttpStatusCodes.BAD_REQUEST);
+  }
+
+  @Test
+  public void simplePropertyWithAcceptHeader() throws Exception {
+    final String url = "Employees('2')/Age";
+    putUri(url, HttpContentType.WILDCARD, "{\"Age\":17}", HttpContentType.APPLICATION_JSON, HttpStatusCodes.NO_CONTENT);
+    assertEquals("{\"d\":{\"Age\":17}}", getBody(callUri(url + "?$format=json")));
     putUri(url, "{\"Age\":\"17\"}", HttpContentType.APPLICATION_JSON, HttpStatusCodes.BAD_REQUEST);
+
+    final String urlForName = "Employees('2')/EmployeeName";
+    putUri(urlForName, HttpContentType.APPLICATION_JSON, "{\"EmployeeName\":\"NewName\"}", HttpContentType.APPLICATION_JSON, HttpStatusCodes.NO_CONTENT);
+    assertEquals("{\"d\":{\"EmployeeName\":\"NewName\"}}", getBody(callUri(urlForName + "?$format=json")));
+    putUri(urlForName, "{\"EmployeeName\":NewName}", HttpContentType.APPLICATION_JSON, HttpStatusCodes.BAD_REQUEST);
   }
 
   @Test
+  public void simplePropertyWithInvalidAcceptHeader() throws Exception {
+    final String url = "Employees('2')/Age";
+    putUri(url, "", "{\"Age\":17}", HttpContentType.APPLICATION_JSON, HttpStatusCodes.NOT_ACCEPTABLE);
+    putUri(url, null, "{\"Age\":17}", HttpContentType.APPLICATION_JSON, HttpStatusCodes.NOT_ACCEPTABLE);
+    
+    final String urlForName = "Employees('2')/EmployeeName";
+    putUri(urlForName, "", "{\"EmployeeName\":\"NewName\"}", HttpContentType.APPLICATION_JSON, HttpStatusCodes.NOT_ACCEPTABLE);
+    putUri(urlForName, null, "{\"EmployeeName\":\"NewName\"}", HttpContentType.APPLICATION_JSON, HttpStatusCodes.NOT_ACCEPTABLE);
+  }
+
+
+  @Test
   public void complexProperty() throws Exception {
     final String url1 = "Employees('2')/Location";
     String requestBody = "{\"Location\":{\"City\":{\"PostalCode\":\"69190\","

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/61ab0780/odata-fit/src/test/resources/batchWithContentIdPart2.batch
----------------------------------------------------------------------
diff --git a/odata-fit/src/test/resources/batchWithContentIdPart2.batch b/odata-fit/src/test/resources/batchWithContentIdPart2.batch
new file mode 100644
index 0000000..b7cd3be
--- /dev/null
+++ b/odata-fit/src/test/resources/batchWithContentIdPart2.batch
@@ -0,0 +1,50 @@
+--batch_cf90-46e5-1246
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+GET Employees('2')/EmployeeName HTTP/1.1
+Content-Id: AAA
+Accept: application/atomsvc+xml;q=0.8, application/json;odata=verbose;q=0.5, */*;q=0.1
+MaxDataServiceVersion: 2.0
+
+
+--batch_cf90-46e5-1246
+Content-Type: multipart/mixed; boundary=changeset_824f-ce08-1e9d
+
+--changeset_824f-ce08-1e9d
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+POST Employees HTTP/1.1
+Content-Type: application/octet-stream
+Content-ID: employee
+Accept: application/atomsvc+xml;q=0.8, application/json;odata=verbose;q=0.5, */*;q=0.1
+MaxDataServiceVersion: 2.0
+
+
+--changeset_824f-ce08-1e9d
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+PUT $employee/EmployeeName HTTP/1.1
+Content-Length: 100000
+Content-Id: AAA
+Accept: application/atomsvc+xml;q=0.8, application/json;odata=verbose;q=0.5, */*;q=0.1
+DataServiceVersion: 1.0
+Content-Type: application/json;odata=verbose
+MaxDataServiceVersion: 2.0
+
+{"EmployeeName":"Robert Fall"}
+
+--changeset_824f-ce08-1e9d--
+
+--batch_cf90-46e5-1246
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+GET Employees('7')/EmployeeName HTTP/1.1
+Accept: application/atomsvc+xml;q=0.8, application/json;odata=verbose;q=0.5, */*;q=0.1
+MaxDataServiceVersion: 2.0
+
+
+--batch_cf90-46e5-1246--
\ No newline at end of file