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 2014/10/29 21:33:39 UTC

[1/3] Updated migrations to separate data migrations and schema migrations.

Repository: incubator-usergrid
Updated Branches:
  refs/heads/key-row-sharding ca943fed7 -> 84c33176e


http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImplTest.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImplTest.java b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImplTest.java
new file mode 100644
index 0000000..3ffcd89
--- /dev/null
+++ b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImplTest.java
@@ -0,0 +1,220 @@
+/*
+ *
+ *  * 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.
+ *
+ */
+
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.Test;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+
+/**
+ * Tests our data migration manager
+ */
+public class DataMigrationManagerImplTest {
+
+
+    @Test
+    public void noMigrations() throws MigrationException {
+        final MigrationInfoSerialization serialization = mock( MigrationInfoSerialization.class );
+
+
+        Set<DataMigration> emptyMigration = new HashSet<>();
+
+
+        DataMigrationManagerImpl migrationManager = new DataMigrationManagerImpl( serialization, emptyMigration );
+
+        migrationManager.migrate();
+
+        verify( serialization, never() ).setStatusMessage( any( String.class ) );
+        verify( serialization, never() ).setStatusCode( any( Integer.class ) );
+        verify( serialization, never() ).setVersion( any( Integer.class ) );
+    }
+
+
+    @Test
+    public void multipleMigrations() throws Throwable {
+        final MigrationInfoSerialization serialization = mock( MigrationInfoSerialization.class );
+
+
+        final DataMigration v1 = mock( DataMigration.class );
+        when( v1.getVersion() ).thenReturn( 1 );
+
+        final DataMigration v2 = mock( DataMigration.class );
+        when( v2.getVersion() ).thenReturn( 2 );
+
+
+        Set<DataMigration> migrations = new HashSet<>();
+        migrations.add( v1 );
+        migrations.add( v2 );
+
+
+        DataMigrationManagerImpl migrationManager = new DataMigrationManagerImpl( serialization, migrations );
+
+        migrationManager.migrate();
+
+
+        verify( v1 ).migrate( any( DataMigration.ProgressObserver.class ) );
+        verify( v2 ).migrate( any( DataMigration.ProgressObserver.class ) );
+
+        //verify we set the running status
+        verify( serialization, times( 2 ) ).setStatusCode( DataMigrationManagerImpl.StatusCode.RUNNING.status );
+
+        //set the status message
+        verify( serialization, times( 2 * 2 ) ).setStatusMessage( any( String.class ) );
+
+        verify( serialization ).setStatusCode( DataMigrationManagerImpl.StatusCode.COMPLETE.status );
+
+        //verify we set version 1
+        verify( serialization ).setVersion( 1 );
+
+        //verify we set version 2
+        verify( serialization ).setVersion( 2 );
+    }
+
+
+    @Test
+    public void shortCircuitVersionFails() throws Throwable {
+        final MigrationInfoSerialization serialization = mock( MigrationInfoSerialization.class );
+
+
+        final DataMigration v1 = mock( DataMigration.class );
+        when( v1.getVersion() ).thenReturn( 1 );
+
+        //throw an exception
+        doThrow( new RuntimeException( "Something bad happened" ) ).when( v1 ).migrate(
+                any( DataMigration.ProgressObserver.class ) );
+
+        final DataMigration v2 = mock( DataMigration.class );
+        when( v2.getVersion() ).thenReturn( 2 );
+
+
+        Set<DataMigration> migrations = new HashSet<>();
+        migrations.add( v1 );
+        migrations.add( v2 );
+
+
+        DataMigrationManagerImpl migrationManager = new DataMigrationManagerImpl( serialization, migrations );
+
+        migrationManager.migrate();
+
+
+        verify( v1 ).migrate( any( DataMigration.ProgressObserver.class ) );
+
+        //verify we don't run migration
+        verify( v2, never() ).migrate( any( DataMigration.ProgressObserver.class ) );
+
+        //verify we set the running status
+        verify( serialization, times( 1 ) ).setStatusCode( DataMigrationManagerImpl.StatusCode.RUNNING.status );
+
+        //set the status message
+        verify( serialization, times( 2 ) ).setStatusMessage( any( String.class ) );
+
+        //verify we set an error
+        verify( serialization ).setStatusCode( DataMigrationManagerImpl.StatusCode.ERROR.status );
+
+        //verify we never set version 1
+        verify( serialization, never() ).setVersion( 1 );
+
+        //verify we never set version 2
+        verify( serialization, never() ).setVersion( 2 );
+    }
+
+
+    @Test
+    public void failStopsProgress() throws Throwable {
+        final MigrationInfoSerialization serialization = mock( MigrationInfoSerialization.class );
+
+
+        final DataMigration v1 = mock( DataMigration.class );
+        when( v1.getVersion() ).thenReturn( 1 );
+
+
+        final int returnedCode = 100;
+
+        final String reason = "test reason";
+
+        //mark as fail but don't
+        doAnswer( new Answer<Object>() {
+            @Override
+            public Object answer( final InvocationOnMock invocation ) throws Throwable {
+                final DataMigration.ProgressObserver progressObserver =
+                        ( DataMigration.ProgressObserver ) invocation.getArguments()[0];
+
+                progressObserver.failed( returnedCode, reason );
+                return null;
+            }
+        } ).when( v1 ).migrate( any( DataMigration.ProgressObserver.class ) );
+
+
+
+        final DataMigration v2 = mock( DataMigration.class );
+        when( v2.getVersion() ).thenReturn( 2 );
+
+
+        Set<DataMigration> migrations = new HashSet<>();
+        migrations.add( v1 );
+        migrations.add( v2 );
+
+
+        DataMigrationManagerImpl migrationManager = new DataMigrationManagerImpl( serialization, migrations );
+
+        migrationManager.migrate();
+
+
+        verify( v1 ).migrate( any( DataMigration.ProgressObserver.class ) );
+
+        //verify we don't run migration
+        verify( v2, never() ).migrate( any( DataMigration.ProgressObserver.class ) );
+
+        //verify we set the running status
+        verify( serialization, times( 1 ) ).setStatusCode( DataMigrationManagerImpl.StatusCode.RUNNING.status );
+
+        //set the status message
+        verify( serialization ).setStatusMessage( "Migration version 1.  Starting migration" );
+
+        verify( serialization ).setStatusMessage( "Migration version 100.  Failed to migrate, reason is appended.  Error 'test reason'" );
+
+        //verify we set an error
+        verify( serialization, times(1) ).setStatusCode( DataMigrationManagerImpl.StatusCode.ERROR.status );
+
+        //verify we never set version 1
+        verify( serialization, never() ).setVersion( 1 );
+
+        //verify we never set version 2
+        verify( serialization, never() ).setVersion( 2 );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerializationTest.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerializationTest.java b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerializationTest.java
new file mode 100644
index 0000000..d1de9c2
--- /dev/null
+++ b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerializationTest.java
@@ -0,0 +1,104 @@
+/*
+ *
+ *  * 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.
+ *
+ */
+
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+import org.jukito.UseModules;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.apache.usergrid.persistence.core.cassandra.ITRunner;
+import org.apache.usergrid.persistence.core.guice.MigrationManagerRule;
+import org.apache.usergrid.persistence.core.guice.TestCommonModule;
+import org.apache.usergrid.persistence.core.scope.ApplicationScope;
+
+import com.google.inject.Inject;
+import com.netflix.astyanax.Keyspace;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+@RunWith( ITRunner.class )
+@UseModules( TestCommonModule.class )
+public class MigrationInfoSerializationTest {
+
+
+    @Inject
+    @Rule
+    public MigrationManagerRule migrationManagerRule;
+
+    @Inject
+    protected Keyspace keyspace;
+
+
+    protected ApplicationScope scope;
+
+    @Inject
+    protected MigrationInfoSerialization migrationInfoSerialization;
+
+
+
+    @Test
+    public void basicTest(){
+
+        //test getting nothing works
+        final String emptyStatus = migrationInfoSerialization.getStatusMessage();
+
+        assertNull(emptyStatus);
+
+        final int unsavedVersion = migrationInfoSerialization.getVersion();
+
+        assertEquals(0, unsavedVersion);
+
+        final int statusCode = migrationInfoSerialization.getStatusCode();
+
+        assertEquals(0, statusCode);
+
+        //now update them
+
+        final String savedStatus = "I'm a test status";
+
+        migrationInfoSerialization.setStatusMessage( savedStatus );
+
+        final String returnedStatus = migrationInfoSerialization.getStatusMessage();
+
+        assertEquals("Correct status returned", savedStatus, returnedStatus);
+
+
+        final int savedVersion = 100;
+
+        migrationInfoSerialization.setVersion( savedVersion );
+
+        final int returnedVersion = migrationInfoSerialization.getVersion();
+
+        assertEquals("Correct version returned", savedVersion, returnedVersion);
+
+        final int savedStatusCode = 200;
+
+        migrationInfoSerialization.setStatusCode( savedStatusCode );
+
+        final int returnedStatusCode = migrationInfoSerialization.getStatusCode();
+
+        assertEquals("Status code was set correctly", savedStatusCode, returnedStatusCode);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/guice/GraphModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/guice/GraphModule.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/guice/GraphModule.java
index 2cbc5e8..6f15e88 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/guice/GraphModule.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/guice/GraphModule.java
@@ -27,7 +27,7 @@ import org.apache.usergrid.persistence.core.consistency.TimeServiceImpl;
 import org.apache.usergrid.persistence.core.guice.CurrentImpl;
 import org.apache.usergrid.persistence.core.guice.PreviousImpl;
 import org.apache.usergrid.persistence.core.guice.ProxyImpl;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
 import org.apache.usergrid.persistence.core.task.NamedTaskExecutorImpl;
 import org.apache.usergrid.persistence.core.task.TaskExecutor;
 import org.apache.usergrid.persistence.graph.GraphFig;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/EdgeMetadataSerialization.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/EdgeMetadataSerialization.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/EdgeMetadataSerialization.java
index 9e0beb5..38916ac 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/EdgeMetadataSerialization.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/EdgeMetadataSerialization.java
@@ -22,7 +22,7 @@ package org.apache.usergrid.persistence.graph.serialization;
 
 import java.util.Iterator;
 
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
 import org.apache.usergrid.persistence.core.scope.ApplicationScope;
 import org.apache.usergrid.persistence.graph.Edge;
 import org.apache.usergrid.persistence.graph.SearchEdgeType;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/NodeSerialization.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/NodeSerialization.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/NodeSerialization.java
index 77e53c8..00dcd92 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/NodeSerialization.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/NodeSerialization.java
@@ -23,7 +23,7 @@ package org.apache.usergrid.persistence.graph.serialization;
 import java.util.Collection;
 import java.util.Map;
 
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
 import org.apache.usergrid.persistence.core.scope.ApplicationScope;
 import org.apache.usergrid.persistence.graph.Edge;
 import org.apache.usergrid.persistence.model.entity.Id;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationV1Impl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationV1Impl.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationV1Impl.java
index 3254dd5..c634684 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationV1Impl.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationV1Impl.java
@@ -36,7 +36,7 @@ import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDef
 import org.apache.usergrid.persistence.core.astyanax.ScopedRowKeySerializer;
 import org.apache.usergrid.persistence.core.astyanax.ScopedRowKey;
 import org.apache.usergrid.persistence.core.astyanax.StringColumnParser;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
 import org.apache.usergrid.persistence.core.scope.ApplicationScope;
 import org.apache.usergrid.persistence.core.util.ValidationUtils;
 import org.apache.usergrid.persistence.graph.Edge;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationV2Impl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationV2Impl.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationV2Impl.java
index 0c3a04a..c9a279a 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationV2Impl.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationV2Impl.java
@@ -42,7 +42,7 @@ import org.apache.usergrid.persistence.core.astyanax.MultiRowColumnIterator;
 import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamily;
 import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
 import org.apache.usergrid.persistence.core.astyanax.StringColumnParser;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
 import org.apache.usergrid.persistence.core.scope.ApplicationScope;
 import org.apache.usergrid.persistence.core.shard.ExpandingShardLocator;
 import org.apache.usergrid.persistence.core.shard.StringHashUtils;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/NodeSerializationImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/NodeSerializationImpl.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/NodeSerializationImpl.java
index eae7fa0..2cc0391 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/NodeSerializationImpl.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/NodeSerializationImpl.java
@@ -39,7 +39,7 @@ import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDef
 import org.apache.usergrid.persistence.core.astyanax.ScopedRowKeySerializer;
 import org.apache.usergrid.persistence.core.astyanax.ScopedRowKey;
 import org.apache.usergrid.persistence.core.hystrix.HystrixCassandra;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
 import org.apache.usergrid.persistence.core.scope.ApplicationScope;
 import org.apache.usergrid.persistence.core.util.ValidationUtils;
 import org.apache.usergrid.persistence.graph.Edge;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/EdgeColumnFamilies.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/EdgeColumnFamilies.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/EdgeColumnFamilies.java
index a7b5128..f1d6e37 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/EdgeColumnFamilies.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/EdgeColumnFamilies.java
@@ -23,8 +23,7 @@ package org.apache.usergrid.persistence.graph.serialization.impl.shard;
 
 import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamily;
 import org.apache.usergrid.persistence.core.astyanax.ScopedRowKey;
-import org.apache.usergrid.persistence.core.migration.Migration;
-import org.apache.usergrid.persistence.core.scope.ApplicationScope;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
 
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/EdgeShardSerialization.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/EdgeShardSerialization.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/EdgeShardSerialization.java
index 568824a..93fd685 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/EdgeShardSerialization.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/EdgeShardSerialization.java
@@ -22,7 +22,7 @@ package org.apache.usergrid.persistence.graph.serialization.impl.shard;
 
 import java.util.Iterator;
 
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
 import org.apache.usergrid.persistence.core.scope.ApplicationScope;
 
 import com.google.common.base.Optional;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/count/NodeShardCounterSerialization.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/count/NodeShardCounterSerialization.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/count/NodeShardCounterSerialization.java
index 4b05401..aafbd26 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/count/NodeShardCounterSerialization.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/count/NodeShardCounterSerialization.java
@@ -19,7 +19,7 @@
 package org.apache.usergrid.persistence.graph.serialization.impl.shard.count;
 
 
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
 
 import com.netflix.astyanax.MutationBatch;
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/GraphManagerShardConsistencyIT.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/GraphManagerShardConsistencyIT.java b/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/GraphManagerShardConsistencyIT.java
index ec3fb29..a748c05 100644
--- a/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/GraphManagerShardConsistencyIT.java
+++ b/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/GraphManagerShardConsistencyIT.java
@@ -48,8 +48,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.usergrid.persistence.core.cassandra.CassandraRule;
-import org.apache.usergrid.persistence.core.migration.MigrationException;
-import org.apache.usergrid.persistence.core.migration.MigrationManager;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManager;
 import org.apache.usergrid.persistence.core.scope.ApplicationScope;
 import org.apache.usergrid.persistence.core.scope.ApplicationScopeImpl;
 import org.apache.usergrid.persistence.graph.guice.TestGraphModule;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/guice/TestGraphModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/guice/TestGraphModule.java b/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/guice/TestGraphModule.java
index 22c6fd9..bbcfa6e 100644
--- a/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/guice/TestGraphModule.java
+++ b/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/guice/TestGraphModule.java
@@ -19,7 +19,7 @@
 package org.apache.usergrid.persistence.graph.guice;
 
 
-import org.apache.usergrid.persistence.collection.guice.TestModule;
+import org.apache.usergrid.persistence.core.guice.TestModule;
 import org.apache.usergrid.persistence.core.guice.CommonModule;
 
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/guice/MapModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/guice/MapModule.java b/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/guice/MapModule.java
index b6c1410..d167151 100644
--- a/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/guice/MapModule.java
+++ b/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/guice/MapModule.java
@@ -18,7 +18,7 @@
 package org.apache.usergrid.persistence.map.guice;
 
 
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
 import org.apache.usergrid.persistence.map.MapManager;
 import org.apache.usergrid.persistence.map.MapManagerFactory;
 import org.apache.usergrid.persistence.map.impl.MapManagerImpl;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapSerialization.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapSerialization.java b/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapSerialization.java
index 8d4206c..33f2043 100644
--- a/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapSerialization.java
+++ b/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapSerialization.java
@@ -20,7 +20,7 @@
 package org.apache.usergrid.persistence.map.impl;
 import java.util.UUID;
 
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
 import org.apache.usergrid.persistence.map.MapScope;
 
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/map/src/test/java/org/apache/usergrid/persistence/map/guice/TestMapModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/map/src/test/java/org/apache/usergrid/persistence/map/guice/TestMapModule.java b/stack/corepersistence/map/src/test/java/org/apache/usergrid/persistence/map/guice/TestMapModule.java
index 739bb67..2868f45 100644
--- a/stack/corepersistence/map/src/test/java/org/apache/usergrid/persistence/map/guice/TestMapModule.java
+++ b/stack/corepersistence/map/src/test/java/org/apache/usergrid/persistence/map/guice/TestMapModule.java
@@ -1,7 +1,7 @@
 package org.apache.usergrid.persistence.map.guice;
 
 
-import org.apache.usergrid.persistence.collection.guice.TestModule;
+import org.apache.usergrid.persistence.core.guice.TestModule;
 import org.apache.usergrid.persistence.core.guice.CommonModule;
 
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/guice/TestIndexModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/guice/TestIndexModule.java b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/guice/TestIndexModule.java
index 2cf3f7a..4d68dda 100644
--- a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/guice/TestIndexModule.java
+++ b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/guice/TestIndexModule.java
@@ -20,7 +20,7 @@ package org.apache.usergrid.persistence.index.guice;
 
 
 import org.apache.usergrid.persistence.collection.guice.CollectionModule;
-import org.apache.usergrid.persistence.collection.guice.TestModule;
+import org.apache.usergrid.persistence.core.guice.TestModule;
 import org.apache.usergrid.persistence.core.guice.CommonModule;
 
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/queue/src/test/java/org/apache/usergrid/persistence/queue/guice/TestQueueModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queue/src/test/java/org/apache/usergrid/persistence/queue/guice/TestQueueModule.java b/stack/corepersistence/queue/src/test/java/org/apache/usergrid/persistence/queue/guice/TestQueueModule.java
index b65725f..aedfe28 100644
--- a/stack/corepersistence/queue/src/test/java/org/apache/usergrid/persistence/queue/guice/TestQueueModule.java
+++ b/stack/corepersistence/queue/src/test/java/org/apache/usergrid/persistence/queue/guice/TestQueueModule.java
@@ -18,7 +18,7 @@
 package org.apache.usergrid.persistence.queue.guice;
 
 
-import org.apache.usergrid.persistence.collection.guice.TestModule;
+import org.apache.usergrid.persistence.core.guice.TestModule;
 import org.apache.usergrid.persistence.core.guice.CommonModule;
 
 


[3/3] git commit: Cleaned up some code. Need to remove mockito. Incorrect proxy wiring is causing NPE

Posted by to...@apache.org.
Cleaned up some code.  Need to remove mockito.  Incorrect proxy wiring is causing NPE


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

Branch: refs/heads/key-row-sharding
Commit: 84c33176eb819216dde6727d09ac19e8669d4f12
Parents: dfed6a0
Author: Todd Nine <tn...@apigee.com>
Authored: Wed Oct 29 14:33:34 2014 -0600
Committer: Todd Nine <tn...@apigee.com>
Committed: Wed Oct 29 14:33:34 2014 -0600

----------------------------------------------------------------------
 .../persistence/core/guice/CommonModule.java    |  14 +-
 .../migration/data/DataMigrationManager.java    |   6 +
 .../data/DataMigrationManagerImpl.java          |  65 ++++++--
 .../persistence/graph/guice/GraphModule.java    |  40 ++---
 .../graph/impl/GraphManagerImpl.java            |   9 +-
 .../EdgeMetadataSerializationProxyImpl.java     | 165 +++++++++++++++++--
 6 files changed, 229 insertions(+), 70 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/84c33176/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java
index 3503178..e37067f 100644
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java
@@ -59,6 +59,13 @@ public class CommonModule extends AbstractModule {
         // bind our migration manager
         bind( MigrationManager.class ).to( MigrationManagerImpl.class );
 
+
+
+        //do multibindings for migrations
+        Multibinder<Migration> migrationBinding = Multibinder.newSetBinder( binder(), Migration.class );
+        migrationBinding.addBinding().to( Key.get( MigrationInfoSerialization.class ) );
+
+
         bind( TimeService.class ).to( TimeServiceImpl.class );
 
         bind( CassandraConfig.class ).to( CassandraConfigImpl.class );
@@ -71,8 +78,11 @@ public class CommonModule extends AbstractModule {
 
         bind( DataMigrationManager.class ).to( DataMigrationManagerImpl.class );
 
+
+
         //do multibindings for migrations
-        Multibinder<Migration> migrationBinding = Multibinder.newSetBinder( binder(), Migration.class );
-        migrationBinding.addBinding().to( Key.get( MigrationInfoSerialization.class ) );
+        Multibinder<DataMigrationManager> dataMigrationManagerMultibinder = Multibinder.newSetBinder( binder(), DataMigrationManager.class );
+//        migrationBinding.addBinding().to( Key.get( MigrationInfoSerialization.class ) );
+
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/84c33176/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java
index 1d7ccec..3357ed4 100644
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java
@@ -41,6 +41,12 @@ public interface DataMigrationManager {
      */
     public boolean isRunning();
 
+    /**
+     * Get the current version of the schema
+     * @return
+     */
+    public int getCurrentVersion();
+
 
     /**
      * Return that last status of the migration

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/84c33176/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java
index ee579ee..4cc98df 100644
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java
@@ -27,12 +27,18 @@ import java.io.StringWriter;
 import java.util.NavigableMap;
 import java.util.Set;
 import java.util.TreeMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
 
+import com.google.common.base.Preconditions;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
@@ -46,14 +52,33 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
 
     private final MigrationInfoSerialization migrationInfoSerialization;
 
+    /**
+     * Cache to cache versions temporarily
+     */
+    private final LoadingCache<String, Integer> versionCache = CacheBuilder.newBuilder()
+            //cache the local value for 1 minute
+            .expireAfterWrite( 1, TimeUnit.MINUTES ).build( new CacheLoader<String, Integer>() {
+                @Override
+                public Integer load( final String key ) throws Exception {
+                    return migrationInfoSerialization.getVersion();
+                }
+            } );
+
 
     @Inject
     public DataMigrationManagerImpl( final MigrationInfoSerialization migrationInfoSerialization,
                                      final Set<DataMigration> migrations ) {
+        Preconditions.checkNotNull( migrationInfoSerialization, "migrationInfoSerialization must not be null" );
+        Preconditions.checkNotNull( migrations, "migrations must not be null" );
+
         this.migrationInfoSerialization = migrationInfoSerialization;
 
+
+
         for ( DataMigration migration : migrations ) {
 
+            Preconditions.checkNotNull( migration, "A migration instance in the set of migrations was null.  This is not allowed" );
+
             final int version = migration.getVersion();
 
             final DataMigration existing = migrationTreeMap.get( version );
@@ -103,7 +128,7 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
 
             LOG.info( "Running migration version {}", migrationVersion );
 
-            observer.update( migrationVersion,  "Starting migration" );
+            observer.update( migrationVersion, "Starting migration" );
 
 
             //perform this migration, if it fails, short circuit
@@ -119,7 +144,7 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
             }
 
             //we had an unhandled exception or the migration failed, short circuit
-            if(observer.failed){
+            if ( observer.failed ) {
                 return;
             }
 
@@ -128,13 +153,9 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
 
             //update the observer for progress so other nodes can see it
             observer.update( migrationVersion, "Completed successfully" );
-
-
         }
 
         migrationInfoSerialization.setStatusCode( StatusCode.COMPLETE.status );
-
-
     }
 
 
@@ -145,6 +166,17 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
 
 
     @Override
+    public int getCurrentVersion() {
+        try {
+            return versionCache.get( "currentVersion" );
+        }
+        catch ( ExecutionException e ) {
+            throw new DataMigrationException( "Unable to get current version", e );
+        }
+    }
+
+
+    @Override
     public String getLastStatus() {
         return migrationInfoSerialization.getStatusMessage();
     }
@@ -153,10 +185,10 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
     /**
      * Different status enums
      */
-    public enum StatusCode{
-        COMPLETE(1),
-        RUNNING(2),
-        ERROR(3);
+    public enum StatusCode {
+        COMPLETE( 1 ),
+        RUNNING( 2 ),
+        ERROR( 3 );
 
         public final int status;
 
@@ -170,14 +202,13 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
         private boolean failed = false;
 
 
-
         @Override
         public void failed( final int migrationVersion, final String reason ) {
 
-            final String storedMessage = String.format( "Failed to migrate, reason is appended.  Error '%s'", reason);
+            final String storedMessage = String.format( "Failed to migrate, reason is appended.  Error '%s'", reason );
 
 
-            update(migrationVersion,  storedMessage );
+            update( migrationVersion, storedMessage );
 
             LOG.error( storedMessage );
 
@@ -193,9 +224,10 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
             throwable.printStackTrace( new PrintWriter( stackTrace ) );
 
 
-            final String storedMessage = String.format( "Failed to migrate, reason is appended.  Error '%s' %s", reason, stackTrace.toString() );
+            final String storedMessage = String.format( "Failed to migrate, reason is appended.  Error '%s' %s", reason,
+                    stackTrace.toString() );
 
-            update(migrationVersion,  storedMessage );
+            update( migrationVersion, storedMessage );
 
 
             LOG.error( "Unable to migrate version {} due to reason {}.", migrationVersion, reason, throwable );
@@ -208,7 +240,7 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
 
         @Override
         public void update( final int migrationVersion, final String message ) {
-            final String error = String.format( "Migration version %d.  %s", migrationVersion, message);
+            final String error = String.format( "Migration version %d.  %s", migrationVersion, message );
 
             migrationInfoSerialization.setStatusMessage( error );
         }
@@ -216,7 +248,6 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
 
         /**
          * Return true if we failed
-         * @return
          */
         public boolean isFailed() {
             return failed;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/84c33176/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/guice/GraphModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/guice/GraphModule.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/guice/GraphModule.java
index 6f15e88..dee53d4 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/guice/GraphModule.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/guice/GraphModule.java
@@ -27,6 +27,7 @@ import org.apache.usergrid.persistence.core.consistency.TimeServiceImpl;
 import org.apache.usergrid.persistence.core.guice.CurrentImpl;
 import org.apache.usergrid.persistence.core.guice.PreviousImpl;
 import org.apache.usergrid.persistence.core.guice.ProxyImpl;
+import org.apache.usergrid.persistence.core.migration.data.DataMigrationManager;
 import org.apache.usergrid.persistence.core.migration.schema.Migration;
 import org.apache.usergrid.persistence.core.task.NamedTaskExecutorImpl;
 import org.apache.usergrid.persistence.core.task.TaskExecutor;
@@ -157,6 +158,15 @@ public class GraphModule extends AbstractModule {
         //Get the old version and the new one
         migrationBinding.addBinding().to( Key.get( EdgeMetadataSerialization.class, PreviousImpl.class) );
         migrationBinding.addBinding().to( Key.get( EdgeMetadataSerialization.class, CurrentImpl.class  ) );
+
+
+        /**
+         * Migrations of our edge meta serialization
+         */
+
+        bind(EdgeMetadataSerialization.class).annotatedWith( PreviousImpl.class ).to( EdgeMetadataSerializationV1Impl.class  );
+        bind(EdgeMetadataSerialization.class).annotatedWith( CurrentImpl.class ).to( EdgeMetadataSerializationV2Impl.class  );
+        bind(EdgeMetadataSerialization.class).annotatedWith( ProxyImpl.class ).to( EdgeMetadataSerializationProxyImpl.class  );
     }
 
 
@@ -170,36 +180,6 @@ public class GraphModule extends AbstractModule {
     }
 
 
-    @Inject
-    @Singleton
-    @Provides
-    @PreviousImpl
-    public EdgeMetadataSerialization getPreviousEdgeMetaSerialization( final Keyspace keyspace,
-                                                                       final CassandraConfig cassandraConfig,
-                                                                       final GraphFig graphFig ) {
-        return new EdgeMetadataSerializationV1Impl( keyspace, cassandraConfig, graphFig );
-    }
-
-
-    @Inject
-    @Singleton
-    @Provides
-    @CurrentImpl
-    public EdgeMetadataSerialization getCurrentEdgeMetaSerialization( final Keyspace keyspace,
-                                                                      final CassandraConfig cassandraConfig,
-                                                                      final GraphFig graphFig ) {
-        return new EdgeMetadataSerializationV2Impl( keyspace, cassandraConfig, graphFig );
-    }
-
-
-    @Inject
-    @Singleton
-    @Provides
-    @ProxyImpl
-    public EdgeMetadataSerialization getCurrentEdgeMetaSerialization( @PreviousImpl final EdgeMetadataSerialization previous,
-                                                   @CurrentImpl final EdgeMetadataSerialization current ) {
-       return new EdgeMetadataSerializationProxyImpl( previous, current );
-    }
 }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/84c33176/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/impl/GraphManagerImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/impl/GraphManagerImpl.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/impl/GraphManagerImpl.java
index 564dc5b..df10816 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/impl/GraphManagerImpl.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/impl/GraphManagerImpl.java
@@ -92,9 +92,11 @@ public class GraphManagerImpl implements GraphManager {
     @Inject
     public GraphManagerImpl( @ProxyImpl final EdgeMetadataSerialization edgeMetadataSerialization,
                              final EdgeSerialization storageEdgeSerialization,
-                             final NodeSerialization nodeSerialization, final GraphFig graphFig,
-                             @Assisted final ApplicationScope scope, final EdgeDeleteListener edgeDeleteListener,
-                             final NodeDeleteListener nodeDeleteListener ) {
+                             final NodeSerialization nodeSerialization,
+                             final GraphFig graphFig,
+                             final EdgeDeleteListener edgeDeleteListener,
+                             final NodeDeleteListener nodeDeleteListener,
+                             @Assisted final ApplicationScope scope) {
 
 
         ValidationUtils.validateApplicationScope( scope );
@@ -103,6 +105,7 @@ public class GraphManagerImpl implements GraphManager {
         Preconditions.checkNotNull( nodeSerialization, "nodeSerialization must not be null" );
         Preconditions.checkNotNull( graphFig, "consistencyFig must not be null" );
         Preconditions.checkNotNull( scope, "scope must not be null" );
+        Preconditions.checkNotNull( nodeDeleteListener, "nodeDeleteListener must not be null" );
 
         this.scope = scope;
         this.edgeMetadataSerialization = edgeMetadataSerialization;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/84c33176/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationProxyImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationProxyImpl.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationProxyImpl.java
index 4fbe801..cc51349 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationProxyImpl.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationProxyImpl.java
@@ -23,11 +23,13 @@ package org.apache.usergrid.persistence.graph.serialization.impl;
 
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Iterator;
 
 import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
 import org.apache.usergrid.persistence.core.guice.CurrentImpl;
 import org.apache.usergrid.persistence.core.guice.PreviousImpl;
+import org.apache.usergrid.persistence.core.migration.data.DataMigrationManager;
 import org.apache.usergrid.persistence.core.scope.ApplicationScope;
 import org.apache.usergrid.persistence.graph.Edge;
 import org.apache.usergrid.persistence.graph.SearchEdgeType;
@@ -37,22 +39,30 @@ import org.apache.usergrid.persistence.model.entity.Id;
 
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
+import com.netflix.astyanax.Keyspace;
 import com.netflix.astyanax.MutationBatch;
 
 
 @Singleton
 public class EdgeMetadataSerializationProxyImpl implements EdgeMetadataSerialization {
 
-    private EdgeMetadataSerialization previous;
-    private EdgeMetadataSerialization current;
+    private static final int MIGRATION_VERSION = 1;
+
+    private final DataMigrationManager dataMigrationManager;
+    private final Keyspace keyspace;
+    private final EdgeMetadataSerialization previous;
+    private final EdgeMetadataSerialization current;
 
 
     /**
-     * TODO fin
+     * Handles routing data to the right implementation, based on the current system migration version
      */
     @Inject
-    public EdgeMetadataSerializationProxyImpl( @PreviousImpl final EdgeMetadataSerialization previous,
+    public EdgeMetadataSerializationProxyImpl( final DataMigrationManager dataMigrationManager, final Keyspace keyspace,
+                                               @PreviousImpl final EdgeMetadataSerialization previous,
                                                @CurrentImpl final EdgeMetadataSerialization current ) {
+        this.dataMigrationManager = dataMigrationManager;
+        this.keyspace = keyspace;
         this.previous = previous;
         this.current = current;
     }
@@ -60,88 +70,207 @@ public class EdgeMetadataSerializationProxyImpl implements EdgeMetadataSerializa
 
     @Override
     public MutationBatch writeEdge( final ApplicationScope scope, final Edge edge ) {
-        return null;
+
+
+        if ( isOldVersion() ) {
+            final MutationBatch aggregateBatch = keyspace.prepareMutationBatch();
+
+            aggregateBatch.mergeShallow( previous.writeEdge( scope, edge ) );
+            aggregateBatch.mergeShallow( current.writeEdge( scope, edge ) );
+
+            return aggregateBatch;
+        }
+
+        return current.writeEdge( scope, edge );
     }
 
 
     @Override
     public MutationBatch removeEdgeTypeFromSource( final ApplicationScope scope, final Edge edge ) {
-        return null;
+
+        if ( isOldVersion() ) {
+            final MutationBatch aggregateBatch = keyspace.prepareMutationBatch();
+
+            aggregateBatch.mergeShallow( previous.removeEdgeTypeFromSource( scope, edge ) );
+            aggregateBatch.mergeShallow( current.removeEdgeTypeFromSource( scope, edge ) );
+
+            return aggregateBatch;
+        }
+
+        return current.removeEdgeTypeFromSource( scope, edge );
     }
 
 
     @Override
     public MutationBatch removeEdgeTypeFromSource( final ApplicationScope scope, final Id sourceNode, final String type,
                                                    final long timestamp ) {
-        return null;
+
+
+        if ( isOldVersion() ) {
+            final MutationBatch aggregateBatch = keyspace.prepareMutationBatch();
+
+            aggregateBatch.mergeShallow( previous.removeEdgeTypeFromSource( scope, sourceNode, type, timestamp ) );
+            aggregateBatch.mergeShallow( current.removeEdgeTypeFromSource( scope, sourceNode, type, timestamp ) );
+
+            return aggregateBatch;
+        }
+
+        return current.removeEdgeTypeFromSource( scope, sourceNode, type, timestamp );
     }
 
 
     @Override
     public MutationBatch removeIdTypeFromSource( final ApplicationScope scope, final Edge edge ) {
-        return null;
+
+        if ( isOldVersion() ) {
+            final MutationBatch aggregateBatch = keyspace.prepareMutationBatch();
+
+            aggregateBatch.mergeShallow( previous.removeIdTypeFromSource( scope, edge ) );
+            aggregateBatch.mergeShallow( current.removeIdTypeFromSource( scope, edge ) );
+
+            return aggregateBatch;
+        }
+
+        return current.removeIdTypeFromSource( scope, edge );
     }
 
 
     @Override
     public MutationBatch removeIdTypeFromSource( final ApplicationScope scope, final Id sourceNode, final String type,
                                                  final String idType, final long timestamp ) {
-        return null;
+
+        if ( isOldVersion() ) {
+            final MutationBatch aggregateBatch = keyspace.prepareMutationBatch();
+
+            aggregateBatch
+                    .mergeShallow( previous.removeIdTypeFromSource( scope, sourceNode, type, idType, timestamp ) );
+            aggregateBatch.mergeShallow( current.removeIdTypeFromSource( scope, sourceNode, type, idType, timestamp ) );
+
+            return aggregateBatch;
+        }
+
+        return current.removeIdTypeFromSource( scope, sourceNode, type, idType, timestamp );
     }
 
 
     @Override
     public MutationBatch removeEdgeTypeToTarget( final ApplicationScope scope, final Edge edge ) {
-        return null;
+
+
+        if ( isOldVersion() ) {
+            final MutationBatch aggregateBatch = keyspace.prepareMutationBatch();
+
+            aggregateBatch.mergeShallow( previous.removeEdgeTypeToTarget( scope, edge ) );
+            aggregateBatch.mergeShallow( current.removeEdgeTypeToTarget( scope, edge ) );
+
+            return aggregateBatch;
+        }
+
+        return current.removeEdgeTypeToTarget( scope, edge );
     }
 
 
     @Override
     public MutationBatch removeEdgeTypeToTarget( final ApplicationScope scope, final Id targetNode, final String type,
                                                  final long timestamp ) {
-        return null;
+
+        if ( isOldVersion() ) {
+            final MutationBatch aggregateBatch = keyspace.prepareMutationBatch();
+
+            aggregateBatch.mergeShallow( previous.removeEdgeTypeToTarget( scope, targetNode, type, timestamp ) );
+            aggregateBatch.mergeShallow( current.removeEdgeTypeToTarget( scope, targetNode, type, timestamp ) );
+
+            return aggregateBatch;
+        }
+
+        return current.removeEdgeTypeToTarget( scope, targetNode, type, timestamp );
     }
 
 
     @Override
     public MutationBatch removeIdTypeToTarget( final ApplicationScope scope, final Edge edge ) {
-        return null;
+
+        if ( isOldVersion() ) {
+            final MutationBatch aggregateBatch = keyspace.prepareMutationBatch();
+
+            aggregateBatch.mergeShallow( previous.removeIdTypeFromSource( scope, edge ) );
+            aggregateBatch.mergeShallow( current.removeIdTypeFromSource( scope, edge ) );
+
+            return aggregateBatch;
+        }
+
+        return current.removeIdTypeFromSource( scope, edge );
     }
 
 
     @Override
     public MutationBatch removeIdTypeToTarget( final ApplicationScope scope, final Id targetNode, final String type,
                                                final String idType, final long timestamp ) {
-        return null;
+
+
+        if ( isOldVersion() ) {
+            final MutationBatch aggregateBatch = keyspace.prepareMutationBatch();
+
+            aggregateBatch.mergeShallow( previous.removeIdTypeToTarget( scope, targetNode, type, idType, timestamp ) );
+            aggregateBatch.mergeShallow( current.removeIdTypeToTarget( scope, targetNode, type, idType, timestamp ) );
+
+            return aggregateBatch;
+        }
+
+        return current.removeIdTypeToTarget( scope, targetNode, type, idType, timestamp );
     }
 
 
     @Override
     public Iterator<String> getEdgeTypesFromSource( final ApplicationScope scope, final SearchEdgeType search ) {
-        return null;
+        if ( isOldVersion() ) {
+            return previous.getEdgeTypesFromSource( scope, search );
+        }
+
+        return current.getEdgeTypesFromSource( scope, search );
     }
 
 
     @Override
     public Iterator<String> getIdTypesFromSource( final ApplicationScope scope, final SearchIdType search ) {
-        return null;
+        if ( isOldVersion() ) {
+            return previous.getIdTypesFromSource( scope, search );
+        }
+
+        return current.getIdTypesFromSource( scope, search );
     }
 
 
     @Override
     public Iterator<String> getEdgeTypesToTarget( final ApplicationScope scope, final SearchEdgeType search ) {
-        return null;
+        if ( isOldVersion() ) {
+            return previous.getEdgeTypesToTarget( scope, search );
+        }
+
+        return current.getEdgeTypesToTarget( scope, search );
     }
 
 
     @Override
     public Iterator<String> getIdTypesToTarget( final ApplicationScope scope, final SearchIdType search ) {
-        return null;
+        if ( isOldVersion() ) {
+            return previous.getIdTypesToTarget( scope, search );
+        }
+
+        return current.getIdTypesToTarget( scope, search );
     }
 
 
     @Override
     public Collection<MultiTennantColumnFamilyDefinition> getColumnFamilies() {
-        return null;
+        return Collections.EMPTY_LIST;
+    }
+
+
+    /**
+     * Return true if we're on an old version
+     */
+    private boolean isOldVersion() {
+        return dataMigrationManager.getCurrentVersion() < MIGRATION_VERSION;
     }
 }


[2/3] git commit: Updated migrations to separate data migrations and schema migrations.

Posted by to...@apache.org.
Updated migrations to separate data migrations and schema migrations.


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

Branch: refs/heads/key-row-sharding
Commit: dfed6a025a7fcb4c49decb4b3cf8bee37abeb1e7
Parents: ca943fe
Author: Todd Nine <tn...@apigee.com>
Authored: Wed Oct 29 10:51:43 2014 -0600
Committer: Todd Nine <tn...@apigee.com>
Committed: Wed Oct 29 10:51:43 2014 -0600

----------------------------------------------------------------------
 .../usergrid/corepersistence/CpSetup.java       |   6 +-
 .../MvccEntitySerializationStrategyImpl.java    |   2 +-
 .../MvccLogEntrySerializationStrategyImpl.java  |   2 +-
 .../serialization/impl/SerializationModule.java |   2 +-
 .../UniqueValueSerializationStrategyImpl.java   |   2 +-
 .../collection/guice/MigrationManagerRule.java  |   4 +-
 .../collection/guice/TestCollectionModule.java  |   3 +-
 .../collection/guice/TestModule.java            |  48 ----
 ...MvccEntitySerializationStrategyImplTest.java |   2 +-
 .../astyanax/StringRowCompositeSerializer.java  |  68 ++++++
 .../persistence/core/guice/CommonModule.java    |  32 ++-
 .../persistence/core/migration/Migration.java   |  36 ---
 .../core/migration/MigrationException.java      |  37 ---
 .../core/migration/MigrationManager.java        |  34 ---
 .../core/migration/MigrationManagerFig.java     |  22 --
 .../core/migration/MigrationManagerImpl.java    | 196 ----------------
 .../core/migration/data/DataMigration.java      |  84 +++++++
 .../migration/data/DataMigrationException.java  |  39 ++++
 .../migration/data/DataMigrationManager.java    |  49 ++++
 .../data/DataMigrationManagerImpl.java          | 225 +++++++++++++++++++
 .../data/MigrationInfoSerialization.java        |  66 ++++++
 .../data/MigrationInfoSerializationImpl.java    | 178 +++++++++++++++
 .../core/migration/schema/Migration.java        |  36 +++
 .../migration/schema/MigrationException.java    |  37 +++
 .../core/migration/schema/MigrationManager.java |  34 +++
 .../migration/schema/MigrationManagerFig.java   |  22 ++
 .../migration/schema/MigrationManagerImpl.java  | 196 ++++++++++++++++
 .../core/guice/MigrationManagerRule.java        |   4 +-
 .../core/guice/TestCommonModule.java            |  34 +++
 .../persistence/core/guice/TestModule.java      |  48 ++++
 .../data/DataMigrationManagerImplTest.java      | 220 ++++++++++++++++++
 .../data/MigrationInfoSerializationTest.java    | 104 +++++++++
 .../persistence/graph/guice/GraphModule.java    |   2 +-
 .../EdgeMetadataSerialization.java              |   2 +-
 .../graph/serialization/NodeSerialization.java  |   2 +-
 .../impl/EdgeMetadataSerializationV1Impl.java   |   2 +-
 .../impl/EdgeMetadataSerializationV2Impl.java   |   2 +-
 .../impl/NodeSerializationImpl.java             |   2 +-
 .../impl/shard/EdgeColumnFamilies.java          |   3 +-
 .../impl/shard/EdgeShardSerialization.java      |   2 +-
 .../count/NodeShardCounterSerialization.java    |   2 +-
 .../graph/GraphManagerShardConsistencyIT.java   |   4 +-
 .../graph/guice/TestGraphModule.java            |   2 +-
 .../persistence/map/guice/MapModule.java        |   2 +-
 .../persistence/map/impl/MapSerialization.java  |   2 +-
 .../persistence/map/guice/TestMapModule.java    |   2 +-
 .../index/guice/TestIndexModule.java            |   2 +-
 .../queue/guice/TestQueueModule.java            |   2 +-
 48 files changed, 1492 insertions(+), 415 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpSetup.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpSetup.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpSetup.java
index c1bab12..4b4ded6 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpSetup.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpSetup.java
@@ -22,7 +22,7 @@ import com.google.inject.Injector;
 import com.netflix.config.ConfigurationManager;
 import java.util.Properties;
 import java.util.UUID;
-import java.util.logging.Level;
+
 import me.prettyprint.cassandra.service.CassandraHost;
 import me.prettyprint.hector.api.ddl.ComparatorType;
 import static me.prettyprint.hector.api.factory.HFactory.createColumnFamilyDefinition;
@@ -44,8 +44,8 @@ import static org.apache.usergrid.persistence.cassandra.CassandraService.TOKENS_
 import static org.apache.usergrid.persistence.cassandra.CassandraService.USE_VIRTUAL_KEYSPACES;
 import static org.apache.usergrid.persistence.cassandra.CassandraService.keyspaceForApplication;
 import org.apache.usergrid.persistence.cassandra.Setup;
-import org.apache.usergrid.persistence.core.migration.MigrationException;
-import org.apache.usergrid.persistence.core.migration.MigrationManager;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManager;
 import org.apache.usergrid.persistence.entities.Application;
 import org.apache.usergrid.persistence.exceptions.ApplicationAlreadyExistsException;
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImpl.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImpl.java
index dfa41ea..dc12087 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImpl.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImpl.java
@@ -49,7 +49,7 @@ import org.apache.usergrid.persistence.core.astyanax.IdRowCompositeSerializer;
 import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamily;
 import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
 import org.apache.usergrid.persistence.core.astyanax.ScopedRowKey;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
 import org.apache.usergrid.persistence.model.entity.Entity;
 import org.apache.usergrid.persistence.model.entity.Id;
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccLogEntrySerializationStrategyImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccLogEntrySerializationStrategyImpl.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccLogEntrySerializationStrategyImpl.java
index 8577fbf..7368e9a 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccLogEntrySerializationStrategyImpl.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccLogEntrySerializationStrategyImpl.java
@@ -48,7 +48,7 @@ import org.apache.usergrid.persistence.core.astyanax.IdRowCompositeSerializer;
 import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamily;
 import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
 import org.apache.usergrid.persistence.core.astyanax.ScopedRowKey;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
 import org.apache.usergrid.persistence.model.entity.Id;
 
 import com.google.common.base.Preconditions;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/SerializationModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/SerializationModule.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/SerializationModule.java
index 89012aa..8a4a9ac 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/SerializationModule.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/SerializationModule.java
@@ -21,7 +21,7 @@ package org.apache.usergrid.persistence.collection.serialization.impl;
 import org.apache.usergrid.persistence.collection.mvcc.MvccEntitySerializationStrategy;
 import org.apache.usergrid.persistence.collection.mvcc.MvccLogEntrySerializationStrategy;
 import org.apache.usergrid.persistence.collection.serialization.UniqueValueSerializationStrategy;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
 
 import com.google.inject.AbstractModule;
 import com.google.inject.multibindings.Multibinder;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java
index 954cd1c..b6b3cab 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java
@@ -38,7 +38,7 @@ import org.apache.usergrid.persistence.core.astyanax.ColumnTypes;
 import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamily;
 import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
 import org.apache.usergrid.persistence.core.astyanax.ScopedRowKey;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
 import org.apache.usergrid.persistence.core.util.ValidationUtils;
 import org.apache.usergrid.persistence.model.entity.Id;
 import org.apache.usergrid.persistence.model.field.Field;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/MigrationManagerRule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/MigrationManagerRule.java b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/MigrationManagerRule.java
index 2d92adb..6b02b63 100644
--- a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/MigrationManagerRule.java
+++ b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/MigrationManagerRule.java
@@ -5,8 +5,8 @@ import org.junit.rules.ExternalResource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.apache.usergrid.persistence.core.migration.MigrationException;
-import org.apache.usergrid.persistence.core.migration.MigrationManager;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManager;
 
 import com.google.inject.Inject;
 import com.google.inject.Singleton;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestCollectionModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestCollectionModule.java b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestCollectionModule.java
index 0b97eb7..73f1b6d 100644
--- a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestCollectionModule.java
+++ b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestCollectionModule.java
@@ -21,6 +21,7 @@ package org.apache.usergrid.persistence.collection.guice;
 
 
 import org.apache.usergrid.persistence.core.guice.CommonModule;
+import org.apache.usergrid.persistence.core.guice.TestModule;
 
 
 public class TestCollectionModule extends TestModule {
@@ -28,6 +29,6 @@ public class TestCollectionModule extends TestModule {
     @Override
     protected void configure() {
         install( new CommonModule() );
-        install(new CollectionModule());
+        install( new CollectionModule() );
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestModule.java b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestModule.java
deleted file mode 100644
index 44a8fe3..0000000
--- a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestModule.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.usergrid.persistence.collection.guice;
-
-
-import java.io.IOException;
-
-import com.google.inject.AbstractModule;
-import com.netflix.config.ConfigurationManager;
-
-
-public abstract class TestModule extends AbstractModule {
-    static {
-      /*
-       * --------------------------------------------------------------------
-       * Bootstrap the config for Archaius Configuration Settings.  We don't want to
-       * bootstrap more than once per JVM
-       * --------------------------------------------------------------------
-       */
-
-        try {
-            //load up the properties
-            ConfigurationManager.getDeploymentContext().setDeploymentEnvironment( "UNIT" );
-            ConfigurationManager.loadCascadedPropertiesFromResources( "usergrid" );
-
-        }
-        catch ( IOException e ) {
-            throw new RuntimeException( "Cannot do much without properly loading our configuration.", e );
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImplTest.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImplTest.java b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImplTest.java
index 73cf848..b298768 100644
--- a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImplTest.java
+++ b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImplTest.java
@@ -45,7 +45,7 @@ import org.apache.usergrid.persistence.collection.util.EntityUtils;
 import org.apache.usergrid.persistence.core.astyanax.AstyanaxKeyspaceProvider;
 import org.apache.usergrid.persistence.core.astyanax.CassandraFig;
 import org.apache.usergrid.persistence.core.cassandra.ITRunner;
-import org.apache.usergrid.persistence.core.migration.MigrationManagerFig;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManagerFig;
 import org.apache.usergrid.persistence.model.entity.Entity;
 import org.apache.usergrid.persistence.model.entity.Id;
 import org.apache.usergrid.persistence.model.entity.SimpleId;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/astyanax/StringRowCompositeSerializer.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/astyanax/StringRowCompositeSerializer.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/astyanax/StringRowCompositeSerializer.java
new file mode 100644
index 0000000..3a246a5
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/astyanax/StringRowCompositeSerializer.java
@@ -0,0 +1,68 @@
+/*
+ *
+ *  * 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.
+ *
+ */
+package org.apache.usergrid.persistence.core.astyanax;
+
+
+import java.util.UUID;
+
+import org.apache.usergrid.persistence.model.entity.Id;
+import org.apache.usergrid.persistence.model.entity.SimpleId;
+
+import com.netflix.astyanax.model.CompositeBuilder;
+import com.netflix.astyanax.model.CompositeParser;
+
+
+/**
+ * Serializer for serializing strings
+ *
+ * @author tnine
+ */
+public class StringRowCompositeSerializer implements CompositeFieldSerializer<String> {
+
+
+    private static final StringRowCompositeSerializer INSTANCE = new StringRowCompositeSerializer();
+
+
+    private StringRowCompositeSerializer() {}
+
+
+    @Override
+    public void toComposite( final CompositeBuilder builder, final String string ) {
+        builder.addString( string );
+    }
+
+
+    @Override
+    public String fromComposite( final CompositeParser composite ) {
+        return composite.readString();
+    }
+
+
+
+    /**
+     * Get the singleton serializer
+     */
+    public static StringRowCompositeSerializer get() {
+        return INSTANCE;
+    }
+}
+
+

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java
index 5f461bb..3503178 100644
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java
@@ -27,17 +27,23 @@ import org.apache.usergrid.persistence.core.astyanax.CassandraConfigImpl;
 import org.apache.usergrid.persistence.core.astyanax.CassandraFig;
 import org.apache.usergrid.persistence.core.consistency.TimeService;
 import org.apache.usergrid.persistence.core.consistency.TimeServiceImpl;
-import org.apache.usergrid.persistence.core.migration.MigrationManager;
-import org.apache.usergrid.persistence.core.migration.MigrationManagerFig;
-import org.apache.usergrid.persistence.core.migration.MigrationManagerImpl;
+import org.apache.usergrid.persistence.core.migration.data.DataMigrationManager;
+import org.apache.usergrid.persistence.core.migration.data.DataMigrationManagerImpl;
+import org.apache.usergrid.persistence.core.migration.data.MigrationInfoSerialization;
+import org.apache.usergrid.persistence.core.migration.data.MigrationInfoSerializationImpl;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManager;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManagerFig;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManagerImpl;
 
 import com.google.inject.AbstractModule;
+import com.google.inject.Key;
+import com.google.inject.multibindings.Multibinder;
 import com.netflix.astyanax.Keyspace;
 
 
 /**
  * Simple module for configuring our core services.  Cassandra etc
- *
  */
 public class CommonModule extends AbstractModule {
 
@@ -45,11 +51,9 @@ public class CommonModule extends AbstractModule {
     @Override
     protected void configure() {
         //noinspection unchecked
-        install( new GuicyFigModule(
-                MigrationManagerFig.class,
-                CassandraFig.class) );
+        install( new GuicyFigModule( MigrationManagerFig.class, CassandraFig.class ) );
 
-             // bind our keyspace to the AstyanaxKeyspaceProvider
+        // bind our keyspace to the AstyanaxKeyspaceProvider
         bind( Keyspace.class ).toProvider( AstyanaxKeyspaceProvider.class ).asEagerSingleton();
 
         // bind our migration manager
@@ -59,10 +63,16 @@ public class CommonModule extends AbstractModule {
 
         bind( CassandraConfig.class ).to( CassandraConfigImpl.class );
 
-    }
-
-
 
+        /**
+         * Data migration beans
+         */
+        bind( MigrationInfoSerialization.class ).to( MigrationInfoSerializationImpl.class );
 
+        bind( DataMigrationManager.class ).to( DataMigrationManagerImpl.class );
 
+        //do multibindings for migrations
+        Multibinder<Migration> migrationBinding = Multibinder.newSetBinder( binder(), Migration.class );
+        migrationBinding.addBinding().to( Key.get( MigrationInfoSerialization.class ) );
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/Migration.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/Migration.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/Migration.java
deleted file mode 100644
index 16f8251..0000000
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/Migration.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.
- */
-package org.apache.usergrid.persistence.core.migration;
-
-
-import java.util.Collection;
-
-import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
-
-
-/**
- * @author tnine
- */
-public interface Migration {
-
-    /**
-     * Get the column families required for this implementation.  If one does not exist it will be created.
-     */
-    public Collection<MultiTennantColumnFamilyDefinition> getColumnFamilies();
-}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationException.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationException.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationException.java
deleted file mode 100644
index 4862b55..0000000
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationException.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.
- */
-package org.apache.usergrid.persistence.core.migration;
-
-
-/**
- * Thrown when a migration cannot be performed
- *
- * @author tnine
- */
-public class MigrationException extends Exception {
-
-    public MigrationException( final String message ) {
-        super( message );
-    }
-
-
-    public MigrationException( final String message, final Throwable cause ) {
-        super( message, cause );
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManager.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManager.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManager.java
deleted file mode 100644
index 98637e0..0000000
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManager.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.
- */
-package org.apache.usergrid.persistence.core.migration;
-
-
-/**
- * A manager that will perform any migrations necessary.  Setup code should invoke the implementation of this interface
- *
- * @author tnine
- */
-public interface MigrationManager {
-
-    /**
-     * Perform any migration necessary in the application.  Will only create keyspaces and column families if they do
-     * not exist
-     */
-    public void migrate() throws MigrationException;
-}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerFig.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerFig.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerFig.java
deleted file mode 100644
index e97dcba..0000000
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerFig.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.apache.usergrid.persistence.core.migration;
-
-
-import org.safehaus.guicyfig.Default;
-import org.safehaus.guicyfig.FigSingleton;
-import org.safehaus.guicyfig.GuicyFig;
-import org.safehaus.guicyfig.Key;
-
-
-/**
- * Configuration for the MigrationManager.
- */
-@FigSingleton
-public interface MigrationManagerFig extends GuicyFig {
-    @Key( "collections.keyspace.strategy.class" )
-    @Default( "org.apache.cassandra.locator.SimpleStrategy" )
-    String getStrategyClass();
-
-    @Key( "collections.keyspace.strategy.options" )
-    String getStrategyOptions();
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerImpl.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerImpl.java
deleted file mode 100644
index ad30d5b..0000000
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerImpl.java
+++ /dev/null
@@ -1,196 +0,0 @@
-package org.apache.usergrid.persistence.core.migration;
-
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import com.netflix.astyanax.Keyspace;
-import com.netflix.astyanax.connectionpool.exceptions.BadRequestException;
-import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
-import com.netflix.astyanax.ddl.ColumnFamilyDefinition;
-import com.netflix.astyanax.ddl.KeyspaceDefinition;
-
-
-/**
- * Implementation of the migration manager to set up keyspace
- *
- * @author tnine
- */
-@Singleton
-public class MigrationManagerImpl implements MigrationManager {
-
-
-    private static final Logger logger = LoggerFactory.getLogger( MigrationManagerImpl.class );
-
-    private final Set<Migration> migrations;
-    private final Keyspace keyspace;
-
-    private final MigrationManagerFig fig;
-
-
-    @Inject
-    public MigrationManagerImpl( final Keyspace keyspace, final Set<Migration> migrations,
-                                 MigrationManagerFig fig ) {
-        this.keyspace = keyspace;
-        this.migrations = migrations;
-        this.fig = fig;
-    }
-
-
-    @Override
-    public void migrate() throws MigrationException {
-
-
-        try {
-
-            testAndCreateKeyspace();
-
-            for ( Migration migration : migrations ) {
-
-                final Collection<MultiTennantColumnFamilyDefinition> columnFamilies = migration.getColumnFamilies();
-
-
-                if ( columnFamilies == null || columnFamilies.size() == 0 ) {
-                    logger.warn(
-                            "Class {} implements {} but returns null column families for migration.  Either implement"
-                                    + " this method or remove the interface from the class", migration.getClass(),
-                            Migration.class );
-                    continue;
-                }
-
-                for ( MultiTennantColumnFamilyDefinition cf : columnFamilies ) {
-                    testAndCreateColumnFamilyDef( cf );
-                }
-            }
-        }
-        catch ( Throwable t ) {
-            logger.error( "Unable to perform migration", t );
-            throw new MigrationException( "Unable to perform migration", t );
-        }
-    }
-
-
-    /**
-     * Check if the column family exists.  If it dosn't create it
-     */
-    private void testAndCreateColumnFamilyDef( MultiTennantColumnFamilyDefinition columnFamily )
-            throws ConnectionException {
-        final KeyspaceDefinition keyspaceDefinition = keyspace.describeKeyspace();
-
-        final ColumnFamilyDefinition existing =
-                keyspaceDefinition.getColumnFamily( columnFamily.getColumnFamily().getName() );
-
-        if ( existing != null ) {
-            return;
-        }
-
-        keyspace.createColumnFamily( columnFamily.getColumnFamily(), columnFamily.getOptions() );
-
-        logger.info( "Created column family {}", columnFamily.getColumnFamily().getName() );
-
-        waitForMigration();
-    }
-
-
-    /**
-     * Check if they keyspace exists.  If it doesn't create it
-     */
-    private void testAndCreateKeyspace() throws ConnectionException {
-
-
-        KeyspaceDefinition keyspaceDefinition = null;
-
-        try {
-            keyspaceDefinition = keyspace.describeKeyspace();
-        }
-        catch ( BadRequestException badRequestException ) {
-
-            //check if it's b/c the keyspace is missing, if so
-            final String message = badRequestException.getMessage();
-
-            boolean missingKeyspace = message.contains( "why:Keyspace" ) && message.contains( "does not exist" );
-
-            if ( !missingKeyspace ) {
-                throw badRequestException;
-            }
-        }
-
-
-        if ( keyspaceDefinition != null ) {
-            return;
-        }
-
-
-        ImmutableMap.Builder<String, Object> strategyOptions = getKeySpaceProps();
-
-
-        ImmutableMap<String, Object> options =
-                ImmutableMap.<String, Object>builder().put( "strategy_class", fig.getStrategyClass() )
-                            .put( "strategy_options", strategyOptions.build() ).build();
-
-
-        keyspace.createKeyspace( options );
-
-        strategyOptions.toString();
-
-        logger.info( "Created keyspace {} with options {}", keyspace.getKeyspaceName(), options.toString() );
-
-        waitForMigration();
-    }
-
-
-    /**
-     * Get keyspace properties
-     */
-    private ImmutableMap.Builder<String, Object> getKeySpaceProps() {
-        ImmutableMap.Builder<String, Object> keyspaceProps = ImmutableMap.<String, Object>builder();
-
-        String optionString = fig.getStrategyOptions();
-
-        if(optionString == null){
-            return keyspaceProps;
-        }
-
-
-
-        for ( String key : optionString.split( "," ) ) {
-
-            final String[] options = key.split( ":" );
-
-            keyspaceProps.put( options[0], options[1] );
-        }
-
-        return keyspaceProps;
-    }
-
-
-    private void waitForMigration() throws ConnectionException {
-
-        while ( true ) {
-
-            final Map<String, List<String>> versions = keyspace.describeSchemaVersions();
-
-            if ( versions != null && versions.size() == 1 ) {
-                return;
-            }
-
-            //sleep and try it again
-            try {
-                Thread.sleep( 100 );
-            }
-            catch ( InterruptedException e ) {
-                //swallow
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigration.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigration.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigration.java
new file mode 100644
index 0000000..ecf9946
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigration.java
@@ -0,0 +1,84 @@
+/*
+ *
+ *  * 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.
+ *
+ */
+
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+/**
+ * An interface for updating data.  Has 2 basic functions. First it will perform the migration and update the status
+ * object.
+ *
+ * Second it will only migrate a single version.  For instance, it will migrate from 0->1, or from 1->2.  All migrations
+ * must follow the following basic rules.
+ *
+ * <ol>
+ *     <li>They must not modify the structure of an existing column family.  If the data format changes, a new
+ * implementation and column family must be created.  A proxy must be defined to do dual writes/single reads. </li>
+ * <li>The migration must update the progress observer.  This information should be made available cluster wide.</li>
+ * <li>In the event a migration fails with an error, we should be able to roll back and remove new column families.  We
+ * can then fix the bug, and deploy again.  Hence the need for the proxy, dual writes, and an immutable CF
+ * format</li>
+ * </ol>
+ */
+
+
+public interface DataMigration {
+
+
+    /**
+     * Migrate the data to the specified version
+     * @param observer
+     * @throws Throwable
+     */
+    public void migrate(final ProgressObserver observer) throws Throwable;
+
+    /**
+     * Get the version of this migration.  It must be unique.
+     * @return
+     */
+    public int getVersion();
+
+    public interface ProgressObserver{
+        /**
+         * Mark the migration as failed
+         * @param migrationVersion The migration version running during the failure
+         * @param reason The reason to save
+         */
+        public void failed(final int migrationVersion, final String reason);
+
+        /**
+         * Mark the migration as failed with a stack trace
+         * @param migrationVersion The migration version running during the failure
+         * @param reason The error description to save
+         * @param throwable The error that happened
+         */
+        public void failed(final int migrationVersion, final String reason, final Throwable throwable);
+
+
+        /**
+         * Update the status of the migration with the message
+         *
+         * @param message The message to save for the status
+         */
+        public void update(final int migrationVersion, final String message);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationException.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationException.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationException.java
new file mode 100644
index 0000000..0e1f29f
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationException.java
@@ -0,0 +1,39 @@
+/*
+ *
+ *  * 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.
+ *
+ */
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+/**
+ * Thrown when a migration cannot be performed
+ *
+ * @author tnine
+ */
+public class DataMigrationException extends RuntimeException {
+
+    public DataMigrationException( final String message ) {
+        super( message );
+    }
+
+
+    public DataMigrationException( final String message, final Throwable cause ) {
+        super( message, cause );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java
new file mode 100644
index 0000000..1d7ccec
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java
@@ -0,0 +1,49 @@
+/*
+ *
+ *  * 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.
+ *
+ */
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
+
+
+/**
+ *  A manager that will perform any data migrations necessary.  Setup code should invoke the implementation of this interface
+ */
+public interface DataMigrationManager {
+
+    /**
+     * Perform any migration necessary in the application.  Will only create keyspaces and column families if they do
+     * not exist
+     */
+    public void migrate() throws MigrationException;
+
+    /**
+     * Returns true if a migration is running.  False otherwise
+     * @return
+     */
+    public boolean isRunning();
+
+
+    /**
+     * Return that last status of the migration
+     */
+    public String getLastStatus();
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java
new file mode 100644
index 0000000..ee579ee
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java
@@ -0,0 +1,225 @@
+/*
+ *
+ *  * 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.
+ *
+ */
+
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.NavigableMap;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+
+@Singleton
+public class DataMigrationManagerImpl implements DataMigrationManager {
+
+    private static final Logger LOG = LoggerFactory.getLogger( DataMigrationManagerImpl.class );
+
+    private final TreeMap<Integer, DataMigration> migrationTreeMap = new TreeMap<>();
+
+    private final MigrationInfoSerialization migrationInfoSerialization;
+
+
+    @Inject
+    public DataMigrationManagerImpl( final MigrationInfoSerialization migrationInfoSerialization,
+                                     final Set<DataMigration> migrations ) {
+        this.migrationInfoSerialization = migrationInfoSerialization;
+
+        for ( DataMigration migration : migrations ) {
+
+            final int version = migration.getVersion();
+
+            final DataMigration existing = migrationTreeMap.get( version );
+
+            if ( existing != null ) {
+
+                final Class<? extends DataMigration> existingClass = existing.getClass();
+
+                final Class<? extends DataMigration> currentClass = migration.getClass();
+
+
+                throw new DataMigrationException(
+                        String.format( "Data migrations must be unique.  Both classes %s and %s have version %d",
+                                existingClass, currentClass, version ) );
+            }
+
+            migrationTreeMap.put( version, migration );
+        }
+    }
+
+
+    @Override
+    public void migrate() throws MigrationException {
+
+        if ( migrationTreeMap.isEmpty() ) {
+            LOG.warn( "No migrations found to run, exiting" );
+            return;
+        }
+
+
+        final int currentVersion = migrationInfoSerialization.getVersion();
+
+        LOG.info( "Saved schema version is {}, max migration version is {}", currentVersion,
+                migrationTreeMap.lastKey() );
+
+        //we have our migrations to run, execute them
+        final NavigableMap<Integer, DataMigration> migrationsToRun = migrationTreeMap.tailMap( currentVersion, false );
+
+        CassandraProgressObserver observer = new CassandraProgressObserver();
+
+
+        for ( DataMigration migration : migrationsToRun.values() ) {
+
+            migrationInfoSerialization.setStatusCode( StatusCode.RUNNING.status );
+
+            final int migrationVersion = migration.getVersion();
+
+            LOG.info( "Running migration version {}", migrationVersion );
+
+            observer.update( migrationVersion,  "Starting migration" );
+
+
+            //perform this migration, if it fails, short circuit
+            try {
+                migration.migrate( observer );
+            }
+            catch ( Throwable throwable ) {
+                observer.failed( migrationVersion, "Exception thrown during migration", throwable );
+
+                LOG.error( "Unable to migration version {}.", migrationVersion, throwable );
+
+                return;
+            }
+
+            //we had an unhandled exception or the migration failed, short circuit
+            if(observer.failed){
+                return;
+            }
+
+            //set the version
+            migrationInfoSerialization.setVersion( migrationVersion );
+
+            //update the observer for progress so other nodes can see it
+            observer.update( migrationVersion, "Completed successfully" );
+
+
+        }
+
+        migrationInfoSerialization.setStatusCode( StatusCode.COMPLETE.status );
+
+
+    }
+
+
+    @Override
+    public boolean isRunning() {
+        return migrationInfoSerialization.getStatusCode() == StatusCode.RUNNING.status;
+    }
+
+
+    @Override
+    public String getLastStatus() {
+        return migrationInfoSerialization.getStatusMessage();
+    }
+
+
+    /**
+     * Different status enums
+     */
+    public enum StatusCode{
+        COMPLETE(1),
+        RUNNING(2),
+        ERROR(3);
+
+        public final int status;
+
+
+        StatusCode( final int status ) {this.status = status;}
+    }
+
+
+    private final class CassandraProgressObserver implements DataMigration.ProgressObserver {
+
+        private boolean failed = false;
+
+
+
+        @Override
+        public void failed( final int migrationVersion, final String reason ) {
+
+            final String storedMessage = String.format( "Failed to migrate, reason is appended.  Error '%s'", reason);
+
+
+            update(migrationVersion,  storedMessage );
+
+            LOG.error( storedMessage );
+
+            failed = true;
+
+            migrationInfoSerialization.setStatusCode( StatusCode.ERROR.status );
+        }
+
+
+        @Override
+        public void failed( final int migrationVersion, final String reason, final Throwable throwable ) {
+            StringWriter stackTrace = new StringWriter();
+            throwable.printStackTrace( new PrintWriter( stackTrace ) );
+
+
+            final String storedMessage = String.format( "Failed to migrate, reason is appended.  Error '%s' %s", reason, stackTrace.toString() );
+
+            update(migrationVersion,  storedMessage );
+
+
+            LOG.error( "Unable to migrate version {} due to reason {}.", migrationVersion, reason, throwable );
+
+            failed = true;
+
+            migrationInfoSerialization.setStatusCode( StatusCode.ERROR.status );
+        }
+
+
+        @Override
+        public void update( final int migrationVersion, final String message ) {
+            final String error = String.format( "Migration version %d.  %s", migrationVersion, message);
+
+            migrationInfoSerialization.setStatusMessage( error );
+        }
+
+
+        /**
+         * Return true if we failed
+         * @return
+         */
+        public boolean isFailed() {
+            return failed;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerialization.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerialization.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerialization.java
new file mode 100644
index 0000000..5cd8a76
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerialization.java
@@ -0,0 +1,66 @@
+/*
+ *
+ *  * 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.
+ *
+ */
+
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
+
+
+public interface MigrationInfoSerialization extends Migration {
+
+    /**
+     * Save the message to the cluster
+     * @param message
+     */
+    public void setStatusMessage( final String message );
+
+    /**
+     * Get the last status
+     * @return
+     */
+    public String getStatusMessage();
+
+    /**
+     * Save the version
+     * @param version
+     */
+    public void setVersion(final int version);
+
+    /**
+     * Return the version
+     * @return
+     */
+    public int getVersion();
+
+    /**
+     * Set the status and save them
+     * @param status
+     * @return
+     */
+    public void setStatusCode( final int status );
+
+    /**
+     *
+     * @return The integer that's saved
+     */
+    public int getStatusCode();
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerializationImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerializationImpl.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerializationImpl.java
new file mode 100644
index 0000000..0460e33
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerializationImpl.java
@@ -0,0 +1,178 @@
+/*
+ *
+ *  * 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.
+ *
+ */
+
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.UUID;
+
+import org.apache.cassandra.db.marshal.BytesType;
+import org.apache.cassandra.db.marshal.UTF8Type;
+
+import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamily;
+import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
+import org.apache.usergrid.persistence.core.astyanax.ScopedRowKey;
+import org.apache.usergrid.persistence.core.astyanax.ScopedRowKeySerializer;
+import org.apache.usergrid.persistence.core.astyanax.StringRowCompositeSerializer;
+import org.apache.usergrid.persistence.model.entity.Id;
+import org.apache.usergrid.persistence.model.entity.SimpleId;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.netflix.astyanax.Keyspace;
+import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
+import com.netflix.astyanax.connectionpool.exceptions.NotFoundException;
+import com.netflix.astyanax.serializers.StringSerializer;
+
+
+@Singleton
+public class MigrationInfoSerializationImpl implements MigrationInfoSerialization {
+
+
+    /**
+     * Just a hard coded scope since we need it
+     */
+    private static final Id STATIC_ID =
+            new SimpleId( UUID.fromString( "00000000-0000-1000-8000-000000000000" ), "status" );
+
+
+    private static final ScopedRowKeySerializer<String> ROW_KEY_SER =
+            new ScopedRowKeySerializer<String>( StringRowCompositeSerializer.get() );
+
+    private static final StringSerializer STRING_SERIALIZER = StringSerializer.get();
+
+
+    private static final MultiTennantColumnFamily<ScopedRowKey<String>, String> CF_MIGRATION_INFO =
+            new MultiTennantColumnFamily<>( "Data_Migration_Info", ROW_KEY_SER, STRING_SERIALIZER );
+
+
+    private static final ScopedRowKey<String> ROW_KEY = ScopedRowKey.fromKey( STATIC_ID, "" );
+
+    private static final String COL_STATUS_MESSAGE = "statusMessage";
+
+    private static final String COLUMN_VERSION = "version";
+
+    private static final String COLUMN_STATUS_CODE = "statusCode";
+
+    private final Keyspace keyspace;
+
+
+    @Inject
+    public MigrationInfoSerializationImpl( final Keyspace keyspace ) {
+        this.keyspace = keyspace;
+    }
+
+
+    @Override
+    public void setStatusMessage( final String message ) {
+
+        try {
+            keyspace.prepareColumnMutation( CF_MIGRATION_INFO, ROW_KEY, COL_STATUS_MESSAGE ).putValue( message, null )
+                    .execute();
+        }
+        catch ( ConnectionException e ) {
+            throw new DataMigrationException( "Unable to save status", e );
+        }
+    }
+
+
+    @Override
+    public String getStatusMessage() {
+        try {
+            return keyspace.prepareQuery( CF_MIGRATION_INFO ).getKey( ROW_KEY ).getColumn( COL_STATUS_MESSAGE )
+                           .execute().getResult().getStringValue();
+        }
+        //swallow, it doesn't exist
+        catch ( NotFoundException nfe ) {
+            return null;
+        }
+        catch ( ConnectionException e ) {
+            throw new DataMigrationException( "Unable to retrieve status", e );
+        }
+    }
+
+
+    @Override
+    public void setVersion( final int version ) {
+        try {
+            keyspace.prepareColumnMutation( CF_MIGRATION_INFO, ROW_KEY, COLUMN_VERSION ).putValue( version, null )
+                    .execute();
+        }
+        catch ( ConnectionException e ) {
+            throw new DataMigrationException( "Unable to save status", e );
+        }
+    }
+
+
+    @Override
+    public int getVersion() {
+        try {
+            return keyspace.prepareQuery( CF_MIGRATION_INFO ).getKey( ROW_KEY ).getColumn( COLUMN_VERSION ).execute()
+                           .getResult().getIntegerValue();
+        }
+        //swallow, it doesn't exist
+        catch ( NotFoundException nfe ) {
+            return 0;
+        }
+        catch ( ConnectionException e ) {
+            throw new DataMigrationException( "Unable to retrieve status", e );
+        }
+    }
+
+
+    @Override
+    public void setStatusCode( final int status ) {
+        try {
+            keyspace.prepareColumnMutation( CF_MIGRATION_INFO, ROW_KEY, COLUMN_STATUS_CODE ).putValue( status, null )
+                    .execute();
+        }
+        catch ( ConnectionException e ) {
+            throw new DataMigrationException( "Unable to save status", e );
+        }
+    }
+
+
+    @Override
+    public int getStatusCode() {
+        try {
+            return keyspace.prepareQuery( CF_MIGRATION_INFO ).getKey( ROW_KEY ).getColumn( COLUMN_STATUS_CODE )
+                           .execute().getResult().getIntegerValue();
+        }
+        //swallow, it doesn't exist
+        catch ( NotFoundException nfe ) {
+            return 0;
+        }
+        catch ( ConnectionException e ) {
+            throw new DataMigrationException( "Unable to retrieve status", e );
+        }
+    }
+
+
+    @Override
+    public Collection<MultiTennantColumnFamilyDefinition> getColumnFamilies() {
+        return Collections.singletonList(
+                new MultiTennantColumnFamilyDefinition( CF_MIGRATION_INFO, BytesType.class.getSimpleName(),
+                        UTF8Type.class.getSimpleName(), BytesType.class.getSimpleName(),
+                        MultiTennantColumnFamilyDefinition.CacheOption.KEYS ) );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/Migration.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/Migration.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/Migration.java
new file mode 100644
index 0000000..fdf483a
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/Migration.java
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+package org.apache.usergrid.persistence.core.migration.schema;
+
+
+import java.util.Collection;
+
+import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
+
+
+/**
+ * @author tnine
+ */
+public interface Migration {
+
+    /**
+     * Get the column families required for this implementation.  If one does not exist it will be created.
+     */
+    public Collection<MultiTennantColumnFamilyDefinition> getColumnFamilies();
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationException.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationException.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationException.java
new file mode 100644
index 0000000..63a1297
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationException.java
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+package org.apache.usergrid.persistence.core.migration.schema;
+
+
+/**
+ * Thrown when a migration cannot be performed
+ *
+ * @author tnine
+ */
+public class MigrationException extends Exception {
+
+    public MigrationException( final String message ) {
+        super( message );
+    }
+
+
+    public MigrationException( final String message, final Throwable cause ) {
+        super( message, cause );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManager.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManager.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManager.java
new file mode 100644
index 0000000..df84247
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManager.java
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+package org.apache.usergrid.persistence.core.migration.schema;
+
+
+/**
+ * A manager that will perform any migrations necessary.  Setup code should invoke the implementation of this interface
+ *
+ * @author tnine
+ */
+public interface MigrationManager {
+
+    /**
+     * Perform any migration necessary in the application.  Will only create keyspaces and column families if they do
+     * not exist
+     */
+    public void migrate() throws MigrationException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerFig.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerFig.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerFig.java
new file mode 100644
index 0000000..9595020
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerFig.java
@@ -0,0 +1,22 @@
+package org.apache.usergrid.persistence.core.migration.schema;
+
+
+import org.safehaus.guicyfig.Default;
+import org.safehaus.guicyfig.FigSingleton;
+import org.safehaus.guicyfig.GuicyFig;
+import org.safehaus.guicyfig.Key;
+
+
+/**
+ * Configuration for the MigrationManager.
+ */
+@FigSingleton
+public interface MigrationManagerFig extends GuicyFig {
+    @Key( "collections.keyspace.strategy.class" )
+    @Default( "org.apache.cassandra.locator.SimpleStrategy" )
+    String getStrategyClass();
+
+    @Key( "collections.keyspace.strategy.options" )
+    String getStrategyOptions();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerImpl.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerImpl.java
new file mode 100644
index 0000000..70ab713
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerImpl.java
@@ -0,0 +1,196 @@
+package org.apache.usergrid.persistence.core.migration.schema;
+
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.netflix.astyanax.Keyspace;
+import com.netflix.astyanax.connectionpool.exceptions.BadRequestException;
+import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
+import com.netflix.astyanax.ddl.ColumnFamilyDefinition;
+import com.netflix.astyanax.ddl.KeyspaceDefinition;
+
+
+/**
+ * Implementation of the migration manager to set up keyspace
+ *
+ * @author tnine
+ */
+@Singleton
+public class MigrationManagerImpl implements MigrationManager {
+
+
+    private static final Logger logger = LoggerFactory.getLogger( MigrationManagerImpl.class );
+
+    private final Set<Migration> migrations;
+    private final Keyspace keyspace;
+
+    private final MigrationManagerFig fig;
+
+
+    @Inject
+    public MigrationManagerImpl( final Keyspace keyspace, final Set<Migration> migrations,
+                                 MigrationManagerFig fig ) {
+        this.keyspace = keyspace;
+        this.migrations = migrations;
+        this.fig = fig;
+    }
+
+
+    @Override
+    public void migrate() throws MigrationException {
+
+
+        try {
+
+            testAndCreateKeyspace();
+
+            for ( Migration migration : migrations ) {
+
+                final Collection<MultiTennantColumnFamilyDefinition> columnFamilies = migration.getColumnFamilies();
+
+
+                if ( columnFamilies == null || columnFamilies.size() == 0 ) {
+                    logger.warn(
+                            "Class {} implements {} but returns null column families for migration.  Either implement"
+                                    + " this method or remove the interface from the class", migration.getClass(),
+                            Migration.class );
+                    continue;
+                }
+
+                for ( MultiTennantColumnFamilyDefinition cf : columnFamilies ) {
+                    testAndCreateColumnFamilyDef( cf );
+                }
+            }
+        }
+        catch ( Throwable t ) {
+            logger.error( "Unable to perform migration", t );
+            throw new MigrationException( "Unable to perform migration", t );
+        }
+    }
+
+
+    /**
+     * Check if the column family exists.  If it dosn't create it
+     */
+    private void testAndCreateColumnFamilyDef( MultiTennantColumnFamilyDefinition columnFamily )
+            throws ConnectionException {
+        final KeyspaceDefinition keyspaceDefinition = keyspace.describeKeyspace();
+
+        final ColumnFamilyDefinition existing =
+                keyspaceDefinition.getColumnFamily( columnFamily.getColumnFamily().getName() );
+
+        if ( existing != null ) {
+            return;
+        }
+
+        keyspace.createColumnFamily( columnFamily.getColumnFamily(), columnFamily.getOptions() );
+
+        logger.info( "Created column family {}", columnFamily.getColumnFamily().getName() );
+
+        waitForMigration();
+    }
+
+
+    /**
+     * Check if they keyspace exists.  If it doesn't create it
+     */
+    private void testAndCreateKeyspace() throws ConnectionException {
+
+
+        KeyspaceDefinition keyspaceDefinition = null;
+
+        try {
+            keyspaceDefinition = keyspace.describeKeyspace();
+        }
+        catch ( BadRequestException badRequestException ) {
+
+            //check if it's b/c the keyspace is missing, if so
+            final String message = badRequestException.getMessage();
+
+            boolean missingKeyspace = message.contains( "why:Keyspace" ) && message.contains( "does not exist" );
+
+            if ( !missingKeyspace ) {
+                throw badRequestException;
+            }
+        }
+
+
+        if ( keyspaceDefinition != null ) {
+            return;
+        }
+
+
+        ImmutableMap.Builder<String, Object> strategyOptions = getKeySpaceProps();
+
+
+        ImmutableMap<String, Object> options =
+                ImmutableMap.<String, Object>builder().put( "strategy_class", fig.getStrategyClass() )
+                            .put( "strategy_options", strategyOptions.build() ).build();
+
+
+        keyspace.createKeyspace( options );
+
+        strategyOptions.toString();
+
+        logger.info( "Created keyspace {} with options {}", keyspace.getKeyspaceName(), options.toString() );
+
+        waitForMigration();
+    }
+
+
+    /**
+     * Get keyspace properties
+     */
+    private ImmutableMap.Builder<String, Object> getKeySpaceProps() {
+        ImmutableMap.Builder<String, Object> keyspaceProps = ImmutableMap.<String, Object>builder();
+
+        String optionString = fig.getStrategyOptions();
+
+        if(optionString == null){
+            return keyspaceProps;
+        }
+
+
+
+        for ( String key : optionString.split( "," ) ) {
+
+            final String[] options = key.split( ":" );
+
+            keyspaceProps.put( options[0], options[1] );
+        }
+
+        return keyspaceProps;
+    }
+
+
+    private void waitForMigration() throws ConnectionException {
+
+        while ( true ) {
+
+            final Map<String, List<String>> versions = keyspace.describeSchemaVersions();
+
+            if ( versions != null && versions.size() == 1 ) {
+                return;
+            }
+
+            //sleep and try it again
+            try {
+                Thread.sleep( 100 );
+            }
+            catch ( InterruptedException e ) {
+                //swallow
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/MigrationManagerRule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/MigrationManagerRule.java b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/MigrationManagerRule.java
index 3b3a45f..522af61 100644
--- a/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/MigrationManagerRule.java
+++ b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/MigrationManagerRule.java
@@ -5,8 +5,8 @@ import org.junit.rules.ExternalResource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.apache.usergrid.persistence.core.migration.MigrationException;
-import org.apache.usergrid.persistence.core.migration.MigrationManager;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManager;
 
 import com.google.inject.Inject;
 import com.google.inject.Singleton;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestCommonModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestCommonModule.java b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestCommonModule.java
new file mode 100644
index 0000000..04f1d47
--- /dev/null
+++ b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestCommonModule.java
@@ -0,0 +1,34 @@
+/*
+ *
+ *  * 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.
+ *
+ */
+
+package org.apache.usergrid.persistence.core.guice;
+
+
+/**
+ * Module for testing common frameworks
+ */
+public class TestCommonModule extends TestModule {
+
+    @Override
+    protected void configure() {
+        install(new CommonModule());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestModule.java b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestModule.java
new file mode 100644
index 0000000..9b175da
--- /dev/null
+++ b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestModule.java
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+package org.apache.usergrid.persistence.core.guice;
+
+
+import java.io.IOException;
+
+import com.google.inject.AbstractModule;
+import com.netflix.config.ConfigurationManager;
+
+
+public abstract class TestModule extends AbstractModule {
+    static {
+      /*
+       * --------------------------------------------------------------------
+       * Bootstrap the config for Archaius Configuration Settings.  We don't want to
+       * bootstrap more than once per JVM
+       * --------------------------------------------------------------------
+       */
+
+        try {
+            //load up the properties
+            ConfigurationManager.getDeploymentContext().setDeploymentEnvironment( "UNIT" );
+            ConfigurationManager.loadCascadedPropertiesFromResources( "usergrid" );
+
+        }
+        catch ( IOException e ) {
+            throw new RuntimeException( "Cannot do much without properly loading our configuration.", e );
+        }
+    }
+}