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 2016/02/16 15:53:57 UTC

olingo-odata4 git commit: [OLINGO-832] Added WriteContentErrorContext and first tests

Repository: olingo-odata4
Updated Branches:
  refs/heads/OLINGO-832_StreamSerializerPoC 67494a789 -> 5b6cccfa9


[OLINGO-832] Added WriteContentErrorContext and first tests


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

Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: 5b6cccfa9cd38262b57409bdc6204b16406afd0e
Parents: 67494a7
Author: Michael Bolz <mi...@sap.com>
Authored: Tue Feb 16 15:46:42 2016 +0100
Committer: Michael Bolz <mi...@sap.com>
Committed: Tue Feb 16 15:46:42 2016 +0100

----------------------------------------------------------------------
 .../apache/olingo/server/api/ODataContent.java  |   1 -
 .../server/api/WriteContentErrorCallback.java   |   2 +-
 .../server/api/WriteContentErrorContext.java    |  25 +++++
 .../server/core/ODataWritableContent.java       |  50 +++++++--
 .../serializer/json/ODataJsonSerializer.java    |   7 +-
 .../json/ODataJsonSerializerTest.java           | 104 ++++++++++++++++++-
 6 files changed, 173 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5b6cccfa/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataContent.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataContent.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataContent.java
index d7e7ec3..e237bf3 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataContent.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataContent.java
@@ -19,7 +19,6 @@
 package org.apache.olingo.server.api;
 
 import java.io.OutputStream;
-import java.nio.channels.ReadableByteChannel;
 import java.nio.channels.WritableByteChannel;
 
 public interface ODataContent {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5b6cccfa/lib/server-api/src/main/java/org/apache/olingo/server/api/WriteContentErrorCallback.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/WriteContentErrorCallback.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/WriteContentErrorCallback.java
index 4219b8f..abc500a 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/WriteContentErrorCallback.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/WriteContentErrorCallback.java
@@ -21,5 +21,5 @@ package org.apache.olingo.server.api;
 import java.nio.channels.WritableByteChannel;
 
 public interface WriteContentErrorCallback {
-  void handleError(ODataContent content, WritableByteChannel channel);
+  void handleError(WriteContentErrorContext context, WritableByteChannel channel);
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5b6cccfa/lib/server-api/src/main/java/org/apache/olingo/server/api/WriteContentErrorContext.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/WriteContentErrorContext.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/WriteContentErrorContext.java
new file mode 100644
index 0000000..d773df1
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/WriteContentErrorContext.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.api;
+
+public interface WriteContentErrorContext {
+  Exception getException();
+  ODataLibraryException getODataLibraryException();
+//  Object getParameter(String name);
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5b6cccfa/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataWritableContent.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataWritableContent.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataWritableContent.java
index ba7025c..1b9cb30 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataWritableContent.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataWritableContent.java
@@ -25,14 +25,19 @@ import java.nio.channels.Channels;
 import java.nio.channels.ReadableByteChannel;
 import java.nio.channels.WritableByteChannel;
 import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.EntityIterator;
 import org.apache.olingo.commons.api.edm.EdmEntityType;
 import org.apache.olingo.commons.api.ex.ODataRuntimeException;
 import org.apache.olingo.server.api.ODataContent;
+import org.apache.olingo.server.api.ODataLibraryException;
 import org.apache.olingo.server.api.ServiceMetadata;
-import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
+import org.apache.olingo.server.api.WriteContentErrorCallback;
+import org.apache.olingo.server.api.WriteContentErrorContext;
+import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
 import org.apache.olingo.server.api.serializer.SerializerException;
 import org.apache.olingo.server.api.serializer.SerializerStreamResult;
 import org.apache.olingo.server.core.serializer.SerializerStreamResultImpl;
@@ -53,11 +58,11 @@ public class ODataWritableContent implements ODataContent {
     private EntityIterator coll;
     private ServiceMetadata metadata;
     private EdmEntityType entityType;
-    private EntitySerializerOptions options;
+    private EntityCollectionSerializerOptions options;
 
     public StreamChannel(EntityIterator coll, EdmEntityType entityType, String head,
                          ODataJsonSerializer jsonSerializer, ServiceMetadata metadata,
-                         EntitySerializerOptions options, String tail) {
+                         EntityCollectionSerializerOptions options, String tail) {
       this.coll = coll;
       this.entityType = entityType;
       this.head = ByteBuffer.wrap(head.getBytes(DEFAULT));
@@ -81,6 +86,11 @@ public class ODataWritableContent implements ODataContent {
           }
           return true;
         } catch (SerializerException e) {
+          final WriteContentErrorCallback errorCallback = options.getWriteContentErrorCallback();
+          if(errorCallback != null) {
+            final ErrorContext errorContext = new ErrorContext(e).setParameter("Sample", "Some exception happened.");
+            errorCallback.handleError(errorContext, Channels.newChannel(out));
+          }
         }
       } else if(tail.hasRemaining()) {
         out.write(tail.array());
@@ -215,22 +225,50 @@ public class ODataWritableContent implements ODataContent {
 
   public static ODataWritableContentBuilder with(EntityIterator coll, EdmEntityType entityType,
                                              ODataJsonSerializer jsonSerializer,
-                                             ServiceMetadata metadata, EntitySerializerOptions options) {
+                                             ServiceMetadata metadata, EntityCollectionSerializerOptions options) {
     return new ODataWritableContentBuilder(coll, entityType, jsonSerializer, metadata, options);
   }
 
+  public static class ErrorContext implements WriteContentErrorContext {
+    private ODataLibraryException exception;
+    final private Map<String, Object> parameters = new HashMap<String, Object>();
+
+    public ErrorContext(ODataLibraryException exception) {
+      this.exception = exception;
+    }
+
+    @Override
+    public Exception getException() {
+      return exception;
+    }
+    @Override
+    public ODataLibraryException getODataLibraryException() {
+      return exception;
+    }
+
+    public ErrorContext setParameter(String name, Object value) {
+      parameters.put(name, value);
+      return this;
+    }
+
+//    @Override
+    public Object getParameter(String name) {
+      return parameters.get(name);
+    }
+  }
+
   public static class ODataWritableContentBuilder {
     private ODataJsonSerializer jsonSerializer;
     private EntityIterator entities;
     private ServiceMetadata metadata;
     private EdmEntityType entityType;
-    private EntitySerializerOptions options;
+    private EntityCollectionSerializerOptions options;
     private String head;
     private String tail;
 
     public ODataWritableContentBuilder(EntityIterator entities, EdmEntityType entityType,
                                    ODataJsonSerializer jsonSerializer,
-                                   ServiceMetadata metadata, EntitySerializerOptions options) {
+                                   ServiceMetadata metadata, EntityCollectionSerializerOptions options) {
       this.entities = entities;
       this.entityType = entityType;
       this.jsonSerializer = jsonSerializer;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5b6cccfa/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
index ba32ab6..df2ee84 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
@@ -211,12 +211,7 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
       outputStream.close();
       String tail = new String(outputStream.toByteArray(), Charset.forName("UTF-8"));
 
-      EntitySerializerOptions.Builder opt = EntitySerializerOptions.with();
-      if(options != null) {
-        opt.expand(options.getExpand()).select(options
-            .getSelect()).writeOnlyReferences(options.getWriteOnlyReferences());
-      }
-      return ODataWritableContent.with(entities, entityType, this, metadata, opt.build())
+      return ODataWritableContent.with(entities, entityType, this, metadata, options)
           .addHead(head).addTail(tail).build();
     } catch (final IOException e) {
       cachedException =

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5b6cccfa/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
index df6e472..4211819 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
@@ -18,18 +18,25 @@
  */
 package org.apache.olingo.server.core.serializer.json;
 
+import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
+import java.nio.ByteBuffer;
+import java.nio.channels.WritableByteChannel;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.Iterator;
+import java.util.Locale;
 import java.util.TimeZone;
 
 import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.output.ByteArrayOutputStream;
 import org.apache.olingo.commons.api.data.ComplexValue;
 import org.apache.olingo.commons.api.data.ContextURL;
 import org.apache.olingo.commons.api.data.ContextURL.Suffix;
 import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.EntityCollection;
+import org.apache.olingo.commons.api.data.EntityIterator;
 import org.apache.olingo.commons.api.data.Property;
 import org.apache.olingo.commons.api.data.ValueType;
 import org.apache.olingo.commons.api.edm.EdmComplexType;
@@ -40,7 +47,10 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
 import org.apache.olingo.commons.api.edm.EdmProperty;
 import org.apache.olingo.commons.api.format.ContentType;
 import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataContent;
 import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.WriteContentErrorCallback;
+import org.apache.olingo.server.api.WriteContentErrorContext;
 import org.apache.olingo.server.api.edmx.EdmxReference;
 import org.apache.olingo.server.api.serializer.ComplexSerializerOptions;
 import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
@@ -85,12 +95,12 @@ public class ODataJsonSerializerTest {
   public void setup() {
     TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
   }
-  
+
   @After
   public void teardown() {
     TimeZone.setDefault(TimeZone.getDefault());
   }
-  
+
   @Test
   public void entitySimple() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
@@ -208,6 +218,96 @@ public class ODataJsonSerializerTest {
   }
 
   @Test
+  public void entityCollectionStreamed() throws Exception {
+    final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
+    final EntityIterator entityIterator = new EntityIterator() {
+      Iterator<Entity> innerIterator = data.readAll(edmEntitySet).iterator();
+      @Override
+      public boolean hasNext() {
+        return innerIterator.hasNext();
+      }
+      @Override
+      public Entity next() {
+        return innerIterator.next();
+      }
+    };
+    CountOption countOption = Mockito.mock(CountOption.class);
+    Mockito.when(countOption.getValue()).thenReturn(true);
+
+    ODataContent result = serializer.entityCollectionStreamed(
+        metadata, edmEntitySet.getEntityType(), entityIterator,
+        EntityCollectionSerializerOptions.with()
+            .contextURL(ContextURL.with().entitySet(edmEntitySet).build())
+            .build()).getODataContent();
+    ByteArrayOutputStream bout = new ByteArrayOutputStream();
+    result.write(bout);
+    final String resultString = new String(bout.toByteArray(), "UTF-8");
+
+    Assert.assertThat(resultString, CoreMatchers.startsWith("{"
+        + "\"@odata.context\":\"$metadata#ESAllPrim\","
+        + "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\","
+        + "\"value\":[{\"PropertyInt16\":32767,\"PropertyString\""));
+    Assert.assertThat(resultString, CoreMatchers.endsWith(
+        "\"PropertyTimeOfDay\":\"00:01:01\"}]}"));
+
+    int count = 0;
+    int index = -1;
+    while ((index = resultString.indexOf("PropertyInt16\":", ++index)) > 0) {
+      count++;
+    }
+    Assert.assertEquals(3, count);
+  }
+
+  @Test
+  public void entityCollectionStreamedWithError() throws Exception {
+    final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
+    final EntityIterator entityIterator = new EntityIterator() {
+      Iterator<Entity> innerIterator = data.readAll(edmEntitySet).iterator();
+      @Override
+      public boolean hasNext() {
+        return innerIterator.hasNext();
+      }
+      @Override
+      public Entity next() {
+        return new Entity();
+      }
+    };
+    CountOption countOption = Mockito.mock(CountOption.class);
+    Mockito.when(countOption.getValue()).thenReturn(true);
+
+    WriteContentErrorCallback errorCallback = new WriteContentErrorCallback() {
+      @Override
+      public void handleError(WriteContentErrorContext context, WritableByteChannel channel) {
+        try {
+          String msgKey = context.getODataLibraryException().getMessageKey().getKey();
+          String toChannel = "ERROR: " + msgKey;
+          channel.write(ByteBuffer.wrap(toChannel.getBytes("UTF-8")));
+        } catch (IOException e) {
+          throw new RuntimeException("Error in error.");
+        }
+      }
+    };
+
+    ODataContent result = serializer.entityCollectionStreamed(
+        metadata, edmEntitySet.getEntityType(), entityIterator,
+        EntityCollectionSerializerOptions.with()
+            .writeContentErrorCallback(errorCallback)
+            .contextURL(ContextURL.with().entitySet(edmEntitySet).build())
+            .build()).getODataContent();
+    ByteArrayOutputStream bout = new ByteArrayOutputStream();
+    result.write(bout);
+    final String resultString = new String(bout.toByteArray(), "UTF-8");
+
+    Assert.assertThat(resultString, CoreMatchers.startsWith("{"
+        + "\"@odata.context\":\"$metadata#ESAllPrim\","
+        + "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\","
+        + "\"value\":"));
+    Assert.assertThat(resultString, CoreMatchers.endsWith(
+        "[ERROR: MISSING_PROPERTY"));
+  }
+
+
+  @Test
   public void entityCollAllPrim() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCollAllPrim");
     final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);