Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ private ReactiveServiceInitiators() {
// Note that Quarkus uses a different list for the initialization of the services:
// If you update this list makes sure to check that reactive still works with Quarkus.
// Also: please try to maintain the same order as Hibernate ORM for sake of comparisons.
// See also test ServiceInitiatorsTest; among basic validations it prints a sorted summary
// for convenience.
private static List<StandardServiceInitiator<?>> buildInitialServiceInitiatorList() {
final ArrayList<StandardServiceInitiator<?>> serviceInitiators = new ArrayList<>();

Expand Down Expand Up @@ -152,22 +154,26 @@ private static List<StandardServiceInitiator<?>> buildInitialServiceInitiatorLis
// Custom for Hibernate Reactive: SqmMultiTableMutationStrategyProvider
serviceInitiators.add( ReactiveSqmMultiTableMutationStrategyProviderInitiator.INSTANCE );

// Custom for Hibernate Reactive: NativeParametersRendering [Could be used by ORM too? TBD]
// Custom for Hibernate Reactive: NativeParametersRendering
serviceInitiators.add( NativeParametersRendering.INSTANCE );

// --- end of services defined by Hibernate ORM

// --- custom ones follow:

// Definitely exclusive to Hibernate Reactive, as it marks this particular registry as Reactive:
// ReactiveMarkerService - Definitely exclusive to Hibernate Reactive, as it marks this particular registry as Reactive:
serviceInitiators.add( ReactiveMarkerServiceInitiator.INSTANCE );

// Exclusive to Hibernate Reactive:
// VertxInstance - Exclusive to Hibernate Reactive:
serviceInitiators.add( VertxInstanceInitiator.INSTANCE );

// Context - Exclusive to Hibernate Reactive:
serviceInitiators.add( VertxContextInitiator.INSTANCE );

// Exclusive to Hibernate Reactive:
// SqlClientPoolConfiguration - Exclusive to Hibernate Reactive:
serviceInitiators.add( SqlClientPoolConfigurationInitiator.INSTANCE );

// ReactiveConnectionPool - Exclusive to Hibernate Reactive:
serviceInitiators.add( ReactiveConnectionPoolInitiator.INSTANCE );

// --- end of custom services.
Expand All @@ -176,4 +182,5 @@ private static List<StandardServiceInitiator<?>> buildInitialServiceInitiatorLis

return unmodifiableList( serviceInitiators );
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/* Hibernate, Relational Persistence for Idiomatic Java
*
* SPDX-License-Identifier: Apache-2.0
* Copyright: Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.reactive.services;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import org.hibernate.boot.registry.StandardServiceInitiator;
import org.hibernate.reactive.provider.impl.ReactiveServiceInitiators;
import org.hibernate.service.StandardServiceInitiators;

import org.junit.Assert;
import org.junit.Test;

/**
* Useful to spot inconsistencies in the default ServiceInitiator lists
* used by Hibernate Reactive compared to Hibernate ORM.
* N.B. Hibernate Reactive defines some additional services.
*/
public class ServiceInitiatorsTest {

private static final Map<String,String> HR_SERVICES = toServicesMap( ReactiveServiceInitiators.LIST );
private static final Map<String,String> ORM_SERVICES = toServicesMap( StandardServiceInitiators.LIST );

// These services are NOT provided by the Hibernate Reactive default initiators, and that should be fine:
private static final Set<String> HR_INTENTIONALLY_OMITTED = Set.of( "org.hibernate.engine.transaction.jta.platform.spi.JtaPlatformResolver" );

@Test
public void serviceInitiatorsAreUnique() {
Assert.assertEquals( HR_SERVICES.size(), ReactiveServiceInitiators.LIST.size() );
Assert.assertEquals( ORM_SERVICES.size(), StandardServiceInitiators.LIST.size() );
}

@Test
public void allORMServicesAreDefined() {
Set<String> sharedServiceImplementations = new TreeSet<>();
Set<String> notSharedServiceImplementations = new TreeSet<>();
reportDivider( "All Services in sorted order" );
int i = 1;
for ( String key : ORM_SERVICES.keySet() ) {
String error = "ORM service '" + key + "' is not defined by the HR services list";
Assert.assertTrue( error, HR_SERVICES.containsKey( key ) || HR_INTENTIONALLY_OMITTED.contains( key ) );
if ( Objects.equals( HR_SERVICES.get( key ), ORM_SERVICES.get( key ) ) ) {
sharedServiceImplementations.add( key );
}
else {
notSharedServiceImplementations.add( key );
}
StringBuilder entry = new StringBuilder();
entry.append( " #" ).append( i++ ).append( '\t' ).append( "service role " ).append( key ).append( '\n' );
entry.append( "\tORM: " ).append( ORM_SERVICES.get( key ) ).append( '\n' );
entry.append( "\tHR: " ).append( HR_SERVICES.get( key ) ).append( '\n' );
System.out.println( entry );
}
reportDivider( "All Services which are shared among ORM and HR:" );
for ( String key : sharedServiceImplementations ) {
System.out.println( key );
}
reportDivider( "All Services which are overridden in HR:" );
for ( String key : notSharedServiceImplementations ) {
StringBuilder entry = new StringBuilder();
entry.append( " service role " ).append( key ).append( '\n' );
entry.append( "\tORM: " ).append( ORM_SERVICES.get( key ) ).append( '\n' );
entry.append( "\tHR: " ).append( HR_SERVICES.get( key ) ).append( '\n' );
System.out.println( entry );
}
}

private void reportDivider(String title) {
System.out.println( "\n ########### " + title + "\n" );
}

//N.B. service identity and class identity are handled by their name:
//this is possibly more restrictive than strictly required in certain environments,
//but we need to ensure safety in all classloading models.
private static Map<String, String> toServicesMap(List<StandardServiceInitiator<?>> list) {
TreeMap<String,String> rolesToImplMap = new TreeMap<>();
for ( StandardServiceInitiator<?> initiator : list ) {
final String serviceRole = initiator.getServiceInitiated().getName();
rolesToImplMap.put( serviceRole, initiator.getClass().getName() );
}
return Collections.unmodifiableMap( rolesToImplMap );
}

}