-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10433 from DavideD/10432-session-producer
[#10432] Allow injection of a reactive session not wrapped in a Mutiny/CompletionStage
- Loading branch information
Showing
10 changed files
with
608 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
124 changes: 124 additions & 0 deletions
124
...ava/io/quarkus/it/hibernate/reactive/db2/HibernateReactiveDB2AlternativeTestEndpoint.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
package io.quarkus.it.hibernate.reactive.db2; | ||
|
||
import java.util.concurrent.CompletionStage; | ||
|
||
import javax.inject.Inject; | ||
import javax.ws.rs.GET; | ||
import javax.ws.rs.Path; | ||
import javax.ws.rs.Produces; | ||
import javax.ws.rs.core.MediaType; | ||
|
||
import org.hibernate.reactive.mutiny.Mutiny; | ||
import org.hibernate.reactive.stage.Stage; | ||
|
||
import io.smallrye.mutiny.Uni; | ||
import io.vertx.mutiny.db2client.DB2Pool; | ||
import io.vertx.mutiny.sqlclient.Row; | ||
import io.vertx.mutiny.sqlclient.RowSet; | ||
import io.vertx.mutiny.sqlclient.Tuple; | ||
|
||
@Path("/alternative-tests") | ||
@Produces(MediaType.APPLICATION_JSON) | ||
public class HibernateReactiveDB2AlternativeTestEndpoint { | ||
|
||
@Inject | ||
Stage.Session stageSession; | ||
|
||
@Inject | ||
Mutiny.Session mutinySession; | ||
|
||
// Injecting a Vert.x Pool is not required, it us only used to | ||
// independently validate the contents of the database for the test | ||
@Inject | ||
DB2Pool db2Pool; | ||
|
||
@GET | ||
@Path("/reactiveFind") | ||
public CompletionStage<GuineaPig> reactiveFind() { | ||
final GuineaPig expectedPig = new GuineaPig(5, "Aloi"); | ||
return populateDB().convert().toCompletionStage() | ||
.thenCompose(junk -> stageSession.find(GuineaPig.class, expectedPig.getId())); | ||
} | ||
|
||
@GET | ||
@Path("/reactiveFindMutiny") | ||
public Uni<GuineaPig> reactiveFindMutiny() { | ||
final GuineaPig expectedPig = new GuineaPig(5, "Aloi"); | ||
return populateDB() | ||
.onItem().produceUni(junk -> mutinySession.find(GuineaPig.class, expectedPig.getId())); | ||
} | ||
|
||
@GET | ||
@Path("/reactivePersist") | ||
public Uni<String> reactivePersist() { | ||
return mutinySession.persist(new GuineaPig(10, "Tulip")) | ||
.onItem().produceUni(s -> s.flush()) | ||
.onItem().produceUni(junk -> selectNameFromId(10)); | ||
} | ||
|
||
@GET | ||
@Path("/reactiveRemoveTransientEntity") | ||
public Uni<String> reactiveRemoveTransientEntity() { | ||
return populateDB() | ||
.onItem().produceUni(junk -> selectNameFromId(5)) | ||
.onItem().apply(name -> { | ||
if (name == null) { | ||
throw new AssertionError("Database was not populated properly"); | ||
} | ||
return name; | ||
}) | ||
.onItem().produceUni(junk -> mutinySession.merge(new GuineaPig(5, "Aloi"))) | ||
.onItem().produceUni(aloi -> mutinySession.remove(aloi)) | ||
.onItem().produceUni(junk -> mutinySession.flush()) | ||
.onItem().produceUni(junk -> selectNameFromId(5)) | ||
.onItem().ifNotNull().apply(result -> result) | ||
.onItem().ifNull().continueWith("OK"); | ||
} | ||
|
||
@GET | ||
@Path("/reactiveRemoveManagedEntity") | ||
public Uni<String> reactiveRemoveManagedEntity() { | ||
return populateDB() | ||
.onItem().produceUni(junk -> mutinySession.find(GuineaPig.class, 5)) | ||
.onItem().produceUni(aloi -> mutinySession.remove(aloi)) | ||
.onItem().produceUni(junk -> mutinySession.flush()) | ||
.onItem().produceUni(junk -> selectNameFromId(5)) | ||
.onItem().ifNotNull().apply(result -> result) | ||
.onItem().ifNull().continueWith("OK"); | ||
} | ||
|
||
@GET | ||
@Path("/reactiveUpdate") | ||
public Uni<String> reactiveUpdate() { | ||
final String NEW_NAME = "Tina"; | ||
return populateDB() | ||
.onItem().produceUni(junk -> mutinySession.find(GuineaPig.class, 5)) | ||
.onItem().apply(pig -> { | ||
if (NEW_NAME.equals(pig.getName())) { | ||
throw new AssertionError("Pig already had name " + NEW_NAME); | ||
} | ||
pig.setName(NEW_NAME); | ||
return pig; | ||
}) | ||
.onItem().produceUni(junk -> mutinySession.flush()) | ||
.onItem().produceUni(junk -> selectNameFromId(5)); | ||
} | ||
|
||
private Uni<RowSet<Row>> populateDB() { | ||
return db2Pool.query("DELETE FROM Pig").execute() | ||
.flatMap(junk -> db2Pool.preparedQuery("INSERT INTO Pig (id, name) VALUES (5, 'Aloi')").execute()); | ||
} | ||
|
||
private Uni<String> selectNameFromId(Integer id) { | ||
return db2Pool.preparedQuery("SELECT name FROM Pig WHERE id = ?").execute(Tuple.of(id)).map(rowSet -> { | ||
if (rowSet.size() == 1) { | ||
return rowSet.iterator().next().getString(0); | ||
} else if (rowSet.size() > 1) { | ||
throw new AssertionError("More than one result returned: " + rowSet.size()); | ||
} else { | ||
return null; // Size 0 | ||
} | ||
}); | ||
} | ||
|
||
} |
7 changes: 7 additions & 0 deletions
7
...t/java/io/quarkus/it/hibernate/reactive/db2/HibernateReactiveDB2AlternativeInGraalIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package io.quarkus.it.hibernate.reactive.db2; | ||
|
||
import io.quarkus.test.junit.NativeImageTest; | ||
|
||
@NativeImageTest | ||
public class HibernateReactiveDB2AlternativeInGraalIT extends HibernateReactiveDB2AlternativeTest { | ||
} |
63 changes: 63 additions & 0 deletions
63
...c/test/java/io/quarkus/it/hibernate/reactive/db2/HibernateReactiveDB2AlternativeTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package io.quarkus.it.hibernate.reactive.db2; | ||
|
||
import static org.hamcrest.Matchers.is; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import io.quarkus.test.junit.QuarkusTest; | ||
import io.restassured.RestAssured; | ||
|
||
/** | ||
* Test various JPA operations running in Quarkus when the session is injected without Uni or CompletionStage. | ||
*/ | ||
@QuarkusTest | ||
public class HibernateReactiveDB2AlternativeTest { | ||
|
||
@Test | ||
public void reactiveFind() { | ||
RestAssured.when() | ||
.get("/alternative-tests/reactiveFind") | ||
.then() | ||
.body(is("{\"id\":5,\"name\":\"Aloi\"}")); | ||
} | ||
|
||
@Test | ||
public void reactiveFindMutiny() { | ||
RestAssured.when() | ||
.get("/alternative-tests/reactiveFindMutiny") | ||
.then() | ||
.body(is("{\"id\":5,\"name\":\"Aloi\"}")); | ||
} | ||
|
||
@Test | ||
public void reactivePersist() { | ||
RestAssured.when() | ||
.get("/alternative-tests/reactivePersist") | ||
.then() | ||
.body(is("Tulip")); | ||
} | ||
|
||
@Test | ||
public void reactiveRemoveTransientEntity() { | ||
RestAssured.when() | ||
.get("/alternative-tests/reactiveRemoveTransientEntity") | ||
.then() | ||
.body(is("OK")); | ||
} | ||
|
||
@Test | ||
public void reactiveRemoveManagedEntity() { | ||
RestAssured.when() | ||
.get("/alternative-tests/reactiveRemoveManagedEntity") | ||
.then() | ||
.body(is("OK")); | ||
} | ||
|
||
@Test | ||
public void reactiveUpdate() { | ||
RestAssured.when() | ||
.get("/alternative-tests/reactiveUpdate") | ||
.then() | ||
.body(is("Tina")); | ||
} | ||
} |
125 changes: 125 additions & 0 deletions
125
...io/quarkus/it/hibernate/reactive/mysql/HibernateReactiveMySQLAlternativeTestEndpoint.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
package io.quarkus.it.hibernate.reactive.mysql; | ||
|
||
import java.util.concurrent.CompletionStage; | ||
|
||
import javax.inject.Inject; | ||
import javax.ws.rs.GET; | ||
import javax.ws.rs.Path; | ||
import javax.ws.rs.Produces; | ||
import javax.ws.rs.core.MediaType; | ||
|
||
import org.hibernate.reactive.mutiny.Mutiny; | ||
import org.hibernate.reactive.stage.Stage; | ||
|
||
import io.smallrye.mutiny.Uni; | ||
import io.vertx.mutiny.mysqlclient.MySQLPool; | ||
import io.vertx.mutiny.sqlclient.Row; | ||
import io.vertx.mutiny.sqlclient.RowSet; | ||
import io.vertx.mutiny.sqlclient.Tuple; | ||
|
||
@Path("/alternative-tests") | ||
@Produces(MediaType.APPLICATION_JSON) | ||
public class HibernateReactiveMySQLAlternativeTestEndpoint { | ||
|
||
@Inject | ||
Stage.Session stageSession; | ||
|
||
@Inject | ||
Mutiny.Session mutinySession; | ||
|
||
// Injecting a Vert.x Pool is not required, it us only used to | ||
// independently validate the contents of the database for the test | ||
@Inject | ||
MySQLPool mysqlPool; | ||
|
||
@GET | ||
@Path("/reactiveFind") | ||
public CompletionStage<GuineaPig> reactiveFind() { | ||
final GuineaPig expectedPig = new GuineaPig(5, "Aloi"); | ||
return populateDB().convert().toCompletionStage() | ||
.thenCompose(junk -> stageSession.find(GuineaPig.class, expectedPig.getId())); | ||
} | ||
|
||
@GET | ||
@Path("/reactiveFindMutiny") | ||
public Uni<GuineaPig> reactiveFindMutiny() { | ||
final GuineaPig expectedPig = new GuineaPig(5, "Aloi"); | ||
return populateDB() | ||
.onItem().produceUni(junk -> mutinySession.find(GuineaPig.class, expectedPig.getId())); | ||
} | ||
|
||
@GET | ||
@Path("/reactivePersist") | ||
@Produces(MediaType.APPLICATION_JSON) | ||
public Uni<String> reactivePersist() { | ||
return mutinySession.persist(new GuineaPig(10, "Tulip")) | ||
.onItem().produceUni(s -> s.flush()) | ||
.onItem().produceUni(junk -> selectNameFromId(10)); | ||
} | ||
|
||
@GET | ||
@Path("/reactiveRemoveTransientEntity") | ||
public Uni<String> reactiveRemoveTransientEntity() { | ||
return populateDB() | ||
.onItem().produceUni(junk -> selectNameFromId(5)) | ||
.onItem().apply(name -> { | ||
if (name == null) { | ||
throw new AssertionError("Database was not populated properly"); | ||
} | ||
return name; | ||
}) | ||
.onItem().produceUni(junk -> mutinySession.merge(new GuineaPig(5, "Aloi"))) | ||
.onItem().produceUni(aloi -> mutinySession.remove(aloi)) | ||
.onItem().produceUni(junk -> mutinySession.flush()) | ||
.onItem().produceUni(junk -> selectNameFromId(5)) | ||
.onItem().ifNotNull().apply(result -> result) | ||
.onItem().ifNull().continueWith("OK"); | ||
} | ||
|
||
@GET | ||
@Path("/reactiveRemoveManagedEntity") | ||
public Uni<String> reactiveRemoveManagedEntity() { | ||
return populateDB() | ||
.onItem().produceUni(junk -> mutinySession.find(GuineaPig.class, 5)) | ||
.onItem().produceUni(aloi -> mutinySession.remove(aloi)) | ||
.onItem().produceUni(junk -> mutinySession.flush()) | ||
.onItem().produceUni(junk -> selectNameFromId(5)) | ||
.onItem().ifNotNull().apply(result -> result) | ||
.onItem().ifNull().continueWith("OK"); | ||
} | ||
|
||
@GET | ||
@Path("/reactiveUpdate") | ||
public Uni<String> reactiveUpdate() { | ||
final String NEW_NAME = "Tina"; | ||
return populateDB() | ||
.onItem().produceUni(junk -> mutinySession.find(GuineaPig.class, 5)) | ||
.onItem().apply(pig -> { | ||
if (NEW_NAME.equals(pig.getName())) { | ||
throw new AssertionError("Pig already had name " + NEW_NAME); | ||
} | ||
pig.setName(NEW_NAME); | ||
return pig; | ||
}) | ||
.onItem().produceUni(junk -> mutinySession.flush()) | ||
.onItem().produceUni(junk -> selectNameFromId(5)); | ||
} | ||
|
||
private Uni<RowSet<Row>> populateDB() { | ||
return mysqlPool.query("DELETE FROM Pig").execute() | ||
.flatMap(junk -> mysqlPool.preparedQuery("INSERT INTO Pig (id, name) VALUES (5, 'Aloi')").execute()); | ||
} | ||
|
||
private Uni<String> selectNameFromId(Integer id) { | ||
return mysqlPool.preparedQuery("SELECT name FROM Pig WHERE id = ?").execute(Tuple.of(id)).map(rowSet -> { | ||
if (rowSet.size() == 1) { | ||
return rowSet.iterator().next().getString(0); | ||
} else if (rowSet.size() > 1) { | ||
throw new AssertionError("More than one result returned: " + rowSet.size()); | ||
} else { | ||
return null; // Size 0 | ||
} | ||
}); | ||
} | ||
|
||
} |
7 changes: 7 additions & 0 deletions
7
...va/io/quarkus/it/hibernate/reactive/mysql/HibernateReactiveMySQLAlternativeInGraalIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package io.quarkus.it.hibernate.reactive.mysql; | ||
|
||
import io.quarkus.test.junit.NativeImageTest; | ||
|
||
@NativeImageTest | ||
public class HibernateReactiveMySQLAlternativeInGraalIT extends HibernateReactiveMySQLAlternativeTest { | ||
} |
Oops, something went wrong.