Skip to content

Commit 0a4946e

Browse files
blafondDavideD
authored andcommitted
[hibernate#929] hibernate-reactive-h2 module
1 parent bff1835 commit 0a4946e

10 files changed

+309
-0
lines changed

hibernate-reactive-h2/build.gradle

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
ext {
2+
mavenPomName = 'Hibernate Reactive H2'
3+
}
4+
5+
description = 'The H2 module of Hibernate Reactive'
6+
7+
apply from: publishScript
8+
9+
dependencies {
10+
implementation project(':hibernate-reactive-core')
11+
implementation "com.h2database:h2:2.1.214"
12+
13+
// Dependencies for using H2 with Vert.x:
14+
implementation "io.vertx:vertx-jdbc-client:${vertxVersion}"
15+
16+
// Testing
17+
testImplementation 'org.assertj:assertj-core:3.20.2'
18+
testImplementation "io.vertx:vertx-unit:${vertxVersion}"
19+
20+
// log4j
21+
testRuntimeOnly 'org.apache.logging.log4j:log4j-core:2.17.1'
22+
}
23+
24+
// Print a summary of the results of the tests (number of failures, successes and skipped)
25+
def loggingSummary(db, result, desc) {
26+
if ( !desc.parent ) { // will match the outermost suite
27+
def output = "${db} results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} passed, ${result.failedTestCount} failed, ${result.skippedTestCount} skipped)"
28+
def repeatLength = output.length() + 1
29+
logger.lifecycle '\n' + ('-' * repeatLength) + '\n' + output + '\n' + ('-' * repeatLength)
30+
}
31+
}
32+
33+
// Configuration for the tests
34+
tasks.withType(Test) {
35+
defaultCharacterEncoding = "UTF-8"
36+
testLogging {
37+
displayGranularity 1
38+
showStandardStreams = project.hasProperty('showStandardOutput')
39+
showStackTraces = true
40+
exceptionFormat = 'full'
41+
events 'PASSED', 'FAILED', 'SKIPPED'
42+
}
43+
systemProperty 'org.hibernate.reactive.common.InternalStateAssertions.ENFORCE', 'true'
44+
45+
if ( project.hasProperty( 'includeTests' ) ) {
46+
// Example: ./gradlew testAll -PincludeTests=DefaultPortTest
47+
filter {
48+
includeTestsMatching project.getProperty( 'includeTests' ) ?: '*'
49+
}
50+
}
51+
}
52+
53+
test {
54+
afterSuite { desc, result ->
55+
loggingSummary( 'H2', result, desc )
56+
}
57+
doFirst {
58+
systemProperty 'db', 'H2'
59+
}
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/* Hibernate, Relational Persistence for Idiomatic Java
2+
*
3+
* SPDX-License-Identifier: Apache-2.0
4+
* Copyright: Red Hat Inc. and Hibernate Authors
5+
*/
6+
package org.hibernate.reactive.jdbc.boot.impl;
7+
8+
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
9+
import org.hibernate.reactive.jdbc.pool.impl.H2ReactiveConnectionPoolInitiator;
10+
import org.hibernate.service.spi.ServiceContributor;
11+
12+
public class H2ServiceContributor implements ServiceContributor {
13+
@Override
14+
public void contribute(StandardServiceRegistryBuilder serviceRegistryBuilder) {
15+
serviceRegistryBuilder.addInitiator( H2ReactiveConnectionPoolInitiator.INSTANCE );
16+
serviceRegistryBuilder.addInitiator( JdbcSqlClientPoolConfigurationInitiator.INSTANCE );
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/* Hibernate, Relational Persistence for Idiomatic Java
2+
*
3+
* SPDX-License-Identifier: Apache-2.0
4+
* Copyright: Red Hat Inc. and Hibernate Authors
5+
*/
6+
package org.hibernate.reactive.jdbc.boot.impl;
7+
8+
import java.util.Map;
9+
10+
import org.hibernate.boot.registry.StandardServiceInitiator;
11+
import org.hibernate.reactive.jdbc.pool.impl.H2ClientPoolConfiguration;
12+
import org.hibernate.reactive.pool.impl.JdbcClientPoolConfiguration;
13+
import org.hibernate.service.spi.ServiceRegistryImplementor;
14+
15+
public class JdbcSqlClientPoolConfigurationInitiator implements StandardServiceInitiator<JdbcClientPoolConfiguration> {
16+
17+
public static final JdbcSqlClientPoolConfigurationInitiator INSTANCE = new JdbcSqlClientPoolConfigurationInitiator() {
18+
};
19+
20+
@Override
21+
public JdbcClientPoolConfiguration initiateService(Map configurationValues, ServiceRegistryImplementor registry) {
22+
return new H2ClientPoolConfiguration();
23+
}
24+
25+
@Override
26+
public Class<JdbcClientPoolConfiguration> getServiceInitiated() {
27+
return JdbcClientPoolConfiguration.class;
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
// * Hibernate Reactive is an adaptation of Hibernate ORM to the
3+
// * world of reactive programming, and replaces JDBC for database
4+
// * access with a non-blocking database client.
5+
// * <p>
6+
// * <p>
7+
*/
8+
package org.hibernate.reactive.jdbc;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/* Hibernate, Relational Persistence for Idiomatic Java
2+
*
3+
* SPDX-License-Identifier: Apache-2.0
4+
* Copyright: Red Hat Inc. and Hibernate Authors
5+
*/
6+
package org.hibernate.reactive.jdbc.pool.impl;
7+
8+
import java.net.URI;
9+
10+
import org.hibernate.reactive.pool.impl.DefaultSqlClientPoolConfiguration;
11+
import org.hibernate.reactive.pool.impl.JdbcClientPoolConfiguration;
12+
13+
import io.vertx.core.json.JsonObject;
14+
15+
public class H2ClientPoolConfiguration extends DefaultSqlClientPoolConfiguration implements JdbcClientPoolConfiguration {
16+
17+
@Override
18+
public JsonObject jdbcConnectOptions(URI uri) {
19+
return new JsonObject()
20+
.put( "url", uri.toString() )
21+
.put( "user", "sa" )
22+
.put( "pass", null );
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* Hibernate, Relational Persistence for Idiomatic Java
2+
*
3+
* SPDX-License-Identifier: Apache-2.0
4+
* Copyright: Red Hat Inc. and Hibernate Authors
5+
*/
6+
package org.hibernate.reactive.jdbc.pool.impl;
7+
8+
import java.util.Map;
9+
10+
import org.hibernate.internal.util.config.ConfigurationHelper;
11+
import org.hibernate.reactive.pool.ReactiveConnectionPool;
12+
import org.hibernate.reactive.pool.impl.ReactiveConnectionPoolInitiator;
13+
import org.hibernate.reactive.provider.Settings;
14+
import org.hibernate.service.spi.ServiceRegistryImplementor;
15+
16+
public class H2ReactiveConnectionPoolInitiator extends ReactiveConnectionPoolInitiator {
17+
18+
public static final H2ReactiveConnectionPoolInitiator INSTANCE = new H2ReactiveConnectionPoolInitiator();
19+
20+
@Override
21+
public ReactiveConnectionPool initiateService(Map configurationValues, ServiceRegistryImplementor registry) {
22+
String url = ConfigurationHelper.getString( Settings.URL, configurationValues );
23+
// Check URL for H2 and return H2 specific pool
24+
if ( url.startsWith( "jdbc:h2:" ) ) {
25+
return new H2SqlClientPool();
26+
}
27+
28+
// delegate to super class to initiate the DefaultSqlClientPool
29+
return super.initiateService( configurationValues, registry );
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/* Hibernate, Relational Persistence for Idiomatic Java
2+
*
3+
* SPDX-License-Identifier: Apache-2.0
4+
* Copyright: Red Hat Inc. and Hibernate Authors
5+
*/
6+
package org.hibernate.reactive.jdbc.pool.impl;
7+
8+
9+
import java.lang.invoke.MethodHandles;
10+
import java.net.URI;
11+
import java.util.Map;
12+
import java.util.concurrent.CompletionStage;
13+
14+
import org.hibernate.engine.jdbc.spi.JdbcServices;
15+
import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
16+
import org.hibernate.internal.util.config.ConfigurationHelper;
17+
import org.hibernate.reactive.logging.impl.Log;
18+
import org.hibernate.reactive.logging.impl.LoggerFactory;
19+
import org.hibernate.reactive.pool.impl.JdbcClientPoolConfiguration;
20+
import org.hibernate.reactive.pool.impl.SqlClientPool;
21+
import org.hibernate.reactive.provider.Settings;
22+
import org.hibernate.reactive.vertx.VertxInstance;
23+
import org.hibernate.service.spi.Configurable;
24+
import org.hibernate.service.spi.ServiceRegistryAwareService;
25+
import org.hibernate.service.spi.ServiceRegistryImplementor;
26+
import org.hibernate.service.spi.Startable;
27+
import org.hibernate.service.spi.Stoppable;
28+
29+
import io.vertx.core.Future;
30+
import io.vertx.core.json.JsonObject;
31+
import io.vertx.jdbcclient.JDBCPool;
32+
import io.vertx.sqlclient.Pool;
33+
34+
public class H2SqlClientPool extends SqlClientPool
35+
implements ServiceRegistryAwareService, Configurable, Stoppable, Startable {
36+
37+
private static final Log LOG = LoggerFactory.make( Log.class, MethodHandles.lookup() );
38+
39+
public static final String DEFAULT_URL = "jdbc:h2:mem:hreact";
40+
41+
//Asynchronous shutdown promise: we can't return it from #close as we implement a
42+
//blocking interface.
43+
private volatile Future<Void> closeFuture = Future.succeededFuture();
44+
45+
private Pool pools;
46+
private URI uri;
47+
private SqlStatementLogger sqlStatementLogger;
48+
private ServiceRegistryImplementor serviceRegistry;
49+
50+
public H2SqlClientPool() {
51+
}
52+
53+
@Override
54+
public void injectServices(ServiceRegistryImplementor serviceRegistry) {
55+
this.serviceRegistry = serviceRegistry;
56+
sqlStatementLogger = serviceRegistry.getService( JdbcServices.class ).getSqlStatementLogger();
57+
}
58+
59+
@Override
60+
public void configure(Map configuration) {
61+
uri = jdbcUrl( configuration );
62+
}
63+
64+
protected URI jdbcUrl(Map<?,?> configurationValues) {
65+
String url = ConfigurationHelper.getString( Settings.URL, configurationValues, DEFAULT_URL );
66+
LOG.sqlClientUrl( url);
67+
return URI.create( url );
68+
}
69+
70+
@Override
71+
public void start() {
72+
if ( pools == null ) {
73+
pools = createPool( uri );
74+
}
75+
}
76+
77+
@Override
78+
public CompletionStage<Void> getCloseFuture() {
79+
return closeFuture.toCompletionStage();
80+
}
81+
82+
@Override
83+
protected Pool getPool() {
84+
return pools;
85+
}
86+
87+
private Pool createPool(URI uri) {
88+
JdbcClientPoolConfiguration configuration = serviceRegistry.getService( JdbcClientPoolConfiguration.class );
89+
VertxInstance vertx = serviceRegistry.getService( VertxInstance.class );
90+
JsonObject poolOptions = configuration.poolOptions().toJson();
91+
JsonObject connectOptions = configuration.jdbcConnectOptions( uri );
92+
JsonObject config = poolOptions.mergeIn( connectOptions );
93+
return JDBCPool.pool( vertx.getVertx(), config );
94+
}
95+
96+
@Override
97+
public void stop() {
98+
if ( pools != null ) {
99+
this.closeFuture = pools.close();
100+
}
101+
}
102+
103+
@Override
104+
protected SqlStatementLogger getSqlStatementLogger() {
105+
return sqlStatementLogger;
106+
}
107+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/* Hibernate, Relational Persistence for Idiomatic Java
2+
*
3+
* SPDX-License-Identifier: Apache-2.0
4+
* Copyright: Red Hat Inc. and Hibernate Authors
5+
*/
6+
package org.hibernate.reactive.pool.impl;
7+
8+
import java.net.URI;
9+
10+
import org.hibernate.service.Service;
11+
12+
import io.vertx.core.json.JsonObject;
13+
import io.vertx.sqlclient.PoolOptions;
14+
15+
public interface JdbcClientPoolConfiguration extends Service {
16+
/**
17+
* The {@link PoolOptions} used to configure the {@code Pool}
18+
*/
19+
PoolOptions poolOptions();
20+
21+
/**
22+
* The {@link JsonObject} used to configure the {@code Pool}
23+
*
24+
* @param uri A {@link URI} representing the JDBC URL or connection URI
25+
* specified in the configuration properties, usually via
26+
* {@link org.hibernate.cfg.Environment#JPA_JDBC_URL}, or
27+
* {@code null} if not specified.
28+
*/
29+
JsonObject jdbcConnectOptions(URI uri);
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
org.hibernate.reactive.jdbc.pool.impl.H2SqlClientPool
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
org.hibernate.reactive.jdbc.boot.impl.H2ServiceContributor

0 commit comments

Comments
 (0)