/*
* Hibernate Search, full-text search for your domain model
*
* 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.search.test.configuration.integration;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.isA;
import static org.easymock.EasyMock.startsWith;
import java.util.Collections;
import java.util.HashMap;
import org.easymock.Capture;
import org.easymock.EasyMock;
import org.hibernate.MultiTenancyStrategy;
import org.hibernate.SessionFactoryObserver;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.engine.config.internal.ConfigurationServiceImpl;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.jndi.spi.JndiService;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventType;
import org.hibernate.search.bridge.spi.IndexManagerTypeSpecificBridgeProvider;
import org.hibernate.search.bridge.spi.BridgeProvider;
import org.hibernate.search.cfg.Environment;
import org.hibernate.search.event.impl.FullTextIndexEventListener;
import org.hibernate.search.hcore.impl.HibernateSearchIntegrator;
import org.hibernate.search.hcore.impl.SearchFactoryReference;
import org.hibernate.search.hcore.spi.BeanResolver;
import org.hibernate.search.hcore.spi.EnvironmentSynchronizer;
import org.hibernate.search.query.engine.impl.LuceneQueryTranslator;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
import org.junit.Test;
import org.unitils.UnitilsJUnit4;
import org.unitils.easymock.EasyMockUnitils;
import org.unitils.easymock.annotation.Mock;
/**
* @author Sanne Grinovero
* @author Hardy Ferentschik
*/
public class HibernateSearchIntegratorTest extends UnitilsJUnit4 {
private static final Boolean SEARCH_DISABLED = Boolean.FALSE;
private static final Boolean SEARCH_ENABLED = Boolean.TRUE;
private static final Boolean SEARCH_IMPLICITLY_ENABLED = null;
@Mock
private SessionFactoryServiceRegistry mockSessionFactoryServiceRegistry;
@Mock
private SessionFactoryImplementor mockSessionFactoryImplementor;
@Mock
private EventListenerRegistry mockEventListenerRegistry;
@Mock
private ClassLoaderService mockClassLoaderService;
@Mock
private SessionFactoryOptions mockSessionFactoryOptions;
@Mock
private JndiService jndiService;
@Mock
private Metadata mockMetadata;
@Test
public void testEventListenersAreNotRegisteredIfSearchIsExplicitlyDisabledInConfiguration() {
programConfigurationMock( SEARCH_DISABLED );
EasyMockUnitils.replay();
// Search should not care about the metadata or the factory if it's disabled
new HibernateSearchIntegrator().integrate( null, null, mockSessionFactoryServiceRegistry );
}
@Test
public void testEventListenersAreRegisteredIfSearchIsExplicitlyEnabledInConfiguration() {
programConfigurationMock( SEARCH_ENABLED );
assertObserverCalledAndEventListenersRegistered();
}
@Test
public void testEventListenersAreRegisteredIfSearchIsImplicitlyEnabledInConfiguration() {
programConfigurationMock( SEARCH_IMPLICITLY_ENABLED );
assertObserverCalledAndEventListenersRegistered();
}
@SuppressWarnings("unchecked")
private void assertObserverCalledAndEventListenersRegistered() {
Capture<SessionFactoryObserver> capturedSessionFactoryObserver = new Capture<SessionFactoryObserver>();
mockSessionFactoryImplementor.addObserver(
EasyMock.and(
EasyMock.capture( capturedSessionFactoryObserver ),
isA( SessionFactoryObserver.class )
)
);
expect( mockSessionFactoryImplementor.getSessionFactoryOptions() ).andReturn(
mockSessionFactoryOptions
);
expect( mockSessionFactoryOptions.getMultiTenancyStrategy() ).andReturn(
MultiTenancyStrategy.NONE
);
expect( mockSessionFactoryServiceRegistry.getService( EventListenerRegistry.class ) ).andReturn(
mockEventListenerRegistry
);
expect( mockSessionFactoryServiceRegistry.getService( SearchFactoryReference.class ) ).andReturn(
new SearchFactoryReference()
);
mockEventListenerRegistry.addDuplicationStrategy( isA( HibernateSearchIntegrator.DuplicationStrategyImpl.class ) );
mockEventListenerRegistry.appendListeners(
eq( EventType.POST_INSERT ),
isA( FullTextIndexEventListener.class )
);
mockEventListenerRegistry.appendListeners(
eq( EventType.POST_UPDATE ),
isA( FullTextIndexEventListener.class )
);
mockEventListenerRegistry.appendListeners(
eq( EventType.POST_DELETE ),
isA( FullTextIndexEventListener.class )
);
mockEventListenerRegistry.appendListeners(
eq( EventType.POST_COLLECTION_RECREATE ),
isA( FullTextIndexEventListener.class )
);
mockEventListenerRegistry.appendListeners(
eq( EventType.POST_COLLECTION_REMOVE ),
isA( FullTextIndexEventListener.class )
);
mockEventListenerRegistry.appendListeners(
eq( EventType.POST_COLLECTION_UPDATE ),
isA( FullTextIndexEventListener.class )
);
mockEventListenerRegistry.appendListeners(
eq( EventType.FLUSH ),
isA( FullTextIndexEventListener.class )
);
expect( mockSessionFactoryServiceRegistry.getService( ClassLoaderService.class ) )
.andReturn( mockClassLoaderService )
.anyTimes();
expect( mockSessionFactoryServiceRegistry.locateServiceBinding( BeanResolver.class ) )
.andReturn( null )
.anyTimes();
expect( mockSessionFactoryServiceRegistry.locateServiceBinding( EnvironmentSynchronizer.class ) )
.andReturn( null )
.anyTimes();
// returning object.class is fair enough for testing purposes
expect( mockClassLoaderService.classForName( "javax.persistence.Id" ) )
.andReturn( Object.class )
.anyTimes();
expect( mockClassLoaderService.classForName( "javax.persistence.EmbeddedId" ) )
.andReturn( Object.class )
.anyTimes();
expect( mockClassLoaderService.loadJavaServices( LuceneQueryTranslator.class ) )
.andReturn( Collections.<LuceneQueryTranslator>emptySet() );
expect( mockClassLoaderService.loadJavaServices( IndexManagerTypeSpecificBridgeProvider.class ) )
.andReturn( Collections.<IndexManagerTypeSpecificBridgeProvider>emptySet() );
expect( mockClassLoaderService.loadJavaServices( BridgeProvider.class ) )
.andReturn( Collections.<BridgeProvider>emptySet() );
expect( mockClassLoaderService.classForName( startsWith( "java.time" ) ) )
.andThrow( new ClassLoadingException( "Called by JavaTimeBridgeProvider; we assume the classes in java.time are not on the ORM class loader" ) )
.anyTimes();
expect( mockMetadata.getEntityBindings() )
.andReturn( Collections.EMPTY_SET )
.anyTimes();
expect( mockSessionFactoryImplementor.getServiceRegistry() )
.andReturn( mockSessionFactoryServiceRegistry )
.anyTimes();
EasyMockUnitils.replay();
HibernateSearchIntegrator testedIntegrator = new HibernateSearchIntegrator();
testedIntegrator.integrate( mockMetadata, mockSessionFactoryImplementor, mockSessionFactoryServiceRegistry );
capturedSessionFactoryObserver.getValue().sessionFactoryCreated( mockSessionFactoryImplementor );
}
private void programConfigurationMock(Boolean enableSearch) {
HashMap<String,String> settings = new HashMap<>();
if ( enableSearch != null ) {
settings.put( Environment.AUTOREGISTER_LISTENERS, String.valueOf( enableSearch ) );
}
ConfigurationService cfg = new ConfigurationServiceImpl( settings );
expect( mockSessionFactoryServiceRegistry.getService( ConfigurationService.class ) )
.andReturn( cfg )
.anyTimes();
expect( mockSessionFactoryServiceRegistry.getService( JndiService.class ) )
.andReturn( jndiService )
.anyTimes();
}
}