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:40 UTC

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

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 );
+        }
+    }
+}