From 447402e22b7302d2daf805fbe1a07ded31041eef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Vav=C5=99=C3=ADk?= Date: Wed, 15 Jun 2022 18:57:50 +0200 Subject: [PATCH] Test Reactive Rest Client support of dynamic number of query parameters Reactive Rest Client newly supports ([Quarkus PR 24783](https://github.com/quarkusio/quarkus/pull/24783)) passing a query parameters as a map. This is very useful when user don't know query parameters in advance. Feature details can be found in a [TP here](https://github.com/quarkus-qe/quarkus-test-plans/pull/82). Test covers situation when query parameters are of primitive type, Java class or an array (supported by `MultivaluedMap`) and more than one formal parameter is annotated with `@RestQuery`. --- .../http/restclient/reactive/BookClient.java | 12 ++++++++++ .../reactive/PlainBookResource.java | 21 +++++++++++++++++ .../reactive/ReactiveClientBookResource.java | 17 ++++++++++++++ .../reactive/json/BookIdWrapper.java | 23 +++++++++++++++++++ .../reactive/json/BookRepository.java | 23 +++++++++++++++++++ .../reactive/ReactiveRestClientIT.java | 17 ++++++++++++++ 6 files changed, 113 insertions(+) create mode 100644 http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/json/BookIdWrapper.java create mode 100644 http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/json/BookRepository.java diff --git a/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/BookClient.java b/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/BookClient.java index b63615eed..f4245d910 100644 --- a/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/BookClient.java +++ b/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/BookClient.java @@ -1,16 +1,22 @@ package io.quarkus.ts.http.restclient.reactive; +import java.util.List; +import java.util.Map; + import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; import org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders; import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; +import org.jboss.resteasy.reactive.RestQuery; import io.quarkus.ts.http.restclient.reactive.json.Book; +import io.quarkus.ts.http.restclient.reactive.json.BookIdWrapper; import io.smallrye.mutiny.Multi; import io.smallrye.mutiny.Uni; @@ -74,4 +80,10 @@ interface CurrencyClient { @Path("/%E3%82%AF%E3%82%A4%E3%83%83%E3%82%AF%E6%A4%9C%E7%B4%A2/%25%20%23%20%5B%20%5D%20+%20=%20&%20@%20:%20!%20*%20(%20)%20'%20$%20,%20%3F/-%20_%20.%20~") Multi getByEncodedSearchTerm(@QueryParam("searchTerm") String searchTerm); + @GET + @Path("/rest-query") + @Produces(MediaType.APPLICATION_JSON) + Uni> getByRestQueryMap(@RestQuery Map primitiveParams, + @RestQuery Map classParams, @RestQuery MultivaluedMap multivaluedMap); + } diff --git a/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/PlainBookResource.java b/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/PlainBookResource.java index 116477609..4b3d37cbe 100644 --- a/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/PlainBookResource.java +++ b/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/PlainBookResource.java @@ -1,5 +1,7 @@ package io.quarkus.ts.http.restclient.reactive; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import javax.ws.rs.Consumes; @@ -9,7 +11,11 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; +import org.jboss.resteasy.reactive.RestQuery; + import io.quarkus.ts.http.restclient.reactive.json.Book; +import io.quarkus.ts.http.restclient.reactive.json.BookIdWrapper; +import io.quarkus.ts.http.restclient.reactive.json.BookRepository; import io.smallrye.mutiny.Multi; import io.smallrye.mutiny.Uni; @@ -27,6 +33,21 @@ public Uni getByQueryMap(@QueryParam("param") Map params) params.get("author"))); } + @GET + @Path("/rest-query") + @Produces(MediaType.APPLICATION_JSON) + public Uni> getRestQuery(@RestQuery Integer firstPlainId, @RestQuery Integer secondPlainId, + @RestQuery BookIdWrapper firstObjectId, @RestQuery BookIdWrapper secondObjectId, + @RestQuery List additionalIds) { + var books = new ArrayList(); + books.add(BookRepository.getById(firstPlainId)); + books.add(BookRepository.getById(secondPlainId)); + books.add(BookRepository.getById(firstObjectId.getId())); + books.add(BookRepository.getById(secondObjectId.getId())); + additionalIds.stream().map(BookRepository::getById).forEach(books::add); + return Uni.createFrom().item(books); + } + @GET @Path("/") @Produces(MediaType.APPLICATION_JSON) diff --git a/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/ReactiveClientBookResource.java b/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/ReactiveClientBookResource.java index b903fd094..ee7d83c7a 100644 --- a/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/ReactiveClientBookResource.java +++ b/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/ReactiveClientBookResource.java @@ -1,5 +1,8 @@ package io.quarkus.ts.http.restclient.reactive; +import java.util.List; +import java.util.Map; + import javax.inject.Inject; import javax.ws.rs.GET; import javax.ws.rs.Path; @@ -7,10 +10,12 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedHashMap; import org.eclipse.microprofile.rest.client.inject.RestClient; import io.quarkus.ts.http.restclient.reactive.json.Book; +import io.quarkus.ts.http.restclient.reactive.json.BookIdWrapper; import io.quarkus.ts.http.restclient.reactive.json.IdBeanParam; import io.quarkus.ts.http.restclient.reactive.json.JsonRestInterface; import io.smallrye.mutiny.Multi; @@ -77,4 +82,16 @@ public Multi getDecodedPath(@QueryParam("searchTerm") String searchTerm) public Multi getEncodedPath(@QueryParam("searchTerm") String searchTerm) { return bookInterface.getByEncodedSearchTerm(searchTerm); } + + @GET + @Path("/rest-query") + @Produces(MediaType.APPLICATION_JSON) + public Uni> getRestQuery() { + var primitiveParamsMap = Map.of("firstPlainId", 1, "secondPlainId", 2); + var classParamsMap = Map.of("firstObjectId", new BookIdWrapper(3), + "secondObjectId", new BookIdWrapper(4)); + var multivaluedMap = new MultivaluedHashMap(); + multivaluedMap.put("additionalIds", List.of(5, 6)); + return bookInterface.getByRestQueryMap(primitiveParamsMap, classParamsMap, multivaluedMap); + } } diff --git a/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/json/BookIdWrapper.java b/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/json/BookIdWrapper.java new file mode 100644 index 000000000..f74a05b72 --- /dev/null +++ b/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/json/BookIdWrapper.java @@ -0,0 +1,23 @@ +package io.quarkus.ts.http.restclient.reactive.json; + +public class BookIdWrapper { + + private final int id; + + public BookIdWrapper(int id) { + this.id = id; + } + + public BookIdWrapper(String id) { + this.id = Integer.parseInt(id); + } + + public int getId() { + return id; + } + + @Override + public String toString() { + return Integer.toString(id); + } +} diff --git a/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/json/BookRepository.java b/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/json/BookRepository.java new file mode 100644 index 000000000..0bc457daa --- /dev/null +++ b/http/rest-client-reactive/src/main/java/io/quarkus/ts/http/restclient/reactive/json/BookRepository.java @@ -0,0 +1,23 @@ +package io.quarkus.ts.http.restclient.reactive.json; + +import java.util.Map; + +public class BookRepository { + + private static final Map REPO = Map.of( + 1, new Book("Title 1", "Author 1"), + 2, new Book("Title 2", "Author 2"), + 3, new Book("Title 3", "Author 3"), + 4, new Book("Title 4", "Author 4"), + 5, new Book("Title 5", "Author 5"), + 6, new Book("Title 6", "Author 6")); + + public static Book getById(Integer id) { + return REPO.get(id); + } + + public static int count() { + return REPO.size(); + } + +} diff --git a/http/rest-client-reactive/src/test/java/io/quarkus/ts/http/restclient/reactive/ReactiveRestClientIT.java b/http/rest-client-reactive/src/test/java/io/quarkus/ts/http/restclient/reactive/ReactiveRestClientIT.java index 7289d4e0a..73c68215d 100644 --- a/http/rest-client-reactive/src/test/java/io/quarkus/ts/http/restclient/reactive/ReactiveRestClientIT.java +++ b/http/rest-client-reactive/src/test/java/io/quarkus/ts/http/restclient/reactive/ReactiveRestClientIT.java @@ -14,6 +14,8 @@ import io.quarkus.test.scenarios.QuarkusScenario; import io.quarkus.test.scenarios.annotations.DisabledOnQuarkusVersion; import io.quarkus.test.services.QuarkusApplication; +import io.quarkus.ts.http.restclient.reactive.json.Book; +import io.quarkus.ts.http.restclient.reactive.json.BookRepository; import io.restassured.response.Response; @QuarkusScenario @@ -56,6 +58,21 @@ public void mapInQueryParam() { assertEquals("Tsuramoto", response.jsonPath().getString("author")); } + @Tag("QUARKUS-2148") + @Test + public void restQueryParam() { + Response response = app.given().when().get("/client/book/rest-query"); + assertEquals(HttpStatus.SC_OK, response.statusCode()); + var books = response.jsonPath().getList(".", Book.class); + assertEquals(BookRepository.count(), books.size()); + for (int i = 0; i < books.size(); i++) { + var expectedBook = BookRepository.getById(i + 1); + var actualBook = books.get(i); + assertEquals(expectedBook.getTitle(), actualBook.getTitle()); + assertEquals(expectedBook.getAuthor(), actualBook.getAuthor()); + } + } + @Test public void resourceDirectly() { Response response = app.given()