Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DRAFT] Upgrade Vert.x SQL client to 5.0.0.CR3 #2038

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ ext {
// Example:
// ./gradlew build -PvertxSqlClientVersion=4.0.0-SNAPSHOT
if ( !project.hasProperty( 'vertxSqlClientVersion' ) ) {
vertxSqlClientVersion = '4.5.12'
vertxSqlClientVersion = '5.0.0.CR4'
}

testcontainersVersion = '1.20.4'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ Optionally, you might also add any of the following additional features:
| Hibernate Validator | `org.hibernate.validator:hibernate-validator` and `org.glassfish:jakarta.el`
| Compile-time checking for your HQL queries | `org.hibernate:query-validator`
| Second-level cache support via JCache and EHCache | `org.hibernate.orm:hibernate-jcache` along with `org.ehcache:ehcache`
| SCRAM authentication support for PostgreSQL | `com.ongres.scram:client:2.1`
| SCRAM authentication support for PostgreSQL | `com.ongres.scram:scram-client:3.1`
|===

You might also add the Hibernate {enhancer}[bytecode enhancer] to your
Expand Down
2 changes: 1 addition & 1 deletion examples/native-sql-example/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ dependencies {
runtimeOnly "org.apache.logging.log4j:log4j-core:2.20.0"

// Allow authentication to PostgreSQL using SCRAM:
runtimeOnly 'com.ongres.scram:client:2.1'
runtimeOnly 'com.ongres.scram:scram-client:3.1'
}

// Optional: enable the bytecode enhancements
Expand Down
2 changes: 1 addition & 1 deletion examples/session-example/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ dependencies {
runtimeOnly "org.apache.logging.log4j:log4j-core:2.20.0"

// Allow authentication to PostgreSQL using SCRAM:
runtimeOnly 'com.ongres.scram:client:2.1'
runtimeOnly 'com.ongres.scram:scram-client:3.1'
}

// Optional: enable the bytecode enhancements
Expand Down
2 changes: 1 addition & 1 deletion hibernate-reactive-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ dependencies {
testImplementation "io.vertx:vertx-micrometer-metrics:${vertxSqlClientVersion}"

// Optional dependency of vertx-pg-client, essential when connecting via SASL SCRAM
testImplementation 'com.ongres.scram:client:2.1'
testImplementation 'com.ongres.scram:scram-client:3.1'

// JUnit Jupiter
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.3'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import java.lang.invoke.MethodHandles;

import io.vertx.core.Vertx;
import io.vertx.core.impl.ContextInternal;
import io.vertx.core.internal.ContextInternal;

import org.hibernate.reactive.context.Context;
import org.hibernate.reactive.logging.impl.Log;
Expand Down Expand Up @@ -36,7 +36,7 @@ public void injectServices(ServiceRegistryImplementor serviceRegistry) {

@Override
public <T> void put(Key<T> key, T instance) {
final io.vertx.core.Context context = Vertx.currentContext();
final ContextInternal context = currentContext();
if ( context != null ) {
if ( trace ) LOG.tracef( "Putting key,value in context: [%1$s, %2$s]", key, instance );
context.putLocal( key, instance );
Expand All @@ -47,9 +47,13 @@ public <T> void put(Key<T> key, T instance) {
}
}

private static ContextInternal currentContext() {
return (ContextInternal) Vertx.currentContext();
}

@Override
public <T> T get(Key<T> key) {
final io.vertx.core.Context context = Vertx.currentContext();
final ContextInternal context = currentContext();
if ( context != null ) {
T local = context.getLocal( key );
if ( trace ) LOG.tracef( "Getting value %2$s from context for key %1$s", key, local );
Expand All @@ -63,7 +67,7 @@ public <T> T get(Key<T> key) {

@Override
public void remove(Key<?> key) {
final io.vertx.core.Context context = Vertx.currentContext();
final ContextInternal context = currentContext();
if ( context != null ) {
boolean removed = context.removeLocal( key );
if ( trace ) LOG.tracef( "Key %s removed from context: %s", key, removed );
Expand All @@ -75,14 +79,15 @@ public void remove(Key<?> key) {

@Override
public void execute(Runnable runnable) {
final io.vertx.core.Context currentContext = Vertx.currentContext();
final io.vertx.core.Context currentContext = currentContext();
if ( currentContext == null ) {
if ( trace ) LOG.tracef( "Not in a Vert.x context, checking the VertxInstance service" );
final io.vertx.core.Context newContext = vertxInstance.getVertx().getOrCreateContext();
// Ensure we don't run on the root context, which is globally scoped:
// that could lead to unintentionally share the same session with other streams.
ContextInternal newContextInternal = (ContextInternal) newContext;
final ContextInternal duplicate = newContextInternal.duplicate();

if ( trace ) LOG.tracef( "Using duplicated context from VertxInstance: %s", duplicate );
duplicate.runOnContext( x -> runnable.run() );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@
*/
package org.hibernate.reactive.id.impl;

import io.vertx.core.Context;
import io.vertx.core.Vertx;
import io.vertx.core.net.impl.pool.CombinerExecutor;
import io.vertx.core.net.impl.pool.Executor;
import io.vertx.core.net.impl.pool.Task;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;

import org.hibernate.reactive.id.ReactiveIdentifierGenerator;
import org.hibernate.reactive.session.ReactiveConnectionSupplier;

import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import io.vertx.core.Context;
import io.vertx.core.Vertx;
import io.vertx.core.internal.pool.CombinerExecutor;
import io.vertx.core.internal.pool.Executor;
import io.vertx.core.internal.pool.Task;

import static org.hibernate.reactive.util.impl.CompletionStages.completedFuture;

Expand Down Expand Up @@ -44,7 +44,7 @@ public abstract class BlockingIdentifierGenerator implements ReactiveIdentifierG
//modification access.
//This replaces the synchronization blocks one would see in a similar
//service in Hibernate ORM, but using a non-blocking cooperative design.
private final CombinerExecutor executor = new CombinerExecutor( state );
private final CombinerExecutor<GeneratorState> executor = new CombinerExecutor<>( state );

/**
* Allocate a new block, by obtaining the next "hi" value from the database
Expand Down Expand Up @@ -138,7 +138,6 @@ public Task execute(GeneratorState state) {
// value in the table, so just increment the lo
// value and return the next id in the block
completedFuture( local ).whenComplete( this::acceptAsReturnValue );
return null;
}
else {
nextHiValue( connectionSupplier )
Expand All @@ -155,8 +154,8 @@ public Task execute(GeneratorState state) {
} );
}
} );
return null;
}
return null;
}

private void acceptAsReturnValue(final Long aLong, final Throwable throwable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import java.util.concurrent.CompletionStage;
import java.util.function.Supplier;

import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
Expand All @@ -31,14 +32,13 @@

import io.vertx.core.Future;
import io.vertx.core.Vertx;
import io.vertx.core.net.NetClientOptions;
import io.vertx.sqlclient.Pool;
import io.vertx.sqlclient.PoolOptions;
import io.vertx.sqlclient.SqlConnectOptions;
import io.vertx.sqlclient.impl.Utils;
import io.vertx.sqlclient.spi.Driver;

import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.toList;

/**
* A pool of reactive connections backed by a Vert.x {@link Pool}.
* The {@code Pool} itself is backed by an instance of {@link Vertx}
Expand Down Expand Up @@ -190,7 +190,7 @@ protected Pool createPool(URI uri) {
*
* @return the new {@link Pool}
*/
protected Pool createPool(URI uri, SqlConnectOptions connectOptions, PoolOptions poolOptions, Vertx vertx) {
protected <T extends SqlConnectOptions> Pool createPool(URI uri, T connectOptions, PoolOptions poolOptions, Vertx vertx) {
try {
// First try to load the Pool using the standard ServiceLoader pattern
// This only works if exactly 1 Driver is on the classpath.
Expand All @@ -199,8 +199,9 @@ protected Pool createPool(URI uri, SqlConnectOptions connectOptions, PoolOptions
catch (ServiceConfigurationError e) {
// Backup option if multiple drivers are on the classpath.
// We will be able to remove this once Vertx 3.9.2 is available
final Driver driver = findDriver( uri, e );
return driver.createPool( vertx, singletonList( connectOptions ), poolOptions );
final Driver<SqlConnectOptions> driver = findDriver( uri, e );
Supplier<Future<SqlConnectOptions>> database = Utils.singletonSupplier( driver.downcast( connectOptions ) );
return driver.createPool( vertx, database, poolOptions, new NetClientOptions(), null );
}
}

Expand All @@ -223,15 +224,14 @@ protected URI jdbcUrl(Map<?,?> configurationValues) {
* so we need to disambiguate according to the scheme specified
* in the given {@link URI}.
*
* @param uri the JDBC URL or database URI
* @param uri the JDBC URL or database URI
* @param originalError the error that was thrown
*
* @return the disambiguated {@link Driver}
*/
private Driver findDriver(URI uri, ServiceConfigurationError originalError) {
private Driver<SqlConnectOptions> findDriver(URI uri, ServiceConfigurationError originalError) {
String scheme = scheme( uri );
List<Driver> selected = new ArrayList<>();
for ( Driver d : ServiceLoader.load( Driver.class ) ) {
List<Driver<SqlConnectOptions>> selected = new ArrayList<>();
for ( Driver<SqlConnectOptions> d : ServiceLoader.load( Driver.class ) ) {
String driverName = d.getClass().getCanonicalName();
if ( matchesScheme( driverName, scheme ) ) {
LOG.selectedDriver( driverName );
Expand All @@ -247,7 +247,7 @@ private Driver findDriver(URI uri, ServiceConfigurationError originalError) {
if ( selected.size() > 1 ) {
List<String> driverClasses = selected.stream()
.map( driver -> driver.getClass().getCanonicalName() )
.collect( toList() );
.toList();
throw new ConfigurationException( "Multiple drivers found matching for URI scheme \"" + scheme + "\". Please, pick one: " + driverClasses, originalError );
}
return selected.get( 0 );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import java.util.Collection;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.function.Supplier;

Expand All @@ -27,6 +26,7 @@
import org.hibernate.reactive.provider.service.ReactiveGenerationTarget;
import org.hibernate.reactive.stage.Stage;
import org.hibernate.reactive.testing.SessionFactoryManager;
import org.hibernate.reactive.util.impl.CompletionStages;
import org.hibernate.tool.schema.spi.SchemaManagementTool;

import org.junit.jupiter.api.AfterAll;
Expand All @@ -39,7 +39,6 @@
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import io.smallrye.mutiny.Uni;
import io.vertx.core.Promise;
import io.vertx.core.VertxOptions;
import io.vertx.junit5.RunTestOnContext;
import io.vertx.junit5.Timeout;
Expand Down Expand Up @@ -73,7 +72,7 @@ public abstract class BaseReactiveTest {
* Configure Vertx JUnit5 test context
*/
@RegisterExtension
static RunTestOnContext testOnContext = new RunTestOnContext( vertxOptions() );
static RunTestOnContext testOnContext = new RunTestOnContext( vertxOptions(), false );

private static VertxOptions vertxOptions() {
Metrics.addRegistry( new SimpleMeterRegistry() );
Expand Down Expand Up @@ -205,33 +204,19 @@ protected CompletionStage<Void> setupSessionFactory(Configuration configuration)
* @return a {@link CompletionStage} void that succeeds when the factory is ready.
*/
protected CompletionStage<Void> setupSessionFactory(Supplier<Configuration> confSupplier) {
CompletableFuture<Void> future = new CompletableFuture<>();
testOnContext.vertx()
return testOnContext.vertx()
.executeBlocking(
// schema generation is a blocking operation and so it causes an
// exception when run on the Vert.x event loop. So call it using
// Vertx.executeBlocking()
promise -> startFactoryManager( promise, confSupplier ),
event -> {
if ( event.succeeded() ) {
future.complete( null );
}
else {
future.completeExceptionally( event.cause() );
}
}
);
return future;
}

private void startFactoryManager(Promise<Object> p, Supplier<Configuration> confSupplier) {
try {
factoryManager.start( () -> createHibernateSessionFactory( confSupplier.get() ) );
p.complete();
}
catch (Throwable e) {
p.fail( e );
}
() -> startFactoryManager( confSupplier ),
false
).toCompletionStage().thenCompose( CompletionStages::voidFuture );
}

private Object startFactoryManager(Supplier<Configuration> confSupplier) {
factoryManager.start( () -> createHibernateSessionFactory( confSupplier.get() ) );
return null;
}

private SessionFactory createHibernateSessionFactory(Configuration configuration) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,12 @@

import java.net.URI;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.hibernate.reactive.MyCurrentTenantIdentifierResolver.Tenant;
import org.hibernate.reactive.pool.impl.DefaultSqlClientPool;

import io.vertx.core.AsyncResult;
import io.vertx.core.Context;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.sqlclient.Pool;
import io.vertx.sqlclient.PoolOptions;
Expand Down Expand Up @@ -58,8 +54,18 @@ protected Pool createPool(URI uri, SqlConnectOptions connectOptions, PoolOptions
return pools;
}

private Pool createPool(URI uri, SqlConnectOptions connectOptions, PoolOptions poolOptions, Vertx vertx, Tenant tenant) {
return super.createPool( changeDbName( uri, tenant ), changeDbName( connectOptions, tenant ), poolOptions, vertx );
private Pool createPool(
URI uri,
SqlConnectOptions connectOptions,
PoolOptions poolOptions,
Vertx vertx,
Tenant tenant) {
return super.createPool(
changeDbName( uri, tenant ),
changeDbName( connectOptions, tenant ),
poolOptions,
vertx
);
}

/**
Expand Down Expand Up @@ -100,11 +106,6 @@ public Pool getTenantPool(Tenant tenantId) {
return poolMap.get( tenantId );
}

@Override
public void getConnection(Handler<AsyncResult<SqlConnection>> handler) {
poolMap.get( defaultTenantId ).getConnection( handler );
}

@Override
public Future<SqlConnection> getConnection() {
return poolMap.get( defaultTenantId ).getConnection();
Expand All @@ -125,21 +126,6 @@ public PreparedQuery<RowSet<Row>> preparedQuery(String sql, PrepareOptions optio
return poolMap.get( defaultTenantId ).preparedQuery( sql, options );
}

@Override
public void close(Handler<AsyncResult<Void>> handler) {
poolMap.forEach( (tenant, pool) -> pool.close( handler ) );
}

@Override
public Pool connectHandler(Handler<SqlConnection> handler) {
return poolMap.get( defaultTenantId ).connectHandler( handler );
}

@Override
public Pool connectionProvider(Function<Context, Future<SqlConnection>> provider) {
return poolMap.get( defaultTenantId ).connectionProvider( provider );
}

@Override
public int size() {
return poolMap.get( defaultTenantId ).size();
Expand Down
Loading
Loading