You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by sk...@apache.org on 2014/01/21 14:20:23 UTC

git commit: [OLINGO-117] TDD implementation

Updated Branches:
  refs/heads/olingo-117 d8159ab0f -> 2de6df261


[OLINGO-117] TDD implementation


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/2de6df26
Tree: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/tree/2de6df26
Diff: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/diff/2de6df26

Branch: refs/heads/olingo-117
Commit: 2de6df2619e987c4a36f299c9e311b9d405c1f2a
Parents: d8159ab
Author: Stephan Klevenz <sk...@apache.org>
Authored: Tue Jan 21 12:25:48 2014 +0100
Committer: Stephan Klevenz <sk...@apache.org>
Committed: Tue Jan 21 13:37:06 2014 +0100

----------------------------------------------------------------------
 .../olingo/odata2/api/ep/feed/ODataFeed.java    |   4 +-
 .../core/ep/consumer/XmlFeedConsumer.java       |  11 +-
 .../olingo/odata2/core/ep/util/FormatXml.java   |   2 +
 .../core/ep/consumer/XmlFeedConsumerTest.java   |  28 ++++-
 .../resources/feed_with_deleted_entries.xml     |  40 ++++++
 .../fit/client/ClientDeltaResponseTest.java     | 122 ++++++++++++-------
 6 files changed, 157 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/2de6df26/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/feed/ODataFeed.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/feed/ODataFeed.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/feed/ODataFeed.java
index bd76e48..ee7ff88 100644
--- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/feed/ODataFeed.java
+++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/feed/ODataFeed.java
@@ -50,8 +50,8 @@ public interface ODataFeed {
 
   /**
    * Delta responses can contain changed feed data and deleted entries metadata. A delta response it the result of
-   * a delta link.
-   * @return metadata of deleted entries in case of feed is result of a delta response
+   * a delta link. If the feed is not a delta feed then the list of deleted entries is null.
+   * @return metadata of deleted entries in case of feed is result of a delta response or null 
    */
   public List<EntryMetadata> getDeletedEntries();
 

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/2de6df26/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlFeedConsumer.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlFeedConsumer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlFeedConsumer.java
index 5cd1258..a20f2f2 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlFeedConsumer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlFeedConsumer.java
@@ -30,6 +30,7 @@ import javax.xml.stream.XMLStreamReader;
 import org.apache.olingo.odata2.api.edm.Edm;
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
 import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties;
+import org.apache.olingo.odata2.api.ep.entry.EntryMetadata;
 import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
 import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
@@ -96,6 +97,14 @@ public class XmlFeedConsumer {
     FeedMetadataImpl metadata = new FeedMetadataImpl();
     XmlEntryConsumer xec = new XmlEntryConsumer();
     List<ODataEntry> results = new ArrayList<ODataEntry>();
+    List<EntryMetadata> deletedEntries = null;
+
+    boolean isDeltaFeed = false;
+    String tombstonePrefix = reader.getNamespaceContext().getPrefix(FormatXml.ATOM_TOMBSTONE_NAMESPACE);
+    if (tombstonePrefix != null) {
+      isDeltaFeed = true;
+      deletedEntries = new ArrayList<EntryMetadata>();
+    }
 
     while (reader.hasNext() && !isFeedEndTag(reader)) {
       if (FormatXml.ATOM_ENTRY.equals(reader.getLocalName())) {
@@ -136,7 +145,7 @@ public class XmlFeedConsumer {
       }
       readTillNextStartTag(reader);
     }
-    return new ODataFeedImpl(results, metadata);
+    return new ODataFeedImpl(results, metadata, isDeltaFeed, deletedEntries);
   }
 
   private void readTillNextStartTag(final XMLStreamReader reader) throws XMLStreamException {

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/2de6df26/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/FormatXml.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/FormatXml.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/FormatXml.java
index 153647b..8ad0181 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/FormatXml.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/FormatXml.java
@@ -91,4 +91,6 @@ public class FormatXml {
   public static final String ATOM_TOMBSTONE_REF = "ref";
   public static final String ATOM_TOMBSTONE_WHEN = "when";
   public static final String ATOM_TOMBSTONE_DELETED_ENTRY = "deleted-entry";
+  public static final String ATOM_TOMBSTONE_NAMESPACE = "http://purl.org/atompub/tombstones/1.0";
+  public static final String ATOM_TOMBSTONE_PREFIX = "at";
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/2de6df26/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlFeedConsumerTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlFeedConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlFeedConsumerTest.java
index 27132df..b2c6267 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlFeedConsumerTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlFeedConsumerTest.java
@@ -19,7 +19,7 @@
 package org.apache.olingo.odata2.core.ep.consumer;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.*;
 
 import java.io.InputStream;
 
@@ -50,6 +50,8 @@ public class XmlFeedConsumerTest extends AbstractXmlConsumerTest {
             .getEntitySet(
                 "Employees"), file, DEFAULT_PROPERTIES);
     assertNotNull(feed);
+    assertFalse(feed.isDeltaFeed());
+    assertNull(feed.getDeletedEntries());
 
     FeedMetadata feedMetadata = feed.getFeedMetadata();
     assertNotNull(feedMetadata);
@@ -71,6 +73,8 @@ public class XmlFeedConsumerTest extends AbstractXmlConsumerTest {
 
     ODataFeed feed = xec.readFeed(entitySet, reqContent, consumerProperties);
     assertNotNull(feed);
+    assertFalse(feed.isDeltaFeed());
+    assertNull(feed.getDeletedEntries());
 
     FeedMetadata feedMetadata = feed.getFeedMetadata();
     assertNotNull(feedMetadata);
@@ -86,7 +90,6 @@ public class XmlFeedConsumerTest extends AbstractXmlConsumerTest {
   public void readEmployeesFeedWithInlineCountNegative() throws Exception {
     // prepare
     String content = readFile("feed_employees_full.xml").replace("<m:count>6</m:count>", "<m:count>-1</m:count>");
-    ;
     assertNotNull(content);
 
     EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
@@ -111,7 +114,6 @@ public class XmlFeedConsumerTest extends AbstractXmlConsumerTest {
   public void readEmployeesFeedWithInlineCountLetters() throws Exception {
     // prepare
     String content = readFile("feed_employees_full.xml").replace("<m:count>6</m:count>", "<m:count>AAA</m:count>");
-    ;
     assertNotNull(content);
 
     EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
@@ -131,4 +133,24 @@ public class XmlFeedConsumerTest extends AbstractXmlConsumerTest {
 
     Assert.fail("Exception expected");
   }
+
+  @Test
+  public void readDeltaFeed() throws Exception {
+    // prepare
+    String content = readFile("feed_with_deleted_entries.xml");
+    assertNotNull(content);
+
+    EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
+    InputStream reqContent = createContentAsStream(content);
+
+    XmlEntityConsumer xec = new XmlEntityConsumer();
+    EntityProviderReadProperties consumerProperties = EntityProviderReadProperties.init().build();
+
+    ODataFeed feed = xec.readFeed(entitySet, reqContent, consumerProperties);
+    
+    assertNotNull(feed);
+    assertTrue(feed.isDeltaFeed());
+    
+    assertNotNull(feed.getDeletedEntries());
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/2de6df26/odata2-lib/odata-core/src/test/resources/feed_with_deleted_entries.xml
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/feed_with_deleted_entries.xml b/odata2-lib/odata-core/src/test/resources/feed_with_deleted_entries.xml
new file mode 100644
index 0000000..78c187e
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/feed_with_deleted_entries.xml
@@ -0,0 +1,40 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!-- 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. -->
+<feed xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
+    xmlns:at="http://purl.org/atompub/tombstones/1.0" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
+    xml:base="https://olingoodata.neo.ondemand.com:443/com.sap.olingo.web/ReferenceScenario.svc/">
+    <id>https://olingoodata.neo.ondemand.com:443/com.sap.olingo.web/ReferenceScenario.svc/Rooms</id>
+    <title type="text">Rooms</title>
+    <updated>2014-01-21T09:15:52.473Z</updated>
+    <author>
+        <name />
+    </author>
+    <link href="Rooms" rel="self" title="Rooms" />
+    <entry m:etag="W/&quot;1&quot;">
+        <id>http://host:123/odata/Rooms('1')</id>
+        <title type="text">Room 1</title>
+        <updated>2014-01-21T09:15:52.474Z</updated>
+        <category term="RefScenario.Room" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
+        <link href="Rooms('1')" rel="edit" title="Room" />
+        <link href="Rooms('1')/nr_Employees" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Employees"
+            title="nr_Employees" type="application/atom+xml;type=feed" />
+        <link href="Rooms('1')/nr_Building" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Building"
+            title="nr_Building" type="application/atom+xml;type=entry" />
+        <content type="application/xml">
+            <m:properties>
+                <d:Id>1</d:Id>
+                <d:Name>Room 1</d:Name>
+                <d:Seats>1</d:Seats>
+                <d:Version>1</d:Version>
+            </m:properties>
+        </content>
+    </entry>
+    <at:deleted-entry ref="http://host:123/odata/Rooms('2')" when="2014-01-14T18:11:06.682+01:00" />
+    <link href="http://host:123/odata/Rooms?$skiptoken=97" rel="delta" />
+</feed>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/2de6df26/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/client/ClientDeltaResponseTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/client/ClientDeltaResponseTest.java b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/client/ClientDeltaResponseTest.java
index f641577..43111fd 100644
--- a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/client/ClientDeltaResponseTest.java
+++ b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/client/ClientDeltaResponseTest.java
@@ -1,10 +1,12 @@
 package org.apache.olingo.odata2.fit.client;
 
-import static org.junit.Assert.*;
+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 java.net.URI;
 import java.net.URISyntaxException;
-import java.net.URL;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -39,40 +41,7 @@ public class ClientDeltaResponseTest extends AbstractFitTest {
   private static final String DELTATOKEN_1234 = "!deltatoken=1234";
 
   private Client client;
-
-  private ArrayList<Map<String, Object>> createRoomData() {
-
-    Map<String, Object> roomData1 = new HashMap<String, Object>();
-    roomData1.put("Id", "1");
-    roomData1.put("Seats", 123);
-    roomData1.put("Version", 1);
-    Map<String, Object> roomData2 = new HashMap<String, Object>();
-    roomData2.put("Id", "2");
-    roomData2.put("Seats", 66);
-    roomData2.put("Version", 2);
-
-    ArrayList<Map<String, Object>> roomsData = new ArrayList<Map<String, Object>>();
-    roomsData.add(roomData1);
-    roomsData.add(roomData2);
-
-    return roomsData;
-  }
-
-  private ArrayList<Map<String, Object>> createDeletedRoomData() {
-    Map<String, Object> roomData1 = new HashMap<String, Object>();
-    roomData1.put("Id", "3");
-    roomData1.put("Seats", 123);
-    roomData1.put("Version", 1);
-    Map<String, Object> roomData2 = new HashMap<String, Object>();
-    roomData2.put("Id", "4");
-    roomData2.put("Seats", 66);
-    roomData2.put("Version", 2);
-
-    ArrayList<Map<String, Object>> deletedRoomData = new ArrayList<Map<String, Object>>();
-    deletedRoomData.add(roomData1);
-    deletedRoomData.add(roomData2);
-    return deletedRoomData;
-  }
+  StubProcessor processor;
 
   @Before
   @Override
@@ -83,12 +52,21 @@ public class ClientDeltaResponseTest extends AbstractFitTest {
     } catch (Exception e) {
       throw new RuntimeException(e);
     }
+  }
 
-    createRoomData();
+  @Override
+  protected ODataService createService() throws ODataException {
+    EdmProvider provider = new ScenarioEdmProvider();
+    processor = new StubProcessor();
+
+    return new ODataSingleProcessorService(provider, processor);
   }
 
   private class StubProcessor extends ODataSingleProcessor {
 
+    private int roomDataCount = 2;
+    private int deletedRoomDataCount = 2;
+
     @Override
     public ODataResponse readEntitySet(GetEntitySetUriInfo uriInfo, String contentType) throws ODataException {
       try {
@@ -125,14 +103,35 @@ public class ClientDeltaResponseTest extends AbstractFitTest {
 
       }
     }
-  }
 
-  @Override
-  protected ODataService createService() throws ODataException {
-    EdmProvider provider = new ScenarioEdmProvider();
-    ODataSingleProcessor processor = new StubProcessor();
+    private ArrayList<Map<String, Object>> createRoomData() {
+      ArrayList<Map<String, Object>> roomsData = new ArrayList<Map<String, Object>>();
 
-    return new ODataSingleProcessorService(provider, processor);
+      for (int i = 1; i <= roomDataCount; i++) {
+        Map<String, Object> roomData = new HashMap<String, Object>();
+        roomData.put("Id", String.valueOf(i));
+        roomData.put("Seats", i);
+        roomData.put("Version", i);
+        roomsData.add(roomData);
+      }
+
+      return roomsData;
+    }
+
+    private ArrayList<Map<String, Object>> createDeletedRoomData() {
+      ArrayList<Map<String, Object>> deletedRoomData = new ArrayList<Map<String, Object>>();
+
+      for (int i = roomDataCount + 1; i < roomDataCount + 1 + deletedRoomDataCount; i++) {
+        Map<String, Object> roomData = new HashMap<String, Object>();
+        roomData.put("Id", String.valueOf(i));
+        roomData.put("Seats", i);
+        roomData.put("Version", i);
+
+        deletedRoomData.add(roomData);
+      }
+
+      return deletedRoomData;
+    }
   }
 
   @Test
@@ -183,15 +182,50 @@ public class ClientDeltaResponseTest extends AbstractFitTest {
     assertEquals("uri4", deletedEntries.get(1).getUri());
   }
 
+  private void testDeltaFeedWithZeroEntries(String contentType) throws Exception {
+    processor.roomDataCount = 0;
+    processor.deletedRoomDataCount = 0;
+
+    ODataFeed feed = client.readFeed("Container1", "Rooms", contentType);
+    String deltaLink = feed.getFeedMetadata().getDeltaLink();
+
+    assertNotNull(feed);
+    assertEquals(0, feed.getEntries().size());
+    assertEquals(getEndpoint().toASCIIString() + "Rooms?" + DELTATOKEN_1234, feed.getFeedMetadata().getDeltaLink());
+    assertFalse(feed.isDeltaFeed());
+
+    URI uri = new URI(deltaLink);
+    String query = uri.getQuery();
+    ODataFeed deltaFeed = client.readFeed("Container1", "Rooms", contentType, query);
+
+    assertNotNull(deltaFeed);
+    assertEquals(0, deltaFeed.getEntries().size());
+    assertEquals(uri.toASCIIString(), deltaFeed.getFeedMetadata().getDeltaLink());
+
+    assertTrue(deltaFeed.isDeltaFeed());
+    List<EntryMetadata> deletedEntries = deltaFeed.getDeletedEntries();
+    assertNotNull(deletedEntries);
+    assertEquals(0, deletedEntries.size());
+  }
+
   @Test
   public void testDeltaFeedWithDeltaLinkXml() throws Exception {
     testDeltaFeedWithDeltaLink("application/atom+xml");
   }
 
   @Test
-  @Ignore("not implemented")
   public void testFeedWithDeltaLinkJson() throws Exception {
     testDeltaFeedWithDeltaLink("application/json");
   }
 
+  @Test
+  public void testDeltaFeedWithZeroEntriesXml() throws Exception {
+    testDeltaFeedWithZeroEntries("application/atom+xml");
+  }
+
+  @Test
+  public void testFeedWithZeroEntriesJson() throws Exception {
+    testDeltaFeedWithZeroEntries("application/json");
+  }
+
 }
\ No newline at end of file