You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by to...@apache.org on 2014/10/29 21:33:40 UTC
[2/3] git commit: Updated migrations to separate data migrations and
schema migrations.
Updated migrations to separate data migrations and schema migrations.
Project: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/commit/dfed6a02
Tree: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/tree/dfed6a02
Diff: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/diff/dfed6a02
Branch: refs/heads/key-row-sharding
Commit: dfed6a025a7fcb4c49decb4b3cf8bee37abeb1e7
Parents: ca943fe
Author: Todd Nine <tn...@apigee.com>
Authored: Wed Oct 29 10:51:43 2014 -0600
Committer: Todd Nine <tn...@apigee.com>
Committed: Wed Oct 29 10:51:43 2014 -0600
----------------------------------------------------------------------
.../usergrid/corepersistence/CpSetup.java | 6 +-
.../MvccEntitySerializationStrategyImpl.java | 2 +-
.../MvccLogEntrySerializationStrategyImpl.java | 2 +-
.../serialization/impl/SerializationModule.java | 2 +-
.../UniqueValueSerializationStrategyImpl.java | 2 +-
.../collection/guice/MigrationManagerRule.java | 4 +-
.../collection/guice/TestCollectionModule.java | 3 +-
.../collection/guice/TestModule.java | 48 ----
...MvccEntitySerializationStrategyImplTest.java | 2 +-
.../astyanax/StringRowCompositeSerializer.java | 68 ++++++
.../persistence/core/guice/CommonModule.java | 32 ++-
.../persistence/core/migration/Migration.java | 36 ---
.../core/migration/MigrationException.java | 37 ---
.../core/migration/MigrationManager.java | 34 ---
.../core/migration/MigrationManagerFig.java | 22 --
.../core/migration/MigrationManagerImpl.java | 196 ----------------
.../core/migration/data/DataMigration.java | 84 +++++++
.../migration/data/DataMigrationException.java | 39 ++++
.../migration/data/DataMigrationManager.java | 49 ++++
.../data/DataMigrationManagerImpl.java | 225 +++++++++++++++++++
.../data/MigrationInfoSerialization.java | 66 ++++++
.../data/MigrationInfoSerializationImpl.java | 178 +++++++++++++++
.../core/migration/schema/Migration.java | 36 +++
.../migration/schema/MigrationException.java | 37 +++
.../core/migration/schema/MigrationManager.java | 34 +++
.../migration/schema/MigrationManagerFig.java | 22 ++
.../migration/schema/MigrationManagerImpl.java | 196 ++++++++++++++++
.../core/guice/MigrationManagerRule.java | 4 +-
.../core/guice/TestCommonModule.java | 34 +++
.../persistence/core/guice/TestModule.java | 48 ++++
.../data/DataMigrationManagerImplTest.java | 220 ++++++++++++++++++
.../data/MigrationInfoSerializationTest.java | 104 +++++++++
.../persistence/graph/guice/GraphModule.java | 2 +-
.../EdgeMetadataSerialization.java | 2 +-
.../graph/serialization/NodeSerialization.java | 2 +-
.../impl/EdgeMetadataSerializationV1Impl.java | 2 +-
.../impl/EdgeMetadataSerializationV2Impl.java | 2 +-
.../impl/NodeSerializationImpl.java | 2 +-
.../impl/shard/EdgeColumnFamilies.java | 3 +-
.../impl/shard/EdgeShardSerialization.java | 2 +-
.../count/NodeShardCounterSerialization.java | 2 +-
.../graph/GraphManagerShardConsistencyIT.java | 4 +-
.../graph/guice/TestGraphModule.java | 2 +-
.../persistence/map/guice/MapModule.java | 2 +-
.../persistence/map/impl/MapSerialization.java | 2 +-
.../persistence/map/guice/TestMapModule.java | 2 +-
.../index/guice/TestIndexModule.java | 2 +-
.../queue/guice/TestQueueModule.java | 2 +-
48 files changed, 1492 insertions(+), 415 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpSetup.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpSetup.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpSetup.java
index c1bab12..4b4ded6 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpSetup.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpSetup.java
@@ -22,7 +22,7 @@ import com.google.inject.Injector;
import com.netflix.config.ConfigurationManager;
import java.util.Properties;
import java.util.UUID;
-import java.util.logging.Level;
+
import me.prettyprint.cassandra.service.CassandraHost;
import me.prettyprint.hector.api.ddl.ComparatorType;
import static me.prettyprint.hector.api.factory.HFactory.createColumnFamilyDefinition;
@@ -44,8 +44,8 @@ import static org.apache.usergrid.persistence.cassandra.CassandraService.TOKENS_
import static org.apache.usergrid.persistence.cassandra.CassandraService.USE_VIRTUAL_KEYSPACES;
import static org.apache.usergrid.persistence.cassandra.CassandraService.keyspaceForApplication;
import org.apache.usergrid.persistence.cassandra.Setup;
-import org.apache.usergrid.persistence.core.migration.MigrationException;
-import org.apache.usergrid.persistence.core.migration.MigrationManager;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManager;
import org.apache.usergrid.persistence.entities.Application;
import org.apache.usergrid.persistence.exceptions.ApplicationAlreadyExistsException;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImpl.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImpl.java
index dfa41ea..dc12087 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImpl.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImpl.java
@@ -49,7 +49,7 @@ import org.apache.usergrid.persistence.core.astyanax.IdRowCompositeSerializer;
import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamily;
import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
import org.apache.usergrid.persistence.core.astyanax.ScopedRowKey;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
import org.apache.usergrid.persistence.model.entity.Entity;
import org.apache.usergrid.persistence.model.entity.Id;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccLogEntrySerializationStrategyImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccLogEntrySerializationStrategyImpl.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccLogEntrySerializationStrategyImpl.java
index 8577fbf..7368e9a 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccLogEntrySerializationStrategyImpl.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccLogEntrySerializationStrategyImpl.java
@@ -48,7 +48,7 @@ import org.apache.usergrid.persistence.core.astyanax.IdRowCompositeSerializer;
import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamily;
import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
import org.apache.usergrid.persistence.core.astyanax.ScopedRowKey;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
import org.apache.usergrid.persistence.model.entity.Id;
import com.google.common.base.Preconditions;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/SerializationModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/SerializationModule.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/SerializationModule.java
index 89012aa..8a4a9ac 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/SerializationModule.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/SerializationModule.java
@@ -21,7 +21,7 @@ package org.apache.usergrid.persistence.collection.serialization.impl;
import org.apache.usergrid.persistence.collection.mvcc.MvccEntitySerializationStrategy;
import org.apache.usergrid.persistence.collection.mvcc.MvccLogEntrySerializationStrategy;
import org.apache.usergrid.persistence.collection.serialization.UniqueValueSerializationStrategy;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
import com.google.inject.AbstractModule;
import com.google.inject.multibindings.Multibinder;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java
index 954cd1c..b6b3cab 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java
@@ -38,7 +38,7 @@ import org.apache.usergrid.persistence.core.astyanax.ColumnTypes;
import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamily;
import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
import org.apache.usergrid.persistence.core.astyanax.ScopedRowKey;
-import org.apache.usergrid.persistence.core.migration.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
import org.apache.usergrid.persistence.core.util.ValidationUtils;
import org.apache.usergrid.persistence.model.entity.Id;
import org.apache.usergrid.persistence.model.field.Field;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/MigrationManagerRule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/MigrationManagerRule.java b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/MigrationManagerRule.java
index 2d92adb..6b02b63 100644
--- a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/MigrationManagerRule.java
+++ b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/MigrationManagerRule.java
@@ -5,8 +5,8 @@ import org.junit.rules.ExternalResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.usergrid.persistence.core.migration.MigrationException;
-import org.apache.usergrid.persistence.core.migration.MigrationManager;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManager;
import com.google.inject.Inject;
import com.google.inject.Singleton;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestCollectionModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestCollectionModule.java b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestCollectionModule.java
index 0b97eb7..73f1b6d 100644
--- a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestCollectionModule.java
+++ b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestCollectionModule.java
@@ -21,6 +21,7 @@ package org.apache.usergrid.persistence.collection.guice;
import org.apache.usergrid.persistence.core.guice.CommonModule;
+import org.apache.usergrid.persistence.core.guice.TestModule;
public class TestCollectionModule extends TestModule {
@@ -28,6 +29,6 @@ public class TestCollectionModule extends TestModule {
@Override
protected void configure() {
install( new CommonModule() );
- install(new CollectionModule());
+ install( new CollectionModule() );
}
}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestModule.java b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestModule.java
deleted file mode 100644
index 44a8fe3..0000000
--- a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/guice/TestModule.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.usergrid.persistence.collection.guice;
-
-
-import java.io.IOException;
-
-import com.google.inject.AbstractModule;
-import com.netflix.config.ConfigurationManager;
-
-
-public abstract class TestModule extends AbstractModule {
- static {
- /*
- * --------------------------------------------------------------------
- * Bootstrap the config for Archaius Configuration Settings. We don't want to
- * bootstrap more than once per JVM
- * --------------------------------------------------------------------
- */
-
- try {
- //load up the properties
- ConfigurationManager.getDeploymentContext().setDeploymentEnvironment( "UNIT" );
- ConfigurationManager.loadCascadedPropertiesFromResources( "usergrid" );
-
- }
- catch ( IOException e ) {
- throw new RuntimeException( "Cannot do much without properly loading our configuration.", e );
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImplTest.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImplTest.java b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImplTest.java
index 73cf848..b298768 100644
--- a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImplTest.java
+++ b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/impl/MvccEntitySerializationStrategyImplTest.java
@@ -45,7 +45,7 @@ import org.apache.usergrid.persistence.collection.util.EntityUtils;
import org.apache.usergrid.persistence.core.astyanax.AstyanaxKeyspaceProvider;
import org.apache.usergrid.persistence.core.astyanax.CassandraFig;
import org.apache.usergrid.persistence.core.cassandra.ITRunner;
-import org.apache.usergrid.persistence.core.migration.MigrationManagerFig;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManagerFig;
import org.apache.usergrid.persistence.model.entity.Entity;
import org.apache.usergrid.persistence.model.entity.Id;
import org.apache.usergrid.persistence.model.entity.SimpleId;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/astyanax/StringRowCompositeSerializer.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/astyanax/StringRowCompositeSerializer.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/astyanax/StringRowCompositeSerializer.java
new file mode 100644
index 0000000..3a246a5
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/astyanax/StringRowCompositeSerializer.java
@@ -0,0 +1,68 @@
+/*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one
+ * * or more contributor license agreements. See the NOTICE file
+ * * distributed with this work for additional information
+ * * regarding copyright ownership. The ASF licenses this file
+ * * to you under the Apache License, Version 2.0 (the
+ * * "License"); you may not use this file except in compliance
+ * * with the License. You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing,
+ * * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * * KIND, either express or implied. See the License for the
+ * * specific language governing permissions and limitations
+ * * under the License.
+ *
+ */
+package org.apache.usergrid.persistence.core.astyanax;
+
+
+import java.util.UUID;
+
+import org.apache.usergrid.persistence.model.entity.Id;
+import org.apache.usergrid.persistence.model.entity.SimpleId;
+
+import com.netflix.astyanax.model.CompositeBuilder;
+import com.netflix.astyanax.model.CompositeParser;
+
+
+/**
+ * Serializer for serializing strings
+ *
+ * @author tnine
+ */
+public class StringRowCompositeSerializer implements CompositeFieldSerializer<String> {
+
+
+ private static final StringRowCompositeSerializer INSTANCE = new StringRowCompositeSerializer();
+
+
+ private StringRowCompositeSerializer() {}
+
+
+ @Override
+ public void toComposite( final CompositeBuilder builder, final String string ) {
+ builder.addString( string );
+ }
+
+
+ @Override
+ public String fromComposite( final CompositeParser composite ) {
+ return composite.readString();
+ }
+
+
+
+ /**
+ * Get the singleton serializer
+ */
+ public static StringRowCompositeSerializer get() {
+ return INSTANCE;
+ }
+}
+
+
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java
index 5f461bb..3503178 100644
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/guice/CommonModule.java
@@ -27,17 +27,23 @@ import org.apache.usergrid.persistence.core.astyanax.CassandraConfigImpl;
import org.apache.usergrid.persistence.core.astyanax.CassandraFig;
import org.apache.usergrid.persistence.core.consistency.TimeService;
import org.apache.usergrid.persistence.core.consistency.TimeServiceImpl;
-import org.apache.usergrid.persistence.core.migration.MigrationManager;
-import org.apache.usergrid.persistence.core.migration.MigrationManagerFig;
-import org.apache.usergrid.persistence.core.migration.MigrationManagerImpl;
+import org.apache.usergrid.persistence.core.migration.data.DataMigrationManager;
+import org.apache.usergrid.persistence.core.migration.data.DataMigrationManagerImpl;
+import org.apache.usergrid.persistence.core.migration.data.MigrationInfoSerialization;
+import org.apache.usergrid.persistence.core.migration.data.MigrationInfoSerializationImpl;
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManager;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManagerFig;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManagerImpl;
import com.google.inject.AbstractModule;
+import com.google.inject.Key;
+import com.google.inject.multibindings.Multibinder;
import com.netflix.astyanax.Keyspace;
/**
* Simple module for configuring our core services. Cassandra etc
- *
*/
public class CommonModule extends AbstractModule {
@@ -45,11 +51,9 @@ public class CommonModule extends AbstractModule {
@Override
protected void configure() {
//noinspection unchecked
- install( new GuicyFigModule(
- MigrationManagerFig.class,
- CassandraFig.class) );
+ install( new GuicyFigModule( MigrationManagerFig.class, CassandraFig.class ) );
- // bind our keyspace to the AstyanaxKeyspaceProvider
+ // bind our keyspace to the AstyanaxKeyspaceProvider
bind( Keyspace.class ).toProvider( AstyanaxKeyspaceProvider.class ).asEagerSingleton();
// bind our migration manager
@@ -59,10 +63,16 @@ public class CommonModule extends AbstractModule {
bind( CassandraConfig.class ).to( CassandraConfigImpl.class );
- }
-
-
+ /**
+ * Data migration beans
+ */
+ bind( MigrationInfoSerialization.class ).to( MigrationInfoSerializationImpl.class );
+ bind( DataMigrationManager.class ).to( DataMigrationManagerImpl.class );
+ //do multibindings for migrations
+ Multibinder<Migration> migrationBinding = Multibinder.newSetBinder( binder(), Migration.class );
+ migrationBinding.addBinding().to( Key.get( MigrationInfoSerialization.class ) );
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/Migration.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/Migration.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/Migration.java
deleted file mode 100644
index 16f8251..0000000
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/Migration.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.usergrid.persistence.core.migration;
-
-
-import java.util.Collection;
-
-import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
-
-
-/**
- * @author tnine
- */
-public interface Migration {
-
- /**
- * Get the column families required for this implementation. If one does not exist it will be created.
- */
- public Collection<MultiTennantColumnFamilyDefinition> getColumnFamilies();
-}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationException.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationException.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationException.java
deleted file mode 100644
index 4862b55..0000000
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationException.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.usergrid.persistence.core.migration;
-
-
-/**
- * Thrown when a migration cannot be performed
- *
- * @author tnine
- */
-public class MigrationException extends Exception {
-
- public MigrationException( final String message ) {
- super( message );
- }
-
-
- public MigrationException( final String message, final Throwable cause ) {
- super( message, cause );
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManager.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManager.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManager.java
deleted file mode 100644
index 98637e0..0000000
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManager.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.usergrid.persistence.core.migration;
-
-
-/**
- * A manager that will perform any migrations necessary. Setup code should invoke the implementation of this interface
- *
- * @author tnine
- */
-public interface MigrationManager {
-
- /**
- * Perform any migration necessary in the application. Will only create keyspaces and column families if they do
- * not exist
- */
- public void migrate() throws MigrationException;
-}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerFig.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerFig.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerFig.java
deleted file mode 100644
index e97dcba..0000000
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerFig.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.apache.usergrid.persistence.core.migration;
-
-
-import org.safehaus.guicyfig.Default;
-import org.safehaus.guicyfig.FigSingleton;
-import org.safehaus.guicyfig.GuicyFig;
-import org.safehaus.guicyfig.Key;
-
-
-/**
- * Configuration for the MigrationManager.
- */
-@FigSingleton
-public interface MigrationManagerFig extends GuicyFig {
- @Key( "collections.keyspace.strategy.class" )
- @Default( "org.apache.cassandra.locator.SimpleStrategy" )
- String getStrategyClass();
-
- @Key( "collections.keyspace.strategy.options" )
- String getStrategyOptions();
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerImpl.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerImpl.java
deleted file mode 100644
index ad30d5b..0000000
--- a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/MigrationManagerImpl.java
+++ /dev/null
@@ -1,196 +0,0 @@
-package org.apache.usergrid.persistence.core.migration;
-
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import com.netflix.astyanax.Keyspace;
-import com.netflix.astyanax.connectionpool.exceptions.BadRequestException;
-import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
-import com.netflix.astyanax.ddl.ColumnFamilyDefinition;
-import com.netflix.astyanax.ddl.KeyspaceDefinition;
-
-
-/**
- * Implementation of the migration manager to set up keyspace
- *
- * @author tnine
- */
-@Singleton
-public class MigrationManagerImpl implements MigrationManager {
-
-
- private static final Logger logger = LoggerFactory.getLogger( MigrationManagerImpl.class );
-
- private final Set<Migration> migrations;
- private final Keyspace keyspace;
-
- private final MigrationManagerFig fig;
-
-
- @Inject
- public MigrationManagerImpl( final Keyspace keyspace, final Set<Migration> migrations,
- MigrationManagerFig fig ) {
- this.keyspace = keyspace;
- this.migrations = migrations;
- this.fig = fig;
- }
-
-
- @Override
- public void migrate() throws MigrationException {
-
-
- try {
-
- testAndCreateKeyspace();
-
- for ( Migration migration : migrations ) {
-
- final Collection<MultiTennantColumnFamilyDefinition> columnFamilies = migration.getColumnFamilies();
-
-
- if ( columnFamilies == null || columnFamilies.size() == 0 ) {
- logger.warn(
- "Class {} implements {} but returns null column families for migration. Either implement"
- + " this method or remove the interface from the class", migration.getClass(),
- Migration.class );
- continue;
- }
-
- for ( MultiTennantColumnFamilyDefinition cf : columnFamilies ) {
- testAndCreateColumnFamilyDef( cf );
- }
- }
- }
- catch ( Throwable t ) {
- logger.error( "Unable to perform migration", t );
- throw new MigrationException( "Unable to perform migration", t );
- }
- }
-
-
- /**
- * Check if the column family exists. If it dosn't create it
- */
- private void testAndCreateColumnFamilyDef( MultiTennantColumnFamilyDefinition columnFamily )
- throws ConnectionException {
- final KeyspaceDefinition keyspaceDefinition = keyspace.describeKeyspace();
-
- final ColumnFamilyDefinition existing =
- keyspaceDefinition.getColumnFamily( columnFamily.getColumnFamily().getName() );
-
- if ( existing != null ) {
- return;
- }
-
- keyspace.createColumnFamily( columnFamily.getColumnFamily(), columnFamily.getOptions() );
-
- logger.info( "Created column family {}", columnFamily.getColumnFamily().getName() );
-
- waitForMigration();
- }
-
-
- /**
- * Check if they keyspace exists. If it doesn't create it
- */
- private void testAndCreateKeyspace() throws ConnectionException {
-
-
- KeyspaceDefinition keyspaceDefinition = null;
-
- try {
- keyspaceDefinition = keyspace.describeKeyspace();
- }
- catch ( BadRequestException badRequestException ) {
-
- //check if it's b/c the keyspace is missing, if so
- final String message = badRequestException.getMessage();
-
- boolean missingKeyspace = message.contains( "why:Keyspace" ) && message.contains( "does not exist" );
-
- if ( !missingKeyspace ) {
- throw badRequestException;
- }
- }
-
-
- if ( keyspaceDefinition != null ) {
- return;
- }
-
-
- ImmutableMap.Builder<String, Object> strategyOptions = getKeySpaceProps();
-
-
- ImmutableMap<String, Object> options =
- ImmutableMap.<String, Object>builder().put( "strategy_class", fig.getStrategyClass() )
- .put( "strategy_options", strategyOptions.build() ).build();
-
-
- keyspace.createKeyspace( options );
-
- strategyOptions.toString();
-
- logger.info( "Created keyspace {} with options {}", keyspace.getKeyspaceName(), options.toString() );
-
- waitForMigration();
- }
-
-
- /**
- * Get keyspace properties
- */
- private ImmutableMap.Builder<String, Object> getKeySpaceProps() {
- ImmutableMap.Builder<String, Object> keyspaceProps = ImmutableMap.<String, Object>builder();
-
- String optionString = fig.getStrategyOptions();
-
- if(optionString == null){
- return keyspaceProps;
- }
-
-
-
- for ( String key : optionString.split( "," ) ) {
-
- final String[] options = key.split( ":" );
-
- keyspaceProps.put( options[0], options[1] );
- }
-
- return keyspaceProps;
- }
-
-
- private void waitForMigration() throws ConnectionException {
-
- while ( true ) {
-
- final Map<String, List<String>> versions = keyspace.describeSchemaVersions();
-
- if ( versions != null && versions.size() == 1 ) {
- return;
- }
-
- //sleep and try it again
- try {
- Thread.sleep( 100 );
- }
- catch ( InterruptedException e ) {
- //swallow
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigration.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigration.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigration.java
new file mode 100644
index 0000000..ecf9946
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigration.java
@@ -0,0 +1,84 @@
+/*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one
+ * * or more contributor license agreements. See the NOTICE file
+ * * distributed with this work for additional information
+ * * regarding copyright ownership. The ASF licenses this file
+ * * to you under the Apache License, Version 2.0 (the
+ * * "License"); you may not use this file except in compliance
+ * * with the License. You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing,
+ * * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * * KIND, either express or implied. See the License for the
+ * * specific language governing permissions and limitations
+ * * under the License.
+ *
+ */
+
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+/**
+ * An interface for updating data. Has 2 basic functions. First it will perform the migration and update the status
+ * object.
+ *
+ * Second it will only migrate a single version. For instance, it will migrate from 0->1, or from 1->2. All migrations
+ * must follow the following basic rules.
+ *
+ * <ol>
+ * <li>They must not modify the structure of an existing column family. If the data format changes, a new
+ * implementation and column family must be created. A proxy must be defined to do dual writes/single reads. </li>
+ * <li>The migration must update the progress observer. This information should be made available cluster wide.</li>
+ * <li>In the event a migration fails with an error, we should be able to roll back and remove new column families. We
+ * can then fix the bug, and deploy again. Hence the need for the proxy, dual writes, and an immutable CF
+ * format</li>
+ * </ol>
+ */
+
+
+public interface DataMigration {
+
+
+ /**
+ * Migrate the data to the specified version
+ * @param observer
+ * @throws Throwable
+ */
+ public void migrate(final ProgressObserver observer) throws Throwable;
+
+ /**
+ * Get the version of this migration. It must be unique.
+ * @return
+ */
+ public int getVersion();
+
+ public interface ProgressObserver{
+ /**
+ * Mark the migration as failed
+ * @param migrationVersion The migration version running during the failure
+ * @param reason The reason to save
+ */
+ public void failed(final int migrationVersion, final String reason);
+
+ /**
+ * Mark the migration as failed with a stack trace
+ * @param migrationVersion The migration version running during the failure
+ * @param reason The error description to save
+ * @param throwable The error that happened
+ */
+ public void failed(final int migrationVersion, final String reason, final Throwable throwable);
+
+
+ /**
+ * Update the status of the migration with the message
+ *
+ * @param message The message to save for the status
+ */
+ public void update(final int migrationVersion, final String message);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationException.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationException.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationException.java
new file mode 100644
index 0000000..0e1f29f
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationException.java
@@ -0,0 +1,39 @@
+/*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one
+ * * or more contributor license agreements. See the NOTICE file
+ * * distributed with this work for additional information
+ * * regarding copyright ownership. The ASF licenses this file
+ * * to you under the Apache License, Version 2.0 (the
+ * * "License"); you may not use this file except in compliance
+ * * with the License. You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing,
+ * * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * * KIND, either express or implied. See the License for the
+ * * specific language governing permissions and limitations
+ * * under the License.
+ *
+ */
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+/**
+ * Thrown when a migration cannot be performed
+ *
+ * @author tnine
+ */
+public class DataMigrationException extends RuntimeException {
+
+ public DataMigrationException( final String message ) {
+ super( message );
+ }
+
+
+ public DataMigrationException( final String message, final Throwable cause ) {
+ super( message, cause );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java
new file mode 100644
index 0000000..1d7ccec
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManager.java
@@ -0,0 +1,49 @@
+/*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one
+ * * or more contributor license agreements. See the NOTICE file
+ * * distributed with this work for additional information
+ * * regarding copyright ownership. The ASF licenses this file
+ * * to you under the Apache License, Version 2.0 (the
+ * * "License"); you may not use this file except in compliance
+ * * with the License. You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing,
+ * * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * * KIND, either express or implied. See the License for the
+ * * specific language governing permissions and limitations
+ * * under the License.
+ *
+ */
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
+
+
+/**
+ * A manager that will perform any data migrations necessary. Setup code should invoke the implementation of this interface
+ */
+public interface DataMigrationManager {
+
+ /**
+ * Perform any migration necessary in the application. Will only create keyspaces and column families if they do
+ * not exist
+ */
+ public void migrate() throws MigrationException;
+
+ /**
+ * Returns true if a migration is running. False otherwise
+ * @return
+ */
+ public boolean isRunning();
+
+
+ /**
+ * Return that last status of the migration
+ */
+ public String getLastStatus();
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java
new file mode 100644
index 0000000..ee579ee
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/DataMigrationManagerImpl.java
@@ -0,0 +1,225 @@
+/*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one
+ * * or more contributor license agreements. See the NOTICE file
+ * * distributed with this work for additional information
+ * * regarding copyright ownership. The ASF licenses this file
+ * * to you under the Apache License, Version 2.0 (the
+ * * "License"); you may not use this file except in compliance
+ * * with the License. You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing,
+ * * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * * KIND, either express or implied. See the License for the
+ * * specific language governing permissions and limitations
+ * * under the License.
+ *
+ */
+
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.NavigableMap;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+
+@Singleton
+public class DataMigrationManagerImpl implements DataMigrationManager {
+
+ private static final Logger LOG = LoggerFactory.getLogger( DataMigrationManagerImpl.class );
+
+ private final TreeMap<Integer, DataMigration> migrationTreeMap = new TreeMap<>();
+
+ private final MigrationInfoSerialization migrationInfoSerialization;
+
+
+ @Inject
+ public DataMigrationManagerImpl( final MigrationInfoSerialization migrationInfoSerialization,
+ final Set<DataMigration> migrations ) {
+ this.migrationInfoSerialization = migrationInfoSerialization;
+
+ for ( DataMigration migration : migrations ) {
+
+ final int version = migration.getVersion();
+
+ final DataMigration existing = migrationTreeMap.get( version );
+
+ if ( existing != null ) {
+
+ final Class<? extends DataMigration> existingClass = existing.getClass();
+
+ final Class<? extends DataMigration> currentClass = migration.getClass();
+
+
+ throw new DataMigrationException(
+ String.format( "Data migrations must be unique. Both classes %s and %s have version %d",
+ existingClass, currentClass, version ) );
+ }
+
+ migrationTreeMap.put( version, migration );
+ }
+ }
+
+
+ @Override
+ public void migrate() throws MigrationException {
+
+ if ( migrationTreeMap.isEmpty() ) {
+ LOG.warn( "No migrations found to run, exiting" );
+ return;
+ }
+
+
+ final int currentVersion = migrationInfoSerialization.getVersion();
+
+ LOG.info( "Saved schema version is {}, max migration version is {}", currentVersion,
+ migrationTreeMap.lastKey() );
+
+ //we have our migrations to run, execute them
+ final NavigableMap<Integer, DataMigration> migrationsToRun = migrationTreeMap.tailMap( currentVersion, false );
+
+ CassandraProgressObserver observer = new CassandraProgressObserver();
+
+
+ for ( DataMigration migration : migrationsToRun.values() ) {
+
+ migrationInfoSerialization.setStatusCode( StatusCode.RUNNING.status );
+
+ final int migrationVersion = migration.getVersion();
+
+ LOG.info( "Running migration version {}", migrationVersion );
+
+ observer.update( migrationVersion, "Starting migration" );
+
+
+ //perform this migration, if it fails, short circuit
+ try {
+ migration.migrate( observer );
+ }
+ catch ( Throwable throwable ) {
+ observer.failed( migrationVersion, "Exception thrown during migration", throwable );
+
+ LOG.error( "Unable to migration version {}.", migrationVersion, throwable );
+
+ return;
+ }
+
+ //we had an unhandled exception or the migration failed, short circuit
+ if(observer.failed){
+ return;
+ }
+
+ //set the version
+ migrationInfoSerialization.setVersion( migrationVersion );
+
+ //update the observer for progress so other nodes can see it
+ observer.update( migrationVersion, "Completed successfully" );
+
+
+ }
+
+ migrationInfoSerialization.setStatusCode( StatusCode.COMPLETE.status );
+
+
+ }
+
+
+ @Override
+ public boolean isRunning() {
+ return migrationInfoSerialization.getStatusCode() == StatusCode.RUNNING.status;
+ }
+
+
+ @Override
+ public String getLastStatus() {
+ return migrationInfoSerialization.getStatusMessage();
+ }
+
+
+ /**
+ * Different status enums
+ */
+ public enum StatusCode{
+ COMPLETE(1),
+ RUNNING(2),
+ ERROR(3);
+
+ public final int status;
+
+
+ StatusCode( final int status ) {this.status = status;}
+ }
+
+
+ private final class CassandraProgressObserver implements DataMigration.ProgressObserver {
+
+ private boolean failed = false;
+
+
+
+ @Override
+ public void failed( final int migrationVersion, final String reason ) {
+
+ final String storedMessage = String.format( "Failed to migrate, reason is appended. Error '%s'", reason);
+
+
+ update(migrationVersion, storedMessage );
+
+ LOG.error( storedMessage );
+
+ failed = true;
+
+ migrationInfoSerialization.setStatusCode( StatusCode.ERROR.status );
+ }
+
+
+ @Override
+ public void failed( final int migrationVersion, final String reason, final Throwable throwable ) {
+ StringWriter stackTrace = new StringWriter();
+ throwable.printStackTrace( new PrintWriter( stackTrace ) );
+
+
+ final String storedMessage = String.format( "Failed to migrate, reason is appended. Error '%s' %s", reason, stackTrace.toString() );
+
+ update(migrationVersion, storedMessage );
+
+
+ LOG.error( "Unable to migrate version {} due to reason {}.", migrationVersion, reason, throwable );
+
+ failed = true;
+
+ migrationInfoSerialization.setStatusCode( StatusCode.ERROR.status );
+ }
+
+
+ @Override
+ public void update( final int migrationVersion, final String message ) {
+ final String error = String.format( "Migration version %d. %s", migrationVersion, message);
+
+ migrationInfoSerialization.setStatusMessage( error );
+ }
+
+
+ /**
+ * Return true if we failed
+ * @return
+ */
+ public boolean isFailed() {
+ return failed;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerialization.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerialization.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerialization.java
new file mode 100644
index 0000000..5cd8a76
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerialization.java
@@ -0,0 +1,66 @@
+/*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one
+ * * or more contributor license agreements. See the NOTICE file
+ * * distributed with this work for additional information
+ * * regarding copyright ownership. The ASF licenses this file
+ * * to you under the Apache License, Version 2.0 (the
+ * * "License"); you may not use this file except in compliance
+ * * with the License. You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing,
+ * * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * * KIND, either express or implied. See the License for the
+ * * specific language governing permissions and limitations
+ * * under the License.
+ *
+ */
+
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+import org.apache.usergrid.persistence.core.migration.schema.Migration;
+
+
+public interface MigrationInfoSerialization extends Migration {
+
+ /**
+ * Save the message to the cluster
+ * @param message
+ */
+ public void setStatusMessage( final String message );
+
+ /**
+ * Get the last status
+ * @return
+ */
+ public String getStatusMessage();
+
+ /**
+ * Save the version
+ * @param version
+ */
+ public void setVersion(final int version);
+
+ /**
+ * Return the version
+ * @return
+ */
+ public int getVersion();
+
+ /**
+ * Set the status and save them
+ * @param status
+ * @return
+ */
+ public void setStatusCode( final int status );
+
+ /**
+ *
+ * @return The integer that's saved
+ */
+ public int getStatusCode();
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerializationImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerializationImpl.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerializationImpl.java
new file mode 100644
index 0000000..0460e33
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/data/MigrationInfoSerializationImpl.java
@@ -0,0 +1,178 @@
+/*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one
+ * * or more contributor license agreements. See the NOTICE file
+ * * distributed with this work for additional information
+ * * regarding copyright ownership. The ASF licenses this file
+ * * to you under the Apache License, Version 2.0 (the
+ * * "License"); you may not use this file except in compliance
+ * * with the License. You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing,
+ * * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * * KIND, either express or implied. See the License for the
+ * * specific language governing permissions and limitations
+ * * under the License.
+ *
+ */
+
+package org.apache.usergrid.persistence.core.migration.data;
+
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.UUID;
+
+import org.apache.cassandra.db.marshal.BytesType;
+import org.apache.cassandra.db.marshal.UTF8Type;
+
+import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamily;
+import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
+import org.apache.usergrid.persistence.core.astyanax.ScopedRowKey;
+import org.apache.usergrid.persistence.core.astyanax.ScopedRowKeySerializer;
+import org.apache.usergrid.persistence.core.astyanax.StringRowCompositeSerializer;
+import org.apache.usergrid.persistence.model.entity.Id;
+import org.apache.usergrid.persistence.model.entity.SimpleId;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.netflix.astyanax.Keyspace;
+import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
+import com.netflix.astyanax.connectionpool.exceptions.NotFoundException;
+import com.netflix.astyanax.serializers.StringSerializer;
+
+
+@Singleton
+public class MigrationInfoSerializationImpl implements MigrationInfoSerialization {
+
+
+ /**
+ * Just a hard coded scope since we need it
+ */
+ private static final Id STATIC_ID =
+ new SimpleId( UUID.fromString( "00000000-0000-1000-8000-000000000000" ), "status" );
+
+
+ private static final ScopedRowKeySerializer<String> ROW_KEY_SER =
+ new ScopedRowKeySerializer<String>( StringRowCompositeSerializer.get() );
+
+ private static final StringSerializer STRING_SERIALIZER = StringSerializer.get();
+
+
+ private static final MultiTennantColumnFamily<ScopedRowKey<String>, String> CF_MIGRATION_INFO =
+ new MultiTennantColumnFamily<>( "Data_Migration_Info", ROW_KEY_SER, STRING_SERIALIZER );
+
+
+ private static final ScopedRowKey<String> ROW_KEY = ScopedRowKey.fromKey( STATIC_ID, "" );
+
+ private static final String COL_STATUS_MESSAGE = "statusMessage";
+
+ private static final String COLUMN_VERSION = "version";
+
+ private static final String COLUMN_STATUS_CODE = "statusCode";
+
+ private final Keyspace keyspace;
+
+
+ @Inject
+ public MigrationInfoSerializationImpl( final Keyspace keyspace ) {
+ this.keyspace = keyspace;
+ }
+
+
+ @Override
+ public void setStatusMessage( final String message ) {
+
+ try {
+ keyspace.prepareColumnMutation( CF_MIGRATION_INFO, ROW_KEY, COL_STATUS_MESSAGE ).putValue( message, null )
+ .execute();
+ }
+ catch ( ConnectionException e ) {
+ throw new DataMigrationException( "Unable to save status", e );
+ }
+ }
+
+
+ @Override
+ public String getStatusMessage() {
+ try {
+ return keyspace.prepareQuery( CF_MIGRATION_INFO ).getKey( ROW_KEY ).getColumn( COL_STATUS_MESSAGE )
+ .execute().getResult().getStringValue();
+ }
+ //swallow, it doesn't exist
+ catch ( NotFoundException nfe ) {
+ return null;
+ }
+ catch ( ConnectionException e ) {
+ throw new DataMigrationException( "Unable to retrieve status", e );
+ }
+ }
+
+
+ @Override
+ public void setVersion( final int version ) {
+ try {
+ keyspace.prepareColumnMutation( CF_MIGRATION_INFO, ROW_KEY, COLUMN_VERSION ).putValue( version, null )
+ .execute();
+ }
+ catch ( ConnectionException e ) {
+ throw new DataMigrationException( "Unable to save status", e );
+ }
+ }
+
+
+ @Override
+ public int getVersion() {
+ try {
+ return keyspace.prepareQuery( CF_MIGRATION_INFO ).getKey( ROW_KEY ).getColumn( COLUMN_VERSION ).execute()
+ .getResult().getIntegerValue();
+ }
+ //swallow, it doesn't exist
+ catch ( NotFoundException nfe ) {
+ return 0;
+ }
+ catch ( ConnectionException e ) {
+ throw new DataMigrationException( "Unable to retrieve status", e );
+ }
+ }
+
+
+ @Override
+ public void setStatusCode( final int status ) {
+ try {
+ keyspace.prepareColumnMutation( CF_MIGRATION_INFO, ROW_KEY, COLUMN_STATUS_CODE ).putValue( status, null )
+ .execute();
+ }
+ catch ( ConnectionException e ) {
+ throw new DataMigrationException( "Unable to save status", e );
+ }
+ }
+
+
+ @Override
+ public int getStatusCode() {
+ try {
+ return keyspace.prepareQuery( CF_MIGRATION_INFO ).getKey( ROW_KEY ).getColumn( COLUMN_STATUS_CODE )
+ .execute().getResult().getIntegerValue();
+ }
+ //swallow, it doesn't exist
+ catch ( NotFoundException nfe ) {
+ return 0;
+ }
+ catch ( ConnectionException e ) {
+ throw new DataMigrationException( "Unable to retrieve status", e );
+ }
+ }
+
+
+ @Override
+ public Collection<MultiTennantColumnFamilyDefinition> getColumnFamilies() {
+ return Collections.singletonList(
+ new MultiTennantColumnFamilyDefinition( CF_MIGRATION_INFO, BytesType.class.getSimpleName(),
+ UTF8Type.class.getSimpleName(), BytesType.class.getSimpleName(),
+ MultiTennantColumnFamilyDefinition.CacheOption.KEYS ) );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/Migration.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/Migration.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/Migration.java
new file mode 100644
index 0000000..fdf483a
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/Migration.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.usergrid.persistence.core.migration.schema;
+
+
+import java.util.Collection;
+
+import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
+
+
+/**
+ * @author tnine
+ */
+public interface Migration {
+
+ /**
+ * Get the column families required for this implementation. If one does not exist it will be created.
+ */
+ public Collection<MultiTennantColumnFamilyDefinition> getColumnFamilies();
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationException.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationException.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationException.java
new file mode 100644
index 0000000..63a1297
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationException.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.usergrid.persistence.core.migration.schema;
+
+
+/**
+ * Thrown when a migration cannot be performed
+ *
+ * @author tnine
+ */
+public class MigrationException extends Exception {
+
+ public MigrationException( final String message ) {
+ super( message );
+ }
+
+
+ public MigrationException( final String message, final Throwable cause ) {
+ super( message, cause );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManager.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManager.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManager.java
new file mode 100644
index 0000000..df84247
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManager.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.usergrid.persistence.core.migration.schema;
+
+
+/**
+ * A manager that will perform any migrations necessary. Setup code should invoke the implementation of this interface
+ *
+ * @author tnine
+ */
+public interface MigrationManager {
+
+ /**
+ * Perform any migration necessary in the application. Will only create keyspaces and column families if they do
+ * not exist
+ */
+ public void migrate() throws MigrationException;
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerFig.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerFig.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerFig.java
new file mode 100644
index 0000000..9595020
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerFig.java
@@ -0,0 +1,22 @@
+package org.apache.usergrid.persistence.core.migration.schema;
+
+
+import org.safehaus.guicyfig.Default;
+import org.safehaus.guicyfig.FigSingleton;
+import org.safehaus.guicyfig.GuicyFig;
+import org.safehaus.guicyfig.Key;
+
+
+/**
+ * Configuration for the MigrationManager.
+ */
+@FigSingleton
+public interface MigrationManagerFig extends GuicyFig {
+ @Key( "collections.keyspace.strategy.class" )
+ @Default( "org.apache.cassandra.locator.SimpleStrategy" )
+ String getStrategyClass();
+
+ @Key( "collections.keyspace.strategy.options" )
+ String getStrategyOptions();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerImpl.java b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerImpl.java
new file mode 100644
index 0000000..70ab713
--- /dev/null
+++ b/stack/corepersistence/common/src/main/java/org/apache/usergrid/persistence/core/migration/schema/MigrationManagerImpl.java
@@ -0,0 +1,196 @@
+package org.apache.usergrid.persistence.core.migration.schema;
+
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.usergrid.persistence.core.astyanax.MultiTennantColumnFamilyDefinition;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.netflix.astyanax.Keyspace;
+import com.netflix.astyanax.connectionpool.exceptions.BadRequestException;
+import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
+import com.netflix.astyanax.ddl.ColumnFamilyDefinition;
+import com.netflix.astyanax.ddl.KeyspaceDefinition;
+
+
+/**
+ * Implementation of the migration manager to set up keyspace
+ *
+ * @author tnine
+ */
+@Singleton
+public class MigrationManagerImpl implements MigrationManager {
+
+
+ private static final Logger logger = LoggerFactory.getLogger( MigrationManagerImpl.class );
+
+ private final Set<Migration> migrations;
+ private final Keyspace keyspace;
+
+ private final MigrationManagerFig fig;
+
+
+ @Inject
+ public MigrationManagerImpl( final Keyspace keyspace, final Set<Migration> migrations,
+ MigrationManagerFig fig ) {
+ this.keyspace = keyspace;
+ this.migrations = migrations;
+ this.fig = fig;
+ }
+
+
+ @Override
+ public void migrate() throws MigrationException {
+
+
+ try {
+
+ testAndCreateKeyspace();
+
+ for ( Migration migration : migrations ) {
+
+ final Collection<MultiTennantColumnFamilyDefinition> columnFamilies = migration.getColumnFamilies();
+
+
+ if ( columnFamilies == null || columnFamilies.size() == 0 ) {
+ logger.warn(
+ "Class {} implements {} but returns null column families for migration. Either implement"
+ + " this method or remove the interface from the class", migration.getClass(),
+ Migration.class );
+ continue;
+ }
+
+ for ( MultiTennantColumnFamilyDefinition cf : columnFamilies ) {
+ testAndCreateColumnFamilyDef( cf );
+ }
+ }
+ }
+ catch ( Throwable t ) {
+ logger.error( "Unable to perform migration", t );
+ throw new MigrationException( "Unable to perform migration", t );
+ }
+ }
+
+
+ /**
+ * Check if the column family exists. If it dosn't create it
+ */
+ private void testAndCreateColumnFamilyDef( MultiTennantColumnFamilyDefinition columnFamily )
+ throws ConnectionException {
+ final KeyspaceDefinition keyspaceDefinition = keyspace.describeKeyspace();
+
+ final ColumnFamilyDefinition existing =
+ keyspaceDefinition.getColumnFamily( columnFamily.getColumnFamily().getName() );
+
+ if ( existing != null ) {
+ return;
+ }
+
+ keyspace.createColumnFamily( columnFamily.getColumnFamily(), columnFamily.getOptions() );
+
+ logger.info( "Created column family {}", columnFamily.getColumnFamily().getName() );
+
+ waitForMigration();
+ }
+
+
+ /**
+ * Check if they keyspace exists. If it doesn't create it
+ */
+ private void testAndCreateKeyspace() throws ConnectionException {
+
+
+ KeyspaceDefinition keyspaceDefinition = null;
+
+ try {
+ keyspaceDefinition = keyspace.describeKeyspace();
+ }
+ catch ( BadRequestException badRequestException ) {
+
+ //check if it's b/c the keyspace is missing, if so
+ final String message = badRequestException.getMessage();
+
+ boolean missingKeyspace = message.contains( "why:Keyspace" ) && message.contains( "does not exist" );
+
+ if ( !missingKeyspace ) {
+ throw badRequestException;
+ }
+ }
+
+
+ if ( keyspaceDefinition != null ) {
+ return;
+ }
+
+
+ ImmutableMap.Builder<String, Object> strategyOptions = getKeySpaceProps();
+
+
+ ImmutableMap<String, Object> options =
+ ImmutableMap.<String, Object>builder().put( "strategy_class", fig.getStrategyClass() )
+ .put( "strategy_options", strategyOptions.build() ).build();
+
+
+ keyspace.createKeyspace( options );
+
+ strategyOptions.toString();
+
+ logger.info( "Created keyspace {} with options {}", keyspace.getKeyspaceName(), options.toString() );
+
+ waitForMigration();
+ }
+
+
+ /**
+ * Get keyspace properties
+ */
+ private ImmutableMap.Builder<String, Object> getKeySpaceProps() {
+ ImmutableMap.Builder<String, Object> keyspaceProps = ImmutableMap.<String, Object>builder();
+
+ String optionString = fig.getStrategyOptions();
+
+ if(optionString == null){
+ return keyspaceProps;
+ }
+
+
+
+ for ( String key : optionString.split( "," ) ) {
+
+ final String[] options = key.split( ":" );
+
+ keyspaceProps.put( options[0], options[1] );
+ }
+
+ return keyspaceProps;
+ }
+
+
+ private void waitForMigration() throws ConnectionException {
+
+ while ( true ) {
+
+ final Map<String, List<String>> versions = keyspace.describeSchemaVersions();
+
+ if ( versions != null && versions.size() == 1 ) {
+ return;
+ }
+
+ //sleep and try it again
+ try {
+ Thread.sleep( 100 );
+ }
+ catch ( InterruptedException e ) {
+ //swallow
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/MigrationManagerRule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/MigrationManagerRule.java b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/MigrationManagerRule.java
index 3b3a45f..522af61 100644
--- a/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/MigrationManagerRule.java
+++ b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/MigrationManagerRule.java
@@ -5,8 +5,8 @@ import org.junit.rules.ExternalResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.usergrid.persistence.core.migration.MigrationException;
-import org.apache.usergrid.persistence.core.migration.MigrationManager;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationException;
+import org.apache.usergrid.persistence.core.migration.schema.MigrationManager;
import com.google.inject.Inject;
import com.google.inject.Singleton;
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestCommonModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestCommonModule.java b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestCommonModule.java
new file mode 100644
index 0000000..04f1d47
--- /dev/null
+++ b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestCommonModule.java
@@ -0,0 +1,34 @@
+/*
+ *
+ * * Licensed to the Apache Software Foundation (ASF) under one
+ * * or more contributor license agreements. See the NOTICE file
+ * * distributed with this work for additional information
+ * * regarding copyright ownership. The ASF licenses this file
+ * * to you under the Apache License, Version 2.0 (the
+ * * "License"); you may not use this file except in compliance
+ * * with the License. You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing,
+ * * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * * KIND, either express or implied. See the License for the
+ * * specific language governing permissions and limitations
+ * * under the License.
+ *
+ */
+
+package org.apache.usergrid.persistence.core.guice;
+
+
+/**
+ * Module for testing common frameworks
+ */
+public class TestCommonModule extends TestModule {
+
+ @Override
+ protected void configure() {
+ install(new CommonModule());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/dfed6a02/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestModule.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestModule.java b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestModule.java
new file mode 100644
index 0000000..9b175da
--- /dev/null
+++ b/stack/corepersistence/common/src/test/java/org/apache/usergrid/persistence/core/guice/TestModule.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.usergrid.persistence.core.guice;
+
+
+import java.io.IOException;
+
+import com.google.inject.AbstractModule;
+import com.netflix.config.ConfigurationManager;
+
+
+public abstract class TestModule extends AbstractModule {
+ static {
+ /*
+ * --------------------------------------------------------------------
+ * Bootstrap the config for Archaius Configuration Settings. We don't want to
+ * bootstrap more than once per JVM
+ * --------------------------------------------------------------------
+ */
+
+ try {
+ //load up the properties
+ ConfigurationManager.getDeploymentContext().setDeploymentEnvironment( "UNIT" );
+ ConfigurationManager.loadCascadedPropertiesFromResources( "usergrid" );
+
+ }
+ catch ( IOException e ) {
+ throw new RuntimeException( "Cannot do much without properly loading our configuration.", e );
+ }
+ }
+}