/* * Hibernate OGM, Domain model persistence for NoSQL datastores * * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.ogm.datastore.infinispan.test.dialect.impl; import static org.fest.assertions.Assertions.assertThat; import static org.hibernate.ogm.utils.GridDialectOperationContexts.emptyTupleContext; import static org.hibernate.ogm.utils.GridDialectOperationContexts.emptyTupleTypeContext; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.transaction.jta.platform.internal.JBossStandAloneJtaPlatform; import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform; import org.hibernate.ogm.datastore.infinispan.InfinispanDialect; import org.hibernate.ogm.datastore.infinispan.InfinispanProperties; import org.hibernate.ogm.datastore.infinispan.impl.InfinispanEmbeddedDatastoreProvider; import org.hibernate.ogm.datastore.spi.DatastoreProvider; import org.hibernate.ogm.dialect.spi.ModelConsumer; import org.hibernate.ogm.dialect.spi.NextValueRequest; import org.hibernate.ogm.dialect.spi.TuplesSupplier; import org.hibernate.ogm.entityentry.impl.TuplePointer; import org.hibernate.ogm.id.spi.PersistentNoSqlIdentifierGenerator; import org.hibernate.ogm.model.impl.DefaultAssociatedEntityKeyMetadata; import org.hibernate.ogm.model.impl.DefaultAssociationKeyMetadata; import org.hibernate.ogm.model.impl.DefaultEntityKeyMetadata; import org.hibernate.ogm.model.impl.DefaultIdSourceKeyMetadata; import org.hibernate.ogm.model.key.spi.AssociationKey; import org.hibernate.ogm.model.key.spi.AssociationKeyMetadata; import org.hibernate.ogm.model.key.spi.EntityKey; import org.hibernate.ogm.model.key.spi.EntityKeyMetadata; import org.hibernate.ogm.model.key.spi.IdSourceKey; import org.hibernate.ogm.model.key.spi.IdSourceKeyMetadata; import org.hibernate.ogm.model.key.spi.RowKey; import org.hibernate.ogm.model.spi.Association; import org.hibernate.ogm.model.spi.Tuple; import org.hibernate.ogm.options.navigation.impl.OptionsServiceImpl; import org.hibernate.ogm.options.spi.OptionsService; import org.hibernate.ogm.persister.impl.OgmCollectionPersister; import org.hibernate.ogm.persister.impl.OgmEntityPersister; import org.hibernate.ogm.service.impl.DefaultSchemaInitializationContext; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.service.spi.ServiceRegistryImplementor; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; /** * Integration test which makes sure that {@link InfinispanDialect} and {@link InfinispanEmbeddedDatastoreProvider} can operate * in clustered mode, in particular that objects can be serialized and de-serialized when being written into and read * from the data grid. * <p> * * @author Gunnar Morling */ public class InfinispanDialectWithClusteredConfigurationTest { private static InfinispanEmbeddedDatastoreProvider provider1; private static InfinispanEmbeddedDatastoreProvider provider2; private static InfinispanDialect dialect1; private static InfinispanDialect dialect2; @BeforeClass public static void setupProvidersAndDialects() throws Exception { SessionFactoryImplementor sessionFactory1 = getSessionFactory(); SessionFactoryImplementor sessionFactory2 = getSessionFactory(); provider1 = (InfinispanEmbeddedDatastoreProvider) sessionFactory1.getServiceRegistry().getService( DatastoreProvider.class ); provider2 = (InfinispanEmbeddedDatastoreProvider) sessionFactory2.getServiceRegistry().getService( DatastoreProvider.class ); dialect1 = new InfinispanDialect( provider1 ); dialect2 = new InfinispanDialect( provider2 ); provider1.getSchemaDefinerType().newInstance().initializeSchema( new DefaultSchemaInitializationContext( null, sessionFactory1 ) ); provider2.getSchemaDefinerType().newInstance().initializeSchema( new DefaultSchemaInitializationContext( null, sessionFactory2 ) ); } @AfterClass public static void stopProvider() { if ( provider1 != null ) { provider1.stop(); } if ( provider2 != null ) { provider2.stop(); } } @Test public void shouldWriteAndReadTupleInClusteredMode() throws Exception { // given String[] columnNames = { "foo", "bar", "baz" }; EntityKeyMetadata keyMetadata = new DefaultEntityKeyMetadata( "Foobar", columnNames ); Object[] values = { 123, "Hello", 456L }; EntityKey key = new EntityKey( keyMetadata, values ); // when Tuple tuple = dialect1.createTuple( key, emptyTupleContext() ); tuple.put( "foo", "bar" ); dialect1.insertOrUpdateTuple( key, new TuplePointer( tuple ), emptyTupleContext() ); // then Tuple readTuple = dialect2.getTuple( key, null ); assertThat( readTuple.get( "foo" ) ).isEqualTo( "bar" ); } @Test public void shoulReadAndWriteSequenceInClusteredMode() throws Exception { // given IdSourceKeyMetadata keyMetadata = DefaultIdSourceKeyMetadata.forTable( "Hibernate_Sequences", "sequence_name", "next_val" ); IdSourceKey key = IdSourceKey.forTable( keyMetadata, "Foo_Sequence" ); // when Number value = dialect1.nextValue( new NextValueRequest( key, 1, 1 ) ); assertThat( value ).isEqualTo( 1L ); // then value = dialect2.nextValue( new NextValueRequest( key, 1, 1 ) ); assertThat( value ).isEqualTo( 2L ); } @Test public void shouldWriteAndReadAssociationInClusteredMode() throws Exception { // given String[] columnNames = { "foo", "bar", "baz" }; AssociationKeyMetadata keyMetadata = new DefaultAssociationKeyMetadata.Builder().table( "Foobar" ).columnNames( columnNames ) .associatedEntityKeyMetadata( new DefaultAssociatedEntityKeyMetadata( null, null ) ).build(); Object[] values = { 123, "Hello", 456L }; AssociationKey key = new AssociationKey( keyMetadata, values, null ); RowKey rowKey = new RowKey( columnNames, values ); Tuple tuple = new Tuple(); tuple.put( "zip", "zap" ); // when Association association = dialect1.createAssociation( key, null ); association.put( rowKey, tuple ); dialect1.insertOrUpdateAssociation( key, association, null ); // then Association readAssociation = dialect2.getAssociation( key, null ); Tuple readKey = readAssociation.get( rowKey ); assertThat( readKey ).isNotNull(); assertThat( readKey.get( "zip" ) ).isEqualTo( "zap" ); } @Test public void shouldApplyForEachTupleInClusteredMode() throws Exception { // given String[] columnNames = { "foo", "bar", "baz" }; EntityKeyMetadata keyMetadata = new DefaultEntityKeyMetadata( "Foobar", columnNames ); Object[] values = { 123, "Hello", 456L }; EntityKey key = new EntityKey( keyMetadata, values ); // when Tuple tuple = dialect1.createTuple( key, emptyTupleContext() ); tuple.put( "foo", "bar" ); dialect1.insertOrUpdateTuple( key, new TuplePointer( tuple ), emptyTupleContext() ); // then MyConsumer consumer = new MyConsumer(); dialect2.forEachTuple( consumer, emptyTupleTypeContext(), keyMetadata ); assertThat( consumer.consumedTuple.get( "foo" ) ).isEqualTo( "bar" ); } private final class MyConsumer implements ModelConsumer { private Tuple consumedTuple; @Override public void consume(TuplesSupplier supplier) { consumedTuple = supplier.get( null ).next(); } } private static InfinispanEmbeddedDatastoreProvider createAndStartNewProvider(ServiceRegistryImplementor serviceRegistry) { Map<String, Object> configurationValues = new HashMap<String, Object>(); configurationValues.put( InfinispanProperties.CONFIGURATION_RESOURCE_NAME, "infinispan-dist.xml" ); InfinispanEmbeddedDatastoreProvider provider = new InfinispanEmbeddedDatastoreProvider(); provider.configure( configurationValues ); provider.injectServices( serviceRegistry ); provider.start(); return provider; } private static ServiceRegistryImplementor getServiceRegistry() { ServiceRegistryImplementor serviceRegistry = mock( ServiceRegistryImplementor.class ); JBossStandAloneJtaPlatform jtaPlatform = new JBossStandAloneJtaPlatform(); jtaPlatform.injectServices( serviceRegistry ); when( serviceRegistry.getService( JtaPlatform.class ) ).thenReturn( jtaPlatform ); InfinispanEmbeddedDatastoreProvider provider = createAndStartNewProvider( serviceRegistry ); when( serviceRegistry.getService( DatastoreProvider.class ) ).thenReturn( provider ); when( serviceRegistry.getService( ClassLoaderService.class ) ).thenReturn( new ClassLoaderServiceImpl() ); OptionsServiceImpl optionsService = new OptionsServiceImpl(); optionsService.injectServices( serviceRegistry ); optionsService.configure( Collections.emptyMap() ); when( serviceRegistry.getService( OptionsService.class ) ).thenReturn( optionsService ); return serviceRegistry; } private static SessionFactoryImplementor getSessionFactory() { SessionFactoryImplementor sessionFactory = mock( SessionFactoryImplementor.class ); // entity persister OgmEntityPersister foobarPersister = mock( OgmEntityPersister.class ); when( foobarPersister.getEntityKeyMetadata() ).thenReturn( new DefaultEntityKeyMetadata( "Foobar", new String[] {} ) ); when( foobarPersister.getPropertyNames() ).thenReturn( new String[] {} ); // id generator PersistentNoSqlIdentifierGenerator generator = mock( PersistentNoSqlIdentifierGenerator.class ); when( generator.getGeneratorKeyMetadata() ).thenReturn( DefaultIdSourceKeyMetadata.forTable( "Hibernate_Sequences", "sequence_name", "next_val" ) ); when( foobarPersister.getIdentifierGenerator() ).thenReturn( generator ); when( sessionFactory.getEntityPersisters() ).thenReturn( Collections.<String, EntityPersister>singletonMap( "Foobar", foobarPersister ) ); // collection persister OgmCollectionPersister foobarCollectionPersister = mock( OgmCollectionPersister.class ); when( foobarCollectionPersister.getAssociationKeyMetadata() ).thenReturn( new DefaultAssociationKeyMetadata.Builder().table( "Foobar" ).build() ); when( sessionFactory.getCollectionPersisters() ).thenReturn( Collections.<String, CollectionPersister>singletonMap( "Foobar", foobarCollectionPersister ) ); // service registry ServiceRegistryImplementor serviceRegistry = getServiceRegistry(); when( sessionFactory.getServiceRegistry() ).thenReturn( serviceRegistry ); return sessionFactory; } }