HHH-12560 - Make sure only one Service registration (initiator/provided) exists per role

- added test (passed without changes)
- added "graceful shutdown" of services already bound during construction of a registry
This commit is contained in:
Steve Ebersole 2018-05-11 14:57:22 -05:00
parent 2ad6bf6724
commit 87c7915a5c
3 changed files with 72 additions and 7 deletions

View File

@ -71,14 +71,20 @@ public class StandardServiceRegistryImpl extends AbstractServiceRegistryImpl imp
this.configurationValues = configurationValues;
// process initiators
for ( ServiceInitiator initiator : serviceInitiators ) {
createServiceBinding( initiator );
}
try {
// process initiators
for ( ServiceInitiator initiator : serviceInitiators ) {
createServiceBinding( initiator );
}
// then, explicitly provided service instances
for ( ProvidedService providedService : providedServices ) {
createServiceBinding( providedService );
// then, explicitly provided service instances
for ( ProvidedService providedService : providedServices ) {
createServiceBinding( providedService );
}
}
catch (RuntimeException e) {
visitServiceBindings( binding -> binding.getLifecycleOwner().stopService( binding ) );
throw e;
}
}

View File

@ -14,6 +14,7 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import org.hibernate.boot.registry.BootstrapServiceRegistry;
import org.hibernate.cfg.Environment;
@ -126,6 +127,10 @@ public abstract class AbstractServiceRegistryImpl
registerService( binding, providedService.getService() );
}
protected void visitServiceBindings(Consumer<ServiceBinding> action) {
serviceBindingList.forEach( action );
}
@Override
@SuppressWarnings( {"unchecked"})
public ServiceRegistry getParentServiceRegistry() {

View File

@ -0,0 +1,54 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* 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.service;
import java.util.Map;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cache.internal.RegionFactoryInitiator;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
/**
* @author Steve Ebersole
*/
public class ServiceContributorTest extends BaseUnitTestCase {
@Test
public void overrideInitiator() {
StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder();
class MyRegionFactoryInitiator extends RegionFactoryInitiator {
private boolean called = false;
@Override
public RegionFactory initiateService(
Map configurationValues,
ServiceRegistryImplementor registry) {
called = true;
return super.initiateService( configurationValues, registry );
}
}
final MyRegionFactoryInitiator initiator = new MyRegionFactoryInitiator();
ssrb.addInitiator( initiator );
final ServiceRegistryImplementor registry = (ServiceRegistryImplementor) ssrb.build();
try {
registry.getService( RegionFactory.class );
assertTrue( initiator.called );
}
finally {
StandardServiceRegistryBuilder.destroy( registry );
}
}
}