You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by to...@apache.org on 2015/09/24 22:13:31 UTC
[35/39] usergrid git commit: Adds rest tests and fixes bugs with
POST/PUT re-ordering
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-909
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 );
}