You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by to...@apache.org on 2014/10/29 21:33:39 UTC
[1/3] Updated migrations to separate data migrations and schema
migrations.
Repository: incubator-usergrid
Updated Branches:
refs/heads/key-row-sharding ca943fed7 -> 84c33176e
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImplTest.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImplTest.java b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImplTest.java
new file mode 100644
index 0000000..3ffcd89
--- /dev/null
+++ b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImplTest.java
@@ -0,0 +1,220 @@
+/*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one
+ * * or more contributor license agreements. See the NOTICE file
+ * * distributed with this work for additional information
+ * * regarding copyright ownership. The ASF licenses this file
+ * * to you under the Apache License, Version 2.0 (the
+ * * "License"); you may not use this file except in compliance
+ * * with the License. You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing,
+ * * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * * KIND, either express or implied. See the License for the
+ * * specific language governing permissions and limitations
+ * * under the License.
+ *
+ */
+
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.Test;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+
+/**
+ * Tests our data migration manager
+ */
+public class DataMigrationManagerImplTest {
+
+
+ @Test
+ public void noMigrations() throws MigrationException {
+ final MigrationInfoSerialization serialization = mock( MigrationInfoSerialization.class );
+
+
+ Set<DataMigration> emptyMigration = new HashSet<>();
+
+
+ DataMigrationManagerImpl migrationManager = new DataMigrationManagerImpl( serialization, emptyMigration );
+
+ migrationManager.migrate();
+
+ verify( serialization, never() ).setStatusMessage( any( String.class ) );
+ verify( serialization, never() ).setStatusCode( any( Integer.class ) );
+ verify( serialization, never() ).setVersion( any( Integer.class ) );
+ }
+
+
+ @Test
+ public void multipleMigrations() throws Throwable {
+ final MigrationInfoSerialization serialization = mock( MigrationInfoSerialization.class );
+
+
+ final DataMigration v1 = mock( DataMigration.class );
+ when( v1.getVersion() ).thenReturn( 1 );
+
+ final DataMigration v2 = mock( DataMigration.class );
+ when( v2.getVersion() ).thenReturn( 2 );
+
+
+ Set<DataMigration> migrations = new HashSet<>();
+ migrations.add( v1 );
+ migrations.add( v2 );
+
+
+ DataMigrationManagerImpl migrationManager = new DataMigrationManagerImpl( serialization, migrations );
+
+ migrationManager.migrate();
+
+
+ verify( v1 ).migrate( any( DataMigration.ProgressObserver.class ) );
+ verify( v2 ).migrate( any( DataMigration.ProgressObserver.class ) );
+
+ //verify we set the running status
+ verify( serialization, times( 2 ) ).setStatusCode( DataMigrationManagerImpl.StatusCode.RUNNING.status );
+
+ //set the status message
+ verify( serialization, times( 2 * 2 ) ).setStatusMessage( any( String.class ) );
+
+ verify( serialization ).setStatusCode( DataMigrationManagerImpl.StatusCode.COMPLETE.status );
+
+ //verify we set version 1
+ verify( serialization ).setVersion( 1 );
+
+ //verify we set version 2
+ verify( serialization ).setVersion( 2 );
+ }
+
+
+ @Test
+ public void shortCircuitVersionFails() throws Throwable {
+ final MigrationInfoSerialization serialization = mock( MigrationInfoSerialization.class );
+
+
+ final DataMigration v1 = mock( DataMigration.class );
+ when( v1.getVersion() ).thenReturn( 1 );
+
+ //throw an exception
+ doThrow( new RuntimeException( "Something bad happened" ) ).when( v1 ).migrate(
+ any( DataMigration.ProgressObserver.class ) );
+
+ final DataMigration v2 = mock( DataMigration.class );
+ when( v2.getVersion() ).thenReturn( 2 );
+
+
+ Set<DataMigration> migrations = new HashSet<>();
+ migrations.add( v1 );
+ migrations.add( v2 );
+
+
+ DataMigrationManagerImpl migrationManager = new DataMigrationManagerImpl( serialization, migrations );
+
+ migrationManager.migrate();
+
+
+ verify( v1 ).migrate( any( DataMigration.ProgressObserver.class ) );
+
+ //verify we don't run migration
+ verify( v2, never() ).migrate( any( DataMigration.ProgressObserver.class ) );
+
+ //verify we set the running status
+ verify( serialization, times( 1 ) ).setStatusCode( DataMigrationManagerImpl.StatusCode.RUNNING.status );
+
+ //set the status message
+ verify( serialization, times( 2 ) ).setStatusMessage( any( String.class ) );
+
+ //verify we set an error
+ verify( serialization ).setStatusCode( DataMigrationManagerImpl.StatusCode.ERROR.status );
+
+ //verify we never set version 1
+ verify( serialization, never() ).setVersion( 1 );
+
+ //verify we never set version 2
+ verify( serialization, never() ).setVersion( 2 );
+ }
+
+
+ @Test
+ public void failStopsProgress() throws Throwable {
+ final MigrationInfoSerialization serialization = mock( MigrationInfoSerialization.class );
+
+
+ final DataMigration v1 = mock( DataMigration.class );
+ when( v1.getVersion() ).thenReturn( 1 );
+
+
+ final int returnedCode = 100;
+
+ final String reason = "test reason";
+
+ //mark as fail but don't
+ doAnswer( new Answer<Object>() {
+ @Override
+ public Object answer( final InvocationOnMock invocation ) throws Throwable {
+ final DataMigration.ProgressObserver progressObserver =
+ ( DataMigration.ProgressObserver ) invocation.getArguments()[0];
+
+ progressObserver.failed( returnedCode, reason );
+ return null;
+ }
+ } ).when( v1 ).migrate( any( DataMigration.ProgressObserver.class ) );
+
+
+
+ final DataMigration v2 = mock( DataMigration.class );
+ when( v2.getVersion() ).thenReturn( 2 );
+
+
+ Set<DataMigration> migrations = new HashSet<>();
+ migrations.add( v1 );
+ migrations.add( v2 );
+
+
+ DataMigrationManagerImpl migrationManager = new DataMigrationManagerImpl( serialization, migrations );
+
+ migrationManager.migrate();
+
+
+ verify( v1 ).migrate( any( DataMigration.ProgressObserver.class ) );
+
+ //verify we don't run migration
+ verify( v2, never() ).migrate( any( DataMigration.ProgressObserver.class ) );
+
+ //verify we set the running status
+ verify( serialization, times( 1 ) ).setStatusCode( DataMigrationManagerImpl.StatusCode.RUNNING.status );
+
+ //set the status message
+ verify( serialization ).setStatusMessage( "Migration version 1. Starting migration" );
+
+ verify( serialization ).setStatusMessage( "Migration version 100. Failed to migrate, reason is appended. Error 'test reason'" );
+
+ //verify we set an error
+ verify( serialization, times(1) ).setStatusCode( DataMigrationManagerImpl.StatusCode.ERROR.status );
+
+ //verify we never set version 1
+ verify( serialization, never() ).setVersion( 1 );
+
+ //verify we never set version 2
+ verify( serialization, never() ).setVersion( 2 );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerializationTest.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerializationTest.java b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerializationTest.java
new file mode 100644
index 0000000..d1de9c2
--- /dev/null
+++ b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerializationTest.java
@@ -0,0 +1,104 @@
+/*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one
+ * * or more contributor license agreements. See the NOTICE file
+ * * distributed with this work for additional information
+ * * regarding copyright ownership. The ASF licenses this file
+ * * to you under the Apache License, Version 2.0 (the
+ * * "License"); you may not use this file except in compliance
+ * * with the License. You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing,
+ * * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * * KIND, either express or implied. See the License for the
+ * * specific language governing permissions and limitations
+ * * under the License.
+ *
+ */
+
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+import org.jukito.UseModules;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.apache.usergrid.persistence.core.cassandra.ITRunner;
+import org.apache.usergrid.persistence.core.guice.MigrationManagerRule;
+import org.apache.usergrid.persistence.core.guice.TestCommonModule;
+import org.apache.usergrid.persistence.core.scope.ApplicationScope;
+
+import com.google.inject.Inject;
+import com.netflix.astyanax.Keyspace;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+@RunWith( ITRunner.class )
+@UseModules( TestCommonModule.class )
+public class MigrationInfoSerializationTest {
+
+
+ @Inject
+ @Rule
+ public MigrationManagerRule migrationManagerRule;
+
+ @Inject
+ protected Keyspace keyspace;
+
+
+ protected ApplicationScope scope;
+
+ @Inject
+ protected MigrationInfoSerialization migrationInfoSerialization;
+
+
+
+ @Test
+ public void basicTest(){
+
+ //test getting nothing works
+ final String emptyStatus = migrationInfoSerialization.getStatusMessage();
+
+ assertNull(emptyStatus);
+
+ final int unsavedVersion = migrationInfoSerialization.getVersion();
+
+ assertEquals(0, unsavedVersion);
+
+ final int statusCode = migrationInfoSerialization.getStatusCode();
+
+ assertEquals(0, statusCode);
+
+ //now update them
+
+ final String savedStatus = "I'm a test status";
+
+ migrationInfoSerialization.setStatusMessage( savedStatus );
+
+ final String returnedStatus = migrationInfoSerialization.getStatusMessage();
+
+ assertEquals("Correct status returned", savedStatus, returnedStatus);
+
+
+ final int savedVersion = 100;
+
+ migrationInfoSerialization.setVersion( savedVersion );
+
+ final int returnedVersion = migrationInfoSerialization.getVersion();
+
+ assertEquals("Correct version returned", savedVersion, returnedVersion);
+
+ final int savedStatusCode = 200;
+
+ migrationInfoSerialization.setStatusCode( savedStatusCode );
+
+ final int returnedStatusCode = migrationInfoSerialization.getStatusCode();
+
+ assertEquals("Status code was set correctly", savedStatusCode, returnedStatusCode);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/guice/GraphModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/guice/GraphModule.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/guice/GraphModule.java
index 2cbc5e8..6f15e88 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/guice/GraphModule.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/guice/GraphModule.java
@@ -27,7 +27,7 @@ import org.apache.usergrid.persistence.core.consistency.TimeServiceImpl;
import org.apache.usergrid.persistence.core.guice.CurrentImpl;
import org.apache.usergrid.persistence.core.guice.PreviousImpl;
import org.apache.usergrid.persistence.core.guice.ProxyImpl;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
import org.apache.usergrid.persistence.core.task.NamedTaskExecutorImpl;
import org.apache.usergrid.persistence.core.task.TaskExecutor;
import org.apache.usergrid.persistence.graph.GraphFig;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/EdgeMetadataSerialization.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/EdgeMetadataSerialization.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/EdgeMetadataSerialization.java
index 9e0beb5..38916ac 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/EdgeMetadataSerialization.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/EdgeMetadataSerialization.java
@@ -22,7 +22,7 @@ package org.apache.usergrid.persistence.graph.serialization;
import java.util.Iterator;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
import org.apache.usergrid.persistence.core.scope.ApplicationScope;
import org.apache.usergrid.persistence.graph.Edge;
import org.apache.usergrid.persistence.graph.SearchEdgeType;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/NodeSerialization.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/NodeSerialization.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/NodeSerialization.java
index 77e53c8..00dcd92 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/NodeSerialization.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/NodeSerialization.java
@@ -23,7 +23,7 @@ package org.apache.usergrid.persistence.graph.serialization;
import java.util.Collection;
import java.util.Map;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
import org.apache.usergrid.persistence.core.scope.ApplicationScope;
import org.apache.usergrid.persistence.graph.Edge;
import org.apache.usergrid.persistence.model.entity.Id;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationV1Impl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationV1Impl.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationV1Impl.java
index 3254dd5..c634684 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationV1Impl.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationV1Impl.java
@@ -36,7 +36,7 @@ import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDef
import org.apache.usergrid.persistence.core.astyanax.ScopedRowKeySerializer;
import org.apache.usergrid.persistence.core.astyanax.ScopedRowKey;
import org.apache.usergrid.persistence.core.astyanax.StringColumnParser;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
import org.apache.usergrid.persistence.core.scope.ApplicationScope;
import org.apache.usergrid.persistence.core.util.ValidationUtils;
import org.apache.usergrid.persistence.graph.Edge;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationV2Impl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationV2Impl.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationV2Impl.java
index 0c3a04a..c9a279a 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationV2Impl.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationV2Impl.java
@@ -42,7 +42,7 @@ import org.apache.usergrid.persistence.core.astyanax.MultiRowColumnIterator;
import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamily;
import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
import org.apache.usergrid.persistence.core.astyanax.StringColumnParser;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
import org.apache.usergrid.persistence.core.scope.ApplicationScope;
import org.apache.usergrid.persistence.core.shard.ExpandingShardLocator;
import org.apache.usergrid.persistence.core.shard.StringHashUtils;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/NodeSerializationImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/NodeSerializationImpl.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/NodeSerializationImpl.java
index eae7fa0..2cc0391 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/NodeSerializationImpl.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/NodeSerializationImpl.java
@@ -39,7 +39,7 @@ import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDef
import org.apache.usergrid.persistence.core.astyanax.ScopedRowKeySerializer;
import org.apache.usergrid.persistence.core.astyanax.ScopedRowKey;
import org.apache.usergrid.persistence.core.hystrix.HystrixCassandra;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
import org.apache.usergrid.persistence.core.scope.ApplicationScope;
import org.apache.usergrid.persistence.core.util.ValidationUtils;
import org.apache.usergrid.persistence.graph.Edge;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/EdgeColumnFamilies.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/EdgeColumnFamilies.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/EdgeColumnFamilies.java
index a7b5128..f1d6e37 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/EdgeColumnFamilies.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/EdgeColumnFamilies.java
@@ -23,8 +23,7 @@ package org.apache.usergrid.persistence.graph.serialization.impl.shard;
import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamily;
import org.apache.usergrid.persistence.core.astyanax.ScopedRowKey;
-import org.apache.usergrid.persistence.core.migration.Migration;
-import org.apache.usergrid.persistence.core.scope.ApplicationScope;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
/**
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/EdgeShardSerialization.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/EdgeShardSerialization.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/EdgeShardSerialization.java
index 568824a..93fd685 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/EdgeShardSerialization.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/EdgeShardSerialization.java
@@ -22,7 +22,7 @@ package org.apache.usergrid.persistence.graph.serialization.impl.shard;
import java.util.Iterator;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
import org.apache.usergrid.persistence.core.scope.ApplicationScope;
import com.google.common.base.Optional;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/count/NodeShardCounterSerialization.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/count/NodeShardCounterSerialization.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/count/NodeShardCounterSerialization.java
index 4b05401..aafbd26 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/count/NodeShardCounterSerialization.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/shard/count/NodeShardCounterSerialization.java
@@ -19,7 +19,7 @@
package org.apache.usergrid.persistence.graph.serialization.impl.shard.count;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
import com.netflix.astyanax.MutationBatch;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/GraphManagerShardConsistencyIT.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/GraphManagerShardConsistencyIT.java b/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/GraphManagerShardConsistencyIT.java
index ec3fb29..a748c05 100644
--- a/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/GraphManagerShardConsistencyIT.java
+++ b/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/GraphManagerShardConsistencyIT.java
@@ -48,8 +48,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.usergrid.persistence.core.cassandra.CassandraRule;
-import org.apache.usergrid.persistence.core.migration.MigrationException;
-import org.apache.usergrid.persistence.core.migration.MigrationManager;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManager;
import org.apache.usergrid.persistence.core.scope.ApplicationScope;
import org.apache.usergrid.persistence.core.scope.ApplicationScopeImpl;
import org.apache.usergrid.persistence.graph.guice.TestGraphModule;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/guice/TestGraphModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/guice/TestGraphModule.java b/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/guice/TestGraphModule.java
index 22c6fd9..bbcfa6e 100644
--- a/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/guice/TestGraphModule.java
+++ b/stack/corepersistence/graph/src/test/java/org/apache/usergrid/persistence/graph/guice/TestGraphModule.java
@@ -19,7 +19,7 @@
package org.apache.usergrid.persistence.graph.guice;
-import org.apache.usergrid.persistence.collection.guice.TestModule;
+import org.apache.usergrid.persistence.core.guice.TestModule;
import org.apache.usergrid.persistence.core.guice.CommonModule;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/guice/MapModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/guice/MapModule.java b/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/guice/MapModule.java
index b6c1410..d167151 100644
--- a/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/guice/MapModule.java
+++ b/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/guice/MapModule.java
@@ -18,7 +18,7 @@
package org.apache.usergrid.persistence.map.guice;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
import org.apache.usergrid.persistence.map.MapManager;
import org.apache.usergrid.persistence.map.MapManagerFactory;
import org.apache.usergrid.persistence.map.impl.MapManagerImpl;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapSerialization.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapSerialization.java b/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapSerialization.java
index 8d4206c..33f2043 100644
--- a/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapSerialization.java
+++ b/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapSerialization.java
@@ -20,7 +20,7 @@
package org.apache.usergrid.persistence.map.impl;
import java.util.UUID;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
import org.apache.usergrid.persistence.map.MapScope;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/map/src/test/java/org/apache/usergrid/persistence/map/guice/TestMapModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/map/src/test/java/org/apache/usergrid/persistence/map/guice/TestMapModule.java b/stack/corepersistence/map/src/test/java/org/apache/usergrid/persistence/map/guice/TestMapModule.java
index 739bb67..2868f45 100644
--- a/stack/corepersistence/map/src/test/java/org/apache/usergrid/persistence/map/guice/TestMapModule.java
+++ b/stack/corepersistence/map/src/test/java/org/apache/usergrid/persistence/map/guice/TestMapModule.java
@@ -1,7 +1,7 @@
package org.apache.usergrid.persistence.map.guice;
-import org.apache.usergrid.persistence.collection.guice.TestModule;
+import org.apache.usergrid.persistence.core.guice.TestModule;
import org.apache.usergrid.persistence.core.guice.CommonModule;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/guice/TestIndexModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/guice/TestIndexModule.java b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/guice/TestIndexModule.java
index 2cf3f7a..4d68dda 100644
--- a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/guice/TestIndexModule.java
+++ b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/guice/TestIndexModule.java
@@ -20,7 +20,7 @@ package org.apache.usergrid.persistence.index.guice;
import org.apache.usergrid.persistence.collection.guice.CollectionModule;
-import org.apache.usergrid.persistence.collection.guice.TestModule;
+import org.apache.usergrid.persistence.core.guice.TestModule;
import org.apache.usergrid.persistence.core.guice.CommonModule;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/queue/src/test/java/org/apache/usergrid/persistence/queue/guice/TestQueueModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queue/src/test/java/org/apache/usergrid/persistence/queue/guice/TestQueueModule.java b/stack/corepersistence/queue/src/test/java/org/apache/usergrid/persistence/queue/guice/TestQueueModule.java
index b65725f..aedfe28 100644
--- a/stack/corepersistence/queue/src/test/java/org/apache/usergrid/persistence/queue/guice/TestQueueModule.java
+++ b/stack/corepersistence/queue/src/test/java/org/apache/usergrid/persistence/queue/guice/TestQueueModule.java
@@ -18,7 +18,7 @@
package org.apache.usergrid.persistence.queue.guice;
-import org.apache.usergrid.persistence.collection.guice.TestModule;
+import org.apache.usergrid.persistence.core.guice.TestModule;
import org.apache.usergrid.persistence.core.guice.CommonModule;
[3/3] git commit: Cleaned up some code. Need to remove mockito.
Incorrect proxy wiring is causing NPE
Posted by to...@apache.org.
Cleaned up some code. Need to remove mockito. Incorrect proxy wiring is causing NPE
Project: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/commit/84c33176
Tree: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/tree/84c33176
Diff: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/diff/84c33176
Branch: refs/heads/key-row-sharding
Commit: 84c33176eb819216dde6727d09ac19e8669d4f12
Parents: dfed6a0
Author: Todd Nine <tn...@apigee.com>
Authored: Wed Oct 29 14:33:34 2014 -0600
Committer: Todd Nine <tn...@apigee.com>
Committed: Wed Oct 29 14:33:34 2014 -0600
----------------------------------------------------------------------
.../persistence/core/guice/CommonModule.java | 14 +-
.../migration/data/DataMigrationManager.java | 6 +
.../data/DataMigrationManagerImpl.java | 65 ++++++--
.../persistence/graph/guice/GraphModule.java | 40 ++---
.../graph/impl/GraphManagerImpl.java | 9 +-
.../EdgeMetadataSerializationProxyImpl.java | 165 +++++++++++++++++--
6 files changed, 229 insertions(+), 70 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/84c33176/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java
index 3503178..e37067f 100644
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java
@@ -59,6 +59,13 @@ public class CommonModule extends AbstractModule {
// bind our migration manager
bind( MigrationManager.class ).to( MigrationManagerImpl.class );
+
+
+ //do multibindings for migrations
+ Multibinder<Migration> migrationBinding = Multibinder.newSetBinder( binder(), Migration.class );
+ migrationBinding.addBinding().to( Key.get( MigrationInfoSerialization.class ) );
+
+
bind( TimeService.class ).to( TimeServiceImpl.class );
bind( CassandraConfig.class ).to( CassandraConfigImpl.class );
@@ -71,8 +78,11 @@ public class CommonModule extends AbstractModule {
bind( DataMigrationManager.class ).to( DataMigrationManagerImpl.class );
+
+
//do multibindings for migrations
- Multibinder<Migration> migrationBinding = Multibinder.newSetBinder( binder(), Migration.class );
- migrationBinding.addBinding().to( Key.get( MigrationInfoSerialization.class ) );
+ Multibinder<DataMigrationManager> dataMigrationManagerMultibinder = Multibinder.newSetBinder( binder(), DataMigrationManager.class );
+// migrationBinding.addBinding().to( Key.get( MigrationInfoSerialization.class ) );
+
}
}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/84c33176/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java
index 1d7ccec..3357ed4 100644
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java
@@ -41,6 +41,12 @@ public interface DataMigrationManager {
*/
public boolean isRunning();
+ /**
+ * Get the current version of the schema
+ * @return
+ */
+ public int getCurrentVersion();
+
/**
* Return that last status of the migration
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/84c33176/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java
index ee579ee..4cc98df 100644
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java
@@ -27,12 +27,18 @@ import java.io.StringWriter;
import java.util.NavigableMap;
import java.util.Set;
import java.util.TreeMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
+import com.google.common.base.Preconditions;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@@ -46,14 +52,33 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
private final MigrationInfoSerialization migrationInfoSerialization;
+ /**
+ * Cache to cache versions temporarily
+ */
+ private final LoadingCache<String, Integer> versionCache = CacheBuilder.newBuilder()
+ //cache the local value for 1 minute
+ .expireAfterWrite( 1, TimeUnit.MINUTES ).build( new CacheLoader<String, Integer>() {
+ @Override
+ public Integer load( final String key ) throws Exception {
+ return migrationInfoSerialization.getVersion();
+ }
+ } );
+
@Inject
public DataMigrationManagerImpl( final MigrationInfoSerialization migrationInfoSerialization,
final Set<DataMigration> migrations ) {
+ Preconditions.checkNotNull( migrationInfoSerialization, "migrationInfoSerialization must not be null" );
+ Preconditions.checkNotNull( migrations, "migrations must not be null" );
+
this.migrationInfoSerialization = migrationInfoSerialization;
+
+
for ( DataMigration migration : migrations ) {
+ Preconditions.checkNotNull( migration, "A migration instance in the set of migrations was null. This is not allowed" );
+
final int version = migration.getVersion();
final DataMigration existing = migrationTreeMap.get( version );
@@ -103,7 +128,7 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
LOG.info( "Running migration version {}", migrationVersion );
- observer.update( migrationVersion, "Starting migration" );
+ observer.update( migrationVersion, "Starting migration" );
//perform this migration, if it fails, short circuit
@@ -119,7 +144,7 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
}
//we had an unhandled exception or the migration failed, short circuit
- if(observer.failed){
+ if ( observer.failed ) {
return;
}
@@ -128,13 +153,9 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
//update the observer for progress so other nodes can see it
observer.update( migrationVersion, "Completed successfully" );
-
-
}
migrationInfoSerialization.setStatusCode( StatusCode.COMPLETE.status );
-
-
}
@@ -145,6 +166,17 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
@Override
+ public int getCurrentVersion() {
+ try {
+ return versionCache.get( "currentVersion" );
+ }
+ catch ( ExecutionException e ) {
+ throw new DataMigrationException( "Unable to get current version", e );
+ }
+ }
+
+
+ @Override
public String getLastStatus() {
return migrationInfoSerialization.getStatusMessage();
}
@@ -153,10 +185,10 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
/**
* Different status enums
*/
- public enum StatusCode{
- COMPLETE(1),
- RUNNING(2),
- ERROR(3);
+ public enum StatusCode {
+ COMPLETE( 1 ),
+ RUNNING( 2 ),
+ ERROR( 3 );
public final int status;
@@ -170,14 +202,13 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
private boolean failed = false;
-
@Override
public void failed( final int migrationVersion, final String reason ) {
- final String storedMessage = String.format( "Failed to migrate, reason is appended. Error '%s'", reason);
+ final String storedMessage = String.format( "Failed to migrate, reason is appended. Error '%s'", reason );
- update(migrationVersion, storedMessage );
+ update( migrationVersion, storedMessage );
LOG.error( storedMessage );
@@ -193,9 +224,10 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
throwable.printStackTrace( new PrintWriter( stackTrace ) );
- final String storedMessage = String.format( "Failed to migrate, reason is appended. Error '%s' %s", reason, stackTrace.toString() );
+ final String storedMessage = String.format( "Failed to migrate, reason is appended. Error '%s' %s", reason,
+ stackTrace.toString() );
- update(migrationVersion, storedMessage );
+ update( migrationVersion, storedMessage );
LOG.error( "Unable to migrate version {} due to reason {}.", migrationVersion, reason, throwable );
@@ -208,7 +240,7 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
@Override
public void update( final int migrationVersion, final String message ) {
- final String error = String.format( "Migration version %d. %s", migrationVersion, message);
+ final String error = String.format( "Migration version %d. %s", migrationVersion, message );
migrationInfoSerialization.setStatusMessage( error );
}
@@ -216,7 +248,6 @@ public class DataMigrationManagerImpl implements DataMigrationManager {
/**
* Return true if we failed
- * @return
*/
public boolean isFailed() {
return failed;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/84c33176/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/guice/GraphModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/guice/GraphModule.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/guice/GraphModule.java
index 6f15e88..dee53d4 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/guice/GraphModule.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/guice/GraphModule.java
@@ -27,6 +27,7 @@ import org.apache.usergrid.persistence.core.consistency.TimeServiceImpl;
import org.apache.usergrid.persistence.core.guice.CurrentImpl;
import org.apache.usergrid.persistence.core.guice.PreviousImpl;
import org.apache.usergrid.persistence.core.guice.ProxyImpl;
+import org.apache.usergrid.persistence.core.migration.data.DataMigrationManager;
import org.apache.usergrid.persistence.core.migration.schema.Migration;
import org.apache.usergrid.persistence.core.task.NamedTaskExecutorImpl;
import org.apache.usergrid.persistence.core.task.TaskExecutor;
@@ -157,6 +158,15 @@ public class GraphModule extends AbstractModule {
//Get the old version and the new one
migrationBinding.addBinding().to( Key.get( EdgeMetadataSerialization.class, PreviousImpl.class) );
migrationBinding.addBinding().to( Key.get( EdgeMetadataSerialization.class, CurrentImpl.class ) );
+
+
+ /**
+ * Migrations of our edge meta serialization
+ */
+
+ bind(EdgeMetadataSerialization.class).annotatedWith( PreviousImpl.class ).to( EdgeMetadataSerializationV1Impl.class );
+ bind(EdgeMetadataSerialization.class).annotatedWith( CurrentImpl.class ).to( EdgeMetadataSerializationV2Impl.class );
+ bind(EdgeMetadataSerialization.class).annotatedWith( ProxyImpl.class ).to( EdgeMetadataSerializationProxyImpl.class );
}
@@ -170,36 +180,6 @@ public class GraphModule extends AbstractModule {
}
- @Inject
- @Singleton
- @Provides
- @PreviousImpl
- public EdgeMetadataSerialization getPreviousEdgeMetaSerialization( final Keyspace keyspace,
- final CassandraConfig cassandraConfig,
- final GraphFig graphFig ) {
- return new EdgeMetadataSerializationV1Impl( keyspace, cassandraConfig, graphFig );
- }
-
-
- @Inject
- @Singleton
- @Provides
- @CurrentImpl
- public EdgeMetadataSerialization getCurrentEdgeMetaSerialization( final Keyspace keyspace,
- final CassandraConfig cassandraConfig,
- final GraphFig graphFig ) {
- return new EdgeMetadataSerializationV2Impl( keyspace, cassandraConfig, graphFig );
- }
-
-
- @Inject
- @Singleton
- @Provides
- @ProxyImpl
- public EdgeMetadataSerialization getCurrentEdgeMetaSerialization( @PreviousImpl final EdgeMetadataSerialization previous,
- @CurrentImpl final EdgeMetadataSerialization current ) {
- return new EdgeMetadataSerializationProxyImpl( previous, current );
- }
}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/84c33176/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/impl/GraphManagerImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/impl/GraphManagerImpl.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/impl/GraphManagerImpl.java
index 564dc5b..df10816 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/impl/GraphManagerImpl.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/impl/GraphManagerImpl.java
@@ -92,9 +92,11 @@ public class GraphManagerImpl implements GraphManager {
@Inject
public GraphManagerImpl( @ProxyImpl final EdgeMetadataSerialization edgeMetadataSerialization,
final EdgeSerialization storageEdgeSerialization,
- final NodeSerialization nodeSerialization, final GraphFig graphFig,
- @Assisted final ApplicationScope scope, final EdgeDeleteListener edgeDeleteListener,
- final NodeDeleteListener nodeDeleteListener ) {
+ final NodeSerialization nodeSerialization,
+ final GraphFig graphFig,
+ final EdgeDeleteListener edgeDeleteListener,
+ final NodeDeleteListener nodeDeleteListener,
+ @Assisted final ApplicationScope scope) {
ValidationUtils.validateApplicationScope( scope );
@@ -103,6 +105,7 @@ public class GraphManagerImpl implements GraphManager {
Preconditions.checkNotNull( nodeSerialization, "nodeSerialization must not be null" );
Preconditions.checkNotNull( graphFig, "consistencyFig must not be null" );
Preconditions.checkNotNull( scope, "scope must not be null" );
+ Preconditions.checkNotNull( nodeDeleteListener, "nodeDeleteListener must not be null" );
this.scope = scope;
this.edgeMetadataSerialization = edgeMetadataSerialization;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/84c33176/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationProxyImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationProxyImpl.java b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationProxyImpl.java
index 4fbe801..cc51349 100644
--- a/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationProxyImpl.java
+++ b/stack/corepersistence/graph/src/main/java/org/apache/usergrid/persistence/graph/serialization/impl/EdgeMetadataSerializationProxyImpl.java
@@ -23,11 +23,13 @@ package org.apache.usergrid.persistence.graph.serialization.impl;
import java.util.Collection;
+import java.util.Collections;
import java.util.Iterator;
import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
import org.apache.usergrid.persistence.core.guice.CurrentImpl;
import org.apache.usergrid.persistence.core.guice.PreviousImpl;
+import org.apache.usergrid.persistence.core.migration.data.DataMigrationManager;
import org.apache.usergrid.persistence.core.scope.ApplicationScope;
import org.apache.usergrid.persistence.graph.Edge;
import org.apache.usergrid.persistence.graph.SearchEdgeType;
@@ -37,22 +39,30 @@ import org.apache.usergrid.persistence.model.entity.Id;
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import com.netflix.astyanax.Keyspace;
import com.netflix.astyanax.MutationBatch;
@Singleton
public class EdgeMetadataSerializationProxyImpl implements EdgeMetadataSerialization {
- private EdgeMetadataSerialization previous;
- private EdgeMetadataSerialization current;
+ private static final int MIGRATION_VERSION = 1;
+
+ private final DataMigrationManager dataMigrationManager;
+ private final Keyspace keyspace;
+ private final EdgeMetadataSerialization previous;
+ private final EdgeMetadataSerialization current;
/**
- * TODO fin
+ * Handles routing data to the right implementation, based on the current system migration version
*/
@Inject
- public EdgeMetadataSerializationProxyImpl( @PreviousImpl final EdgeMetadataSerialization previous,
+ public EdgeMetadataSerializationProxyImpl( final DataMigrationManager dataMigrationManager, final Keyspace keyspace,
+ @PreviousImpl final EdgeMetadataSerialization previous,
@CurrentImpl final EdgeMetadataSerialization current ) {
+ this.dataMigrationManager = dataMigrationManager;
+ this.keyspace = keyspace;
this.previous = previous;
this.current = current;
}
@@ -60,88 +70,207 @@ public class EdgeMetadataSerializationProxyImpl implements EdgeMetadataSerializa
@Override
public MutationBatch writeEdge( final ApplicationScope scope, final Edge edge ) {
- return null;
+
+
+ if ( isOldVersion() ) {
+ final MutationBatch aggregateBatch = keyspace.prepareMutationBatch();
+
+ aggregateBatch.mergeShallow( previous.writeEdge( scope, edge ) );
+ aggregateBatch.mergeShallow( current.writeEdge( scope, edge ) );
+
+ return aggregateBatch;
+ }
+
+ return current.writeEdge( scope, edge );
}
@Override
public MutationBatch removeEdgeTypeFromSource( final ApplicationScope scope, final Edge edge ) {
- return null;
+
+ if ( isOldVersion() ) {
+ final MutationBatch aggregateBatch = keyspace.prepareMutationBatch();
+
+ aggregateBatch.mergeShallow( previous.removeEdgeTypeFromSource( scope, edge ) );
+ aggregateBatch.mergeShallow( current.removeEdgeTypeFromSource( scope, edge ) );
+
+ return aggregateBatch;
+ }
+
+ return current.removeEdgeTypeFromSource( scope, edge );
}
@Override
public MutationBatch removeEdgeTypeFromSource( final ApplicationScope scope, final Id sourceNode, final String type,
final long timestamp ) {
- return null;
+
+
+ if ( isOldVersion() ) {
+ final MutationBatch aggregateBatch = keyspace.prepareMutationBatch();
+
+ aggregateBatch.mergeShallow( previous.removeEdgeTypeFromSource( scope, sourceNode, type, timestamp ) );
+ aggregateBatch.mergeShallow( current.removeEdgeTypeFromSource( scope, sourceNode, type, timestamp ) );
+
+ return aggregateBatch;
+ }
+
+ return current.removeEdgeTypeFromSource( scope, sourceNode, type, timestamp );
}
@Override
public MutationBatch removeIdTypeFromSource( final ApplicationScope scope, final Edge edge ) {
- return null;
+
+ if ( isOldVersion() ) {
+ final MutationBatch aggregateBatch = keyspace.prepareMutationBatch();
+
+ aggregateBatch.mergeShallow( previous.removeIdTypeFromSource( scope, edge ) );
+ aggregateBatch.mergeShallow( current.removeIdTypeFromSource( scope, edge ) );
+
+ return aggregateBatch;
+ }
+
+ return current.removeIdTypeFromSource( scope, edge );
}
@Override
public MutationBatch removeIdTypeFromSource( final ApplicationScope scope, final Id sourceNode, final String type,
final String idType, final long timestamp ) {
- return null;
+
+ if ( isOldVersion() ) {
+ final MutationBatch aggregateBatch = keyspace.prepareMutationBatch();
+
+ aggregateBatch
+ .mergeShallow( previous.removeIdTypeFromSource( scope, sourceNode, type, idType, timestamp ) );
+ aggregateBatch.mergeShallow( current.removeIdTypeFromSource( scope, sourceNode, type, idType, timestamp ) );
+
+ return aggregateBatch;
+ }
+
+ return current.removeIdTypeFromSource( scope, sourceNode, type, idType, timestamp );
}
@Override
public MutationBatch removeEdgeTypeToTarget( final ApplicationScope scope, final Edge edge ) {
- return null;
+
+
+ if ( isOldVersion() ) {
+ final MutationBatch aggregateBatch = keyspace.prepareMutationBatch();
+
+ aggregateBatch.mergeShallow( previous.removeEdgeTypeToTarget( scope, edge ) );
+ aggregateBatch.mergeShallow( current.removeEdgeTypeToTarget( scope, edge ) );
+
+ return aggregateBatch;
+ }
+
+ return current.removeEdgeTypeToTarget( scope, edge );
}
@Override
public MutationBatch removeEdgeTypeToTarget( final ApplicationScope scope, final Id targetNode, final String type,
final long timestamp ) {
- return null;
+
+ if ( isOldVersion() ) {
+ final MutationBatch aggregateBatch = keyspace.prepareMutationBatch();
+
+ aggregateBatch.mergeShallow( previous.removeEdgeTypeToTarget( scope, targetNode, type, timestamp ) );
+ aggregateBatch.mergeShallow( current.removeEdgeTypeToTarget( scope, targetNode, type, timestamp ) );
+
+ return aggregateBatch;
+ }
+
+ return current.removeEdgeTypeToTarget( scope, targetNode, type, timestamp );
}
@Override
public MutationBatch removeIdTypeToTarget( final ApplicationScope scope, final Edge edge ) {
- return null;
+
+ if ( isOldVersion() ) {
+ final MutationBatch aggregateBatch = keyspace.prepareMutationBatch();
+
+ aggregateBatch.mergeShallow( previous.removeIdTypeFromSource( scope, edge ) );
+ aggregateBatch.mergeShallow( current.removeIdTypeFromSource( scope, edge ) );
+
+ return aggregateBatch;
+ }
+
+ return current.removeIdTypeFromSource( scope, edge );
}
@Override
public MutationBatch removeIdTypeToTarget( final ApplicationScope scope, final Id targetNode, final String type,
final String idType, final long timestamp ) {
- return null;
+
+
+ if ( isOldVersion() ) {
+ final MutationBatch aggregateBatch = keyspace.prepareMutationBatch();
+
+ aggregateBatch.mergeShallow( previous.removeIdTypeToTarget( scope, targetNode, type, idType, timestamp ) );
+ aggregateBatch.mergeShallow( current.removeIdTypeToTarget( scope, targetNode, type, idType, timestamp ) );
+
+ return aggregateBatch;
+ }
+
+ return current.removeIdTypeToTarget( scope, targetNode, type, idType, timestamp );
}
@Override
public Iterator<String> getEdgeTypesFromSource( final ApplicationScope scope, final SearchEdgeType search ) {
- return null;
+ if ( isOldVersion() ) {
+ return previous.getEdgeTypesFromSource( scope, search );
+ }
+
+ return current.getEdgeTypesFromSource( scope, search );
}
@Override
public Iterator<String> getIdTypesFromSource( final ApplicationScope scope, final SearchIdType search ) {
- return null;
+ if ( isOldVersion() ) {
+ return previous.getIdTypesFromSource( scope, search );
+ }
+
+ return current.getIdTypesFromSource( scope, search );
}
@Override
public Iterator<String> getEdgeTypesToTarget( final ApplicationScope scope, final SearchEdgeType search ) {
- return null;
+ if ( isOldVersion() ) {
+ return previous.getEdgeTypesToTarget( scope, search );
+ }
+
+ return current.getEdgeTypesToTarget( scope, search );
}
@Override
public Iterator<String> getIdTypesToTarget( final ApplicationScope scope, final SearchIdType search ) {
- return null;
+ if ( isOldVersion() ) {
+ return previous.getIdTypesToTarget( scope, search );
+ }
+
+ return current.getIdTypesToTarget( scope, search );
}
@Override
public Collection<MultiTennantColumnFamilyDefinition> getColumnFamilies() {
- return null;
+ return Collections.EMPTY_LIST;
+ }
+
+
+ /**
+ * Return true if we're on an old version
+ */
+ private boolean isOldVersion() {
+ return dataMigrationManager.getCurrentVersion() < MIGRATION_VERSION;
}
}
[2/3] git commit: Updated migrations to separate data migrations and
schema migrations.
Posted by to...@apache.org.
Updated migrations to separate data migrations and schema migrations.
Project: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/commit/dfed6a02
Tree: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/tree/dfed6a02
Diff: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/diff/dfed6a02
Branch: refs/heads/key-row-sharding
Commit: dfed6a025a7fcb4c49decb4b3cf8bee37abeb1e7
Parents: ca943fe
Author: Todd Nine <tn...@apigee.com>
Authored: Wed Oct 29 10:51:43 2014 -0600
Committer: Todd Nine <tn...@apigee.com>
Committed: Wed Oct 29 10:51:43 2014 -0600
----------------------------------------------------------------------
.../usergrid/corepersistence/CpSetup.java | 6 +-
.../MvccEntitySerializationStrategyImpl.java | 2 +-
.../MvccLogEntrySerializationStrategyImpl.java | 2 +-
.../serialization/impl/SerializationModule.java | 2 +-
.../UniqueValueSerializationStrategyImpl.java | 2 +-
.../collection/guice/MigrationManagerRule.java | 4 +-
.../collection/guice/TestCollectionModule.java | 3 +-
.../collection/guice/TestModule.java | 48 ----
...MvccEntitySerializationStrategyImplTest.java | 2 +-
.../astyanax/StringRowCompositeSerializer.java | 68 ++++++
.../persistence/core/guice/CommonModule.java | 32 ++-
.../persistence/core/migration/Migration.java | 36 ---
.../core/migration/MigrationException.java | 37 ---
.../core/migration/MigrationManager.java | 34 ---
.../core/migration/MigrationManagerFig.java | 22 --
.../core/migration/MigrationManagerImpl.java | 196 ----------------
.../core/migration/data/DataMigration.java | 84 +++++++
.../migration/data/DataMigrationException.java | 39 ++++
.../migration/data/DataMigrationManager.java | 49 ++++
.../data/DataMigrationManagerImpl.java | 225 +++++++++++++++++++
.../data/MigrationInfoSerialization.java | 66 ++++++
.../data/MigrationInfoSerializationImpl.java | 178 +++++++++++++++
.../core/migration/schema/Migration.java | 36 +++
.../migration/schema/MigrationException.java | 37 +++
.../core/migration/schema/MigrationManager.java | 34 +++
.../migration/schema/MigrationManagerFig.java | 22 ++
.../migration/schema/MigrationManagerImpl.java | 196 ++++++++++++++++
.../core/guice/MigrationManagerRule.java | 4 +-
.../core/guice/TestCommonModule.java | 34 +++
.../persistence/core/guice/TestModule.java | 48 ++++
.../data/DataMigrationManagerImplTest.java | 220 ++++++++++++++++++
.../data/MigrationInfoSerializationTest.java | 104 +++++++++
.../persistence/graph/guice/GraphModule.java | 2 +-
.../EdgeMetadataSerialization.java | 2 +-
.../graph/serialization/NodeSerialization.java | 2 +-
.../impl/EdgeMetadataSerializationV1Impl.java | 2 +-
.../impl/EdgeMetadataSerializationV2Impl.java | 2 +-
.../impl/NodeSerializationImpl.java | 2 +-
.../impl/shard/EdgeColumnFamilies.java | 3 +-
.../impl/shard/EdgeShardSerialization.java | 2 +-
.../count/NodeShardCounterSerialization.java | 2 +-
.../graph/GraphManagerShardConsistencyIT.java | 4 +-
.../graph/guice/TestGraphModule.java | 2 +-
.../persistence/map/guice/MapModule.java | 2 +-
.../persistence/map/impl/MapSerialization.java | 2 +-
.../persistence/map/guice/TestMapModule.java | 2 +-
.../index/guice/TestIndexModule.java | 2 +-
.../queue/guice/TestQueueModule.java | 2 +-
48 files changed, 1492 insertions(+), 415 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpSetup.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpSetup.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpSetup.java
index c1bab12..4b4ded6 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpSetup.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpSetup.java
@@ -22,7 +22,7 @@ import com.google.inject.Injector;
import com.netflix.config.ConfigurationManager;
import java.util.Properties;
import java.util.UUID;
-import java.util.logging.Level;
+
import me.prettyprint.cassandra.service.CassandraHost;
import me.prettyprint.hector.api.ddl.ComparatorType;
import static me.prettyprint.hector.api.factory.HFactory.createColumnFamilyDefinition;
@@ -44,8 +44,8 @@ import static org.apache.usergrid.persistence.cassandra.CassandraService.TOKENS_
import static org.apache.usergrid.persistence.cassandra.CassandraService.USE_VIRTUAL_KEYSPACES;
import static org.apache.usergrid.persistence.cassandra.CassandraService.keyspaceForApplication;
import org.apache.usergrid.persistence.cassandra.Setup;
-import org.apache.usergrid.persistence.core.migration.MigrationException;
-import org.apache.usergrid.persistence.core.migration.MigrationManager;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManager;
import org.apache.usergrid.persistence.entities.Application;
import org.apache.usergrid.persistence.exceptions.ApplicationAlreadyExistsException;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImpl.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImpl.java
index dfa41ea..dc12087 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImpl.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImpl.java
@@ -49,7 +49,7 @@ import org.apache.usergrid.persistence.core.astyanax.IdRowCompositeSerializer;
import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamily;
import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
import org.apache.usergrid.persistence.core.astyanax.ScopedRowKey;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
import org.apache.usergrid.persistence.model.entity.Entity;
import org.apache.usergrid.persistence.model.entity.Id;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccLogEntrySerializationStrategyImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccLogEntrySerializationStrategyImpl.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccLogEntrySerializationStrategyImpl.java
index 8577fbf..7368e9a 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccLogEntrySerializationStrategyImpl.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccLogEntrySerializationStrategyImpl.java
@@ -48,7 +48,7 @@ import org.apache.usergrid.persistence.core.astyanax.IdRowCompositeSerializer;
import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamily;
import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
import org.apache.usergrid.persistence.core.astyanax.ScopedRowKey;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
import org.apache.usergrid.persistence.model.entity.Id;
import com.google.common.base.Preconditions;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/SerializationModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/SerializationModule.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/SerializationModule.java
index 89012aa..8a4a9ac 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/SerializationModule.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/SerializationModule.java
@@ -21,7 +21,7 @@ package org.apache.usergrid.persistence.collection.serialization.impl;
import org.apache.usergrid.persistence.collection.mvcc.MvccEntitySerializationStrategy;
import org.apache.usergrid.persistence.collection.mvcc.MvccLogEntrySerializationStrategy;
import org.apache.usergrid.persistence.collection.serialization.UniqueValueSerializationStrategy;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
import com.google.inject.AbstractModule;
import com.google.inject.multibindings.Multibinder;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java
index 954cd1c..b6b3cab 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java
@@ -38,7 +38,7 @@ import org.apache.usergrid.persistence.core.astyanax.ColumnTypes;
import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamily;
import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
import org.apache.usergrid.persistence.core.astyanax.ScopedRowKey;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
import org.apache.usergrid.persistence.core.util.ValidationUtils;
import org.apache.usergrid.persistence.model.entity.Id;
import org.apache.usergrid.persistence.model.field.Field;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/MigrationManagerRule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/MigrationManagerRule.java b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/MigrationManagerRule.java
index 2d92adb..6b02b63 100644
--- a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/MigrationManagerRule.java
+++ b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/MigrationManagerRule.java
@@ -5,8 +5,8 @@ import org.junit.rules.ExternalResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.usergrid.persistence.core.migration.MigrationException;
-import org.apache.usergrid.persistence.core.migration.MigrationManager;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManager;
import com.google.inject.Inject;
import com.google.inject.Singleton;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestCollectionModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestCollectionModule.java b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestCollectionModule.java
index 0b97eb7..73f1b6d 100644
--- a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestCollectionModule.java
+++ b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestCollectionModule.java
@@ -21,6 +21,7 @@ package org.apache.usergrid.persistence.collection.guice;
import org.apache.usergrid.persistence.core.guice.CommonModule;
+import org.apache.usergrid.persistence.core.guice.TestModule;
public class TestCollectionModule extends TestModule {
@@ -28,6 +29,6 @@ public class TestCollectionModule extends TestModule {
@Override
protected void configure() {
install( new CommonModule() );
- install(new CollectionModule());
+ install( new CollectionModule() );
}
}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestModule.java b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestModule.java
deleted file mode 100644
index 44a8fe3..0000000
--- a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestModule.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.usergrid.persistence.collection.guice;
-
-
-import java.io.IOException;
-
-import com.google.inject.AbstractModule;
-import com.netflix.config.ConfigurationManager;
-
-
-public abstract class TestModule extends AbstractModule {
- static {
- /*
- * --------------------------------------------------------------------
- * Bootstrap the config for Archaius Configuration Settings. We don't want to
- * bootstrap more than once per JVM
- * --------------------------------------------------------------------
- */
-
- try {
- //load up the properties
- ConfigurationManager.getDeploymentContext().setDeploymentEnvironment( "UNIT" );
- ConfigurationManager.loadCascadedPropertiesFromResources( "usergrid" );
-
- }
- catch ( IOException e ) {
- throw new RuntimeException( "Cannot do much without properly loading our configuration.", e );
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImplTest.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImplTest.java b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImplTest.java
index 73cf848..b298768 100644
--- a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImplTest.java
+++ b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImplTest.java
@@ -45,7 +45,7 @@ import org.apache.usergrid.persistence.collection.util.EntityUtils;
import org.apache.usergrid.persistence.core.astyanax.AstyanaxKeyspaceProvider;
import org.apache.usergrid.persistence.core.astyanax.CassandraFig;
import org.apache.usergrid.persistence.core.cassandra.ITRunner;
-import org.apache.usergrid.persistence.core.migration.MigrationManagerFig;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManagerFig;
import org.apache.usergrid.persistence.model.entity.Entity;
import org.apache.usergrid.persistence.model.entity.Id;
import org.apache.usergrid.persistence.model.entity.SimpleId;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/astyanax/StringRowCompositeSerializer.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/astyanax/StringRowCompositeSerializer.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/astyanax/StringRowCompositeSerializer.java
new file mode 100644
index 0000000..3a246a5
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/astyanax/StringRowCompositeSerializer.java
@@ -0,0 +1,68 @@
+/*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one
+ * * or more contributor license agreements. See the NOTICE file
+ * * distributed with this work for additional information
+ * * regarding copyright ownership. The ASF licenses this file
+ * * to you under the Apache License, Version 2.0 (the
+ * * "License"); you may not use this file except in compliance
+ * * with the License. You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing,
+ * * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * * KIND, either express or implied. See the License for the
+ * * specific language governing permissions and limitations
+ * * under the License.
+ *
+ */
+package org.apache.usergrid.persistence.core.astyanax;
+
+
+import java.util.UUID;
+
+import org.apache.usergrid.persistence.model.entity.Id;
+import org.apache.usergrid.persistence.model.entity.SimpleId;
+
+import com.netflix.astyanax.model.CompositeBuilder;
+import com.netflix.astyanax.model.CompositeParser;
+
+
+/**
+ * Serializer for serializing strings
+ *
+ * @author tnine
+ */
+public class StringRowCompositeSerializer implements CompositeFieldSerializer<String> {
+
+
+ private static final StringRowCompositeSerializer INSTANCE = new StringRowCompositeSerializer();
+
+
+ private StringRowCompositeSerializer() {}
+
+
+ @Override
+ public void toComposite( final CompositeBuilder builder, final String string ) {
+ builder.addString( string );
+ }
+
+
+ @Override
+ public String fromComposite( final CompositeParser composite ) {
+ return composite.readString();
+ }
+
+
+
+ /**
+ * Get the singleton serializer
+ */
+ public static StringRowCompositeSerializer get() {
+ return INSTANCE;
+ }
+}
+
+
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java
index 5f461bb..3503178 100644
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java
@@ -27,17 +27,23 @@ import org.apache.usergrid.persistence.core.astyanax.CassandraConfigImpl;
import org.apache.usergrid.persistence.core.astyanax.CassandraFig;
import org.apache.usergrid.persistence.core.consistency.TimeService;
import org.apache.usergrid.persistence.core.consistency.TimeServiceImpl;
-import org.apache.usergrid.persistence.core.migration.MigrationManager;
-import org.apache.usergrid.persistence.core.migration.MigrationManagerFig;
-import org.apache.usergrid.persistence.core.migration.MigrationManagerImpl;
+import org.apache.usergrid.persistence.core.migration.data.DataMigrationManager;
+import org.apache.usergrid.persistence.core.migration.data.DataMigrationManagerImpl;
+import org.apache.usergrid.persistence.core.migration.data.MigrationInfoSerialization;
+import org.apache.usergrid.persistence.core.migration.data.MigrationInfoSerializationImpl;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManager;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManagerFig;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManagerImpl;
import com.google.inject.AbstractModule;
+import com.google.inject.Key;
+import com.google.inject.multibindings.Multibinder;
import com.netflix.astyanax.Keyspace;
/**
* Simple module for configuring our core services. Cassandra etc
- *
*/
public class CommonModule extends AbstractModule {
@@ -45,11 +51,9 @@ public class CommonModule extends AbstractModule {
@Override
protected void configure() {
//noinspection unchecked
- install( new GuicyFigModule(
- MigrationManagerFig.class,
- CassandraFig.class) );
+ install( new GuicyFigModule( MigrationManagerFig.class, CassandraFig.class ) );
- // bind our keyspace to the AstyanaxKeyspaceProvider
+ // bind our keyspace to the AstyanaxKeyspaceProvider
bind( Keyspace.class ).toProvider( AstyanaxKeyspaceProvider.class ).asEagerSingleton();
// bind our migration manager
@@ -59,10 +63,16 @@ public class CommonModule extends AbstractModule {
bind( CassandraConfig.class ).to( CassandraConfigImpl.class );
- }
-
-
+ /**
+ * Data migration beans
+ */
+ bind( MigrationInfoSerialization.class ).to( MigrationInfoSerializationImpl.class );
+ bind( DataMigrationManager.class ).to( DataMigrationManagerImpl.class );
+ //do multibindings for migrations
+ Multibinder<Migration> migrationBinding = Multibinder.newSetBinder( binder(), Migration.class );
+ migrationBinding.addBinding().to( Key.get( MigrationInfoSerialization.class ) );
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/Migration.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/Migration.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/Migration.java
deleted file mode 100644
index 16f8251..0000000
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/Migration.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.usergrid.persistence.core.migration;
-
-
-import java.util.Collection;
-
-import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
-
-
-/**
- * @author tnine
- */
-public interface Migration {
-
- /**
- * Get the column families required for this implementation. If one does not exist it will be created.
- */
- public Collection<MultiTennantColumnFamilyDefinition> getColumnFamilies();
-}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationException.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationException.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationException.java
deleted file mode 100644
index 4862b55..0000000
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationException.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.usergrid.persistence.core.migration;
-
-
-/**
- * Thrown when a migration cannot be performed
- *
- * @author tnine
- */
-public class MigrationException extends Exception {
-
- public MigrationException( final String message ) {
- super( message );
- }
-
-
- public MigrationException( final String message, final Throwable cause ) {
- super( message, cause );
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManager.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManager.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManager.java
deleted file mode 100644
index 98637e0..0000000
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManager.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.usergrid.persistence.core.migration;
-
-
-/**
- * A manager that will perform any migrations necessary. Setup code should invoke the implementation of this interface
- *
- * @author tnine
- */
-public interface MigrationManager {
-
- /**
- * Perform any migration necessary in the application. Will only create keyspaces and column families if they do
- * not exist
- */
- public void migrate() throws MigrationException;
-}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerFig.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerFig.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerFig.java
deleted file mode 100644
index e97dcba..0000000
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerFig.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.apache.usergrid.persistence.core.migration;
-
-
-import org.safehaus.guicyfig.Default;
-import org.safehaus.guicyfig.FigSingleton;
-import org.safehaus.guicyfig.GuicyFig;
-import org.safehaus.guicyfig.Key;
-
-
-/**
- * Configuration for the MigrationManager.
- */
-@FigSingleton
-public interface MigrationManagerFig extends GuicyFig {
- @Key( "collections.keyspace.strategy.class" )
- @Default( "org.apache.cassandra.locator.SimpleStrategy" )
- String getStrategyClass();
-
- @Key( "collections.keyspace.strategy.options" )
- String getStrategyOptions();
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerImpl.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerImpl.java
deleted file mode 100644
index ad30d5b..0000000
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerImpl.java
+++ /dev/null
@@ -1,196 +0,0 @@
-package org.apache.usergrid.persistence.core.migration;
-
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import com.netflix.astyanax.Keyspace;
-import com.netflix.astyanax.connectionpool.exceptions.BadRequestException;
-import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
-import com.netflix.astyanax.ddl.ColumnFamilyDefinition;
-import com.netflix.astyanax.ddl.KeyspaceDefinition;
-
-
-/**
- * Implementation of the migration manager to set up keyspace
- *
- * @author tnine
- */
-@Singleton
-public class MigrationManagerImpl implements MigrationManager {
-
-
- private static final Logger logger = LoggerFactory.getLogger( MigrationManagerImpl.class );
-
- private final Set<Migration> migrations;
- private final Keyspace keyspace;
-
- private final MigrationManagerFig fig;
-
-
- @Inject
- public MigrationManagerImpl( final Keyspace keyspace, final Set<Migration> migrations,
- MigrationManagerFig fig ) {
- this.keyspace = keyspace;
- this.migrations = migrations;
- this.fig = fig;
- }
-
-
- @Override
- public void migrate() throws MigrationException {
-
-
- try {
-
- testAndCreateKeyspace();
-
- for ( Migration migration : migrations ) {
-
- final Collection<MultiTennantColumnFamilyDefinition> columnFamilies = migration.getColumnFamilies();
-
-
- if ( columnFamilies == null || columnFamilies.size() == 0 ) {
- logger.warn(
- "Class {} implements {} but returns null column families for migration. Either implement"
- + " this method or remove the interface from the class", migration.getClass(),
- Migration.class );
- continue;
- }
-
- for ( MultiTennantColumnFamilyDefinition cf : columnFamilies ) {
- testAndCreateColumnFamilyDef( cf );
- }
- }
- }
- catch ( Throwable t ) {
- logger.error( "Unable to perform migration", t );
- throw new MigrationException( "Unable to perform migration", t );
- }
- }
-
-
- /**
- * Check if the column family exists. If it dosn't create it
- */
- private void testAndCreateColumnFamilyDef( MultiTennantColumnFamilyDefinition columnFamily )
- throws ConnectionException {
- final KeyspaceDefinition keyspaceDefinition = keyspace.describeKeyspace();
-
- final ColumnFamilyDefinition existing =
- keyspaceDefinition.getColumnFamily( columnFamily.getColumnFamily().getName() );
-
- if ( existing != null ) {
- return;
- }
-
- keyspace.createColumnFamily( columnFamily.getColumnFamily(), columnFamily.getOptions() );
-
- logger.info( "Created column family {}", columnFamily.getColumnFamily().getName() );
-
- waitForMigration();
- }
-
-
- /**
- * Check if they keyspace exists. If it doesn't create it
- */
- private void testAndCreateKeyspace() throws ConnectionException {
-
-
- KeyspaceDefinition keyspaceDefinition = null;
-
- try {
- keyspaceDefinition = keyspace.describeKeyspace();
- }
- catch ( BadRequestException badRequestException ) {
-
- //check if it's b/c the keyspace is missing, if so
- final String message = badRequestException.getMessage();
-
- boolean missingKeyspace = message.contains( "why:Keyspace" ) && message.contains( "does not exist" );
-
- if ( !missingKeyspace ) {
- throw badRequestException;
- }
- }
-
-
- if ( keyspaceDefinition != null ) {
- return;
- }
-
-
- ImmutableMap.Builder<String, Object> strategyOptions = getKeySpaceProps();
-
-
- ImmutableMap<String, Object> options =
- ImmutableMap.<String, Object>builder().put( "strategy_class", fig.getStrategyClass() )
- .put( "strategy_options", strategyOptions.build() ).build();
-
-
- keyspace.createKeyspace( options );
-
- strategyOptions.toString();
-
- logger.info( "Created keyspace {} with options {}", keyspace.getKeyspaceName(), options.toString() );
-
- waitForMigration();
- }
-
-
- /**
- * Get keyspace properties
- */
- private ImmutableMap.Builder<String, Object> getKeySpaceProps() {
- ImmutableMap.Builder<String, Object> keyspaceProps = ImmutableMap.<String, Object>builder();
-
- String optionString = fig.getStrategyOptions();
-
- if(optionString == null){
- return keyspaceProps;
- }
-
-
-
- for ( String key : optionString.split( "," ) ) {
-
- final String[] options = key.split( ":" );
-
- keyspaceProps.put( options[0], options[1] );
- }
-
- return keyspaceProps;
- }
-
-
- private void waitForMigration() throws ConnectionException {
-
- while ( true ) {
-
- final Map<String, List<String>> versions = keyspace.describeSchemaVersions();
-
- if ( versions != null && versions.size() == 1 ) {
- return;
- }
-
- //sleep and try it again
- try {
- Thread.sleep( 100 );
- }
- catch ( InterruptedException e ) {
- //swallow
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigration.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigration.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigration.java
new file mode 100644
index 0000000..ecf9946
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigration.java
@@ -0,0 +1,84 @@
+/*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one
+ * * or more contributor license agreements. See the NOTICE file
+ * * distributed with this work for additional information
+ * * regarding copyright ownership. The ASF licenses this file
+ * * to you under the Apache License, Version 2.0 (the
+ * * "License"); you may not use this file except in compliance
+ * * with the License. You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing,
+ * * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * * KIND, either express or implied. See the License for the
+ * * specific language governing permissions and limitations
+ * * under the License.
+ *
+ */
+
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+/**
+ * An interface for updating data. Has 2 basic functions. First it will perform the migration and update the status
+ * object.
+ *
+ * Second it will only migrate a single version. For instance, it will migrate from 0->1, or from 1->2. All migrations
+ * must follow the following basic rules.
+ *
+ * <ol>
+ * <li>They must not modify the structure of an existing column family. If the data format changes, a new
+ * implementation and column family must be created. A proxy must be defined to do dual writes/single reads. </li>
+ * <li>The migration must update the progress observer. This information should be made available cluster wide.</li>
+ * <li>In the event a migration fails with an error, we should be able to roll back and remove new column families. We
+ * can then fix the bug, and deploy again. Hence the need for the proxy, dual writes, and an immutable CF
+ * format</li>
+ * </ol>
+ */
+
+
+public interface DataMigration {
+
+
+ /**
+ * Migrate the data to the specified version
+ * @param observer
+ * @throws Throwable
+ */
+ public void migrate(final ProgressObserver observer) throws Throwable;
+
+ /**
+ * Get the version of this migration. It must be unique.
+ * @return
+ */
+ public int getVersion();
+
+ public interface ProgressObserver{
+ /**
+ * Mark the migration as failed
+ * @param migrationVersion The migration version running during the failure
+ * @param reason The reason to save
+ */
+ public void failed(final int migrationVersion, final String reason);
+
+ /**
+ * Mark the migration as failed with a stack trace
+ * @param migrationVersion The migration version running during the failure
+ * @param reason The error description to save
+ * @param throwable The error that happened
+ */
+ public void failed(final int migrationVersion, final String reason, final Throwable throwable);
+
+
+ /**
+ * Update the status of the migration with the message
+ *
+ * @param message The message to save for the status
+ */
+ public void update(final int migrationVersion, final String message);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationException.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationException.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationException.java
new file mode 100644
index 0000000..0e1f29f
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationException.java
@@ -0,0 +1,39 @@
+/*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one
+ * * or more contributor license agreements. See the NOTICE file
+ * * distributed with this work for additional information
+ * * regarding copyright ownership. The ASF licenses this file
+ * * to you under the Apache License, Version 2.0 (the
+ * * "License"); you may not use this file except in compliance
+ * * with the License. You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing,
+ * * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * * KIND, either express or implied. See the License for the
+ * * specific language governing permissions and limitations
+ * * under the License.
+ *
+ */
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+/**
+ * Thrown when a migration cannot be performed
+ *
+ * @author tnine
+ */
+public class DataMigrationException extends RuntimeException {
+
+ public DataMigrationException( final String message ) {
+ super( message );
+ }
+
+
+ public DataMigrationException( final String message, final Throwable cause ) {
+ super( message, cause );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java
new file mode 100644
index 0000000..1d7ccec
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java
@@ -0,0 +1,49 @@
+/*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one
+ * * or more contributor license agreements. See the NOTICE file
+ * * distributed with this work for additional information
+ * * regarding copyright ownership. The ASF licenses this file
+ * * to you under the Apache License, Version 2.0 (the
+ * * "License"); you may not use this file except in compliance
+ * * with the License. You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing,
+ * * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * * KIND, either express or implied. See the License for the
+ * * specific language governing permissions and limitations
+ * * under the License.
+ *
+ */
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
+
+
+/**
+ * A manager that will perform any data migrations necessary. Setup code should invoke the implementation of this interface
+ */
+public interface DataMigrationManager {
+
+ /**
+ * Perform any migration necessary in the application. Will only create keyspaces and column families if they do
+ * not exist
+ */
+ public void migrate() throws MigrationException;
+
+ /**
+ * Returns true if a migration is running. False otherwise
+ * @return
+ */
+ public boolean isRunning();
+
+
+ /**
+ * Return that last status of the migration
+ */
+ public String getLastStatus();
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java
new file mode 100644
index 0000000..ee579ee
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java
@@ -0,0 +1,225 @@
+/*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one
+ * * or more contributor license agreements. See the NOTICE file
+ * * distributed with this work for additional information
+ * * regarding copyright ownership. The ASF licenses this file
+ * * to you under the Apache License, Version 2.0 (the
+ * * "License"); you may not use this file except in compliance
+ * * with the License. You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing,
+ * * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * * KIND, either express or implied. See the License for the
+ * * specific language governing permissions and limitations
+ * * under the License.
+ *
+ */
+
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.NavigableMap;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+
+@Singleton
+public class DataMigrationManagerImpl implements DataMigrationManager {
+
+ private static final Logger LOG = LoggerFactory.getLogger( DataMigrationManagerImpl.class );
+
+ private final TreeMap<Integer, DataMigration> migrationTreeMap = new TreeMap<>();
+
+ private final MigrationInfoSerialization migrationInfoSerialization;
+
+
+ @Inject
+ public DataMigrationManagerImpl( final MigrationInfoSerialization migrationInfoSerialization,
+ final Set<DataMigration> migrations ) {
+ this.migrationInfoSerialization = migrationInfoSerialization;
+
+ for ( DataMigration migration : migrations ) {
+
+ final int version = migration.getVersion();
+
+ final DataMigration existing = migrationTreeMap.get( version );
+
+ if ( existing != null ) {
+
+ final Class<? extends DataMigration> existingClass = existing.getClass();
+
+ final Class<? extends DataMigration> currentClass = migration.getClass();
+
+
+ throw new DataMigrationException(
+ String.format( "Data migrations must be unique. Both classes %s and %s have version %d",
+ existingClass, currentClass, version ) );
+ }
+
+ migrationTreeMap.put( version, migration );
+ }
+ }
+
+
+ @Override
+ public void migrate() throws MigrationException {
+
+ if ( migrationTreeMap.isEmpty() ) {
+ LOG.warn( "No migrations found to run, exiting" );
+ return;
+ }
+
+
+ final int currentVersion = migrationInfoSerialization.getVersion();
+
+ LOG.info( "Saved schema version is {}, max migration version is {}", currentVersion,
+ migrationTreeMap.lastKey() );
+
+ //we have our migrations to run, execute them
+ final NavigableMap<Integer, DataMigration> migrationsToRun = migrationTreeMap.tailMap( currentVersion, false );
+
+ CassandraProgressObserver observer = new CassandraProgressObserver();
+
+
+ for ( DataMigration migration : migrationsToRun.values() ) {
+
+ migrationInfoSerialization.setStatusCode( StatusCode.RUNNING.status );
+
+ final int migrationVersion = migration.getVersion();
+
+ LOG.info( "Running migration version {}", migrationVersion );
+
+ observer.update( migrationVersion, "Starting migration" );
+
+
+ //perform this migration, if it fails, short circuit
+ try {
+ migration.migrate( observer );
+ }
+ catch ( Throwable throwable ) {
+ observer.failed( migrationVersion, "Exception thrown during migration", throwable );
+
+ LOG.error( "Unable to migration version {}.", migrationVersion, throwable );
+
+ return;
+ }
+
+ //we had an unhandled exception or the migration failed, short circuit
+ if(observer.failed){
+ return;
+ }
+
+ //set the version
+ migrationInfoSerialization.setVersion( migrationVersion );
+
+ //update the observer for progress so other nodes can see it
+ observer.update( migrationVersion, "Completed successfully" );
+
+
+ }
+
+ migrationInfoSerialization.setStatusCode( StatusCode.COMPLETE.status );
+
+
+ }
+
+
+ @Override
+ public boolean isRunning() {
+ return migrationInfoSerialization.getStatusCode() == StatusCode.RUNNING.status;
+ }
+
+
+ @Override
+ public String getLastStatus() {
+ return migrationInfoSerialization.getStatusMessage();
+ }
+
+
+ /**
+ * Different status enums
+ */
+ public enum StatusCode{
+ COMPLETE(1),
+ RUNNING(2),
+ ERROR(3);
+
+ public final int status;
+
+
+ StatusCode( final int status ) {this.status = status;}
+ }
+
+
+ private final class CassandraProgressObserver implements DataMigration.ProgressObserver {
+
+ private boolean failed = false;
+
+
+
+ @Override
+ public void failed( final int migrationVersion, final String reason ) {
+
+ final String storedMessage = String.format( "Failed to migrate, reason is appended. Error '%s'", reason);
+
+
+ update(migrationVersion, storedMessage );
+
+ LOG.error( storedMessage );
+
+ failed = true;
+
+ migrationInfoSerialization.setStatusCode( StatusCode.ERROR.status );
+ }
+
+
+ @Override
+ public void failed( final int migrationVersion, final String reason, final Throwable throwable ) {
+ StringWriter stackTrace = new StringWriter();
+ throwable.printStackTrace( new PrintWriter( stackTrace ) );
+
+
+ final String storedMessage = String.format( "Failed to migrate, reason is appended. Error '%s' %s", reason, stackTrace.toString() );
+
+ update(migrationVersion, storedMessage );
+
+
+ LOG.error( "Unable to migrate version {} due to reason {}.", migrationVersion, reason, throwable );
+
+ failed = true;
+
+ migrationInfoSerialization.setStatusCode( StatusCode.ERROR.status );
+ }
+
+
+ @Override
+ public void update( final int migrationVersion, final String message ) {
+ final String error = String.format( "Migration version %d. %s", migrationVersion, message);
+
+ migrationInfoSerialization.setStatusMessage( error );
+ }
+
+
+ /**
+ * Return true if we failed
+ * @return
+ */
+ public boolean isFailed() {
+ return failed;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerialization.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerialization.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerialization.java
new file mode 100644
index 0000000..5cd8a76
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerialization.java
@@ -0,0 +1,66 @@
+/*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one
+ * * or more contributor license agreements. See the NOTICE file
+ * * distributed with this work for additional information
+ * * regarding copyright ownership. The ASF licenses this file
+ * * to you under the Apache License, Version 2.0 (the
+ * * "License"); you may not use this file except in compliance
+ * * with the License. You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing,
+ * * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * * KIND, either express or implied. See the License for the
+ * * specific language governing permissions and limitations
+ * * under the License.
+ *
+ */
+
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
+
+
+public interface MigrationInfoSerialization extends Migration {
+
+ /**
+ * Save the message to the cluster
+ * @param message
+ */
+ public void setStatusMessage( final String message );
+
+ /**
+ * Get the last status
+ * @return
+ */
+ public String getStatusMessage();
+
+ /**
+ * Save the version
+ * @param version
+ */
+ public void setVersion(final int version);
+
+ /**
+ * Return the version
+ * @return
+ */
+ public int getVersion();
+
+ /**
+ * Set the status and save them
+ * @param status
+ * @return
+ */
+ public void setStatusCode( final int status );
+
+ /**
+ *
+ * @return The integer that's saved
+ */
+ public int getStatusCode();
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerializationImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerializationImpl.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerializationImpl.java
new file mode 100644
index 0000000..0460e33
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerializationImpl.java
@@ -0,0 +1,178 @@
+/*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one
+ * * or more contributor license agreements. See the NOTICE file
+ * * distributed with this work for additional information
+ * * regarding copyright ownership. The ASF licenses this file
+ * * to you under the Apache License, Version 2.0 (the
+ * * "License"); you may not use this file except in compliance
+ * * with the License. You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing,
+ * * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * * KIND, either express or implied. See the License for the
+ * * specific language governing permissions and limitations
+ * * under the License.
+ *
+ */
+
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.UUID;
+
+import org.apache.cassandra.db.marshal.BytesType;
+import org.apache.cassandra.db.marshal.UTF8Type;
+
+import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamily;
+import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
+import org.apache.usergrid.persistence.core.astyanax.ScopedRowKey;
+import org.apache.usergrid.persistence.core.astyanax.ScopedRowKeySerializer;
+import org.apache.usergrid.persistence.core.astyanax.StringRowCompositeSerializer;
+import org.apache.usergrid.persistence.model.entity.Id;
+import org.apache.usergrid.persistence.model.entity.SimpleId;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.netflix.astyanax.Keyspace;
+import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
+import com.netflix.astyanax.connectionpool.exceptions.NotFoundException;
+import com.netflix.astyanax.serializers.StringSerializer;
+
+
+@Singleton
+public class MigrationInfoSerializationImpl implements MigrationInfoSerialization {
+
+
+ /**
+ * Just a hard coded scope since we need it
+ */
+ private static final Id STATIC_ID =
+ new SimpleId( UUID.fromString( "00000000-0000-1000-8000-000000000000" ), "status" );
+
+
+ private static final ScopedRowKeySerializer<String> ROW_KEY_SER =
+ new ScopedRowKeySerializer<String>( StringRowCompositeSerializer.get() );
+
+ private static final StringSerializer STRING_SERIALIZER = StringSerializer.get();
+
+
+ private static final MultiTennantColumnFamily<ScopedRowKey<String>, String> CF_MIGRATION_INFO =
+ new MultiTennantColumnFamily<>( "Data_Migration_Info", ROW_KEY_SER, STRING_SERIALIZER );
+
+
+ private static final ScopedRowKey<String> ROW_KEY = ScopedRowKey.fromKey( STATIC_ID, "" );
+
+ private static final String COL_STATUS_MESSAGE = "statusMessage";
+
+ private static final String COLUMN_VERSION = "version";
+
+ private static final String COLUMN_STATUS_CODE = "statusCode";
+
+ private final Keyspace keyspace;
+
+
+ @Inject
+ public MigrationInfoSerializationImpl( final Keyspace keyspace ) {
+ this.keyspace = keyspace;
+ }
+
+
+ @Override
+ public void setStatusMessage( final String message ) {
+
+ try {
+ keyspace.prepareColumnMutation( CF_MIGRATION_INFO, ROW_KEY, COL_STATUS_MESSAGE ).putValue( message, null )
+ .execute();
+ }
+ catch ( ConnectionException e ) {
+ throw new DataMigrationException( "Unable to save status", e );
+ }
+ }
+
+
+ @Override
+ public String getStatusMessage() {
+ try {
+ return keyspace.prepareQuery( CF_MIGRATION_INFO ).getKey( ROW_KEY ).getColumn( COL_STATUS_MESSAGE )
+ .execute().getResult().getStringValue();
+ }
+ //swallow, it doesn't exist
+ catch ( NotFoundException nfe ) {
+ return null;
+ }
+ catch ( ConnectionException e ) {
+ throw new DataMigrationException( "Unable to retrieve status", e );
+ }
+ }
+
+
+ @Override
+ public void setVersion( final int version ) {
+ try {
+ keyspace.prepareColumnMutation( CF_MIGRATION_INFO, ROW_KEY, COLUMN_VERSION ).putValue( version, null )
+ .execute();
+ }
+ catch ( ConnectionException e ) {
+ throw new DataMigrationException( "Unable to save status", e );
+ }
+ }
+
+
+ @Override
+ public int getVersion() {
+ try {
+ return keyspace.prepareQuery( CF_MIGRATION_INFO ).getKey( ROW_KEY ).getColumn( COLUMN_VERSION ).execute()
+ .getResult().getIntegerValue();
+ }
+ //swallow, it doesn't exist
+ catch ( NotFoundException nfe ) {
+ return 0;
+ }
+ catch ( ConnectionException e ) {
+ throw new DataMigrationException( "Unable to retrieve status", e );
+ }
+ }
+
+
+ @Override
+ public void setStatusCode( final int status ) {
+ try {
+ keyspace.prepareColumnMutation( CF_MIGRATION_INFO, ROW_KEY, COLUMN_STATUS_CODE ).putValue( status, null )
+ .execute();
+ }
+ catch ( ConnectionException e ) {
+ throw new DataMigrationException( "Unable to save status", e );
+ }
+ }
+
+
+ @Override
+ public int getStatusCode() {
+ try {
+ return keyspace.prepareQuery( CF_MIGRATION_INFO ).getKey( ROW_KEY ).getColumn( COLUMN_STATUS_CODE )
+ .execute().getResult().getIntegerValue();
+ }
+ //swallow, it doesn't exist
+ catch ( NotFoundException nfe ) {
+ return 0;
+ }
+ catch ( ConnectionException e ) {
+ throw new DataMigrationException( "Unable to retrieve status", e );
+ }
+ }
+
+
+ @Override
+ public Collection<MultiTennantColumnFamilyDefinition> getColumnFamilies() {
+ return Collections.singletonList(
+ new MultiTennantColumnFamilyDefinition( CF_MIGRATION_INFO, BytesType.class.getSimpleName(),
+ UTF8Type.class.getSimpleName(), BytesType.class.getSimpleName(),
+ MultiTennantColumnFamilyDefinition.CacheOption.KEYS ) );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/Migration.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/Migration.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/Migration.java
new file mode 100644
index 0000000..fdf483a
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/Migration.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.usergrid.persistence.core.migration.schema;
+
+
+import java.util.Collection;
+
+import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
+
+
+/**
+ * @author tnine
+ */
+public interface Migration {
+
+ /**
+ * Get the column families required for this implementation. If one does not exist it will be created.
+ */
+ public Collection<MultiTennantColumnFamilyDefinition> getColumnFamilies();
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationException.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationException.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationException.java
new file mode 100644
index 0000000..63a1297
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationException.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.usergrid.persistence.core.migration.schema;
+
+
+/**
+ * Thrown when a migration cannot be performed
+ *
+ * @author tnine
+ */
+public class MigrationException extends Exception {
+
+ public MigrationException( final String message ) {
+ super( message );
+ }
+
+
+ public MigrationException( final String message, final Throwable cause ) {
+ super( message, cause );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManager.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManager.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManager.java
new file mode 100644
index 0000000..df84247
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManager.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.usergrid.persistence.core.migration.schema;
+
+
+/**
+ * A manager that will perform any migrations necessary. Setup code should invoke the implementation of this interface
+ *
+ * @author tnine
+ */
+public interface MigrationManager {
+
+ /**
+ * Perform any migration necessary in the application. Will only create keyspaces and column families if they do
+ * not exist
+ */
+ public void migrate() throws MigrationException;
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerFig.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerFig.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerFig.java
new file mode 100644
index 0000000..9595020
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerFig.java
@@ -0,0 +1,22 @@
+package org.apache.usergrid.persistence.core.migration.schema;
+
+
+import org.safehaus.guicyfig.Default;
+import org.safehaus.guicyfig.FigSingleton;
+import org.safehaus.guicyfig.GuicyFig;
+import org.safehaus.guicyfig.Key;
+
+
+/**
+ * Configuration for the MigrationManager.
+ */
+@FigSingleton
+public interface MigrationManagerFig extends GuicyFig {
+ @Key( "collections.keyspace.strategy.class" )
+ @Default( "org.apache.cassandra.locator.SimpleStrategy" )
+ String getStrategyClass();
+
+ @Key( "collections.keyspace.strategy.options" )
+ String getStrategyOptions();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerImpl.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerImpl.java
new file mode 100644
index 0000000..70ab713
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerImpl.java
@@ -0,0 +1,196 @@
+package org.apache.usergrid.persistence.core.migration.schema;
+
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.netflix.astyanax.Keyspace;
+import com.netflix.astyanax.connectionpool.exceptions.BadRequestException;
+import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
+import com.netflix.astyanax.ddl.ColumnFamilyDefinition;
+import com.netflix.astyanax.ddl.KeyspaceDefinition;
+
+
+/**
+ * Implementation of the migration manager to set up keyspace
+ *
+ * @author tnine
+ */
+@Singleton
+public class MigrationManagerImpl implements MigrationManager {
+
+
+ private static final Logger logger = LoggerFactory.getLogger( MigrationManagerImpl.class );
+
+ private final Set<Migration> migrations;
+ private final Keyspace keyspace;
+
+ private final MigrationManagerFig fig;
+
+
+ @Inject
+ public MigrationManagerImpl( final Keyspace keyspace, final Set<Migration> migrations,
+ MigrationManagerFig fig ) {
+ this.keyspace = keyspace;
+ this.migrations = migrations;
+ this.fig = fig;
+ }
+
+
+ @Override
+ public void migrate() throws MigrationException {
+
+
+ try {
+
+ testAndCreateKeyspace();
+
+ for ( Migration migration : migrations ) {
+
+ final Collection<MultiTennantColumnFamilyDefinition> columnFamilies = migration.getColumnFamilies();
+
+
+ if ( columnFamilies == null || columnFamilies.size() == 0 ) {
+ logger.warn(
+ "Class {} implements {} but returns null column families for migration. Either implement"
+ + " this method or remove the interface from the class", migration.getClass(),
+ Migration.class );
+ continue;
+ }
+
+ for ( MultiTennantColumnFamilyDefinition cf : columnFamilies ) {
+ testAndCreateColumnFamilyDef( cf );
+ }
+ }
+ }
+ catch ( Throwable t ) {
+ logger.error( "Unable to perform migration", t );
+ throw new MigrationException( "Unable to perform migration", t );
+ }
+ }
+
+
+ /**
+ * Check if the column family exists. If it dosn't create it
+ */
+ private void testAndCreateColumnFamilyDef( MultiTennantColumnFamilyDefinition columnFamily )
+ throws ConnectionException {
+ final KeyspaceDefinition keyspaceDefinition = keyspace.describeKeyspace();
+
+ final ColumnFamilyDefinition existing =
+ keyspaceDefinition.getColumnFamily( columnFamily.getColumnFamily().getName() );
+
+ if ( existing != null ) {
+ return;
+ }
+
+ keyspace.createColumnFamily( columnFamily.getColumnFamily(), columnFamily.getOptions() );
+
+ logger.info( "Created column family {}", columnFamily.getColumnFamily().getName() );
+
+ waitForMigration();
+ }
+
+
+ /**
+ * Check if they keyspace exists. If it doesn't create it
+ */
+ private void testAndCreateKeyspace() throws ConnectionException {
+
+
+ KeyspaceDefinition keyspaceDefinition = null;
+
+ try {
+ keyspaceDefinition = keyspace.describeKeyspace();
+ }
+ catch ( BadRequestException badRequestException ) {
+
+ //check if it's b/c the keyspace is missing, if so
+ final String message = badRequestException.getMessage();
+
+ boolean missingKeyspace = message.contains( "why:Keyspace" ) && message.contains( "does not exist" );
+
+ if ( !missingKeyspace ) {
+ throw badRequestException;
+ }
+ }
+
+
+ if ( keyspaceDefinition != null ) {
+ return;
+ }
+
+
+ ImmutableMap.Builder<String, Object> strategyOptions = getKeySpaceProps();
+
+
+ ImmutableMap<String, Object> options =
+ ImmutableMap.<String, Object>builder().put( "strategy_class", fig.getStrategyClass() )
+ .put( "strategy_options", strategyOptions.build() ).build();
+
+
+ keyspace.createKeyspace( options );
+
+ strategyOptions.toString();
+
+ logger.info( "Created keyspace {} with options {}", keyspace.getKeyspaceName(), options.toString() );
+
+ waitForMigration();
+ }
+
+
+ /**
+ * Get keyspace properties
+ */
+ private ImmutableMap.Builder<String, Object> getKeySpaceProps() {
+ ImmutableMap.Builder<String, Object> keyspaceProps = ImmutableMap.<String, Object>builder();
+
+ String optionString = fig.getStrategyOptions();
+
+ if(optionString == null){
+ return keyspaceProps;
+ }
+
+
+
+ for ( String key : optionString.split( "," ) ) {
+
+ final String[] options = key.split( ":" );
+
+ keyspaceProps.put( options[0], options[1] );
+ }
+
+ return keyspaceProps;
+ }
+
+
+ private void waitForMigration() throws ConnectionException {
+
+ while ( true ) {
+
+ final Map<String, List<String>> versions = keyspace.describeSchemaVersions();
+
+ if ( versions != null && versions.size() == 1 ) {
+ return;
+ }
+
+ //sleep and try it again
+ try {
+ Thread.sleep( 100 );
+ }
+ catch ( InterruptedException e ) {
+ //swallow
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/MigrationManagerRule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/MigrationManagerRule.java b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/MigrationManagerRule.java
index 3b3a45f..522af61 100644
--- a/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/MigrationManagerRule.java
+++ b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/MigrationManagerRule.java
@@ -5,8 +5,8 @@ import org.junit.rules.ExternalResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.usergrid.persistence.core.migration.MigrationException;
-import org.apache.usergrid.persistence.core.migration.MigrationManager;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManager;
import com.google.inject.Inject;
import com.google.inject.Singleton;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestCommonModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestCommonModule.java b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestCommonModule.java
new file mode 100644
index 0000000..04f1d47
--- /dev/null
+++ b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestCommonModule.java
@@ -0,0 +1,34 @@
+/*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one
+ * * or more contributor license agreements. See the NOTICE file
+ * * distributed with this work for additional information
+ * * regarding copyright ownership. The ASF licenses this file
+ * * to you under the Apache License, Version 2.0 (the
+ * * "License"); you may not use this file except in compliance
+ * * with the License. You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing,
+ * * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * * KIND, either express or implied. See the License for the
+ * * specific language governing permissions and limitations
+ * * under the License.
+ *
+ */
+
+package org.apache.usergrid.persistence.core.guice;
+
+
+/**
+ * Module for testing common frameworks
+ */
+public class TestCommonModule extends TestModule {
+
+ @Override
+ protected void configure() {
+ install(new CommonModule());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestModule.java b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestModule.java
new file mode 100644
index 0000000..9b175da
--- /dev/null
+++ b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestModule.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.usergrid.persistence.core.guice;
+
+
+import java.io.IOException;
+
+import com.google.inject.AbstractModule;
+import com.netflix.config.ConfigurationManager;
+
+
+public abstract class TestModule extends AbstractModule {
+ static {
+ /*
+ * --------------------------------------------------------------------
+ * Bootstrap the config for Archaius Configuration Settings. We don't want to
+ * bootstrap more than once per JVM
+ * --------------------------------------------------------------------
+ */
+
+ try {
+ //load up the properties
+ ConfigurationManager.getDeploymentContext().setDeploymentEnvironment( "UNIT" );
+ ConfigurationManager.loadCascadedPropertiesFromResources( "usergrid" );
+
+ }
+ catch ( IOException e ) {
+ throw new RuntimeException( "Cannot do much without properly loading our configuration.", e );
+ }
+ }
+}