Skip to content

Commit

Permalink
Merge pull request #34542 from Sgitario/34432
Browse files Browse the repository at this point in the history
Fix user methods requiring a session in Panache REST Data with Reactive
  • Loading branch information
Sgitario authored Jul 7, 2023
2 parents 6067699 + 72a264c commit ac845a8
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import io.quarkus.gizmo.MethodCreator;
import io.quarkus.gizmo.MethodDescriptor;
import io.quarkus.gizmo.ResultHandle;
import io.quarkus.hibernate.reactive.panache.common.WithSession;
import io.quarkus.hibernate.reactive.panache.common.WithSessionOnDemand;
import io.quarkus.hibernate.reactive.panache.common.WithTransaction;
import io.quarkus.panache.common.Page;
import io.quarkus.panache.common.Sort;
Expand Down Expand Up @@ -62,6 +62,7 @@ String implement(ClassOutput classOutput, DataAccessImplementor dataAccessImplem
// when injecting the resource in user beans:
classCreator.addAnnotation(Alternative.class);
classCreator.addAnnotation(Priority.class).add("value", Integer.MAX_VALUE);
classCreator.addAnnotation(WithSessionOnDemand.class);

HibernateReactiveResourceMethodListenerImplementor resourceMethodListenerImplementor = new HibernateReactiveResourceMethodListenerImplementor(
classCreator, resourceMethodListeners);
Expand All @@ -82,7 +83,6 @@ String implement(ClassOutput classOutput, DataAccessImplementor dataAccessImplem

private void implementList(ClassCreator classCreator, DataAccessImplementor dataAccessImplementor) {
MethodCreator methodCreator = classCreator.getMethodCreator("list", Uni.class, Page.class, Sort.class);
methodCreator.addAnnotation(WithSession.class);
ResultHandle page = methodCreator.getMethodParam(0);
ResultHandle sort = methodCreator.getMethodParam(1);
ResultHandle columns = methodCreator.invokeVirtualMethod(ofMethod(Sort.class, "getColumns", List.class), sort);
Expand All @@ -98,7 +98,6 @@ private void implementList(ClassCreator classCreator, DataAccessImplementor data
private void implementListWithQuery(ClassCreator classCreator, DataAccessImplementor dataAccessImplementor) {
MethodCreator methodCreator = classCreator.getMethodCreator("list", Uni.class, Page.class, Sort.class,
String.class, Map.class);
methodCreator.addAnnotation(WithSession.class);
ResultHandle page = methodCreator.getMethodParam(0);
ResultHandle sort = methodCreator.getMethodParam(1);
ResultHandle query = methodCreator.getMethodParam(2);
Expand All @@ -120,7 +119,6 @@ private void implementListWithQuery(ClassCreator classCreator, DataAccessImpleme
*/
private void implementCount(ClassCreator classCreator, DataAccessImplementor dataAccessImplementor) {
MethodCreator methodCreator = classCreator.getMethodCreator("count", Uni.class);
methodCreator.addAnnotation(WithSession.class);
methodCreator.returnValue(dataAccessImplementor.count(methodCreator));
methodCreator.close();
}
Expand All @@ -132,15 +130,13 @@ private void implementCount(ClassCreator classCreator, DataAccessImplementor dat
private void implementListPageCount(ClassCreator classCreator, DataAccessImplementor dataAccessImplementor) {
MethodCreator methodCreator = classCreator.getMethodCreator(Constants.PAGE_COUNT_METHOD_PREFIX + "list", Uni.class,
Page.class);
methodCreator.addAnnotation(WithSession.class);
ResultHandle page = methodCreator.getMethodParam(0);
methodCreator.returnValue(dataAccessImplementor.pageCount(methodCreator, page));
methodCreator.close();
}

private void implementGet(ClassCreator classCreator, DataAccessImplementor dataAccessImplementor) {
MethodCreator methodCreator = classCreator.getMethodCreator("get", Uni.class, Object.class);
methodCreator.addAnnotation(WithSession.class);
ResultHandle id = methodCreator.getMethodParam(0);
methodCreator.returnValue(dataAccessImplementor.findById(methodCreator, id));
methodCreator.close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.is;

import org.junit.jupiter.api.Test;

Expand All @@ -14,4 +15,13 @@ void shouldGetListOfItems() {
.then().statusCode(200)
.and().body("id", contains(1, 2));
}

@Test
void shouldCollectionByName() {
given().accept("application/json")
.when().get("/call/resource/collectionByName/full collection")
.then().statusCode(200)
.and().body("id", is("full"))
.and().body("name", is("full collection"));
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,30 @@
package io.quarkus.hibernate.reactive.rest.data.panache.deployment.entity;

import java.util.Collections;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;

import io.quarkus.hibernate.reactive.rest.data.panache.PanacheEntityResource;
import io.quarkus.rest.data.panache.ResourceProperties;
import io.smallrye.mutiny.Uni;

@ResourceProperties(hal = true, paged = false, halCollectionName = "item-collections")
public interface CollectionsResource extends PanacheEntityResource<Collection, String> {
@GET
@Path("/name/{name}")
default Uni<Collection> findByName(@PathParam("name") String name) {
return Collection.find("name = :name", Collections.singletonMap("name", name)).singleResult();
}

@POST
@Path("/name/{name}")
default Uni<Collection> addByName(@PathParam("name") String name) {
Collection collection = new Collection();
collection.id = name;
collection.name = name;
return Collection.persist(collection).onItem().transform(res -> collection);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

Expand All @@ -18,10 +19,20 @@ public class InjectionResource {
@Inject
ItemsResource itemsResource;

@Inject
CollectionsResource collectionsResource;

@GET
@Path("/items")
@Produces(MediaType.APPLICATION_JSON)
public Uni<List<Item>> items() {
return itemsResource.list(new Page(5), Sort.by("id"));
}

@GET
@Path("/collectionByName/{name}")
@Produces(MediaType.APPLICATION_JSON)
public Uni<Collection> collectionByName(@PathParam("name") String name) {
return collectionsResource.findByName(name);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package io.quarkus.hibernate.reactive.rest.data.panache.deployment.entity;

import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.is;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.hibernate.reactive.rest.data.panache.deployment.AbstractGetMethodTest;
Expand All @@ -15,4 +19,13 @@ class PanacheEntityResourceGetMethodTest extends AbstractGetMethodTest {
EmptyListItem.class, EmptyListItemsResource.class)
.addAsResource("application.properties")
.addAsResource("import.sql"));

@Test
void shouldCopyAdditionalMethodsAsResources() {
given().accept("application/json")
.when().get("/collections/name/full collection")
.then().statusCode(200)
.and().body("id", is("full"))
.and().body("name", is("full collection"));
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package io.quarkus.hibernate.reactive.rest.data.panache.deployment.entity;

import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.is;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.hibernate.reactive.rest.data.panache.deployment.AbstractPostMethodTest;
Expand All @@ -14,4 +18,13 @@ class PanacheEntityResourcePostMethodTest extends AbstractPostMethodTest {
Item.class, ItemsResource.class)
.addAsResource("application.properties")
.addAsResource("import.sql"));

@Test
void shouldCopyAdditionalMethodsAsResources() {
given().accept("application/json")
.when().post("/collections/name/mycollection")
.then().statusCode(200)
.and().body("id", is("mycollection"))
.and().body("name", is("mycollection"));
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package io.quarkus.hibernate.reactive.rest.data.panache.deployment.repository;

import java.util.Collections;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;

import io.quarkus.hibernate.reactive.rest.data.panache.PanacheRepositoryResource;
import io.quarkus.rest.data.panache.MethodProperties;
import io.quarkus.rest.data.panache.ResourceProperties;
Expand All @@ -10,4 +17,19 @@ public interface CollectionsResource extends PanacheRepositoryResource<Collectio

@MethodProperties(rolesAllowed = "admin")
Uni<Boolean> delete(String name);

@GET
@Path("/name/{name}")
default Uni<Collection> findByName(@PathParam("name") String name) {
return Collection.find("name = :name", Collections.singletonMap("name", name)).singleResult();
}

@POST
@Path("/name/{name}")
default Uni<Collection> addByName(@PathParam("name") String name) {
Collection collection = new Collection();
collection.id = name;
collection.name = name;
return Collection.persist(collection).onItem().transform(res -> collection);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package io.quarkus.hibernate.reactive.rest.data.panache.deployment.repository;

import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.is;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.hibernate.reactive.rest.data.panache.deployment.AbstractGetMethodTest;
Expand All @@ -16,4 +20,13 @@ class PanacheRepositoryResourceGetMethodTest extends AbstractGetMethodTest {
EmptyListItemsResource.class)
.addAsResource("application.properties")
.addAsResource("import.sql"));

@Test
void shouldCopyAdditionalMethodsAsResources() {
given().accept("application/json")
.when().get("/collections/name/full collection")
.then().statusCode(200)
.and().body("id", is("full"))
.and().body("name", is("full collection"));
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package io.quarkus.hibernate.reactive.rest.data.panache.deployment.repository;

import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.is;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.hibernate.reactive.rest.data.panache.deployment.AbstractPostMethodTest;
Expand All @@ -15,4 +19,13 @@ class PanacheRepositoryResourcePostMethodTest extends AbstractPostMethodTest {
ItemsRepository.class)
.addAsResource("application.properties")
.addAsResource("import.sql"));

@Test
void shouldCopyAdditionalMethodsAsResources() {
given().accept("application/json")
.when().post("/collections/name/mycollection")
.then().statusCode(200)
.and().body("id", is("mycollection"))
.and().body("name", is("mycollection"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class JaxRsResourceImplementor {

private static final Logger LOGGER = Logger.getLogger(JaxRsResourceImplementor.class);
private static final String OPENAPI_TAG_ANNOTATION = "org.eclipse.microprofile.openapi.annotations.tags.Tag";
private static final String WITH_SESSION_ON_DEMAND_ANNOTATION = "io.quarkus.hibernate.reactive.panache.common.WithSessionOnDemand";

private final List<MethodImplementor> methodImplementors;

Expand Down Expand Up @@ -107,6 +108,9 @@ private void implementClassAnnotations(ClassCreator classCreator, ResourceMetada
classCreator.addAnnotation(classAnnotation);
}
}
if (capabilities.isPresent(Capability.HIBERNATE_REACTIVE)) {
classCreator.addAnnotation(WITH_SESSION_ON_DEMAND_ANNOTATION);
}
}

private FieldDescriptor implementResourceField(ClassCreator classCreator, ResourceMetadata resourceMetadata) {
Expand Down

0 comments on commit ac845a8

Please sign in to comment.