You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by gr...@apache.org on 2015/03/19 23:20:20 UTC

[30/50] [abbrv] incubator-usergrid git commit: Refactored plugins to allow a "bootstrap" system plugin.

Refactored plugins to allow a "bootstrap" system plugin.

Also added phase configuration for plugins, so if they require root configuration, it can be implemented.


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

Branch: refs/heads/USERGRID-493
Commit: 275e74a5b83b36ee0b75f5f2fc6d6f21faeb7e82
Parents: 4ee788d
Author: Todd Nine <tn...@apigee.com>
Authored: Thu Mar 5 21:03:10 2015 -0700
Committer: Todd Nine <tn...@apigee.com>
Committed: Thu Mar 5 21:03:10 2015 -0700

----------------------------------------------------------------------
 stack/core/pom.xml                              |  10 +
 .../usergrid/corepersistence/CoreModule.java    |  10 +-
 .../migration/CoreDataVersions.java             |   3 +-
 .../migration/CoreMigrationPlugin.java          |   5 +
 .../migration/EntityTypeMappingMigration.java   |   2 +-
 .../migration/MigrationModuleVersion.java       | 112 --------
 .../migration/MigrationModuleVersionPlugin.java | 136 ++++++++++
 .../migration/MigrationSystemVersions.java      |  43 +++
 .../MigrationModuleVersionPluginTest.java       | 259 +++++++++++++++++++
 .../migration/CollectionMigrationPlugin.java    |   5 +
 .../data/DataMigrationManagerImpl.java          |  49 +++-
 .../core/migration/data/MigrationPlugin.java    |   7 +-
 .../core/migration/data/PluginPhase.java        |  42 +++
 .../data/DataMigrationManagerImplTest.java      | 119 ++++++---
 .../impl/migration/GraphMigrationPlugin.java    |   7 +
 15 files changed, 648 insertions(+), 161 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/275e74a5/stack/core/pom.xml
----------------------------------------------------------------------
diff --git a/stack/core/pom.xml b/stack/core/pom.xml
index d30bedb..23a0618 100644
--- a/stack/core/pom.xml
+++ b/stack/core/pom.xml
@@ -423,6 +423,15 @@
       <scope>test</scope>
     </dependency>
 
+
+       <dependency>
+        <groupId>org.apache.usergrid</groupId>
+        <artifactId>common</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+        <type>test-jar</type>
+           <scope>test</scope>
+       </dependency>
+
     <!-- Core Persistence deps -->
     <dependency>
 	    <groupId>org.apache.usergrid</groupId>
@@ -441,6 +450,7 @@
       </exclusions>
     </dependency>
 
+
     <dependency>
 	    <groupId>org.apache.usergrid</groupId>
 	    <artifactId>queryindex</artifactId>

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/275e74a5/stack/core/src/main/java/org/apache/usergrid/corepersistence/CoreModule.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CoreModule.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CoreModule.java
index 62be6cf..cf927ce 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CoreModule.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CoreModule.java
@@ -24,7 +24,7 @@ import org.apache.usergrid.corepersistence.events.EntityVersionDeletedHandler;
 import org.apache.usergrid.corepersistence.migration.CoreMigration;
 import org.apache.usergrid.corepersistence.migration.CoreMigrationPlugin;
 import org.apache.usergrid.corepersistence.migration.EntityTypeMappingMigration;
-import org.apache.usergrid.corepersistence.migration.MigrationModuleVersion;
+import org.apache.usergrid.corepersistence.migration.MigrationModuleVersionPlugin;
 import org.apache.usergrid.corepersistence.rx.impl.AllEntitiesInSystemImpl;
 import org.apache.usergrid.corepersistence.rx.impl.AllNodesInGraphImpl;
 import org.apache.usergrid.corepersistence.rx.impl.AllApplicationsObservableImpl;
@@ -34,7 +34,6 @@ import org.apache.usergrid.persistence.collection.event.EntityVersionCreated;
 import org.apache.usergrid.persistence.collection.event.EntityVersionDeleted;
 import org.apache.usergrid.persistence.collection.guice.CollectionModule;
 import org.apache.usergrid.persistence.collection.serialization.impl.migration.EntityIdScope;
-import org.apache.usergrid.persistence.collection.serialization.impl.migration.MvccEntityDataMigrationImpl;
 import org.apache.usergrid.persistence.core.guice.CommonModule;
 import org.apache.usergrid.persistence.core.migration.data.DataMigration;
 import org.apache.usergrid.persistence.core.migration.data.MigrationDataProvider;
@@ -128,13 +127,14 @@ public class CoreModule  extends AbstractModule {
 
 
         dataMigrationMultibinder.addBinding().to( EntityTypeMappingMigration.class );
-        dataMigrationMultibinder.addBinding().to( MigrationModuleVersion.class );
 
 
         //wire up the collection migration plugin
-        Multibinder.newSetBinder( binder(), MigrationPlugin.class ).addBinding().to( CoreMigrationPlugin.class );
+        final Multibinder<MigrationPlugin> plugins = Multibinder.newSetBinder( binder(), MigrationPlugin.class );
+        plugins.addBinding().to( CoreMigrationPlugin.class );
+        plugins.addBinding().to(MigrationModuleVersionPlugin.class );
 
-        bind(AllApplicationsObservable.class).to(AllApplicationsObservableImpl.class);
+        bind( AllApplicationsObservable.class).to(AllApplicationsObservableImpl.class);
 
 
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/275e74a5/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/CoreDataVersions.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/CoreDataVersions.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/CoreDataVersions.java
index 58ba6a3..94ff88c 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/CoreDataVersions.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/CoreDataVersions.java
@@ -28,8 +28,7 @@ public enum CoreDataVersions {
     //up to date so that our new migration module can proceed.
 
     INITIAL(0),
-    MIGRATION_VERSION_FIX(1),
-    ID_MAP_FIX(2);
+    ID_MAP_FIX(1);
 
 
     private final int version;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/275e74a5/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/CoreMigrationPlugin.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/CoreMigrationPlugin.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/CoreMigrationPlugin.java
index 91c1570..58233e0 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/CoreMigrationPlugin.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/CoreMigrationPlugin.java
@@ -27,6 +27,7 @@ import org.apache.usergrid.persistence.core.migration.data.MigrationInfoSerializ
 import org.apache.usergrid.persistence.core.migration.data.AbstractMigrationPlugin;
 import org.apache.usergrid.persistence.core.migration.data.DataMigration;
 import org.apache.usergrid.persistence.core.migration.data.MigrationDataProvider;
+import org.apache.usergrid.persistence.core.migration.data.PluginPhase;
 
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
@@ -56,4 +57,8 @@ public class CoreMigrationPlugin extends AbstractMigrationPlugin<EntityIdScope>
     }
 
 
+    @Override
+    public PluginPhase getPhase() {
+        return PluginPhase.MIGRATE;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/275e74a5/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/EntityTypeMappingMigration.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/EntityTypeMappingMigration.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/EntityTypeMappingMigration.java
index 1a5ef13..ad50c18 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/EntityTypeMappingMigration.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/EntityTypeMappingMigration.java
@@ -99,7 +99,7 @@ public class EntityTypeMappingMigration implements DataMigration<EntityIdScope>
     @Override
     public boolean supports( final int currentVersion ) {
         //we move from the migration version fix to the current version
-        return CoreDataVersions.MIGRATION_VERSION_FIX.getVersion() == currentVersion;
+        return CoreDataVersions.INITIAL.getVersion() == currentVersion;
     }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/275e74a5/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/MigrationModuleVersion.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/MigrationModuleVersion.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/MigrationModuleVersion.java
deleted file mode 100644
index 9ddc219..0000000
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/MigrationModuleVersion.java
+++ /dev/null
@@ -1,112 +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.corepersistence.migration;
-
-
-import org.apache.usergrid.persistence.collection.serialization.impl.MvccEntitySerializationStrategyV2Impl;
-import org.apache.usergrid.persistence.collection.serialization.impl.migration.CollectionMigrationPlugin;
-import org.apache.usergrid.persistence.collection.serialization.impl.migration.EntityIdScope;
-import org.apache.usergrid.persistence.core.migration.data.MigrationInfoSerialization;
-import org.apache.usergrid.persistence.core.migration.data.DataMigration;
-import org.apache.usergrid.persistence.core.migration.data.MigrationDataProvider;
-import org.apache.usergrid.persistence.core.migration.data.ProgressObserver;
-import org.apache.usergrid.persistence.graph.serialization.impl.EdgeMetadataSerializationV2Impl;
-import org.apache.usergrid.persistence.graph.serialization.impl.migration.GraphMigrationPlugin;
-
-import com.google.inject.Inject;
-
-
-/**
- * Migration to set our module versions now that we've refactor for sub modules Keeps the EntityIdScope because it won't
- * subscribe to the data provider.
- */
-public class MigrationModuleVersion implements DataMigration<EntityIdScope> {
-
-
-    /**
-     * The migration from 0 -> 1 that re-writes all the entity id's into the map module
-     */
-    private static final int ID_MIGRATION = 1;
-
-    /**
-     * The migration from 1-> 2 that shards our edge meta data
-     */
-    private static final int EDGE_SHARD_MIGRATION = 2;
-
-    /**
-     * The migration from 2-> 3 that fixed the short truncation bug
-     */
-    private static final int ENTITY_V2_MIGRATION = 3;
-
-    private final MigrationInfoSerialization migrationInfoSerialization;
-
-    private final MvccEntitySerializationStrategyV2Impl serializationStrategyV2;
-
-    private final EdgeMetadataSerializationV2Impl edgeMetadataSerializationV2;
-
-
-    @Inject
-    public MigrationModuleVersion( final MigrationInfoSerialization migrationInfoSerialization,
-                                   final MvccEntitySerializationStrategyV2Impl serializationStrategyV2,
-                                   final EdgeMetadataSerializationV2Impl edgeMetadataSerializationV2 ) {
-        this.migrationInfoSerialization = migrationInfoSerialization;
-        this.serializationStrategyV2 = serializationStrategyV2;
-        this.edgeMetadataSerializationV2 = edgeMetadataSerializationV2;
-    }
-
-
-    @Override
-    public int migrate( final int currentVersion, final MigrationDataProvider<EntityIdScope> migrationDataProvider,
-                        final ProgressObserver observer ) {
-
-        //we ignore our current version, since it will always be 0
-        final int legacyVersion = migrationInfoSerialization.getSystemVersion();
-
-        //now we store versions for each of our modules
-
-        switch ( legacyVersion ) {
-            case ID_MIGRATION:
-                //no op, we need to migration everything in all modules
-                break;
-            //we need to set the version of the entity data, and our edge shard migration.  The fall through (no break) is deliberate
-            case ENTITY_V2_MIGRATION:
-               migrationInfoSerialization.setVersion( CollectionMigrationPlugin.PLUGIN_NAME, serializationStrategyV2.getImplementationVersion() );
-            case EDGE_SHARD_MIGRATION:
-                //set our shard migration to the migrated version
-                migrationInfoSerialization.setVersion( GraphMigrationPlugin.PLUGIN_NAME, edgeMetadataSerializationV2.getImplementationVersion() );
-                break;
-        }
-
-        return CoreDataVersions.MIGRATION_VERSION_FIX.getVersion();
-    }
-
-
-    @Override
-    public boolean supports( final int currentVersion ) {
-        //we move from the migration version fix to the current version
-        return CoreDataVersions.INITIAL.getVersion() == currentVersion;
-    }
-
-
-    @Override
-    public int getMaxVersion() {
-        return CoreDataVersions.MIGRATION_VERSION_FIX.getVersion();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/275e74a5/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/MigrationModuleVersionPlugin.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/MigrationModuleVersionPlugin.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/MigrationModuleVersionPlugin.java
new file mode 100644
index 0000000..e548410
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/MigrationModuleVersionPlugin.java
@@ -0,0 +1,136 @@
+/*
+ * 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.corepersistence.migration;
+
+
+import org.apache.usergrid.persistence.collection.serialization.impl.MvccEntitySerializationStrategyV2Impl;
+import org.apache.usergrid.persistence.collection.serialization.impl.migration.CollectionMigrationPlugin;
+import org.apache.usergrid.persistence.collection.serialization.impl.migration.EntityIdScope;
+import org.apache.usergrid.persistence.core.migration.data.MigrationInfoSerialization;
+import org.apache.usergrid.persistence.core.migration.data.DataMigration;
+import org.apache.usergrid.persistence.core.migration.data.MigrationDataProvider;
+import org.apache.usergrid.persistence.core.migration.data.MigrationPlugin;
+import org.apache.usergrid.persistence.core.migration.data.PluginPhase;
+import org.apache.usergrid.persistence.core.migration.data.ProgressObserver;
+import org.apache.usergrid.persistence.graph.serialization.impl.EdgeMetadataSerializationV2Impl;
+import org.apache.usergrid.persistence.graph.serialization.impl.migration.GraphMigrationPlugin;
+
+import com.google.inject.Inject;
+
+
+/**
+ * Migration to set our module versions now that we've refactor for sub modules Keeps the EntityIdScope because it won't
+ * subscribe to the data provider.
+ */
+public class MigrationModuleVersionPlugin implements MigrationPlugin{
+
+    public static final String NAME = "migration-system";
+
+    private static final int INITIAL = 0;
+    /**
+     * The migration from 0 -> 1 that re-writes all the entity id's into the map module
+     */
+    private static final int ID_MIGRATION = 1;
+
+    /**
+     * The migration from 1-> 2 that shards our edge meta data
+     */
+    private static final int EDGE_SHARD_MIGRATION = 2;
+
+    /**
+     * The migration from 2-> 3 that fixed the short truncation bug
+     */
+    private static final int ENTITY_V2_MIGRATION = 3;
+
+
+    /**
+     * Get versions directly from impls so we know they're accurate
+     */
+    private final MigrationInfoSerialization migrationInfoSerialization;
+
+    private final MvccEntitySerializationStrategyV2Impl serializationStrategyV2;
+
+    private final EdgeMetadataSerializationV2Impl edgeMetadataSerializationV2;
+
+
+    @Inject
+    public MigrationModuleVersionPlugin( final MigrationInfoSerialization migrationInfoSerialization,
+                                         final MvccEntitySerializationStrategyV2Impl serializationStrategyV2,
+                                         final EdgeMetadataSerializationV2Impl edgeMetadataSerializationV2 ) {
+        this.migrationInfoSerialization = migrationInfoSerialization;
+        this.serializationStrategyV2 = serializationStrategyV2;
+        this.edgeMetadataSerializationV2 = edgeMetadataSerializationV2;
+    }
+
+    @Override
+      public void run( final ProgressObserver observer ) {
+
+
+        observer.start();
+
+        //we ignore our current version, since it will always be 0
+        final int legacyVersion = migrationInfoSerialization.getSystemVersion();
+
+
+
+        //now we store versions for each of our modules
+
+        switch ( legacyVersion ) {
+            //we need to set the version of the entity data, and our edge shard migration.  The fall through (no break) is deliberate
+            //if it's initial, set both
+            case INITIAL:
+               //if it's entity v2, set all, it's current
+            case ENTITY_V2_MIGRATION:
+               migrationInfoSerialization.setVersion( CollectionMigrationPlugin.PLUGIN_NAME, serializationStrategyV2.getImplementationVersion() );
+                //if it's edge shard, we need to run the v2 migration
+            case EDGE_SHARD_MIGRATION:
+                //set our shard migration to the migrated version
+                migrationInfoSerialization.setVersion( GraphMigrationPlugin.PLUGIN_NAME, edgeMetadataSerializationV2.getImplementationVersion() );
+            case ID_MIGRATION:
+                migrationInfoSerialization.setVersion( CoreMigrationPlugin.PLUGIN_NAME, CoreDataVersions.ID_MAP_FIX.getVersion() );
+        }
+
+        //save the version
+        migrationInfoSerialization.setVersion( NAME, getMaxVersion() );
+
+        observer.stop();
+      }
+
+
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
+
+
+
+    @Override
+    public int getMaxVersion() {
+        return MigrationSystemVersions.LEGACY_ID_MAPPED.getVersion();
+    }
+
+
+    @Override
+    public PluginPhase getPhase() {
+        return PluginPhase.BOOTSTRAP;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/275e74a5/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/MigrationSystemVersions.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/MigrationSystemVersions.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/MigrationSystemVersions.java
new file mode 100644
index 0000000..8b96541
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/MigrationSystemVersions.java
@@ -0,0 +1,43 @@
+/*
+ * 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.corepersistence.migration;
+
+
+/**
+ * Versions of data as they exist across our system
+ */
+public enum MigrationSystemVersions {
+     //even though this didn't really come first in time, we need to run this first in order to bring our system
+    //up to date so that our new migration module can proceed.
+
+    INITIAL(0),
+    LEGACY_ID_MAPPED(1);
+
+
+    private final int version;
+
+
+    private MigrationSystemVersions( final int version ) {this.version = version;}
+
+
+    public int getVersion() {
+        return version;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/275e74a5/stack/core/src/test/java/org/apache/usergrid/corepersistence/migration/MigrationModuleVersionPluginTest.java
----------------------------------------------------------------------
diff --git a/stack/core/src/test/java/org/apache/usergrid/corepersistence/migration/MigrationModuleVersionPluginTest.java b/stack/core/src/test/java/org/apache/usergrid/corepersistence/migration/MigrationModuleVersionPluginTest.java
new file mode 100644
index 0000000..657bd16
--- /dev/null
+++ b/stack/core/src/test/java/org/apache/usergrid/corepersistence/migration/MigrationModuleVersionPluginTest.java
@@ -0,0 +1,259 @@
+/*
+ * 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.corepersistence.migration;
+
+
+import org.junit.Test;
+
+import org.apache.usergrid.persistence.collection.serialization.MvccEntitySerializationStrategy;
+import org.apache.usergrid.persistence.collection.serialization.impl.MvccEntitySerializationStrategyV2Impl;
+import org.apache.usergrid.persistence.collection.serialization.impl.migration.CollectionMigrationPlugin;
+import org.apache.usergrid.persistence.core.migration.data.MigrationInfoSerialization;
+import org.apache.usergrid.persistence.core.migration.data.TestProgressObserver;
+import org.apache.usergrid.persistence.graph.serialization.EdgeMetadataSerialization;
+import org.apache.usergrid.persistence.graph.serialization.impl.EdgeMetadataSerializationV2Impl;
+import org.apache.usergrid.persistence.graph.serialization.impl.migration.GraphMigrationPlugin;
+
+import com.google.inject.Inject;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+
+/**
+ * Tests the system sets itself up as wxpected
+ */
+public class MigrationModuleVersionPluginTest {
+
+
+    @Test
+    public void testNewSystem(){
+
+        //mock up an initial system state
+        final int systemState = 0;
+
+        final MigrationInfoSerialization migrationInfoSerialization = mock(MigrationInfoSerialization.class);
+
+        when(migrationInfoSerialization.getSystemVersion()).thenReturn( systemState );
+
+
+
+
+        final int mvccVersion = 2;
+
+        final MvccEntitySerializationStrategyV2Impl serializationStrategyV2 = mock(MvccEntitySerializationStrategyV2Impl.class);
+        when(serializationStrategyV2.getImplementationVersion()).thenReturn( mvccVersion );
+
+
+        final int edgeMetaVersion = 1;
+
+        final EdgeMetadataSerializationV2Impl edgeMetadataSerializationV2 = mock(EdgeMetadataSerializationV2Impl.class);
+        when(edgeMetadataSerializationV2.getImplementationVersion()).thenReturn(edgeMetaVersion);
+
+
+        final MigrationModuleVersionPlugin plugin = new MigrationModuleVersionPlugin(migrationInfoSerialization, serializationStrategyV2,  edgeMetadataSerializationV2 );
+
+        final TestProgressObserver testProgressObserver = new TestProgressObserver();
+
+        plugin.run( testProgressObserver );
+
+
+
+        //first version that should be set
+        verify(migrationInfoSerialization).setVersion( CoreMigrationPlugin.PLUGIN_NAME, CoreDataVersions.ID_MAP_FIX.getVersion() );
+
+        //second version that should be set
+
+        verify(migrationInfoSerialization).setVersion( GraphMigrationPlugin.PLUGIN_NAME, edgeMetaVersion );
+
+        //last version that should be set
+        verify(migrationInfoSerialization).setVersion( CollectionMigrationPlugin.PLUGIN_NAME, mvccVersion );
+
+
+        //set this plugin as run
+        verify(migrationInfoSerialization).setVersion( MigrationModuleVersionPlugin.NAME, MigrationSystemVersions.LEGACY_ID_MAPPED.getVersion() );
+
+
+
+    }
+
+
+
+    @Test
+    public void testIdMapping(){
+
+           //mock up an initial system state
+        final int systemState = 1;
+
+        final MigrationInfoSerialization migrationInfoSerialization = mock(MigrationInfoSerialization.class);
+
+        when(migrationInfoSerialization.getSystemVersion()).thenReturn( systemState );
+
+
+
+
+        final int mvccVersion = 2;
+
+        final MvccEntitySerializationStrategyV2Impl serializationStrategyV2 = mock(MvccEntitySerializationStrategyV2Impl.class);
+        when(serializationStrategyV2.getImplementationVersion()).thenReturn( mvccVersion );
+
+
+        final int edgeMetaVersion = 1;
+
+        final EdgeMetadataSerializationV2Impl edgeMetadataSerializationV2 = mock(EdgeMetadataSerializationV2Impl.class);
+        when(edgeMetadataSerializationV2.getImplementationVersion()).thenReturn(edgeMetaVersion);
+
+
+        final MigrationModuleVersionPlugin plugin = new MigrationModuleVersionPlugin(migrationInfoSerialization, serializationStrategyV2,  edgeMetadataSerializationV2 );
+
+        final TestProgressObserver testProgressObserver = new TestProgressObserver();
+
+        plugin.run( testProgressObserver );
+
+
+        //first version that should be set
+        verify(migrationInfoSerialization).setVersion( CoreMigrationPlugin.PLUGIN_NAME, CoreDataVersions.ID_MAP_FIX.getVersion() );
+
+        //second version that should be set
+
+        verify(migrationInfoSerialization, never()).setVersion( GraphMigrationPlugin.PLUGIN_NAME, edgeMetaVersion );
+
+        //last version that should be set
+        verify(migrationInfoSerialization, never()).setVersion( CollectionMigrationPlugin.PLUGIN_NAME, mvccVersion );
+
+
+        //set this plugin as run
+        verify(migrationInfoSerialization).setVersion( MigrationModuleVersionPlugin.NAME, MigrationSystemVersions.LEGACY_ID_MAPPED.getVersion() );
+
+
+
+
+    }
+
+
+    @Test
+    public void testEdgeMigration(){
+
+           //mock up an initial system state
+        final int systemState = 2;
+
+        final MigrationInfoSerialization migrationInfoSerialization = mock(MigrationInfoSerialization.class);
+
+        when(migrationInfoSerialization.getSystemVersion()).thenReturn( systemState );
+
+
+
+
+        final int mvccVersion = 2;
+
+        final MvccEntitySerializationStrategyV2Impl serializationStrategyV2 = mock(MvccEntitySerializationStrategyV2Impl.class);
+        when(serializationStrategyV2.getImplementationVersion()).thenReturn( mvccVersion );
+
+
+        final int edgeMetaVersion = 1;
+
+        final EdgeMetadataSerializationV2Impl edgeMetadataSerializationV2 = mock(EdgeMetadataSerializationV2Impl.class);
+        when(edgeMetadataSerializationV2.getImplementationVersion()).thenReturn(edgeMetaVersion);
+
+
+        final MigrationModuleVersionPlugin plugin = new MigrationModuleVersionPlugin(migrationInfoSerialization, serializationStrategyV2,  edgeMetadataSerializationV2 );
+
+        final TestProgressObserver testProgressObserver = new TestProgressObserver();
+
+        plugin.run( testProgressObserver );
+
+
+        //first version that should be set
+        verify(migrationInfoSerialization).setVersion( CoreMigrationPlugin.PLUGIN_NAME, CoreDataVersions.ID_MAP_FIX.getVersion() );
+
+        //second version that should be set
+
+        verify(migrationInfoSerialization).setVersion( GraphMigrationPlugin.PLUGIN_NAME, edgeMetaVersion );
+
+        //last version that should be set
+        verify(migrationInfoSerialization, never()).setVersion( CollectionMigrationPlugin.PLUGIN_NAME, mvccVersion );
+
+
+        //set this plugin as run
+        verify(migrationInfoSerialization).setVersion( MigrationModuleVersionPlugin.NAME, MigrationSystemVersions.LEGACY_ID_MAPPED.getVersion() );
+
+
+
+
+    }
+
+
+
+
+    @Test
+    public void testEntityV2Migration(){
+
+           //mock up an initial system state
+        final int systemState = 3;
+
+        final MigrationInfoSerialization migrationInfoSerialization = mock(MigrationInfoSerialization.class);
+
+        when(migrationInfoSerialization.getSystemVersion()).thenReturn( systemState );
+
+
+
+
+        final int mvccVersion = 2;
+
+        final MvccEntitySerializationStrategyV2Impl serializationStrategyV2 = mock(MvccEntitySerializationStrategyV2Impl.class);
+        when(serializationStrategyV2.getImplementationVersion()).thenReturn( mvccVersion );
+
+
+        final int edgeMetaVersion = 1;
+
+        final EdgeMetadataSerializationV2Impl edgeMetadataSerializationV2 = mock(EdgeMetadataSerializationV2Impl.class);
+        when(edgeMetadataSerializationV2.getImplementationVersion()).thenReturn(edgeMetaVersion);
+
+
+        final MigrationModuleVersionPlugin plugin = new MigrationModuleVersionPlugin(migrationInfoSerialization, serializationStrategyV2,  edgeMetadataSerializationV2 );
+
+        final TestProgressObserver testProgressObserver = new TestProgressObserver();
+
+        plugin.run( testProgressObserver );
+
+
+        //first version that should be set
+        verify(migrationInfoSerialization).setVersion( CoreMigrationPlugin.PLUGIN_NAME, CoreDataVersions.ID_MAP_FIX.getVersion() );
+
+        //second version that should be set
+
+        verify(migrationInfoSerialization).setVersion( GraphMigrationPlugin.PLUGIN_NAME, edgeMetaVersion );
+
+        //last version that should be set
+        verify(migrationInfoSerialization).setVersion( CollectionMigrationPlugin.PLUGIN_NAME, mvccVersion );
+
+
+        //set this plugin as run
+        verify(migrationInfoSerialization).setVersion( MigrationModuleVersionPlugin.NAME, MigrationSystemVersions.LEGACY_ID_MAPPED.getVersion() );
+
+
+
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/275e74a5/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/migration/CollectionMigrationPlugin.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/migration/CollectionMigrationPlugin.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/migration/CollectionMigrationPlugin.java
index 55e42ff..3f83c66 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/migration/CollectionMigrationPlugin.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/migration/CollectionMigrationPlugin.java
@@ -30,6 +30,7 @@ import org.apache.usergrid.persistence.core.migration.data.MigrationInfoSerializ
 import org.apache.usergrid.persistence.core.migration.data.AbstractMigrationPlugin;
 import org.apache.usergrid.persistence.core.migration.data.DataMigration;
 import org.apache.usergrid.persistence.core.migration.data.MigrationDataProvider;
+import org.apache.usergrid.persistence.core.migration.data.PluginPhase;
 
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
@@ -60,4 +61,8 @@ public class CollectionMigrationPlugin extends AbstractMigrationPlugin<EntityIdS
     }
 
 
+    @Override
+    public PluginPhase getPhase() {
+        return PluginPhase.MIGRATE;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/275e74a5/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 7b97e8e..3f763a2 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
@@ -21,7 +21,11 @@ package org.apache.usergrid.persistence.core.migration.data;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -40,7 +44,9 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
 
     private static final Logger LOG = LoggerFactory.getLogger( DataMigrationManagerImpl.class );
 
-    private final Map<String, MigrationPlugin> migrationPlugins = new HashMap<>();
+    private final Map<String, MigrationPlugin> migrationPlugins;
+
+    private final List<MigrationPlugin> executionOrder;
 
     private final MigrationInfoSerialization migrationInfoSerialization;
 
@@ -50,12 +56,17 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
     public DataMigrationManagerImpl( final Set<MigrationPlugin> plugins,
                                      final MigrationInfoSerialization migrationInfoSerialization ) {
 
+
         Preconditions.checkNotNull( plugins, "plugins must not be null" );
         Preconditions.checkNotNull( migrationInfoSerialization, "migrationInfoSerialization must not be null" );
 
         this.migrationInfoSerialization = migrationInfoSerialization;
 
 
+        this.executionOrder = new ArrayList<>(plugins.size());
+        this.migrationPlugins = new HashMap<>();
+
+
         for ( MigrationPlugin plugin : plugins ) {
             final String name = plugin.getName();
 
@@ -68,8 +79,16 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
                         .getClass().getName() + "' is also trying to implement this name." );
             }
 
-            migrationPlugins.put( name, plugin );
+            this.migrationPlugins.put( name, plugin );
+            this.executionOrder.add( plugin );
+
         }
+
+        //now sort based on execution order
+
+        Collections.sort(executionOrder, MigrationPluginComparator.INSTANCE);
+
+
     }
 
 
@@ -79,12 +98,10 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
         /**
          * Invoke each plugin to attempt a migration
          */
-        for(final MigrationPlugin plugin: migrationPlugins.values()){
+        for(final MigrationPlugin plugin: executionOrder){
             final ProgressObserver observer = new CassandraProgressObserver(plugin.getName());
 
             plugin.run( observer );
-
-
         }
 
 
@@ -236,4 +253,26 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
             return failed;
         }
     }
+
+    private final static class MigrationPluginComparator implements Comparator<MigrationPlugin> {
+
+        public static  final MigrationPluginComparator INSTANCE = new MigrationPluginComparator();
+
+        @Override
+        public int compare( final MigrationPlugin o1, final MigrationPlugin o2 ) {
+
+            //first one is less
+            if(o1.getPhase().ordinal() < o2.getPhase().ordinal()){
+                return -1;
+            }
+
+            //second one is first
+            if(o2.getPhase().ordinal() < o2.getPhase().ordinal()){
+                return 1;
+            }
+
+            //if our phase for
+            return o1.getName().compareTo( o2.getName() );
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/275e74a5/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationPlugin.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationPlugin.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationPlugin.java
index 897ce27..4953f25 100644
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationPlugin.java
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationPlugin.java
@@ -24,7 +24,6 @@
 package org.apache.usergrid.persistence.core.migration.data;
 
 
-
 /**
  * A simple interface to return migration plugins.  All versions within this migration plugin should have a name
  */
@@ -48,4 +47,10 @@ public interface MigrationPlugin {
      * @return
      */
     int getMaxVersion();
+
+    /**
+     * Get the phase of the plugin
+     * @return
+     */
+    PluginPhase getPhase();
 }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/275e74a5/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/PluginPhase.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/PluginPhase.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/PluginPhase.java
new file mode 100644
index 0000000..186ecae
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/PluginPhase.java
@@ -0,0 +1,42 @@
+/*
+ * 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;
+
+
+/**
+ * This is the plugin lifeccyle where plugins should be executed.  Plugins are executed in the following order
+ *
+ *
+ */
+public enum PluginPhase {
+
+    /**
+     * Runs before any data migration.  This is used to prepare our migration subsystem.
+     * For instance, a change in the migration system itself.  Most plugins won't need to use this
+     */
+    BOOTSTRAP,
+
+    /**
+     * This is where data migration actually happens.  Plugins should be able to run concurrently.
+     * If a plugin has a race condition with another plugin, they should be refactored into a single plugin,
+     * with migration versions encapsulated within the plugin itself
+     */
+    MIGRATE
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/275e74a5/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
index 5d516d4..453958e 100644
--- 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
@@ -21,14 +21,19 @@ package org.apache.usergrid.persistence.core.migration.data;
 
 
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.Set;
 
 import org.junit.Test;
+import org.mockito.InOrder;
 
 import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -38,11 +43,11 @@ public class DataMigrationManagerImplTest {
 
 
     @Test
-    public void testNoPlugins(){
+    public void testNoPlugins() {
 
-        final Set<MigrationPlugin> plugins = new HashSet<>(  );
+        final Set<MigrationPlugin> plugins = new HashSet<>();
 
-        final  MigrationInfoSerialization migrationInfoSerialization = mock(MigrationInfoSerialization.class);
+        final MigrationInfoSerialization migrationInfoSerialization = mock( MigrationInfoSerialization.class );
 
 
         DataMigrationManagerImpl migrationManager = new DataMigrationManagerImpl( plugins, migrationInfoSerialization );
@@ -50,31 +55,30 @@ public class DataMigrationManagerImplTest {
 
         Set<String> pluginNames = migrationManager.getPluginNames();
 
-        assertEquals(0, pluginNames.size());
-
+        assertEquals( 0, pluginNames.size() );
     }
 
 
-
     @Test
     public void test2Plugins() throws MigrationException {
 
-        final Set<MigrationPlugin> plugins = new HashSet<>(  );
+        final Set<MigrationPlugin> plugins = new HashSet<>();
 
-        MigrationPlugin plugin1 = mock(MigrationPlugin.class);
+        MigrationPlugin plugin1 = mock( MigrationPlugin.class );
+        when( plugin1.getPhase() ).thenReturn( PluginPhase.MIGRATE );
 
-        when(plugin1.getName()).thenReturn("plugin1");
+        when( plugin1.getName() ).thenReturn( "plugin1" );
 
-        MigrationPlugin plugin2 = mock(MigrationPlugin.class);
+        MigrationPlugin plugin2 = mock( MigrationPlugin.class );
+        when( plugin2.getPhase() ).thenReturn( PluginPhase.MIGRATE );
 
-        when(plugin2.getName()).thenReturn("plugin2");
+        when( plugin2.getName() ).thenReturn( "plugin2" );
 
         plugins.add( plugin1 );
         plugins.add( plugin2 );
 
 
-
-        final  MigrationInfoSerialization migrationInfoSerialization = mock(MigrationInfoSerialization.class);
+        final MigrationInfoSerialization migrationInfoSerialization = mock( MigrationInfoSerialization.class );
 
 
         DataMigrationManagerImpl migrationManager = new DataMigrationManagerImpl( plugins, migrationInfoSerialization );
@@ -82,43 +86,39 @@ public class DataMigrationManagerImplTest {
 
         Set<String> pluginNames = migrationManager.getPluginNames();
 
-        assertEquals(2, pluginNames.size());
+        assertEquals( 2, pluginNames.size() );
 
-        assertTrue(pluginNames.contains( "plugin1"));
+        assertTrue( pluginNames.contains( "plugin1" ) );
 
-        assertTrue(pluginNames.contains( "plugin2" ));
+        assertTrue( pluginNames.contains( "plugin2" ) );
 
         //now run them
 
         migrationManager.migrate();
 
-        verify(plugin1).run( any(ProgressObserver.class) );
-
-        verify(plugin2).run( any(ProgressObserver.class) );
+        verify( plugin1 ).run( any( ProgressObserver.class ) );
 
+        verify( plugin2 ).run( any( ProgressObserver.class ) );
     }
 
 
-
-
     @Test
     public void testRunning() throws MigrationException {
 
-        final Set<MigrationPlugin> plugins = new HashSet<>(  );
+        final Set<MigrationPlugin> plugins = new HashSet<>();
 
-        MigrationPlugin plugin1 = mock(MigrationPlugin.class);
+        MigrationPlugin plugin1 = mock( MigrationPlugin.class );
 
-        when(plugin1.getName()).thenReturn("plugin1");
+        when( plugin1.getName() ).thenReturn( "plugin1" );
+        when( plugin1.getPhase() ).thenReturn( PluginPhase.MIGRATE );
 
         plugins.add( plugin1 );
 
 
+        final MigrationInfoSerialization migrationInfoSerialization = mock( MigrationInfoSerialization.class );
 
-        final  MigrationInfoSerialization migrationInfoSerialization = mock(MigrationInfoSerialization.class);
-
-        when(migrationInfoSerialization.getStatusCode( "plugin1" )).thenReturn( DataMigrationManagerImpl.StatusCode.RUNNING.status );
-
-
+        when( migrationInfoSerialization.getStatusCode( "plugin1" ) )
+            .thenReturn( DataMigrationManagerImpl.StatusCode.RUNNING.status );
 
 
         DataMigrationManagerImpl migrationManager = new DataMigrationManagerImpl( plugins, migrationInfoSerialization );
@@ -126,23 +126,72 @@ public class DataMigrationManagerImplTest {
 
         boolean status = migrationManager.isRunning();
 
-        assertTrue("Status is set", status);
+        assertTrue( "Status is set", status );
 
 
-        when(migrationInfoSerialization.getStatusCode( "plugin1" )).thenReturn( DataMigrationManagerImpl.StatusCode.COMPLETE.status );
+        when( migrationInfoSerialization.getStatusCode( "plugin1" ) )
+            .thenReturn( DataMigrationManagerImpl.StatusCode.COMPLETE.status );
 
         status = migrationManager.isRunning();
 
         assertFalse( "Status is not running", status );
 
 
-        when(migrationInfoSerialization.getStatusCode( "plugin1" )).thenReturn( DataMigrationManagerImpl.StatusCode.ERROR.status );
+        when( migrationInfoSerialization.getStatusCode( "plugin1" ) )
+            .thenReturn( DataMigrationManagerImpl.StatusCode.ERROR.status );
 
-       status = migrationManager.isRunning();
+        status = migrationManager.isRunning();
 
-       assertFalse("Status is not running", status);
+        assertFalse( "Status is not running", status );
     }
 
 
+    @Test
+    public void testExecutionOrder() throws MigrationException {
+
+
+        //linked hash set is intentional here.  For iteration order we can boostrap to come second so we can
+        //verify it was actually run first
+        final Set<MigrationPlugin> plugins = new LinkedHashSet<>();
+
+        MigrationPlugin plugin1 = mock( MigrationPlugin.class );
+        when( plugin1.getPhase() ).thenReturn( PluginPhase.MIGRATE );
 
+        when( plugin1.getName() ).thenReturn( "plugin1" );
+
+        //boostrap plugin, should run first
+        MigrationPlugin plugin2 = mock( MigrationPlugin.class );
+        when( plugin2.getPhase() ).thenReturn( PluginPhase.BOOTSTRAP );
+
+        when( plugin2.getName() ).thenReturn( "plugin2" );
+
+        plugins.add( plugin1 );
+        plugins.add( plugin2 );
+
+
+        final MigrationInfoSerialization migrationInfoSerialization = mock( MigrationInfoSerialization.class );
+
+
+        DataMigrationManagerImpl migrationManager = new DataMigrationManagerImpl( plugins, migrationInfoSerialization );
+
+
+        Set<String> pluginNames = migrationManager.getPluginNames();
+
+        assertEquals( 2, pluginNames.size() );
+
+        assertTrue( pluginNames.contains( "plugin1" ) );
+
+        assertTrue( pluginNames.contains( "plugin2" ) );
+
+        //now run them
+
+        migrationManager.migrate();
+
+
+
+        //we want to verify the bootsrap plugin was called first
+        InOrder inOrderVerification = inOrder( plugin1, plugin2 );
+        inOrderVerification.verify( plugin2 ).run( any( ProgressObserver.class ) );
+        inOrderVerification.verify( plugin1 ).run( any( ProgressObserver.class ) );
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/275e74a5/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/migration/GraphMigrationPlugin.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/migration/GraphMigrationPlugin.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/migration/GraphMigrationPlugin.java
index 8da102d..22f34ff 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/migration/GraphMigrationPlugin.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/migration/GraphMigrationPlugin.java
@@ -30,10 +30,13 @@ import org.apache.usergrid.persistence.core.migration.data.MigrationInfoSerializ
 import org.apache.usergrid.persistence.core.migration.data.AbstractMigrationPlugin;
 import org.apache.usergrid.persistence.core.migration.data.DataMigration;
 import org.apache.usergrid.persistence.core.migration.data.MigrationDataProvider;
+import org.apache.usergrid.persistence.core.migration.data.PluginPhase;
 
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
+import sun.plugin2.main.server.Plugin;
+
 
 /**
  * Migration plugin for the collection module
@@ -60,4 +63,8 @@ public class GraphMigrationPlugin extends AbstractMigrationPlugin<GraphNode> {
     }
 
 
+    @Override
+    public PluginPhase getPhase() {
+        return PluginPhase.MIGRATE;
+    }
 }