Adds rest tests and fixes bugs with POST/PUT re-ordering

Project: http://git-wip-us.apache.org/repos/asf/usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/usergrid/commit/82814303
Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/82814303
Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/82814303

Branch: refs/heads/USERGRID-933
Commit: 82814303135e47cc976fea373396aad85afb07f5
Parents: 079ba97
Author: Todd Nine <tn...@apigee.com>
Authored: Wed Sep 23 11:32:11 2015 -0600
Committer: Todd Nine <tn...@apigee.com>
Committed: Wed Sep 23 11:32:11 2015 -0600

----------------------------------------------------------------------
 .../corepersistence/CpRelationManager.java      |   7 +-
 .../users/ConnectionResourceTest.java           | 302 ++++++++++++++-----
 .../services/AbstractConnectionsService.java    |  43 ++-
 3 files changed, 275 insertions(+), 77 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/usergrid/blob/82814303/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
----------------------------------------------------------------------
diff --git 
a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
 
b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
index 21a2ee7..de687b3 100644
--- 
a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
+++ 
b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpRelationManager.java
@@ -713,15 +713,16 @@ public class CpRelationManager implements RelationManager 
{
             if ( logger.isDebugEnabled() ) {
                 logger.debug( "Marking edge {} for deletion", edgeToDelete );
             }
-            return gm.markEdge( edge );
+            return gm.markEdge( edgeToDelete );
         } ).lastOrDefault( null ).doOnNext( lastEdge -> {
             //no op if we hit our default
             if(lastEdge == null){
                 return;
             }
 
-            //queue up async processing
-            indexService.queueDeleteEdge( applicationScope, lastEdge );
+            //don't queue delete b/c that de-indexes, we need to delete the 
edges only since we have a version still existing to index.
+
+            gm.deleteEdge( lastEdge ).subscribe();
         }).subscribe();
 
 

http://git-wip-us.apache.org/repos/asf/usergrid/blob/82814303/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/ConnectionResourceTest.java
----------------------------------------------------------------------
diff --git 
a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/ConnectionResourceTest.java
 
b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/ConnectionResourceTest.java
index 22a6165..777b04e 100644
--- 
a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/ConnectionResourceTest.java
+++ 
b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/collection/users/ConnectionResourceTest.java
@@ -17,19 +17,26 @@
 package org.apache.usergrid.rest.applications.collection.users;
 
 
-import com.sun.jersey.api.client.UniformInterfaceException;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import org.apache.usergrid.rest.test.resource.AbstractRestIT;
 import org.apache.usergrid.rest.test.resource.endpoints.CollectionEndpoint;
+import org.apache.usergrid.rest.test.resource.model.ApiResponse;
 import org.apache.usergrid.rest.test.resource.model.Collection;
 import org.apache.usergrid.rest.test.resource.model.Entity;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.usergrid.rest.test.resource.model.QueryParameters;
 
-import java.io.IOException;
-import java.util.Map;
+import com.sun.jersey.api.client.UniformInterfaceException;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
 
 
 /**
@@ -39,44 +46,46 @@ import static org.junit.Assert.*;
  * @since 4.0
  */
 public class ConnectionResourceTest extends AbstractRestIT {
-    private static Logger log = 
LoggerFactory.getLogger(ConnectionResourceTest.class);
+    private static Logger log = LoggerFactory.getLogger( 
ConnectionResourceTest.class );
+
 
     @Test
     public void connectionsQueryTest() throws IOException {
 
         //create a peep
         Entity peep = new Entity();
-        peep.put("type", "chicken");
+        peep.put( "type", "chicken" );
 
-        peep = this.app().collection("peeps").post(peep);
+        peep = this.app().collection( "peeps" ).post( peep );
 
 
         Entity todd = new Entity();
-        todd.put("username", "todd");
-        todd = this.app().collection("users").post(todd);
+        todd.put( "username", "todd" );
+        todd = this.app().collection( "users" ).post( todd );
 
         Entity scott = new Entity();
-        scott.put("username", "scott");
-        scott = this.app().collection("users").post(scott);
+        scott.put( "username", "scott" );
+        scott = this.app().collection( "users" ).post( scott );
 
         Entity objectOfDesire = new Entity();
-        objectOfDesire.put("codingmunchies", "doritoes");
-        objectOfDesire = this.app().collection("snacks").post(objectOfDesire);
+        objectOfDesire.put( "codingmunchies", "doritoes" );
+        objectOfDesire = this.app().collection( "snacks" ).post( 
objectOfDesire );
         refreshIndex();
 
-        Entity toddWant = 
this.app().collection("users").entity(todd).collection("likes").collection("snacks").entity(objectOfDesire).post();
-        assertNotNull(toddWant);
+        Entity toddWant = this.app().collection( "users" ).entity( todd 
).collection( "likes" ).collection( "snacks" )
+                              .entity( objectOfDesire ).post();
+        assertNotNull( toddWant );
 
         try {
 
-            
this.app().collection("users").entity(scott).collection("likes").collection("peeps").entity(peep).get();
-            fail("This should throw an exception");
-        } catch (UniformInterfaceException uie) {
+            this.app().collection( "users" ).entity( scott ).collection( 
"likes" ).collection( "peeps" ).entity( peep )
+                .get();
+            fail( "This should throw an exception" );
+        }
+        catch ( UniformInterfaceException uie ) {
             // Should return a 404 Not Found
-            assertEquals(404, uie.getResponse().getStatus());
+            assertEquals( 404, uie.getResponse().getStatus() );
         }
-
-
     }
 
 
@@ -85,125 +94,274 @@ public class ConnectionResourceTest extends 
AbstractRestIT {
 
         // create entities thing1 and thing2
         Entity thing1 = new Entity();
-        thing1.put("name", "thing1");
-        thing1 = this.app().collection("things").post(thing1);
+        thing1.put( "name", "thing1" );
+        thing1 = this.app().collection( "things" ).post( thing1 );
 
         Entity thing2 = new Entity();
-        thing2.put("name", "thing2");
-        thing2 = this.app().collection("things").post(thing2);
+        thing2.put( "name", "thing2" );
+        thing2 = this.app().collection( "things" ).post( thing2 );
 
         refreshIndex();
         //create the connection: thing1 likes thing2
-        
this.app().collection("things").entity(thing1).connection("likes").collection("things").entity(thing2).post();
+        this.app().collection( "things" ).entity( thing1 ).connection( "likes" 
).collection( "things" ).entity( thing2 )
+            .post();
         refreshIndex();
 
         //test we have the "likes" in our connection meta data response
-        thing1 = this.app().collection("things").entity(thing1).get();
+        thing1 = this.app().collection( "things" ).entity( thing1 ).get();
         //TODO this is ugly. revisit.
-        String url = (String) ((Map<String, Object>) ((Map<String, Object>) 
thing1.get("metadata")).get("connections")).get("likes");
-        assertNotNull("Connection url returned with entity", url);
+        String url = ( String ) ( ( Map<String, Object> ) ( ( Map<String, 
Object> ) thing1.get( "metadata" ) )
+            .get( "connections" ) ).get( "likes" );
+        assertNotNull( "Connection url returned with entity", url );
 
         //now that we know the URl is correct, follow it
-        CollectionEndpoint likesEndpoint = new CollectionEndpoint(url, 
this.context(), this.app());
+        CollectionEndpoint likesEndpoint = new CollectionEndpoint( url, 
this.context(), this.app() );
         Collection likes = likesEndpoint.get();
-        assertNotNull(likes);
+        assertNotNull( likes );
         Entity likedEntity = likes.next();
-        assertNotNull(likedEntity);
+        assertNotNull( likedEntity );
 
         //make sure the returned entity is thing2
-        assertEquals(thing2.getUuid(), likedEntity.getUuid());
+        assertEquals( thing2.getUuid(), likedEntity.getUuid() );
 
 
         //now follow the loopback, which should be pointers to the other entity
-        thing2 = this.app().collection("things").entity(thing2).get();
+        thing2 = this.app().collection( "things" ).entity( thing2 ).get();
         //TODO this is ugly. revisit.
-        url = (String) ((Map<String, Object>) ((Map<String, Object>) 
thing2.get("metadata")).get("connecting")).get("likes");
-        assertNotNull("Connecting url returned with entity", url);
+        url = ( String ) ( ( Map<String, Object> ) ( ( Map<String, Object> ) 
thing2.get( "metadata" ) )
+            .get( "connecting" ) ).get( "likes" );
+        assertNotNull( "Connecting url returned with entity", url );
 
-        CollectionEndpoint likedByEndpoint = new CollectionEndpoint(url, 
this.context(), this.app());
+        CollectionEndpoint likedByEndpoint = new CollectionEndpoint( url, 
this.context(), this.app() );
         Collection likedBy = likedByEndpoint.get();
-        assertNotNull(likedBy);
+        assertNotNull( likedBy );
         Entity likedByEntity = likedBy.next();
-        assertNotNull(likedByEntity);
+        assertNotNull( likedByEntity );
 
         //make sure the returned entity is thing1
-        assertEquals(thing1.getUuid(), likedByEntity.getUuid());
-
+        assertEquals( thing1.getUuid(), likedByEntity.getUuid() );
     }
 
 
     /**
-     * Ensure that the connected entity can be deleted
-     * properly after it has been connected to another entity
-     *
-     * @throws IOException
+     * Ensure that the connected entity can be deleted properly after it has 
been connected to another entity
      */
     @Test //USERGRID-3011
     public void connectionsDeleteSecondEntityInConnectionTest() throws 
IOException {
 
         //Create 2 entities, thing1 and thing2
         Entity thing1 = new Entity();
-        thing1.put("name", "thing1");
-        thing1 = this.app().collection("things").post(thing1);
+        thing1.put( "name", "thing1" );
+        thing1 = this.app().collection( "things" ).post( thing1 );
 
         Entity thing2 = new Entity();
-        thing2.put("name", "thing2");
-        thing2 = this.app().collection("things").post(thing2);
+        thing2.put( "name", "thing2" );
+        thing2 = this.app().collection( "things" ).post( thing2 );
 
         refreshIndex();
         //create the connection: thing1 likes thing2
-        
this.app().collection("things").entity(thing1).connection("likes").collection("things").entity(thing2).post();
+        this.app().collection( "things" ).entity( thing1 ).connection( "likes" 
).collection( "things" ).entity( thing2 )
+            .post();
         //delete thing2
-        this.app().collection("things").entity(thing2).delete();
+        this.app().collection( "things" ).entity( thing2 ).delete();
 
         refreshIndex();
 
         try {
             //attempt to retrieve thing1
-            thing2 = this.app().collection("things").entity(thing2).get();
-            fail("This should throw an exception");
-        } catch (UniformInterfaceException uie) {
+            thing2 = this.app().collection( "things" ).entity( thing2 ).get();
+            fail( "This should throw an exception" );
+        }
+        catch ( UniformInterfaceException uie ) {
             // Should return a 404 Not Found
-            assertEquals(404, uie.getResponse().getStatus());
+            assertEquals( 404, uie.getResponse().getStatus() );
         }
     }
 
+
     /**
-     * Ensure that the connecting entity can be deleted
-     * properly after a connection has been added
-     *
-     * @throws IOException
+     * Ensure that the connecting entity can be deleted properly after a 
connection has been added
      */
     @Test //USERGRID-3011
     public void connectionsDeleteFirstEntityInConnectionTest() throws 
IOException {
 
         //Create 2 entities, thing1 and thing2
         Entity thing1 = new Entity();
-        thing1.put("name", "thing1");
-        thing1 = this.app().collection("things").post(thing1);
+        thing1.put( "name", "thing1" );
+        thing1 = this.app().collection( "things" ).post( thing1 );
 
         Entity thing2 = new Entity();
-        thing2.put("name", "thing2");
-        thing2 = this.app().collection("things").post(thing2);
+        thing2.put( "name", "thing2" );
+        thing2 = this.app().collection( "things" ).post( thing2 );
 
         refreshIndex();
         //create the connection: thing1 likes thing2
-        
this.app().collection("things").entity(thing1).connection("likes").collection("things").entity(thing2).post();
+        this.app().collection( "things" ).entity( thing1 ).connection( "likes" 
).collection( "things" ).entity( thing2 )
+            .post();
         //delete thing1
-        this.app().collection("things").entity(thing1).delete();
+        this.app().collection( "things" ).entity( thing1 ).delete();
 
         refreshIndex();
 
         try {
             //attempt to retrieve thing1
-            thing1 = this.app().collection("things").entity(thing1).get();
-            fail("This should throw an exception");
-        } catch (UniformInterfaceException uie) {
+            thing1 = this.app().collection( "things" ).entity( thing1 ).get();
+            fail( "This should throw an exception" );
+        }
+        catch ( UniformInterfaceException uie ) {
             // Should return a 404 Not Found
-            assertEquals(404, uie.getResponse().getStatus());
+            assertEquals( 404, uie.getResponse().getStatus() );
         }
+    }
+
+
+    /**
+     * UERGRID-1018
+     */
+    @Test
+    public void testRePostOrder() {
+
+        Entity thing1 = new Entity();
+        thing1.put( "name", "thing1" );
+
+        final CollectionEndpoint collection = this.app().collection( "things" 
);
+
+        thing1 = collection.post( thing1 );
+
+        Entity thing2 = new Entity();
+        thing2.put( "name", "thing2" );
+        thing2 = collection.post( thing2 );
+
+        Entity thing3 = new Entity();
+        thing3.put( "name", "thing3" );
+        thing3 = collection.post( thing3 );
+
+        //now connect them
+
+        //connect thing1 -> thing2
+
+        final CollectionEndpoint connectionEndpoint = collection.entity( 
thing1 ).connection( "connectorder" );
+        connectionEndpoint.entity( thing2 ).post();
 
+        //connect thing1 -> thing3
+        connectionEndpoint.entity( thing3 ).post();
+
+        refreshIndex();
+
+        //now do a GET, we should see thing2 then thing3
+
+        final ApiResponse order1 = connectionEndpoint.get().getResponse();
+
+        //now verify order
+        verifyOrder( order1, thing3, thing2 );
+
+        final QueryParameters queryParameters = new QueryParameters();
+        queryParameters.setQuery( "select * order by modified desc" );
+
+        final ApiResponse order1Query = connectionEndpoint.get( 
queryParameters ).getResponse();
+
+        //now verify order
+        verifyOrder( order1Query, thing3, thing2 );
+
+
+        //now re-post thing 2 it should appear second
+        connectionEndpoint.entity( thing2 ).post();
+
+        refreshIndex();
+
+
+        final ApiResponse order2 = connectionEndpoint.get().getResponse();
+
+        //now verify order
+        verifyOrder( order2, thing2, thing3 );
+
+        final ApiResponse order2Query = connectionEndpoint.get( 
queryParameters ).getResponse();
+
+        //now verify order
+        verifyOrder( order2Query, thing3, thing2 );
     }
 
 
+    /**
+     * UERGRID-1018
+     */
+    @Test
+    public void testRePutOrder() {
+
+        Entity thing1 = new Entity();
+        thing1.put( "name", "thing1" );
+
+        final CollectionEndpoint collection = this.app().collection( "things" 
);
+
+        thing1 = collection.post( thing1 );
+
+        Entity thing2 = new Entity();
+        thing2.put( "name", "thing2" );
+        thing2 = collection.post( thing2 );
+
+
+        Entity thing3 = new Entity();
+        thing3.put( "name", "thing3" );
+        thing3 = collection.post( thing3 );
+
+        //now connect them
+
+        //connect thing1 -> thing2
+
+        final CollectionEndpoint connectionEndpoint = collection.entity( 
thing1 ).connection( "connectorder" );
+        connectionEndpoint.entity( thing2 ).put( thing2 );
+
+        //connect thing1 -> thing3
+        connectionEndpoint.entity( thing3 ).put( thing3 );
+
+        refreshIndex();
+
+        //now do a GET, we should see thing2 then thing3
+
+        final ApiResponse order1 = connectionEndpoint.get().getResponse();
+
+        //now verify order
+        verifyOrder( order1, thing3, thing2 );
+
+        final QueryParameters queryParameters = new QueryParameters();
+        queryParameters.setQuery( "select * order by modified desc" );
+
+        final ApiResponse order1Query = connectionEndpoint.get( 
queryParameters ).getResponse();
+
+        //now verify order
+        verifyOrder( order1Query, thing3, thing2 );
+
+
+        //now re-post thing 2 it should appear second
+        connectionEndpoint.entity( thing2 ).put( thing2 );
+
+        refreshIndex();
+
+        final ApiResponse order2 = connectionEndpoint.get().getResponse();
+
+
+        //now verify order
+        verifyOrder( order2, thing2, thing3 );
+    }
+
+
+    /**
+     * Verify our response
+     */
+    private void verifyOrder( final ApiResponse apiResponse, final Entity... 
verifyOrder ) {
+
+        final List<Entity> responseEntities = apiResponse.getEntities();
+
+        assertEquals( "Size should be equals", verifyOrder.length, 
responseEntities.size() );
+
+
+        for ( int i = 0; i < verifyOrder.length; i++ ) {
+
+            final Entity verifyEntity = verifyOrder[i];
+
+            final Entity returned = responseEntities.get( i );
+
+            assertEquals( "Should be the same entity", verifyEntity.getUuid(), 
returned.getUuid() );
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/usergrid/blob/82814303/stack/services/src/main/java/org/apache/usergrid/services/AbstractConnectionsService.java
----------------------------------------------------------------------
diff --git 
a/stack/services/src/main/java/org/apache/usergrid/services/AbstractConnectionsService.java
 
b/stack/services/src/main/java/org/apache/usergrid/services/AbstractConnectionsService.java
index c4142a0..ee322d2 100644
--- 
a/stack/services/src/main/java/org/apache/usergrid/services/AbstractConnectionsService.java
+++ 
b/stack/services/src/main/java/org/apache/usergrid/services/AbstractConnectionsService.java
@@ -23,20 +23,25 @@ import java.util.UUID;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+
 import org.apache.usergrid.persistence.ConnectionRef;
 import org.apache.usergrid.persistence.Entity;
 import org.apache.usergrid.persistence.EntityRef;
-import org.apache.usergrid.persistence.index.query.Identifier;
 import org.apache.usergrid.persistence.Query;
+import org.apache.usergrid.persistence.Query.Level;
 import org.apache.usergrid.persistence.Results;
 import org.apache.usergrid.persistence.Schema;
 import org.apache.usergrid.persistence.SimpleEntityRef;
-import org.apache.usergrid.persistence.Query.Level;
+import org.apache.usergrid.persistence.index.query.Identifier;
 import org.apache.usergrid.services.ServiceParameter.IdParameter;
 import org.apache.usergrid.services.ServiceParameter.NameParameter;
 import org.apache.usergrid.services.ServiceParameter.QueryParameter;
 import org.apache.usergrid.services.ServiceResults.Type;
 import 
org.apache.usergrid.services.exceptions.ServiceResourceNotFoundException;
+
+import rx.Observable;
+import rx.schedulers.Schedulers;
+
 import static org.apache.usergrid.services.ServiceParameter.filter;
 import static 
org.apache.usergrid.services.ServiceParameter.firstParameterIsName;
 import static org.apache.usergrid.utils.ClassUtils.cast;
@@ -398,6 +403,11 @@ public class AbstractConnectionsService extends 
AbstractService {
             String entityType = getEntityType();
             item = em.create( id, entityType, 
context.getPayload().getProperties() );
         }
+
+        //create the connection
+        createConnection( context.getOwner(), context.getCollectionName(), 
item );
+
+
         return new ServiceResults( this, context, Type.CONNECTION, 
Results.fromEntity( item ), null, null );
     }
 
@@ -426,6 +436,35 @@ public class AbstractConnectionsService extends 
AbstractService {
 
         updateEntities( context, r );
 
+          //create the connection
+
+        //TODO wire the RX scheduler in here and use our parallelism system
+
+
+        /**
+         * Create all the connections for all the entities
+         */
+        final List<Entity> entities = r.getEntities();
+        if ( entities != null ) {
+
+            /**
+             * Save up to 10 connections in parallel
+             */
+            Observable.from(entities).flatMap( emittedEntity -> {
+                return Observable.just( emittedEntity ).doOnNext( toSave -> {
+                    try {
+                        createConnection( context.getOwner(), 
context.getCollectionName(), toSave );
+                    }
+                    catch ( Exception e ) {
+                        throw new RuntimeException( "Unable to save 
connection", e );
+                    }
+                }).subscribeOn( Schedulers.io() );
+            }, 10).subscribe();
+
+
+        }
+
+
         return new ServiceResults( this, context, Type.CONNECTION, r, null, 
null );
     }
 

Reply via email to