Repository: usergrid Updated Branches: refs/heads/readRepairForIndexValues 3d5ae4647 -> b38f5bcb4
Added cleanup for false unique property cleanup if there were no corresponding entities Added test for 1000 such entities and verifying that they were indeed fixed correctly. Project: http://git-wip-us.apache.org/repos/asf/usergrid/repo Commit: http://git-wip-us.apache.org/repos/asf/usergrid/commit/b38f5bcb Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/b38f5bcb Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/b38f5bcb Branch: refs/heads/readRepairForIndexValues Commit: b38f5bcb48dd2603a0b095d2c651ba2575a006f1 Parents: 3d5ae46 Author: George Reyes <[email protected]> Authored: Tue Nov 10 16:00:08 2015 -0800 Committer: George Reyes <[email protected]> Committed: Tue Nov 10 16:00:08 2015 -0800 ---------------------------------------------------------------------- .../cassandra/EntityManagerImpl.java | 12 +++ .../usergrid/services/ServiceRequestIT.java | 107 +++++++++++++++---- 2 files changed, 101 insertions(+), 18 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/usergrid/blob/b38f5bcb/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/EntityManagerImpl.java ---------------------------------------------------------------------- diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/EntityManagerImpl.java b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/EntityManagerImpl.java index 76cb6d7..bd7773a 100644 --- a/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/EntityManagerImpl.java +++ b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/EntityManagerImpl.java @@ -547,6 +547,18 @@ public class EntityManagerImpl implements EntityManager { false ); + //check to see if the single value is valid. If it is not valid then it will be zero and go through + //the code below. + if(cols.size() == 1){ + logger.info("Verifying that column is still valid, if not will be removed"); + UUID indexCorruptionUuid = ue.fromByteBuffer( cols.get( 0 ).getName()); + + if (get(indexCorruptionUuid) == null ) { + deleteUniqueColumn( ownerEntityId, key, indexCorruptionUuid ); + cols.remove( 0 ); + } + } + //No columns at all, it's unique if ( cols.size() == 0 ) { return Collections.emptySet(); http://git-wip-us.apache.org/repos/asf/usergrid/blob/b38f5bcb/stack/services/src/test/java/org/apache/usergrid/services/ServiceRequestIT.java ---------------------------------------------------------------------- diff --git a/stack/services/src/test/java/org/apache/usergrid/services/ServiceRequestIT.java b/stack/services/src/test/java/org/apache/usergrid/services/ServiceRequestIT.java index d89536f..c678ba9 100644 --- a/stack/services/src/test/java/org/apache/usergrid/services/ServiceRequestIT.java +++ b/stack/services/src/test/java/org/apache/usergrid/services/ServiceRequestIT.java @@ -31,6 +31,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.commons.lang.RandomStringUtils; +import org.apache.http.annotation.NotThreadSafe; import org.apache.usergrid.ServiceITSetup; import org.apache.usergrid.ServiceITSetupImpl; @@ -41,6 +42,8 @@ import org.apache.usergrid.management.ApplicationInfo; import org.apache.usergrid.management.OrganizationOwnerInfo; import org.apache.usergrid.persistence.Entity; import org.apache.usergrid.persistence.EntityManager; +import org.apache.usergrid.persistence.EntityRef; +import org.apache.usergrid.persistence.SimpleEntityRef; import org.apache.usergrid.persistence.cassandra.CassandraPersistenceUtils; import org.apache.usergrid.persistence.cassandra.CassandraService; import org.apache.usergrid.persistence.entities.User; @@ -64,7 +67,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; -@Concurrent() +@NotThreadSafe() public class ServiceRequestIT { private static final Logger logger = LoggerFactory.getLogger( ServiceRequestIT.class ); @@ -153,16 +156,9 @@ public class ServiceRequestIT { Entity entityToBeCorrupted = null; try { entityToBeCorrupted = entityManager.create( collectionName, userInfo ); - fail(); - }catch(DuplicateUniquePropertyExistsException dup){ - + }catch(Exception e){ + fail("Create call should have worked"); } - catch(Exception e){ - fail("shouldn't throw something else i think"); - } - - - entityToBeCorrupted = entityManager.create( collectionName,userInfo ); assertNotNull( entityToBeCorrupted ); assertEquals( username,( ( User ) entityToBeCorrupted ).getUsername() ); @@ -230,17 +226,92 @@ public class ServiceRequestIT { throw e; } - //should return null since we have duplicate alias. Will Cause index corruptions to be thrown. - //TODO: fix the below so that it fails everytime. - //50/50 chance to succeed or fail - // assertNull( entityManager - // .get( entityManager.getAlias( applicationInfo.getId(), collectionName, username ).getUuid() ) ); - - - //verifies it works now. assertNotNull( entityManager .get( entityManager.getAlias( applicationInfo.getId(), collectionName, username ).getUuid() ) ); } + + //For this test you need to insert a dummy key with a dummy column that leads to nowhere + //then run the unique index cleanup. + //checks for bug when only column doesn't exist make sure to delete the row as well. + @Test + public void testRepairOfMultipleEntitiesAndRemainingEntities() throws Exception{ + String rand = RandomStringUtils.randomAlphanumeric( 10 ); + + int numberOfEntitiesToCreate = 1000; + + String orgName = "org_" + rand; + String appName = "app_" +rand; + String username = "username_" + rand; + String adminUsername = "admin_"+rand; + String email = username+"@derp.com"; + String password = username; + + String collectionName = "users"; + + + OrganizationOwnerInfo organizationOwnerInfo = setup.getMgmtSvc().createOwnerAndOrganization( orgName,adminUsername,adminUsername,email,password ); + + ApplicationInfo applicationInfo = setup.getMgmtSvc().createApplication( organizationOwnerInfo.getOrganization().getUuid(),appName ); + + EntityManager entityManager = setup.getEmf().getEntityManager( applicationInfo.getId() ); + + String[] usernames = new String[numberOfEntitiesToCreate]; + Entity[] entities = new Entity[numberOfEntitiesToCreate]; + + int index = 0; + while(index < numberOfEntitiesToCreate) { + + usernames[index]=username+index; + + Map<String, Object> userInfo = new HashMap<String, Object>(); + userInfo.put( "username", usernames[index] ); + + CassandraService cass = setup.getCassSvc(); + + entities[index] = entityManager.create( collectionName,userInfo ); + + Object key = CassandraPersistenceUtils.key( applicationInfo.getId(), collectionName, "username", usernames[index] ); + + Keyspace ko = cass.getApplicationKeyspace( applicationInfo.getId() ); + Mutator<ByteBuffer> m = createMutator( ko, be ); + + UUID testEntityUUID = UUIDUtils.newTimeUUID(); + //this below calll should make the column family AND the column name + addInsertToMutator( m, ENTITY_UNIQUE, key, testEntityUUID, 0, createTimestamp() ); + + m.execute(); + index++; + + //the below works but not needed for this test. + //assertNull( entityManager.getAlias("user",username)); + + //verify that we cannot recreate the entity due to duplicate unique property exception + Entity entityToBeCorrupted = null; + try { + entityToBeCorrupted = entityManager.create( collectionName, userInfo ); + fail(); + }catch(DuplicateUniquePropertyExistsException dup){ + + } + catch(Exception e){ + fail("shouldn't throw something else i think"); + } + + } + + + for(String user:usernames ) { + Map<String, Object> userInfo = new HashMap<String, Object>(); + userInfo.put( "username", user); + + + EntityRef entityRef = entityManager.getAlias( collectionName,user ); + + Entity entityToBeCorrupted = entityManager.get( entityRef ); + assertNotNull( entityToBeCorrupted ); + assertEquals( user, ( ( User ) entityToBeCorrupted ).getUsername() ); + } + } }
