You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by sn...@apache.org on 2014/12/08 22:23:52 UTC

[10/50] [abbrv] incubator-usergrid git commit: Migration for new no-source-in-ES Index Mappings.

Migration for new no-source-in-ES Index Mappings.


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

Branch: refs/heads/no-source-in-es
Commit: 7c9ee651f701128336500e0b93dd53d230f3a510
Parents: 967807e
Author: Dave Johnson <dm...@apigee.com>
Authored: Thu Dec 4 11:01:57 2014 -0500
Committer: Dave Johnson <dm...@apigee.com>
Committed: Thu Dec 4 11:01:57 2014 -0500

----------------------------------------------------------------------
 .../usergrid/corepersistence/GuiceModule.java   |  11 +-
 .../ApplyQueryIndexMappingsMigration.java       |  19 ++-
 .../migration/EntityTypeMappingMigration.java   |  45 +++---
 .../corepersistence/migration/Versions.java     |   3 +
 .../migration/EntityDataMigrationIT.java        | 145 ++++++++++---------
 ...vccEntitySerializationStrategyProxyImpl.java |   2 +-
 .../usergrid/persistence/index/EntityIndex.java |   5 +
 .../index/impl/EsEntityIndexImpl.java           |  20 ++-
 8 files changed, 134 insertions(+), 116 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/7c9ee651/stack/core/src/main/java/org/apache/usergrid/corepersistence/GuiceModule.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/GuiceModule.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/GuiceModule.java
index 018a9b7..60ec5da 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/GuiceModule.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/GuiceModule.java
@@ -13,13 +13,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.usergrid.corepersistence;
 
-
 import com.google.inject.AbstractModule;
 import com.google.inject.multibindings.Multibinder;
-
+import org.apache.usergrid.corepersistence.migration.ApplyQueryIndexMappingsMigration;
 import org.apache.usergrid.corepersistence.migration.EntityDataMigration;
 import org.apache.usergrid.corepersistence.migration.EntityTypeMappingMigration;
 import org.apache.usergrid.corepersistence.migration.GraphShardVersionMigration;
@@ -54,12 +52,13 @@ public class GuiceModule  extends AbstractModule {
         bind(CpEntityIndexDeleteListener.class).asEagerSingleton();
         bind(ManagerCache.class).to( CpManagerCache.class );
 
-        Multibinder<DataMigration> dataMigrationMultibinder = Multibinder.newSetBinder( binder(), DataMigration.class );
+        Multibinder<DataMigration> dataMigrationMultibinder = 
+                Multibinder.newSetBinder( binder(), DataMigration.class );
+
         dataMigrationMultibinder.addBinding().to( EntityTypeMappingMigration.class );
         dataMigrationMultibinder.addBinding().to( GraphShardVersionMigration.class );
         dataMigrationMultibinder.addBinding().to( EntityDataMigration.class );
-
-
+        dataMigrationMultibinder.addBinding().to( ApplyQueryIndexMappingsMigration.class );
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/7c9ee651/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/ApplyQueryIndexMappingsMigration.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/ApplyQueryIndexMappingsMigration.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/ApplyQueryIndexMappingsMigration.java
index 782c48e..47afa28 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/ApplyQueryIndexMappingsMigration.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/ApplyQueryIndexMappingsMigration.java
@@ -19,19 +19,14 @@
 
 package org.apache.usergrid.corepersistence.migration;
 
-
 import java.util.concurrent.atomic.AtomicLong;
-
-
 import org.apache.usergrid.corepersistence.ManagerCache;
 import org.apache.usergrid.persistence.core.migration.data.DataMigration;
 import org.apache.usergrid.persistence.model.entity.Id;
-
 import com.google.inject.Inject;
 import org.apache.usergrid.corepersistence.rx.ApplicationObservable;
 import org.apache.usergrid.persistence.core.scope.ApplicationScopeImpl;
 import org.apache.usergrid.persistence.index.EntityIndex;
-
 import rx.functions.Action1;
 
 
@@ -43,6 +38,7 @@ public class ApplyQueryIndexMappingsMigration implements DataMigration {
     
     private final ManagerCache managerCache;
 
+
     @Inject
     public ApplyQueryIndexMappingsMigration( final ManagerCache managerCache) {
        this.managerCache = managerCache;
@@ -51,6 +47,8 @@ public class ApplyQueryIndexMappingsMigration implements DataMigration {
 
     @Override
     public void migrate( final ProgressObserver observer ) throws Throwable {
+        
+        final AtomicLong atomicLong = new AtomicLong();
 
         ApplicationObservable.getAllApplicationIds( managerCache )
             .doOnNext( new Action1<Id>() {
@@ -58,7 +56,12 @@ public class ApplyQueryIndexMappingsMigration implements DataMigration {
                 @Override
                 public void call( final Id appId ) {
                     EntityIndex ei = managerCache.getEntityIndex(new ApplicationScopeImpl( appId ));
-                    ei.initializeIndex();
+                    ei.updateMappings();
+
+                    // update status every 10 applications, there are probably not that many
+                    if ( atomicLong.incrementAndGet() % 10 == 0 ) {
+                        updateStatus( atomicLong, observer );
+                    }
                 }
 
             } ).toBlocking().lastOrDefault( null );
@@ -66,12 +69,12 @@ public class ApplyQueryIndexMappingsMigration implements DataMigration {
 
 
     private void updateStatus( final AtomicLong counter, final ProgressObserver observer ) {
-        observer.update( getVersion(), String.format( "Updated %d entities", counter.get() ) );
+        observer.update( getVersion(), String.format( "Updated %d index mappings", counter.get()));
     }
 
 
     @Override
     public int getVersion() {
-        return Versions.VERSION_1;
+        return Versions.VERSION_4;
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/7c9ee651/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 8089dfd..c89b8e9 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
@@ -19,13 +19,8 @@
 
 package org.apache.usergrid.corepersistence.migration;
 
-
 import java.util.UUID;
 import java.util.concurrent.atomic.AtomicLong;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import org.apache.usergrid.corepersistence.ManagerCache;
 import org.apache.usergrid.corepersistence.rx.AllEntitiesInSystemObservable;
 import org.apache.usergrid.corepersistence.util.CpNamingUtils;
@@ -33,21 +28,18 @@ import org.apache.usergrid.persistence.core.migration.data.DataMigration;
 import org.apache.usergrid.persistence.map.MapManager;
 import org.apache.usergrid.persistence.map.MapScope;
 import org.apache.usergrid.persistence.model.entity.Id;
-
 import com.google.inject.Inject;
-
 import rx.functions.Action1;
 
 
 /**
- * Migration to ensure that our entity id is written into our map data
+ * Migration to ensure that our entity id is written into our map data.
  */
 public class EntityTypeMappingMigration implements DataMigration {
 
     private final ManagerCache managerCache;
 
 
-
     @Inject
     public EntityTypeMappingMigration( final ManagerCache managerCache) {
        this.managerCache = managerCache;
@@ -60,34 +52,33 @@ public class EntityTypeMappingMigration implements DataMigration {
         final AtomicLong atomicLong = new AtomicLong();
 
         AllEntitiesInSystemObservable.getAllEntitiesInSystem(managerCache, 1000 )
-                                     .doOnNext( new Action1<AllEntitiesInSystemObservable.ApplicationEntityGroup>() {
-
+            .doOnNext( new Action1<AllEntitiesInSystemObservable.ApplicationEntityGroup>() {
 
-                                         @Override
-                                         public void call( final AllEntitiesInSystemObservable.ApplicationEntityGroup applicationEntityGroup ) {
+                @Override
+                public void call( final AllEntitiesInSystemObservable.ApplicationEntityGroup aeg ) {
 
-                                             final MapScope ms = CpNamingUtils.getEntityTypeMapScope( applicationEntityGroup.applicationScope.getApplication() );
+                    final MapScope ms = CpNamingUtils.getEntityTypeMapScope(
+                            aeg.applicationScope.getApplication() );
 
+                    final MapManager mapManager = managerCache.getMapManager( ms );
 
-                                             final MapManager mapManager = managerCache.getMapManager( ms );
+                    for(Id entityId: aeg.entityIds) {
+                        final UUID entityUuid = entityId.getUuid();
+                        final String entityType = entityId.getType();
 
-                                             for(Id entityId: applicationEntityGroup.entityIds) {
-                                                 final UUID entityUuid = entityId.getUuid();
-                                                 final String entityType = entityId.getType();
+                        mapManager.putString( entityUuid.toString(), entityType );
 
-                                                 mapManager.putString( entityUuid.toString(), entityType );
-
-                                                 if ( atomicLong.incrementAndGet() % 100 == 0 ) {
-                                                     updateStatus( atomicLong, observer );
-                                                 }
-                                             }
-                                         }
-                                     } ).toBlocking().lastOrDefault( null );
+                        // only update status every 1000 entities, there are probably a lot
+                        if ( atomicLong.incrementAndGet() % 1000 == 0 ) {
+                            updateStatus( atomicLong, observer );
+                        }
+                    }
+                }
+            } ).toBlocking().lastOrDefault( null );
     }
 
 
     private void updateStatus( final AtomicLong counter, final ProgressObserver observer ) {
-
         observer.update( getVersion(), String.format( "Updated %d entities", counter.get() ) );
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/7c9ee651/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/Versions.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/Versions.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/Versions.java
index 99067b7..3dcabd5 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/Versions.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/migration/Versions.java
@@ -24,6 +24,7 @@ package org.apache.usergrid.corepersistence.migration;
 
 import org.apache.usergrid.persistence.collection.serialization.impl.MvccEntitySerializationStrategyProxyImpl;
 import org.apache.usergrid.persistence.graph.serialization.impl.EdgeMetadataSerializationProxyImpl;
+import org.apache.usergrid.persistence.index.impl.EsEntityIndexImpl;
 
 
 /**
@@ -42,4 +43,6 @@ public class Versions {
     public static final int VERSION_2 = EdgeMetadataSerializationProxyImpl.MIGRATION_VERSION;
 
     public static final int VERSION_3 = MvccEntitySerializationStrategyProxyImpl.MIGRATION_VERSION;
+
+    public static final int VERSION_4 = EsEntityIndexImpl.MIGRATION_VERSION;
 }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/7c9ee651/stack/core/src/test/java/org/apache/usergrid/corepersistence/migration/EntityDataMigrationIT.java
----------------------------------------------------------------------
diff --git a/stack/core/src/test/java/org/apache/usergrid/corepersistence/migration/EntityDataMigrationIT.java b/stack/core/src/test/java/org/apache/usergrid/corepersistence/migration/EntityDataMigrationIT.java
index d5f2fe1..e11025d 100644
--- a/stack/core/src/test/java/org/apache/usergrid/corepersistence/migration/EntityDataMigrationIT.java
+++ b/stack/core/src/test/java/org/apache/usergrid/corepersistence/migration/EntityDataMigrationIT.java
@@ -61,10 +61,8 @@ import static org.junit.Assert.assertTrue;
 
 public class EntityDataMigrationIT extends AbstractCoreIT {
 
-
     private Injector injector;
 
-
     private EntityDataMigration entityDataMigration;
     private ManagerCache managerCache;
     private DataMigrationManager dataMigrationManager;
@@ -74,12 +72,13 @@ public class EntityDataMigrationIT extends AbstractCoreIT {
     private EntityManagerFactory emf;
 
 
-
     /**
      * Rule to do the resets we need
      */
     @Rule
-    public MigrationTestRule migrationTestRule = new MigrationTestRule( app, CpSetup.getInjector() ,EntityDataMigration.class  );
+    public MigrationTestRule migrationTestRule = 
+            new MigrationTestRule( app, CpSetup.getInjector() ,EntityDataMigration.class  );
+
 
     @Before
     public void setup() {
@@ -129,36 +128,36 @@ public class EntityDataMigrationIT extends AbstractCoreIT {
         //using a test system, and it's not a huge amount of data, otherwise we'll overflow.
 
         AllEntitiesInSystemObservable.getAllEntitiesInSystem( managerCache, 1000 )
-                                     .doOnNext( new Action1<AllEntitiesInSystemObservable.ApplicationEntityGroup>() {
-                                         @Override
-                                         public void call(
-                                                 final AllEntitiesInSystemObservable.ApplicationEntityGroup entity ) {
+            .doOnNext( new Action1<AllEntitiesInSystemObservable.ApplicationEntityGroup>() {
+                @Override
+                public void call(
+                        final AllEntitiesInSystemObservable.ApplicationEntityGroup entity ) {
 
-                                             //add all versions from history to our comparison
-                                             for ( final Id id : entity.entityIds ) {
+                    //add all versions from history to our comparison
+                    for ( final Id id : entity.entityIds ) {
 
-                                                 CollectionScope scope = CpNamingUtils
-                                                         .getCollectionScopeNameFromEntityType(
-                                                                 entity.applicationScope.getApplication(),
-                                                                 id.getType() );
+                        CollectionScope scope = CpNamingUtils
+                                .getCollectionScopeNameFromEntityType(
+                                        entity.applicationScope.getApplication(),
+                                        id.getType() );
 
-                                                 final Iterator<MvccEntity> versions = v1Strategy
-                                                         .loadDescendingHistory( scope, id, UUIDGenerator.newTimeUUID(),
-                                                                 100 );
+                        final Iterator<MvccEntity> versions = v1Strategy
+                                .loadDescendingHistory( scope, id, UUIDGenerator.newTimeUUID(),
+                                        100 );
 
-                                                 while ( versions.hasNext() ) {
+                        while ( versions.hasNext() ) {
 
-                                                     final MvccEntity mvccEntity = versions.next();
+                            final MvccEntity mvccEntity = versions.next();
 
-                                                     savedEntities.add( mvccEntity );
+                            savedEntities.add( mvccEntity );
 
-                                                     createdEntityIds.remove( mvccEntity.getId() );
+                            createdEntityIds.remove( mvccEntity.getId() );
 
-                                                     entityIds.add( id );
-                                                 }
-                                             }
-                                         }
-                                     } ).toBlocking().lastOrDefault( null );
+                            entityIds.add( id );
+                        }
+                    }
+                }
+            } ).toBlocking().lastOrDefault( null );
 
         assertEquals( "Newly saved entities encountered", 0, createdEntityIds.size() );
         assertTrue( "Saved new entities", savedEntities.size() > 0 );
@@ -175,76 +174,78 @@ public class EntityDataMigrationIT extends AbstractCoreIT {
         migrationInfoSerialization.setVersion( entityDataMigration.getVersion() );
         dataMigrationManager.invalidate();
 
-        assertEquals( "New version saved, and we should get new implementation", entityDataMigration.getVersion(),
-                dataMigrationManager.getCurrentVersion() );
+        assertEquals( "New version saved, and we should get new implementation", 
+                entityDataMigration.getVersion(), dataMigrationManager.getCurrentVersion() );
 
 
         //now visit all entities in the system again, load them from v2, and ensure they're the same
         AllEntitiesInSystemObservable.getAllEntitiesInSystem( managerCache, 1000 )
-                                     .doOnNext( new Action1<AllEntitiesInSystemObservable.ApplicationEntityGroup>() {
-                                                    @Override
-                                                    public void call(
-                                                            final AllEntitiesInSystemObservable
-                                                                    .ApplicationEntityGroup entity ) {
-                                                        //add all versions from history to our comparison
-                                                        for ( final Id id : entity.entityIds ) {
+            .doOnNext( new Action1<AllEntitiesInSystemObservable.ApplicationEntityGroup>() {
+                @Override
+                public void call(
+                        final AllEntitiesInSystemObservable.ApplicationEntityGroup entity ) {
+
+                    //add all versions from history to our comparison
+                    for ( final Id id : entity.entityIds ) {
 
-                                                            CollectionScope scope = CpNamingUtils
-                                                                    .getCollectionScopeNameFromEntityType(
-                                                                            entity.applicationScope.getApplication(),
-                                                                            id.getType() );
+                        CollectionScope scope = CpNamingUtils
+                                .getCollectionScopeNameFromEntityType(
+                                        entity.applicationScope.getApplication(),
+                                        id.getType() );
 
-                                                            final Iterator<MvccEntity> versions = v2Strategy
-                                                                    .loadDescendingHistory( scope, id,
-                                                                            UUIDGenerator.newTimeUUID(), 100 );
+                        final Iterator<MvccEntity> versions = v2Strategy
+                                .loadDescendingHistory( scope, id,
+                                        UUIDGenerator.newTimeUUID(), 100 );
 
-                                                            while ( versions.hasNext() ) {
+                        while ( versions.hasNext() ) {
 
-                                                                final MvccEntity mvccEntity = versions.next();
+                            final MvccEntity mvccEntity = versions.next();
 
-                                                                savedEntities.remove( mvccEntity );
-                                                            }
-                                                        }
-                                                    }
-                                                }
+                            savedEntities.remove( mvccEntity );
+                        }
+                    }
+                }
+            }
 
 
-                                              ).toBlocking().lastOrDefault( null );
+            ).toBlocking().lastOrDefault( null );
 
 
         assertEquals( "All entities migrated", 0, savedEntities.size() );
 
 
-        //now visit all entities in the system again, and load them from the EM, ensure we see everything we did in the v1 traversal
+        // now visit all entities in the system again, and load them from the EM, 
+        // ensure we see everything we did in the v1 traversal
         AllEntitiesInSystemObservable.getAllEntitiesInSystem( managerCache, 1000 )
-                                     .doOnNext( new Action1<AllEntitiesInSystemObservable.ApplicationEntityGroup>() {
-                                                    @Override
-                                                    public void call(
-                                                            final AllEntitiesInSystemObservable
-                                                                    .ApplicationEntityGroup entity ) {
+            .doOnNext( new Action1<AllEntitiesInSystemObservable.ApplicationEntityGroup>() {
+                @Override
+                public void call(
+                        final AllEntitiesInSystemObservable
+                                .ApplicationEntityGroup entity ) {
 
-                                                        final EntityManager em = emf.getEntityManager( entity.applicationScope.getApplication().getUuid() );
+                    final EntityManager em = emf.getEntityManager( 
+                            entity.applicationScope.getApplication().getUuid() );
 
-                                                        //add all versions from history to our comparison
-                                                        for ( final Id id : entity.entityIds ) {
+                    //add all versions from history to our comparison
+                    for ( final Id id : entity.entityIds ) {
 
 
-                                                            try {
-                                                                final Entity emEntity = em.get( SimpleEntityRef.fromId( id ) );
+                        try {
+                            final Entity emEntity = em.get( SimpleEntityRef.fromId( id ) );
 
-                                                                if(emEntity != null){
-                                                                    entityIds.remove( id );
-                                                                }
-                                                            }
-                                                            catch ( Exception e ) {
-                                                                throw new RuntimeException("Error loading entity", e);
-                                                            }
-                                                        }
-                                                    }
-                                                }
+                            if(emEntity != null){
+                                entityIds.remove( id );
+                            }
+                        }
+                        catch ( Exception e ) {
+                            throw new RuntimeException("Error loading entity", e);
+                        }
+                    }
+                }
+            }
 
 
-                                              ).toBlocking().lastOrDefault( null );
+            ).toBlocking().lastOrDefault( null );
 
 
         assertEquals("All entities could be loaded by the entity manager", 0, entityIds.size());

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/7c9ee651/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyProxyImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyProxyImpl.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyProxyImpl.java
index cf17812..64ad54a 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyProxyImpl.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyProxyImpl.java
@@ -43,7 +43,7 @@ import com.netflix.astyanax.MutationBatch;
 
 /**
  * Version 3 implementation of entity serialization. This will proxy writes and reads so that during
- * migration data goes to both sources and is read from the old source. After the ugprade completes,
+ * migration data goes to both sources and is read from the old source. After the upgrade completes,
  * it will be available from the new source
  */
 @Singleton

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/7c9ee651/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/EntityIndex.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/EntityIndex.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/EntityIndex.java
index 88498b3..4b87c70 100644
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/EntityIndex.java
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/EntityIndex.java
@@ -37,6 +37,11 @@ public interface EntityIndex {
     public void initializeIndex();
 
     /**
+     * Update mappings for this index.
+     */
+    public void updateMappings();
+
+    /**
      * Create the index batch.
      */
     public EntityIndexBatch createBatch();

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/7c9ee651/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexImpl.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexImpl.java
index 1a9b152..c623c09 100644
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexImpl.java
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/index/impl/EsEntityIndexImpl.java
@@ -73,7 +73,7 @@ import com.google.common.collect.ImmutableMap;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
 
-import static org.apache.usergrid.persistence.index.impl.IndexingUtils.BOOLEAN_PREFIX;
+import static org.apache.usergrid.persistence.index.impl.IndexingUtils.BOOLEAN_PREFIX; 
 import static org.apache.usergrid.persistence.index.impl.IndexingUtils.NUMBER_PREFIX;
 import static org.apache.usergrid.persistence.index.impl.IndexingUtils.SPLITTER;
 import static org.apache.usergrid.persistence.index.impl.IndexingUtils.STRING_PREFIX;
@@ -88,6 +88,8 @@ public class EsEntityIndexImpl implements EntityIndex {
 
     private static final AtomicBoolean mappingsCreated = new AtomicBoolean( false );
 
+    public static final int MIGRATION_VERSION = 4;
+
     /**
      * We purposefully make this per instance. Some indexes may work, while others may fail
      */
@@ -172,13 +174,27 @@ public class EsEntityIndexImpl implements EntityIndex {
     }
 
 
+    @Override
+    public void updateMappings() {
+        try {
+            // index may not exist yet, that's fine
+            initializeIndex();
+
+            // create mappings does a PUT, that works for updating mappings
+            createMappings();
+
+        } catch (IOException e) {
+            throw new RuntimeException( "Unable to update mappings", e );
+        }
+    }
+
+
     /**
      * Tests writing a document to a new index to ensure it's working correctly. See this post:
      * http://s.apache.org/index-missing-exception
      */
     private void testNewIndex() {
 
-
         logger.info( "Refreshing Created new Index Name [{}]", indexName );
 
         final RetryOperation retryOperation = new RetryOperation() {