/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. 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. For additional information regarding * copyright in this work, please see the NOTICE file in the top level * directory of this distribution. */ package org.apache.usergrid.persistence.collection.serialization.impl; import org.apache.usergrid.persistence.collection.serialization.MvccEntitySerializationStrategy; import org.apache.usergrid.persistence.collection.serialization.MvccLogEntrySerializationStrategy; import org.apache.usergrid.persistence.collection.serialization.UniqueValueSerializationStrategy; import org.apache.usergrid.persistence.collection.serialization.impl.migration.CollectionMigration; import org.apache.usergrid.persistence.collection.serialization.impl.migration.CollectionMigrationPlugin; import org.apache.usergrid.persistence.collection.serialization.impl.migration.EntityIdScope; import org.apache.usergrid.persistence.collection.serialization.impl.migration.MvccEntityDataMigrationImpl; import org.apache.usergrid.persistence.core.migration.data.DataMigration; import org.apache.usergrid.persistence.core.migration.data.MigrationPlugin; import org.apache.usergrid.persistence.core.migration.data.MigrationRelationship; import org.apache.usergrid.persistence.core.migration.data.VersionedMigrationSet; import org.apache.usergrid.persistence.core.migration.schema.Migration; import com.google.inject.AbstractModule; import com.google.inject.Inject; import com.google.inject.Key; import com.google.inject.Provides; import com.google.inject.Singleton; import com.google.inject.TypeLiteral; import com.google.inject.multibindings.Multibinder; /** * @author tnine */ public class SerializationModule extends AbstractModule { @Override protected void configure() { // bind the serialization strategies //bind all 3 implementations bind( MvccEntitySerializationStrategyV1Impl.class ); bind( MvccEntitySerializationStrategyV2Impl.class ); bind( MvccEntitySerializationStrategyV3Impl.class ); //We've migrated this one, so we need to set up the previous, current, and proxy bind( MvccEntitySerializationStrategy.class ).to( MvccEntitySerializationStrategyProxyImpl.class ); //bind 2 implementations bind( MvccLogEntrySerializationStrategyV1Impl.class ); bind( MvccLogEntrySerializationStrategyV2Impl.class ); bind( MvccLogEntrySerializationStrategy.class ).to( MvccLogEntrySerializationProxyImpl.class ); bind( UniqueValueSerializationStrategyV1Impl.class ); bind(UniqueValueSerializationStrategyV2Impl.class); bind( UniqueValueSerializationStrategy.class ).to( UniqueValueSerializationStrategyProxyImpl.class ); //do multibindings for migrations Multibinder<Migration> migrationBinder = Multibinder.newSetBinder( binder(), Migration.class ); //entity serialization versions migrationBinder.addBinding().to( Key.get( MvccEntitySerializationStrategyV1Impl.class ) ); migrationBinder.addBinding().to( Key.get( MvccEntitySerializationStrategyV2Impl.class ) ); migrationBinder.addBinding().to( Key.get( MvccEntitySerializationStrategyV3Impl.class ) ); //log serialization versions migrationBinder.addBinding().to( Key.get( MvccLogEntrySerializationStrategyV1Impl.class ) ); migrationBinder.addBinding().to( Key.get( MvccLogEntrySerializationStrategyV2Impl.class ) ); //unique value serialization versions migrationBinder.addBinding().to( Key.get( UniqueValueSerializationStrategyV1Impl.class ) ); migrationBinder.addBinding().to( Key.get( UniqueValueSerializationStrategyV2Impl.class ) ); //bind our settings as an eager singleton so it's checked on startup bind( SettingsValidation.class ).asEagerSingleton(); //migrations //we want to make sure our generics are retained, so we use a typeliteral Multibinder<DataMigration> dataMigrationMultibinder = Multibinder .newSetBinder( binder(), new TypeLiteral<DataMigration>() {}, CollectionMigration.class ); dataMigrationMultibinder.addBinding().to( MvccEntityDataMigrationImpl.class ); //wire up the collection migration plugin Multibinder.newSetBinder( binder(), MigrationPlugin.class ).addBinding().to( CollectionMigrationPlugin.class ); } /** * Configure via explicit declaration the migration path we can follow */ @Singleton @Inject @Provides public VersionedMigrationSet<MvccEntitySerializationStrategy> getVersions( final MvccEntitySerializationStrategyV1Impl v1, final MvccEntitySerializationStrategyV2Impl v2, final MvccEntitySerializationStrategyV3Impl v3 ) { //we must perform a migration from v1 to v3 in order to maintain consistency MigrationRelationship<MvccEntitySerializationStrategy> v1Tov3 = new MigrationRelationship<>( v1, v3 ); //we must migrate from 2 to 3, this is a bridge that must happen to maintain data consistency MigrationRelationship<MvccEntitySerializationStrategy> v2Tov3 = new MigrationRelationship<>( v2, v3 ); //note that we MUST migrate to v3 before our next migration, if v4 and v5 is implemented we will need a // v3->v5 and a v4->v5 set MigrationRelationship<MvccEntitySerializationStrategy> current = new MigrationRelationship<>( v3, v3 ); //now create our set of versions VersionedMigrationSet<MvccEntitySerializationStrategy> set = new VersionedMigrationSet<>( v1Tov3, v2Tov3, current ); return set; } /** * Configure via explicit declaration the migration path we can follow */ @Singleton @Inject @Provides public VersionedMigrationSet<MvccLogEntrySerializationStrategy> getVersions( final MvccLogEntrySerializationStrategyV1Impl v1, final MvccLogEntrySerializationStrategyV2Impl v2) { //we must perform a migration from v1 to v3 in order to maintain consistency MigrationRelationship<MvccLogEntrySerializationStrategy> v1Tov2 = new MigrationRelationship<>( v1, v2 ); //note that we MUST migrate to v3 before our next migration, if v4 and v5 is implemented we will need a // v3->v5 and a v4->v5 set MigrationRelationship<MvccLogEntrySerializationStrategy> current = new MigrationRelationship<>( v2, v2 ); //now create our set of versions VersionedMigrationSet<MvccLogEntrySerializationStrategy> set = new VersionedMigrationSet<>( v1Tov2, current ); return set; } /** * Configure via explicit declaration the migration path we can follow */ @Singleton @Inject @Provides public VersionedMigrationSet<UniqueValueSerializationStrategy> getVersions( final UniqueValueSerializationStrategyV1Impl v1, final UniqueValueSerializationStrategyV2Impl v2) { //we must perform a migration from v1 to v3 in order to maintain consistency MigrationRelationship<UniqueValueSerializationStrategy> v1Tov2 = new MigrationRelationship<>( v1, v2 ); //note that we MUST migrate to v3 before our next migration, if v4 and v5 is implemented we will need a // v3->v5 and a v4->v5 set MigrationRelationship<UniqueValueSerializationStrategy> current = new MigrationRelationship<>( v2, v2 ); //now create our set of versions VersionedMigrationSet<UniqueValueSerializationStrategy> set = new VersionedMigrationSet<>( v1Tov2, current ); return set; } }