You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2016/12/13 09:22:13 UTC

[1/2] olingo-odata4 git commit: NextLink Support in streaming

Repository: olingo-odata4
Updated Branches:
  refs/heads/master 6a736db10 -> 01c6aa159


NextLink Support in streaming

Change-Id: I199fe29991f9c02b870fd524b4276d16c1e5382e
Signed-off-by: Archana Rai <ar...@sap.com>
Signed-off-by: Christian Amend <ch...@sap.com>


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

Branch: refs/heads/master
Commit: 4b3c02373fa4e237fbefbb0038628c6aef907283
Parents: 6a736db
Author: Archana Rai <ar...@sap.com>
Authored: Wed Nov 30 00:09:08 2016 +0530
Committer: Christian Amend <ch...@sap.com>
Committed: Tue Dec 13 10:09:44 2016 +0100

----------------------------------------------------------------------
 .../fit/tecsvc/http/BasicStreamITCase.java      | 77 ++++++++++++++++++++
 .../olingo/commons/api/data/EntityIterator.java | 20 +++--
 .../api/uri/queryoption/expression/Literal.java |  3 +-
 .../serializer/json/ODataJsonSerializer.java    |  4 +-
 .../core/serializer/xml/ODataXmlSerializer.java |  4 +-
 .../olingo/server/tecsvc/data/DataCreator.java  | 32 ++++++++
 .../processor/TechnicalEntityProcessor.java     | 10 ++-
 .../options/ServerSidePagingHandler.java        |  4 +-
 .../tecsvc/provider/ContainerProvider.java      | 19 ++++-
 .../tecsvc/provider/EntityTypeProvider.java     | 11 +++
 .../server/tecsvc/provider/SchemaProvider.java  |  1 +
 11 files changed, 171 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4b3c0237/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicStreamITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicStreamITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicStreamITCase.java
index 8935f97..ce77536 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicStreamITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicStreamITCase.java
@@ -77,6 +77,83 @@ public class BasicStreamITCase extends AbstractBaseTestITCase {
     assertTrue(content.contains("<d:PropertyString>TEST 2->streamed</d:PropertyString>"));
   }
 
+  @Test
+  public void streamESStreamServerSidePagingXml() throws Exception {
+    URL url = new URL(SERVICE_URI + "ESStreamServerSidePaging?$format=xml");
+
+    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+    connection.setRequestMethod(HttpMethod.GET.name());
+    connection.connect();
+
+    assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
+    assertEquals(ContentType.APPLICATION_XML, ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE)));
+
+    final String content = IOUtils.toString(connection.getInputStream());
+    assertTrue(content.contains("<a:link rel=\"next\" href="));
+    assertTrue(content.contains("ESStreamServerSidePaging?$format=xml&amp;%24skiptoken=1%2A10\"/>"));
+    assertTrue(content.contains("<a:id>ESStreamServerSidePaging(1)</a:id>"));
+    assertTrue(content.contains("<d:PropertyInt16 m:type=\"Int16\">1</d:PropertyInt16>"));
+    assertTrue(content.contains("<d:PropertyStream m:type=\"Stream\">readLink</d:PropertyStream>"));
+  }
+  
+  @Test
+  public void streamESStreamServerSidePagingNextXml() throws Exception {
+    URL url = new URL(SERVICE_URI + "ESStreamServerSidePaging?$format=xml&$skiptoken=1%2A10");
+
+    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+    connection.setRequestMethod(HttpMethod.GET.name());
+    connection.connect();
+
+    assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
+    assertEquals(ContentType.APPLICATION_XML, ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE)));
+
+    final String content = IOUtils.toString(connection.getInputStream());
+    assertTrue(content.contains("<a:link rel=\"next\" href="));
+    assertTrue(content.contains("ESStreamServerSidePaging?$format=xml&amp;%24skiptoken=2%2A10\"/>"));
+    assertTrue(content.contains("<a:id>ESStreamServerSidePaging(11)</a:id>"));
+    assertTrue(content.contains("<d:PropertyInt16 m:type=\"Int16\">11</d:PropertyInt16>"));
+    assertTrue(content.contains("<d:PropertyStream m:type=\"Stream\">readLink</d:PropertyStream>"));
+  }
+  
+  @Test
+  public void streamESStreamServerSidePagingJson() throws Exception {
+    URL url = new URL(SERVICE_URI + "ESStreamServerSidePaging?$format=json");
+
+    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+    connection.setRequestMethod(HttpMethod.GET.name());
+    connection.connect();
+
+    assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
+    assertEquals(ContentType.JSON, ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE)));
+
+    final String content = IOUtils.toString(connection.getInputStream());
+
+    assertTrue(content.contains("{\"PropertyInt16\":2,"+
+    "\"PropertyStream@odata.mediaEtag\":\"eTag\",\"PropertyStream@odata.mediaContentType\":\"image/jpeg\"}"));
+    assertTrue(content.contains("\"@odata.nextLink\""));
+    assertTrue(content.contains("ESStreamServerSidePaging?$format=json&%24skiptoken=1%2A10"));
+  }
+  
+  
+  @Test
+  public void streamESStreamServerSidePagingJsonNext() throws Exception {
+    URL url = new URL(SERVICE_URI + "ESStreamServerSidePaging?$format=json&$skiptoken=1%2A10");
+
+    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+    connection.setRequestMethod(HttpMethod.GET.name());
+    connection.connect();
+
+    assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
+    assertEquals(ContentType.JSON, ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE)));
+
+    final String content = IOUtils.toString(connection.getInputStream());
+
+    assertTrue(content.contains("{\"PropertyInt16\":12,"+
+    "\"PropertyStream@odata.mediaEtag\":\"eTag\",\"PropertyStream@odata.mediaContentType\":\"image/jpeg\"}"));
+    assertTrue(content.contains("\"@odata.nextLink\""));
+    assertTrue(content.contains("ESStreamServerSidePaging?$format=json&%24skiptoken=2%2A10"));
+  }
+  
   @Override
   protected ODataClient getClient() {
     return null;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4b3c0237/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/EntityIterator.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/EntityIterator.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/EntityIterator.java
index 728bf9a..145b2ac 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/EntityIterator.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/EntityIterator.java
@@ -28,7 +28,8 @@ import java.util.List;
  * Data representation as an Iterator for a collection of single entities.
  */
 public abstract class EntityIterator extends AbstractEntityCollection implements Iterator<Entity> {
-
+  
+  private URI next;
   /**
    * {@inheritDoc}
    */
@@ -80,12 +81,12 @@ public abstract class EntityIterator extends AbstractEntityCollection implements
   }
 
   /**
-   * {@inheritDoc}
-   * <p/>
-   * <b>ATTENTION:</b> <code>getNext</code> is not supported by default.
+   * Gets next link.
+   *
+   * @param next next link.
    */
   public URI getNext() {
-    throw new ODataNotSupportedException("Entity Iterator does not support getNext()");
+    return next;
   }
 
   /**
@@ -96,4 +97,13 @@ public abstract class EntityIterator extends AbstractEntityCollection implements
   public URI getDeltaLink() {
     throw new ODataNotSupportedException("Entity Iterator does not support getDeltaLink()");
   }
+  
+  /**
+   * Sets next link.
+   *
+   * @param next next link.
+   */
+  public void setNext(final URI next) {
+    this.next = next;
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4b3c0237/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/expression/Literal.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/expression/Literal.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/expression/Literal.java
index d967c9b..2029551 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/expression/Literal.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/expression/Literal.java
@@ -22,6 +22,7 @@ import org.apache.olingo.commons.api.edm.EdmType;
 
 /**
  * Represents a literal expression node in the expression tree
+ * Literal is not validated by default
  */
 public interface Literal extends Expression {
 
@@ -39,5 +40,5 @@ public interface Literal extends Expression {
    * @return Type of the literal if detected. The type of the literal is guessed by the parser.
    */
   public EdmType getType();
-
+  
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4b3c0237/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 a86bdf0..0cf307f 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
@@ -241,8 +241,8 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
         writeEntitySet(metadata, entityType, entitySet,
             options.getExpand(), null, options.getSelect(), options.getWriteOnlyReferences(), null, json);
       }
-      // next link not supported by default for streaming results
-//      writeNextLink(entitySet, json);
+      // next link support for streaming results
+      writeNextLink(entitySet, json);
 
       json.close();
     } catch (final IOException e) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4b3c0237/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
index 0f0a673..c7ea2e2 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
@@ -314,7 +314,9 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
           && entitySet.getCount() != null) {
         writeCount(entitySet, writer);
       }
-
+      if (entitySet!=null && entitySet.getNext() != null) {
+        writeNextLink(entitySet, writer);
+      }
       boolean writeOnlyRef = (options != null && options.getWriteOnlyReferences());
       if (options == null) {
         writeEntitySet(metadata, entityType, entitySet, null, null, null, null, writer, writeOnlyRef,null);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4b3c0237/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 39f7c81..1533dbd 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
@@ -76,6 +76,7 @@ public class DataCreator {
     data.put("ESTwoKeyNav", createESTwoKeyNav(edm, odata));
     data.put("ESCompCollComp", createESCompCollComp(edm, odata));
     data.put("ESServerSidePaging", createESServerSidePaging(edm, odata));
+    data.put("ESStreamServerSidePaging", createESStreamServerSidePaging(edm, odata));
     data.put("ESTwoKeyTwoPrim", createESTwoKeyTwoPrim(edm, odata));
     data.put("ESAllNullable", createESAllNullable(edm, odata));
     data.put("ESTwoBase", createESTwoBase(edm, odata));
@@ -498,6 +499,37 @@ public class DataCreator {
     createOperations("ESServerSidePaging", entityCollection, EntityTypeProvider.nameETServerSidePaging);
     return entityCollection;
   }
+  
+  private EntityCollection createESStreamServerSidePaging(final Edm edm, final OData odata) {
+    EntityCollection entityCollection = new EntityCollection();
+
+    for (short i = 1; i <= 503; i++) {
+
+      Link readLink = new Link();
+      readLink.setRel(Constants.NS_MEDIA_READ_LINK_REL);
+      readLink.setHref("readLink");
+      
+      entityCollection.getEntities().add(new Entity()
+          .addProperty(createPrimitive("PropertyInt16", i))
+          .addProperty(new Property(null, "PropertyStream", ValueType.PRIMITIVE, readLink)));
+
+      Link editLink = new Link();
+      editLink.setRel(Constants.NS_MEDIA_EDIT_LINK_REL);
+      editLink.setHref("http://mediaserver:1234/editLink");
+      editLink.setMediaETag("eTag");
+      editLink.setType("image/jpeg");
+
+      entityCollection.getEntities().add(new Entity()
+          .addProperty(createPrimitive("PropertyInt16", ++i))
+          .addProperty(new Property(null, "PropertyStream", ValueType.PRIMITIVE, editLink)));   
+    }
+
+    setEntityType(entityCollection, edm.getEntityType(EntityTypeProvider.nameETStreamServerSidePaging));
+    
+    createEntityId(edm, odata, "ESStreamServerSidePaging", entityCollection);
+    createOperations("ESStreamServerSidePaging", entityCollection, EntityTypeProvider.nameETStreamServerSidePaging);
+    return entityCollection;
+  }
 
   private EntityCollection createESKeyNav(final Edm edm, final OData odata) {
     final EntityCollection entityCollection = new EntityCollection();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4b3c0237/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 da2e936..e21b646 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
@@ -18,6 +18,7 @@
  */
 package org.apache.olingo.server.tecsvc.processor;
 
+import java.net.URI;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
@@ -600,7 +601,8 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
    *          otherwise <code>FALSE</code>.
    */
   private boolean isStreaming(EdmEntitySet edmEntitySet, ContentType contentType) {
-    return ContainerProvider.ES_STREAM.equalsIgnoreCase(edmEntitySet.getName());
+    return (ContainerProvider.ES_STREAM.equalsIgnoreCase(edmEntitySet.getName())||
+        ContainerProvider.ES_STREAM_SERVER_PAGINATION.equalsIgnoreCase(edmEntitySet.getName()));
   }
 
   private SerializerResult serializeEntityCollection(final ODataRequest request, final EntityCollection
@@ -630,12 +632,16 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
 
     EntityIterator streamCollection = new EntityIterator() {
       Iterator<Entity> entityIterator = entityCollection.iterator();
-
+      private URI next = entityCollection.getNext();
       @Override
       public List<Operation> getOperations() {
         return entityCollection.getOperations();
       } 
       
+      public URI getNext() {
+        return next;
+      }
+      
       @Override
       public boolean hasNext() {
         return entityIterator.hasNext();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4b3c0237/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/ServerSidePagingHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/ServerSidePagingHandler.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/ServerSidePagingHandler.java
index ad8b7dd..7a8c1b4 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/ServerSidePagingHandler.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/ServerSidePagingHandler.java
@@ -32,6 +32,7 @@ import org.apache.olingo.server.api.uri.queryoption.SystemQueryOptionKind;
 public class ServerSidePagingHandler {
   private static final int MAX_PAGE_SIZE = 10;
   private static final String ES_SERVER_SIDE_PAGING = "ESServerSidePaging";
+  private static final String ES_STREAM_SERVER_SIDE_PAGING = "ESStreamServerSidePaging";
 
   /**
    * <p>Applies server-side paging to the given entity collection.</p>
@@ -97,7 +98,8 @@ public class ServerSidePagingHandler {
   }
 
   private static boolean shouldApplyServerSidePaging(final EdmEntitySet edmEntitySet) {
-    return ES_SERVER_SIDE_PAGING.equals(edmEntitySet.getName());
+    return (ES_SERVER_SIDE_PAGING.equals(edmEntitySet.getName())||
+        ES_STREAM_SERVER_SIDE_PAGING.equals(edmEntitySet.getName()));
   }
 
   private static int getPageSize(final int skipTokenPageSize, final Integer preferredPageSize) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4b3c0237/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ContainerProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ContainerProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ContainerProvider.java
index cb554f7..9cbd5e8 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ContainerProvider.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ContainerProvider.java
@@ -53,6 +53,7 @@ public class ContainerProvider {
   public static final String AIRT_TWO_PARAM = "AIRTTwoParam";
   public static final String AIRT_BYTE_NINE_PARAM = "AIRTByteNineParam";
   public static final String ES_STREAM = "ESStream";
+  public static final String ES_STREAM_SERVER_PAGINATION = "ESStreamServerSidePaging";
 
   private final CsdlEdmProvider prov;
 
@@ -91,6 +92,7 @@ public class ContainerProvider {
     entitySets.add(prov.getEntitySet(ContainerProvider.nameContainer, "ESMedia"));
     entitySets.add(prov.getEntitySet(ContainerProvider.nameContainer, "ESInvisible"));
     entitySets.add(prov.getEntitySet(ContainerProvider.nameContainer, "ESServerSidePaging"));
+    entitySets.add(prov.getEntitySet(ContainerProvider.nameContainer, ES_STREAM_SERVER_PAGINATION));
     entitySets.add(prov.getEntitySet(ContainerProvider.nameContainer, "ESAllNullable"));
     entitySets.add(prov.getEntitySet(ContainerProvider.nameContainer, "ESKeyNav"));
     entitySets.add(prov.getEntitySet(ContainerProvider.nameContainer, "ESTwoKeyNav"));
@@ -359,8 +361,21 @@ public class ContainerProvider {
                         .setValue("Divides the response to several pages using $skiptoken and providing a nextLink")),
                 new CsdlAnnotation().setTerm(TermProvider.TERM_DATA.getFullQualifiedNameAsString()).setExpression(
                     new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.Bool, "true"))));
-
-      } else if (name.equals("ESAllNullable")) {
+        
+      } else if (name.equals(ES_STREAM_SERVER_PAGINATION)) {  
+        return new CsdlEntitySet()
+          .setName(ES_STREAM_SERVER_PAGINATION)
+          .setType(EntityTypeProvider.nameETStreamServerSidePaging)
+          .setAnnotations(Arrays.asList(
+              new CsdlAnnotation().setTerm("Core.Description")
+                  .setExpression(new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.String)
+                      .setValue("Divides the stream response to several pages using $skiptoken and providing a nextLink"
+                          + "Entity set will be streamed and it contains entities with various properties of " +
+                          "type primitive, collection of primitive, complex and collection of complex")),
+              new CsdlAnnotation().setTerm(TermProvider.TERM_DATA.getFullQualifiedNameAsString()).setExpression(
+                  new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.Bool, "true"))));
+        
+        } else if (name.equals("ESAllNullable")) {
         return new CsdlEntitySet()
             .setName("ESAllNullable")
             .setType(EntityTypeProvider.nameETAllNullable)

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4b3c0237/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/EntityTypeProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/EntityTypeProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/EntityTypeProvider.java
index 6e9a1b7..26c6f19 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/EntityTypeProvider.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/EntityTypeProvider.java
@@ -68,6 +68,8 @@ public class EntityTypeProvider {
       "ETMixPrimCollComp");
   public static final FullQualifiedName nameETServerSidePaging =
       new FullQualifiedName(SchemaProvider.NAMESPACE, "ETServerSidePaging");
+  public static final FullQualifiedName nameETStreamServerSidePaging =
+      new FullQualifiedName(SchemaProvider.NAMESPACE, "ETStreamServerSidePaging");
   public static final FullQualifiedName nameETTwoBase = new FullQualifiedName(SchemaProvider.NAMESPACE, "ETTwoBase");
   public static final FullQualifiedName nameETTwoBaseTwoKeyNav =
       new FullQualifiedName(SchemaProvider.NAMESPACE, "ETTwoBaseTwoKeyNav");
@@ -277,6 +279,15 @@ public class EntityTypeProvider {
           .setProperties(Arrays.asList(PropertyProvider.propertyInt16_NotNullable,
               PropertyProvider.propertyString_NotNullable));
 
+    }else if (entityTypeName.equals(nameETStreamServerSidePaging)) {
+      return new CsdlEntityType()
+          .setName(nameETStreamServerSidePaging.getName())
+          .setKey(Arrays.asList(
+              new CsdlPropertyRef()
+                  .setName("PropertyInt16")))
+          .setProperties(Arrays.asList(
+              PropertyProvider.propertyInt16_NotNullable,
+              PropertyProvider.propertyStream));     
     } else if (entityTypeName.equals(nameETAllNullable)) {
       return new CsdlEntityType()
           .setName("ETAllNullable")

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4b3c0237/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/SchemaProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/SchemaProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/SchemaProvider.java
index ac2f916..b8c525a 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/SchemaProvider.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/SchemaProvider.java
@@ -75,6 +75,7 @@ public class SchemaProvider {
     entityTypes.add(prov.getEntityType(EntityTypeProvider.nameETMedia));
     entityTypes.add(prov.getEntityType(EntityTypeProvider.nameETFourKeyAlias));
     entityTypes.add(prov.getEntityType(EntityTypeProvider.nameETServerSidePaging));
+    entityTypes.add(prov.getEntityType(EntityTypeProvider.nameETStreamServerSidePaging));
     entityTypes.add(prov.getEntityType(EntityTypeProvider.nameETAllNullable));
     entityTypes.add(prov.getEntityType(EntityTypeProvider.nameETKeyNav));
     entityTypes.add(prov.getEntityType(EntityTypeProvider.nameETTwoKeyNav));


[2/2] olingo-odata4 git commit: Cross Service EDM

Posted by ch...@apache.org.
Cross Service EDM

Change-Id: I14ed9771c85e576c33d51ed3ea05e6323c20c51a
Signed-off-by: Archana Rai <ar...@sap.com>
Signed-off-by: Christian Amend <ch...@sap.com>


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

Branch: refs/heads/master
Commit: 01c6aa1592eeb041556be23253424cc2a04e1627
Parents: 4b3c023
Author: Archana Rai <ar...@sap.com>
Authored: Wed Dec 7 15:29:04 2016 +0530
Committer: Christian Amend <ch...@sap.com>
Committed: Tue Dec 13 10:10:22 2016 +0100

----------------------------------------------------------------------
 .../commons/core/edm/CrossServiceTest.java      | 237 +++++++++++++++++++
 1 file changed, 237 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/01c6aa15/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/CrossServiceTest.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/CrossServiceTest.java b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/CrossServiceTest.java
new file mode 100644
index 0000000..f2c7430
--- /dev/null
+++ b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/CrossServiceTest.java
@@ -0,0 +1,237 @@
+package org.apache.olingo.commons.core.edm;
+ /*
+  * 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.
+  */
+ 
+ import java.util.Arrays;
+ import java.util.Collections;
+ import java.util.List;
+ 
+ import org.apache.olingo.commons.api.edm.Edm;
+ import org.apache.olingo.commons.api.edm.EdmEntitySet;
+ import org.apache.olingo.commons.api.edm.EdmEntityType;
+ import org.apache.olingo.commons.api.edm.FullQualifiedName;
+ import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider;
+ import org.apache.olingo.commons.api.edm.provider.CsdlAliasInfo;
+ import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider;
+ import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer;
+ import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainerInfo;
+ import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet;
+ import org.apache.olingo.commons.api.edm.provider.CsdlEntityType;
+ import org.apache.olingo.commons.api.edm.provider.CsdlNavigationProperty;
+ import org.apache.olingo.commons.api.edm.provider.CsdlProperty;
+ import org.apache.olingo.commons.api.edm.provider.CsdlPropertyRef;
+ import org.apache.olingo.commons.api.edm.provider.CsdlSchema;
+ import org.apache.olingo.commons.api.ex.ODataException;
+import org.apache.olingo.commons.core.edm.EdmProviderImpl;
+import org.junit.Assert;
+ import org.junit.Test;
+ 
+ public class CrossServiceTest {
+ 
+   private final CsdlEdmProvider provider1 = new CsdlProvider("One");
+   private final CsdlEdmProvider provider2 = new CsdlProvider("Two");
+   private final Edm edm1 = new EdmProviderImpl(provider1);
+   private final Edm edm2 = new EdmProviderImpl(provider2);
+ 
+   private class CsdlProvider extends CsdlAbstractEdmProvider {
+ 
+     private static final String NAMESPACE_PREFIX = "Namespace.";
+     private static final String ALIAS_PREFIX = "Alias";
+     private static final String CONTAINER_PREFIX = "Container";
+     private static final String ENTITY_SET_PREFIX = "EntitySet";
+     private static final String ENTITY_TYPE_PREFIX = "EntityType";
+     private final String name;
+     private final String namespace;
+     private final String other;
+     private final CsdlEntitySet entitySet;
+     private final CsdlEntityType entityType;
+ 
+     private CsdlProvider(final String name) {
+       this.name = name;
+    namespace = NAMESPACE_PREFIX + name;
+       other = name.equals("One") ? "Two" : "One";
+       entitySet = new CsdlEntitySet().setName(ENTITY_SET_PREFIX + name)
+           .setType(new FullQualifiedName(namespace, ENTITY_TYPE_PREFIX + name));
+       entityType = new CsdlEntityType().setName(ENTITY_TYPE_PREFIX + name)
+           .setKey(Collections.singletonList(new CsdlPropertyRef().setName("ID" + name)))
+           .setProperties(Collections.singletonList(
+               new CsdlProperty().setName("ID" + name).setNullable(false).setType("Edm.Guid")))
+           .setNavigationProperties(Collections.singletonList(
+               new CsdlNavigationProperty().setName("Navigation" + other)
+                   .setType(new FullQualifiedName(ALIAS_PREFIX + other, ENTITY_TYPE_PREFIX + other))));
+     }
+ 
+     @Override
+     public List<CsdlAliasInfo> getAliasInfos() throws ODataException {
+       return Arrays.asList(
+           new CsdlAliasInfo().setNamespace(NAMESPACE_PREFIX + name).setAlias(ALIAS_PREFIX + name),
+           new CsdlAliasInfo().setNamespace(NAMESPACE_PREFIX + other).setAlias(ALIAS_PREFIX + other));
+     }
+ 
+     @Override
+     public List<CsdlSchema> getSchemas() throws ODataException {
+       return Collections.singletonList(
+           new CsdlSchema().setNamespace(namespace).setAlias(ALIAS_PREFIX + name)
+               .setEntityContainer(getEntityContainer())
+               .setEntityTypes(Collections.singletonList(entityType)));
+     }
+ 
+     @Override
+    public CsdlEntityContainerInfo getEntityContainerInfo(final FullQualifiedName entityContainerName)
+        throws ODataException {
+      if (entityContainerName == null) {
+        return new CsdlEntityContainerInfo().setContainerName(
+            new FullQualifiedName(namespace, CONTAINER_PREFIX + name));
+      } else if (namespace.equals(entityContainerName.getNamespace())) {
+        if ((CONTAINER_PREFIX + name).equals(entityContainerName.getName())) {
+          return new CsdlEntityContainerInfo().setContainerName(entityContainerName);
+        }
+        return null;
+      } else if ((NAMESPACE_PREFIX + other).equals(entityContainerName.getNamespace())) {
+        final CsdlEdmProvider otherProvider = this == provider1 ? provider2 : provider1;
+        return otherProvider.getEntityContainerInfo(entityContainerName);
+      }
+      return null;
+    }
+
+    @Override
+    public CsdlEntityContainer getEntityContainer() throws ODataException {
+      return new CsdlEntityContainer().setName(CONTAINER_PREFIX + name)
+          .setEntitySets(Collections.singletonList(entitySet));
+    }
+
+    @Override
+    public CsdlEntitySet getEntitySet(final FullQualifiedName entityContainer, final String entitySetName)
+        throws ODataException {
+      if (namespace.equals(entityContainer.getNamespace())) {
+        if ((CONTAINER_PREFIX + name).equals(entityContainer.getName())
+            && (ENTITY_SET_PREFIX + name).equals(entitySetName)) {
+          return entitySet;
+        }
+        return null;
+      } else if ((NAMESPACE_PREFIX + other).equals(entityContainer.getNamespace())) {
+        final CsdlEdmProvider otherProvider = this == provider1 ? provider2 : provider1;
+        return otherProvider.getEntitySet(entityContainer, entitySetName);
+      }
+      return null;
+    }
+
+    @Override
+    public CsdlEntityType getEntityType(final FullQualifiedName entityTypeName) throws ODataException {
+      if (namespace.equals(entityTypeName.getNamespace())) {
+        if ((ENTITY_TYPE_PREFIX + name).equals(entityTypeName.getName())) {
+          return entityType;
+        }
+        return null;
+      } else if ((NAMESPACE_PREFIX + other).equals(entityTypeName.getNamespace())) {
+        // Requesting a type in a foreign namespace delegates the request to another CSDL provider.
+        final CsdlEdmProvider otherProvider = this == provider1 ? provider2 : provider1;
+        return otherProvider.getEntityType(entityTypeName);
+      }
+      return null;
+    }
+  }
+
+  @Test
+  public void entityType() throws Exception {
+    final FullQualifiedName typeName = new FullQualifiedName("Namespace.One", "EntityTypeOne");
+    final EdmEntityType entityType = edm1.getEntityType(typeName);
+    Assert.assertNotNull(entityType);
+    Assert.assertNotNull(entityType.getNavigationProperty("NavigationTwo"));
+
+    // We get an entity type in a foreign namespace if it is used in our namespace.
+    final EdmEntityType targetType = entityType.getNavigationProperty("NavigationTwo").getType();
+    Assert.assertNotNull(targetType);
+    final FullQualifiedName targetName = new FullQualifiedName("Namespace.Two", "EntityTypeTwo");
+    Assert.assertEquals(targetName, targetType.getFullQualifiedName());
+
+    // Directly accessing the foreign type is also possible.
+    Assert.assertNotNull(edm1.getEntityType(targetName));
+    Assert.assertEquals(targetType, edm1.getEntityType(targetName));
+
+    // However, the schema contains only elements from the own namespace.
+    final List<EdmEntityType> entityTypes = edm1.getSchema("Namespace.One").getEntityTypes();
+    Assert.assertNotNull(entityTypes);
+    Assert.assertEquals(1, entityTypes.size());
+    Assert.assertEquals(typeName, entityTypes.get(0).getFullQualifiedName());
+
+    // The foreign service has the foreign type available, both directly and in its schema.
+    Assert.assertNotNull(edm2.getEntityType(targetName));
+    Assert.assertEquals(targetName, edm2.getEntityType(targetName).getFullQualifiedName());
+    Assert.assertEquals(targetName,
+        edm2.getSchema("AliasTwo").getEntityTypes().get(0).getFullQualifiedName());
+
+    // Alias access is also supported.
+    Assert.assertNotNull(edm1.getEntityType(new FullQualifiedName("AliasOne", "EntityTypeOne")));
+
+    // A wrong name leads to null result.
+    Assert.assertNull(edm1.getEntityType(new FullQualifiedName("AliasOne", "EntityTypeWrong")));
+    Assert.assertNull(edm1.getEntityType(new FullQualifiedName("AliasTwo", "EntityTypeWrong")));
+    Assert.assertNull(edm1.getEntityType(new FullQualifiedName("AliasWrong", "EntityTypeOne")));
+  }
+
+  @Test
+  public void entityContainer() throws Exception {
+    Assert.assertNotNull(edm1.getEntityContainer());
+    Assert.assertNotNull(edm1.getEntityContainer(new FullQualifiedName("Namespace.One", "ContainerOne")));
+    Assert.assertEquals(edm1.getEntityContainer(),
+        edm1.getEntityContainer(new FullQualifiedName("Namespace.One", "ContainerOne")));
+    Assert.assertEquals(edm1.getEntityContainer(),
+        edm1.getEntityContainer(new FullQualifiedName("AliasOne", "ContainerOne")));
+    Assert.assertNotNull(edm1.getEntityContainer(new FullQualifiedName("AliasTwo", "ContainerTwo")));
+
+    // A wrong name leads to null result.
+    Assert.assertNull(edm1.getEntityContainer(new FullQualifiedName("AliasTwo", "ContainerOne")));
+    Assert.assertNull(edm1.getEntityContainer(new FullQualifiedName("AliasWrong", "ContainerOne")));
+  }
+
+  @Test
+  public void entitySet() throws Exception {
+    final EdmEntitySet entitySet = edm1.getEntityContainer(new FullQualifiedName("AliasTwo", "ContainerTwo"))
+        .getEntitySet("EntitySetTwo");
+    Assert.assertNotNull(entitySet);
+    Assert.assertEquals("EntitySetTwo", entitySet.getName());
+    Assert.assertNotNull(entitySet.getEntityType());
+    Assert.assertEquals("EntityTypeTwo", entitySet.getEntityType().getName());
+
+    // A wrong name leads to null result.
+    Assert.assertNull(edm1.getEntityContainer().getEntitySet("EntitySetTwo"));
+    Assert.assertNull(
+        edm1.getEntityContainer(new FullQualifiedName("AliasTwo", "ContainerTwo")).getEntitySet("EntitySetOne"));
+  }
+
+  @Test
+  public void schema() throws Exception {
+    Assert.assertNotNull(edm1.getSchemas());
+    Assert.assertEquals(1, edm1.getSchemas().size());
+    Assert.assertEquals("AliasOne", edm1.getSchemas().get(0).getAlias());
+    Assert.assertNotNull(edm1.getSchemas().get(0).getEntityTypes());
+    Assert.assertEquals(1, edm1.getSchemas().get(0).getEntityTypes().size());
+    Assert.assertEquals(new FullQualifiedName("Namespace.One", "EntityTypeOne"),
+        edm1.getSchemas().get(0).getEntityTypes().get(0).getFullQualifiedName());
+  }
+
+  @Test
+  public void entitySets() throws Exception {
+    Assert.assertNotNull(edm1.getEntityContainer());
+    Assert.assertNotNull(edm1.getEntityContainer().getEntitySets());
+    Assert.assertEquals(1, edm1.getEntityContainer().getEntitySets().size());
+    Assert.assertEquals("EntitySetOne", edm1.getEntityContainer().getEntitySets().get(0).getName());
+  }
+}