HHH-8619 - Account for "shadow" services as part of ServiceRegistry impls

This commit is contained in:
Steve Ebersole 2013-10-17 15:18:32 -05:00
parent c88494698e
commit 859eaaa1c5
7 changed files with 73 additions and 36 deletions

View File

@ -56,6 +56,7 @@ import org.hibernate.engine.loading.internal.EntityLoadContext;
import org.hibernate.engine.spi.CollectionKey;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.id.IntegralDataTypeHolder;
import org.hibernate.service.Service;
import org.hibernate.type.BasicType;
import org.hibernate.type.SerializationException;
import org.hibernate.type.Type;
@ -1629,4 +1630,11 @@ public interface CoreMessageLogger extends BasicLogger {
"using 'key'/'value' as required by spec; attempting to DoTheRightThing"
)
void nonCompliantMapConversion(String collectionRole);
@LogMessage(level = WARN)
@Message(
id = 450,
value = "Encountered request for Service by non-primary service role [%s -> %s]; please update usage"
)
void alternateServiceRole(String requestedRole, String targetRole);
}

View File

@ -28,11 +28,12 @@ import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.ConcurrentHashMap;
import org.jboss.logging.Logger;
import org.hibernate.cfg.Environment;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.boot.registry.BootstrapServiceRegistry;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.Service;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.UnknownServiceException;
@ -48,19 +49,22 @@ import org.hibernate.service.spi.Startable;
import org.hibernate.service.spi.Stoppable;
/**
* Basic implementation of the ServiceRegistry and ServiceRegistryImplementor contracts
*
* @author Steve Ebersole
*/
public abstract class AbstractServiceRegistryImpl
implements ServiceRegistryImplementor, ServiceBinding.ServiceLifecycleOwner {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
AbstractServiceRegistryImpl.class.getName()
);
private static final CoreMessageLogger log = CoreLogging.messageLogger( AbstractServiceRegistryImpl.class );
public static final String ALLOW_CRAWLING = "hibernate.service.allow_crawling";
private final ServiceRegistryImplementor parent;
private final boolean allowCrawling;
private final ConcurrentHashMap<Class,ServiceBinding> serviceBindingMap = CollectionHelper.concurrentMap( 20 );
private ConcurrentHashMap<Class,Class> roleXref;
// IMPL NOTE : the list used for ordered destruction. Cannot used map above because we need to
// iterate it in reverse order which is only available through ListIterator
@ -74,13 +78,15 @@ public abstract class AbstractServiceRegistryImpl
protected AbstractServiceRegistryImpl(ServiceRegistryImplementor parent) {
this.parent = parent;
this.allowCrawling = ConfigurationHelper.getBoolean( ALLOW_CRAWLING, Environment.getProperties(), true );
}
public AbstractServiceRegistryImpl(BootstrapServiceRegistry bootstrapServiceRegistry) {
if ( ! ServiceRegistryImplementor.class.isInstance( bootstrapServiceRegistry ) ) {
throw new IllegalArgumentException( "Boot-strap registry was not " );
throw new IllegalArgumentException( "ServiceRegistry parent needs to implement ServiceRegistryImplementor" );
}
this.parent = (ServiceRegistryImplementor) bootstrapServiceRegistry;
this.allowCrawling = ConfigurationHelper.getBoolean( ALLOW_CRAWLING, Environment.getProperties(), true );
}
@SuppressWarnings({ "unchecked" })
@ -117,7 +123,47 @@ public abstract class AbstractServiceRegistryImpl
// look in parent
serviceBinding = parent.locateServiceBinding( serviceRole );
}
return serviceBinding;
if ( serviceBinding != null ) {
return serviceBinding;
}
if ( !allowCrawling ) {
return null;
}
// look for a previously resolved alternate registration
if ( roleXref != null ) {
if ( roleXref.containsKey( serviceRole ) ) {
return serviceBindingMap.get( roleXref.get( serviceRole ) );
}
}
// perform a crawl looking for an alternate registration
for ( ServiceBinding binding : serviceBindingMap.values() ) {
if ( serviceRole.isAssignableFrom( binding.getServiceRole() ) ) {
// we found an alternate...
log.alternateServiceRole( serviceRole.getName(), binding.getServiceRole().getName() );
registerAlternate( serviceRole, binding.getServiceRole() );
return binding;
}
if ( binding.getService() != null && serviceRole.isInstance( binding.getService() ) ) {
// we found an alternate...
log.alternateServiceRole( serviceRole.getName(), binding.getServiceRole().getName() );
registerAlternate( serviceRole, binding.getServiceRole() );
return binding;
}
}
return null;
}
private void registerAlternate(Class alternate, Class target) {
if ( roleXref == null ) {
roleXref = CollectionHelper.concurrentMap( 20 );
}
roleXref.put( alternate, target );
}
@Override
@ -143,8 +189,8 @@ public abstract class AbstractServiceRegistryImpl
}
private <R extends Service> R initializeService(ServiceBinding<R> serviceBinding) {
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Initializing service [role={0}]", serviceBinding.getServiceRole().getName() );
if ( log.isTraceEnabled() ) {
log.tracev( "Initializing service [role={0}]", serviceBinding.getServiceRole().getName() );
}
// PHASE 1 : create service
@ -211,7 +257,7 @@ public abstract class AbstractServiceRegistryImpl
}
}
catch (NullPointerException e) {
LOG.error("NPE injecting service deps : " + service.getClass().getName());
log.error( "NPE injecting service deps : " + service.getClass().getName() );
}
}
@ -285,7 +331,7 @@ public abstract class AbstractServiceRegistryImpl
( (Stoppable) service ).stop();
}
catch ( Exception e ) {
LOG.unableToStopService( service.getClass(), e.toString() );
log.unableToStopService( service.getClass(), e.toString() );
}
}
}

View File

@ -40,3 +40,4 @@ hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFa
hibernate.jdbc.batch_versioned_data true
javax.persistence.validation.mode=NONE
hibernate.service.allow_crawling=false

View File

@ -32,3 +32,4 @@ hibernate.cache.region_prefix hibernate.test
# NOTE: hibernate.jdbc.batch_versioned_data should be set to false when testing with Oracle
hibernate.jdbc.batch_versioned_data true
hibernate.service.allow_crawling=false

View File

@ -40,3 +40,4 @@ hibernate.jdbc.batch_size 0
# NOTE: hibernate.jdbc.batch_versioned_data should be set to false when testing with Oracle
hibernate.jdbc.batch_versioned_data true
hibernate.service.allow_crawling=false

View File

@ -37,3 +37,4 @@ hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFa
# NOTE: hibernate.jdbc.batch_versioned_data should be set to false when testing with Oracle
hibernate.jdbc.batch_versioned_data true
hibernate.service.allow_crawling=false

View File

@ -1,26 +1,4 @@
################################################################################
# Hibernate, Relational Persistence for Idiomatic Java #
# #
# Copyright (c) 2007, Red Hat, Inc. and/or it's affiliates or third-party contributors as #
# indicated by the @author tags or express copyright attribution #
# statements applied by the authors.  All third-party contributions are #
# distributed under license by Red Hat, Inc. and/or it's affiliates. #
# #
# This copyrighted material is made available to anyone wishing to use, modify,#
# copy, or redistribute it subject to the terms and conditions of the GNU #
# Lesser General Public License, as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# for more details. #
# #
# You should have received a copy of the GNU Lesser General Public License #
# along with this distribution; if not, write to: #
# Free Software Foundation, Inc. #
# 51 Franklin Street, Fifth Floor #
# Boston, MA 02110-1301 USA #
################################################################################
hibernate.dialect org.hibernate.dialect.H2Dialect
hibernate.connection.driver_class org.h2.Driver
hibernate.connection.url jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE
@ -37,3 +15,4 @@ hibernate.generate_statistics true
# NOTE: hibernate.jdbc.batch_versioned_data should be set to false when testing with Oracle
hibernate.jdbc.batch_versioned_data true
hibernate.service.allow_crawling=false