From 3ecaaaec2827f2b06473d578ae8415faf228d029 Mon Sep 17 00:00:00 2001 From: Thiago dos Santos Hora Date: Tue, 3 Oct 2023 22:33:24 +0200 Subject: [PATCH] Bael 6917/api versioning micronaut (#14868) * BAEL-6917: Micronaut API Versioning * Fix test names --- microservices-modules/micronaut/pom.xml | 163 ++++++++++-------- .../custom/client/BirdCountClient.java | 42 +++++ .../custom/server/BirdCountController.java | 36 ++++ .../custom/server/CustomVersionResolver.java | 31 ++++ .../header/client/DogCountClient.java | 42 +++++ .../header/server/DogCountController.java | 36 ++++ .../param/client/CatCountClient.java | 23 +++ .../param/server/CatCountController.java | 37 ++++ .../url/client/SheepCountClient.java | 39 +++++ .../url/server/SheepCountControllerV1.java | 26 +++ .../url/server/SheepCountControllerV2.java | 27 +++ .../client/ConcreteGreetingClient.java | 15 +- .../controller/AsyncGreetController.java | 4 +- .../server/controller/GreetController.java | 2 +- .../service/EnglishGreetingService.java | 2 +- .../service/SpanishGreetingService.java | 2 +- .../vs/springboot/CompareApplication.java | 6 +- .../client/ArithmeticClientImpl.java | 30 ++-- .../controller/ArithmeticController.java | 2 +- .../springboot/service/ArithmeticService.java | 2 +- .../src/main/resources/application.yml | 22 ++- .../micronaut/src/main/resources/logback.xml | 6 + .../client/BirdCountClientUnitTest.java | 42 +++++ .../header/client/DogCountClientUnitTest.java | 40 +++++ .../param/client/CatCountClientUnitTest.java | 38 ++++ .../url/client/SheepCountClientUnitTest.java | 44 +++++ .../ConcreteGreetingClientUnitTest.java | 32 ++-- .../client/GreetingClientUnitTest.java | 31 ++-- .../springboot/ArithmeticClientUnitTest.java | 37 ++-- 29 files changed, 683 insertions(+), 176 deletions(-) create mode 100644 microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/custom/client/BirdCountClient.java create mode 100644 microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/custom/server/BirdCountController.java create mode 100644 microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/custom/server/CustomVersionResolver.java create mode 100644 microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/header/client/DogCountClient.java create mode 100644 microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/header/server/DogCountController.java create mode 100644 microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/param/client/CatCountClient.java create mode 100644 microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/param/server/CatCountController.java create mode 100644 microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/url/client/SheepCountClient.java create mode 100644 microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/url/server/SheepCountControllerV1.java create mode 100644 microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/url/server/SheepCountControllerV2.java create mode 100644 microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/apiversioning/custom/client/BirdCountClientUnitTest.java create mode 100644 microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/apiversioning/header/client/DogCountClientUnitTest.java create mode 100644 microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/apiversioning/param/client/CatCountClientUnitTest.java create mode 100644 microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/apiversioning/url/client/SheepCountClientUnitTest.java diff --git a/microservices-modules/micronaut/pom.xml b/microservices-modules/micronaut/pom.xml index 716b5497d8..d3f4326a85 100644 --- a/microservices-modules/micronaut/pom.xml +++ b/microservices-modules/micronaut/pom.xml @@ -7,6 +7,7 @@ micronaut 0.1 micronaut + ${packaging} com.baeldung @@ -18,7 +19,7 @@ io.micronaut - bom + micronaut-bom ${micronaut.version} pom import @@ -29,120 +30,136 @@ io.micronaut - http-client + micronaut-runtime + compile + + + io.micronaut + micronaut-jackson-databind + + + + + io.micronaut + micronaut-http-client compile io.micronaut - http-server-netty + micronaut-http-server-netty + compile + + + jakarta.annotation + jakarta.annotation-api compile io.micronaut - inject + micronaut-inject compile io.micronaut - runtime + micronaut-validation compile - - javax.annotation - javax.annotation-api - ${annotation.api.version} - compile - - - io.micronaut - inject-java - provided - ch.qos.logback logback-classic - ${logback.version} runtime - io.projectreactor - reactor-core - ${reactor.version} + io.micronaut.rxjava3 + micronaut-rxjava3 + compile + + + io.micronaut.rxjava3 + micronaut-rxjava3-http-client + compile + + + io.micronaut.serde + micronaut-serde-jackson + compile + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.assertj + assertj-core + test + + + io.micronaut.test + micronaut-test-junit5 + test + + io.micronaut.build + micronaut-maven-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + + ${jdk.version} + ${jdk.version} + + -parameters + + + + + + + + io.micronaut + micronaut-inject-java + ${micronaut.version} + + + + io.micronaut + micronaut-http-validation + ${micronaut.version} + + + + + org.apache.maven.plugins maven-shade-plugin ${shade.plugin.version} - package - - shade - - - - - ${exec.mainClass} - - - - + default-shade + none - - org.codehaus.mojo - exec-maven-plugin - - java - - -classpath - - ${exec.mainClass} - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - ${compiler.plugin.version} - - ${jdk.version} - ${jdk.version} - - -parameters - - - - io.micronaut - inject-java - ${micronaut.version} - - - - - - com.baeldung.micronaut.vs.springboot.CompareApplication - 1.0.0.RC2 + 3.10.1 17 - 1.3.2 - 3.1.6.RELEASE + 17 + jar 3.7.0 - 3.1.0 + netty + 3.2.0 \ No newline at end of file diff --git a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/custom/client/BirdCountClient.java b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/custom/client/BirdCountClient.java new file mode 100644 index 0000000000..d9e09b1c6e --- /dev/null +++ b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/custom/client/BirdCountClient.java @@ -0,0 +1,42 @@ +package com.baeldung.micronaut.apiversioning.custom.client; + +import io.micronaut.core.annotation.Nullable; +import io.micronaut.core.async.annotation.SingleResult; +import io.micronaut.http.HttpHeaders; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.annotation.Header; +import io.micronaut.http.annotation.QueryValue; +import io.micronaut.http.client.annotation.Client; +import io.reactivex.rxjava3.core.Flowable; + +@Client("/") +@Header(name = HttpHeaders.ACCEPT, value = "application/json") +public interface BirdCountClient { + + @Get( + uri = "/bird/count", + consumes = {"application/json"}, + produces = {"application/json"} + ) + @Header(name = "api-key", value = "11") + @SingleResult + Flowable countV1(@QueryValue("max") @Nullable Integer max); + + @Get( + uri = "/bird/count", + consumes = {"application/json"}, + produces = {"application/json"} + ) + @Header(name = "api-key", value = "10") + @SingleResult + Flowable countV2(@QueryValue("max") @Nullable Integer max); + + @Get( + uri = "/bird/count", + consumes = {"application/json"}, + produces = {"application/json"} + ) + @Header(name = "api-key", value = "") + @SingleResult + Flowable countDefault(@QueryValue("max") @Nullable Integer max); +} diff --git a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/custom/server/BirdCountController.java b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/custom/server/BirdCountController.java new file mode 100644 index 0000000000..c836761266 --- /dev/null +++ b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/custom/server/BirdCountController.java @@ -0,0 +1,36 @@ +package com.baeldung.micronaut.apiversioning.custom.server; + +import io.micronaut.core.annotation.NonNull; +import io.micronaut.core.annotation.Nullable; +import io.micronaut.core.version.annotation.Version; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.annotation.QueryValue; +import io.reactivex.rxjava3.core.Flowable; + +import java.util.stream.Stream; + +@Controller("/bird") +public class BirdCountController { + + @Get(value = "/count", produces = {"application/json"}) + @Version("1") + public Flowable countV1(@QueryValue("max") @Nullable Integer max) { + return Flowable.fromStream( + Stream.iterate(0, i -> i + 1) + .map(index -> "Bird " + index) + .limit(max == null ? 10 : max) + ); + } + + @Get(value = "/count", produces = {"application/json"}) + @Version("2") + public Flowable countV2(@QueryValue("max") @NonNull Integer max) { + return Flowable.fromStream( + Stream.iterate(0, i -> i + 1) + .map(index -> "Bird " + index) + .limit(max) + ); + } + +} diff --git a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/custom/server/CustomVersionResolver.java b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/custom/server/CustomVersionResolver.java new file mode 100644 index 0000000000..3075a135c8 --- /dev/null +++ b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/custom/server/CustomVersionResolver.java @@ -0,0 +1,31 @@ +package com.baeldung.micronaut.apiversioning.custom.server; + +import io.micronaut.context.annotation.Requires; +import io.micronaut.context.annotation.Value; +import io.micronaut.http.HttpRequest; +import io.micronaut.web.router.version.resolution.RequestVersionResolver; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; + +import java.util.Optional; + +@Singleton +@Requires(property = "my.router.versioning.enabled", value = "true") +public class CustomVersionResolver implements RequestVersionResolver { + + @Inject + @Value("${micronaut.router.versioning.default-version}") + private String defaultVersion; + + @Override + public Optional resolve(HttpRequest request) { + var apiKey = Optional.ofNullable(request.getHeaders().get("api-key")); + + if (apiKey.isPresent() && !apiKey.get().isEmpty()) { + return Optional.of(Integer.parseInt(apiKey.get()) % 2 == 0 ? "2" : "1"); + } + + return Optional.of(defaultVersion); + } + +} diff --git a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/header/client/DogCountClient.java b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/header/client/DogCountClient.java new file mode 100644 index 0000000000..487bff4d57 --- /dev/null +++ b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/header/client/DogCountClient.java @@ -0,0 +1,42 @@ +package com.baeldung.micronaut.apiversioning.header.client; + +import io.micronaut.core.annotation.Nullable; +import io.micronaut.core.async.annotation.SingleResult; +import io.micronaut.core.version.annotation.Version; +import io.micronaut.http.HttpHeaders; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.annotation.Header; +import io.micronaut.http.annotation.QueryValue; +import io.micronaut.http.client.annotation.Client; +import io.reactivex.rxjava3.core.Flowable; + +@Client("/") +@Header(name = HttpHeaders.ACCEPT, value = "application/json") +public interface DogCountClient { + + @Get( + uri = "/dog/count", + consumes = {"application/json"}, + produces = {"application/json"} + ) + @Version("1") + @SingleResult + Flowable countV1(@QueryValue("max") @Nullable Integer max); + + @Get( + uri = "/dog/count", + consumes = {"application/json"}, + produces = {"application/json"} + ) + @Version("2") + @SingleResult + Flowable countV2(@QueryValue("max") @Nullable Integer max); + + @Get( + uri = "/dog/count", + consumes = {"application/json"}, + produces = {"application/json"} + ) + @SingleResult + Flowable countDefault(@QueryValue("max") @Nullable Integer max); +} diff --git a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/header/server/DogCountController.java b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/header/server/DogCountController.java new file mode 100644 index 0000000000..de0f6788cf --- /dev/null +++ b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/header/server/DogCountController.java @@ -0,0 +1,36 @@ +package com.baeldung.micronaut.apiversioning.header.server; + +import io.micronaut.core.annotation.NonNull; +import io.micronaut.core.annotation.Nullable; +import io.micronaut.core.version.annotation.Version; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.annotation.QueryValue; +import io.reactivex.rxjava3.core.Flowable; + +import java.util.stream.Stream; + +@Controller("/dog") +public class DogCountController { + + @Get(value = "/count", produces = {"application/json"}) + @Version("1") + public Flowable countV1(@QueryValue("max") @Nullable Integer max) { + return Flowable.fromStream( + Stream.iterate(0, i -> i + 1) + .map(index -> "Dog " + index) + .limit(max == null ? 10 : max) + ); + } + + @Get(value = "/count", produces = {"application/json"}) + @Version("2") + public Flowable countV2(@QueryValue("max") @NonNull Integer max) { + return Flowable.fromStream( + Stream.iterate(0, i -> i + 1) + .map(index -> "Dog " + index) + .limit(max) + ); + } + +} diff --git a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/param/client/CatCountClient.java b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/param/client/CatCountClient.java new file mode 100644 index 0000000000..2332ade98e --- /dev/null +++ b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/param/client/CatCountClient.java @@ -0,0 +1,23 @@ +package com.baeldung.micronaut.apiversioning.param.client; + +import io.micronaut.core.annotation.Nullable; +import io.micronaut.core.async.annotation.SingleResult; +import io.micronaut.http.HttpHeaders; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.annotation.Header; +import io.micronaut.http.annotation.QueryValue; +import io.micronaut.http.client.annotation.Client; +import io.reactivex.rxjava3.core.Flowable; + +@Client("/") +@Header(name = HttpHeaders.ACCEPT, value = "application/json") +public interface CatCountClient { + + @Get( + uri = "/cat/count", + consumes = {"application/json"}, + produces = {"application/json"} + ) + @SingleResult + Flowable count(@QueryValue("max") @Nullable Integer max, @QueryValue(value = "v", defaultValue = "1") @Nullable Integer version); +} diff --git a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/param/server/CatCountController.java b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/param/server/CatCountController.java new file mode 100644 index 0000000000..43a34a2272 --- /dev/null +++ b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/param/server/CatCountController.java @@ -0,0 +1,37 @@ +package com.baeldung.micronaut.apiversioning.param.server; + +import io.micronaut.core.annotation.NonNull; +import io.micronaut.core.annotation.Nullable; +import io.micronaut.core.version.annotation.Version; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.annotation.QueryValue; +import io.reactivex.rxjava3.core.Flowable; + +import java.util.stream.Stream; + +@Controller("/cat") +public class CatCountController { + + @Get(value = "/count", produces = {"application/json"}) + @Version("1") + public Flowable countV1(@QueryValue("max") @Nullable Integer max) { + return Flowable.fromStream( + Stream.iterate(0, i -> i + 1) + .map(index -> "Cat " + index) + .limit(max == null ? 10 : max) + ); + } + + + @Get(value = "/count", produces = {"application/json"}) + @Version("2") + public Flowable countV2(@QueryValue("max") @NonNull Integer max) { + return Flowable.fromStream( + Stream.iterate(0, i -> i + 1) + .map(index -> "Cat " + index) + .limit(max) + ); + } + +} diff --git a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/url/client/SheepCountClient.java b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/url/client/SheepCountClient.java new file mode 100644 index 0000000000..cdb344b4e5 --- /dev/null +++ b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/url/client/SheepCountClient.java @@ -0,0 +1,39 @@ +package com.baeldung.micronaut.apiversioning.url.client; + +import io.micronaut.core.annotation.Nullable; +import io.micronaut.core.async.annotation.SingleResult; +import io.micronaut.http.HttpHeaders; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.annotation.Header; +import io.micronaut.http.annotation.QueryValue; +import io.micronaut.http.client.annotation.Client; +import io.reactivex.rxjava3.core.Flowable; + +@Client("/") +@Header(name = HttpHeaders.ACCEPT, value = "application/json") +public interface SheepCountClient { + + @Get( + uri = "/v1/sheep/count", + consumes = {"application/json"}, + produces = {"application/json"} + ) + @SingleResult + Flowable countV1(@QueryValue("max") @Nullable Integer max); + + @Get( + uri = "/v2/sheep/count", + consumes = {"application/json"}, + produces = {"application/json"} + ) + @SingleResult + Flowable countV2(@QueryValue("max") @Nullable Integer max); + + @Get( + uri = "/sheep/count", + consumes = {"application/json"}, + produces = {"application/json"} + ) + @SingleResult + Flowable countDefault(@QueryValue("max") @Nullable Integer max); +} diff --git a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/url/server/SheepCountControllerV1.java b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/url/server/SheepCountControllerV1.java new file mode 100644 index 0000000000..5ee6a2a57d --- /dev/null +++ b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/url/server/SheepCountControllerV1.java @@ -0,0 +1,26 @@ +package com.baeldung.micronaut.apiversioning.url.server; + +import io.micronaut.core.annotation.Nullable; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import io.reactivex.rxjava3.core.Flowable; + +import java.util.stream.Stream; + +@Controller("/v1/sheep/count") +public class SheepCountControllerV1 { + + @Get( + uri = "{?max}", + consumes = {"application/json"}, + produces = {"application/json"} + ) + Flowable countV1(@Nullable Integer max) { + return Flowable.fromStream( + Stream.iterate(0, i -> i + 1) + .map(index -> "Sheep " + index) + .limit(max == null ? 10 : max) + ); + } + +} diff --git a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/url/server/SheepCountControllerV2.java b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/url/server/SheepCountControllerV2.java new file mode 100644 index 0000000000..d95f4a3cca --- /dev/null +++ b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/apiversioning/url/server/SheepCountControllerV2.java @@ -0,0 +1,27 @@ +package com.baeldung.micronaut.apiversioning.url.server; + +import io.micronaut.core.annotation.NonNull; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.annotation.QueryValue; +import io.reactivex.rxjava3.core.Flowable; + +import java.util.stream.Stream; + +@Controller +public class SheepCountControllerV2 { + + @Get( + uris = {"/v2/sheep/count", "/sheep/count"}, + consumes = {"application/json"}, + produces = {"application/json"} + ) + Flowable countV2(@QueryValue("max") @NonNull Integer max) { + return Flowable.fromStream( + Stream.iterate(0, i -> i + 1) + .map(index -> "Sheep " + index) + .limit(max) + ); + } + +} diff --git a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/helloworld/client/ConcreteGreetingClient.java b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/helloworld/client/ConcreteGreetingClient.java index 96bc51f235..943b2f703e 100644 --- a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/helloworld/client/ConcreteGreetingClient.java +++ b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/helloworld/client/ConcreteGreetingClient.java @@ -1,28 +1,27 @@ package com.baeldung.micronaut.helloworld.client; import io.micronaut.http.HttpRequest; +import io.micronaut.http.client.HttpClient; import io.micronaut.http.client.annotation.Client; -import io.micronaut.http.client.RxHttpClient; -import io.reactivex.Single; - -import javax.inject.Singleton; +import io.reactivex.rxjava3.core.Single; +import jakarta.inject.Singleton; @Singleton public class ConcreteGreetingClient { - private RxHttpClient httpClient; + private HttpClient httpClient; - public ConcreteGreetingClient(@Client("/") RxHttpClient httpClient) { + public ConcreteGreetingClient(@Client("/") HttpClient httpClient) { this.httpClient = httpClient; } public String greet(String name) { HttpRequest req = HttpRequest.GET("/greet/" + name); - return httpClient.retrieve(req).blockingFirst(); + return Single.fromPublisher(httpClient.retrieve(req)).blockingGet(); } public Single greetAsync(String name) { HttpRequest req = HttpRequest.GET("/async/greet/" + name); - return httpClient.retrieve(req).first("An error as occurred"); + return Single.fromPublisher(httpClient.retrieve(req)); } } diff --git a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/controller/AsyncGreetController.java b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/controller/AsyncGreetController.java index 4d86b9dfed..862a822573 100644 --- a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/controller/AsyncGreetController.java +++ b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/controller/AsyncGreetController.java @@ -3,9 +3,9 @@ package com.baeldung.micronaut.helloworld.server.controller; import com.baeldung.micronaut.helloworld.server.service.GreetingService; import io.micronaut.http.annotation.Controller; import io.micronaut.http.annotation.Get; -import io.reactivex.Single; -import javax.inject.Inject; +import io.reactivex.rxjava3.core.Single; +import jakarta.inject.Inject; @Controller("/async/greet") public class AsyncGreetController { diff --git a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/controller/GreetController.java b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/controller/GreetController.java index c890c037e4..ba3b6197d8 100644 --- a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/controller/GreetController.java +++ b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/controller/GreetController.java @@ -7,7 +7,7 @@ import io.micronaut.http.annotation.Controller; import io.micronaut.http.annotation.Get; import io.micronaut.http.annotation.Post; -import javax.inject.Inject; +import jakarta.inject.Inject; @Controller("/greet") public class GreetController { diff --git a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/service/EnglishGreetingService.java b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/service/EnglishGreetingService.java index 8ea5172cf6..865ee0b639 100644 --- a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/service/EnglishGreetingService.java +++ b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/service/EnglishGreetingService.java @@ -2,7 +2,7 @@ package com.baeldung.micronaut.helloworld.server.service; import io.micronaut.context.annotation.Primary; -import javax.inject.Singleton; +import jakarta.inject.Singleton; @Primary @Singleton diff --git a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/service/SpanishGreetingService.java b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/service/SpanishGreetingService.java index 1ec53d8b2d..e426c2911e 100644 --- a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/service/SpanishGreetingService.java +++ b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/service/SpanishGreetingService.java @@ -1,6 +1,6 @@ package com.baeldung.micronaut.helloworld.server.service; -import javax.inject.Singleton; +import jakarta.inject.Singleton; @Singleton public class SpanishGreetingService implements GreetingService { diff --git a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/vs/springboot/CompareApplication.java b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/vs/springboot/CompareApplication.java index 4654526b28..0fea9f970b 100644 --- a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/vs/springboot/CompareApplication.java +++ b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/vs/springboot/CompareApplication.java @@ -1,9 +1,11 @@ package com.baeldung.micronaut.vs.springboot; + import io.micronaut.runtime.Micronaut; public class CompareApplication { + public static void main(String[] args) { - Micronaut.run(CompareApplication.class); + Micronaut.run(CompareApplication.class, args); } -} +} \ No newline at end of file diff --git a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/vs/springboot/client/ArithmeticClientImpl.java b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/vs/springboot/client/ArithmeticClientImpl.java index 6b7ae900be..95e3157bfe 100644 --- a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/vs/springboot/client/ArithmeticClientImpl.java +++ b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/vs/springboot/client/ArithmeticClientImpl.java @@ -1,46 +1,46 @@ package com.baeldung.micronaut.vs.springboot.client; -import javax.inject.Singleton; - import io.micronaut.http.HttpRequest; -import io.micronaut.http.client.RxHttpClient; +import io.micronaut.http.client.HttpClient; import io.micronaut.http.client.annotation.Client; +import io.reactivex.rxjava3.core.Single; +import jakarta.inject.Singleton; @Singleton public class ArithmeticClientImpl { - private RxHttpClient httpClient; + private HttpClient httpClient; - public ArithmeticClientImpl(@Client("/") RxHttpClient httpClient) { + public ArithmeticClientImpl(@Client("/") HttpClient httpClient) { this.httpClient = httpClient; } public String sum(float number1, float number2) { HttpRequest req = HttpRequest.GET("/math/sum/" + number1 + "/" + number2); - return httpClient.retrieve(req) - .blockingFirst(); + return Single.fromPublisher(httpClient.retrieve(req)) + .blockingGet(); } public String subtract(float number1, float number2) { HttpRequest req = HttpRequest.GET("/math/subtract/" + number1 + "/" + number2); - return httpClient.retrieve(req) - .blockingFirst(); + return Single.fromPublisher(httpClient.retrieve(req)) + .blockingGet(); } public String multiply(float number1, float number2) { HttpRequest req = HttpRequest.GET("/math/multiply/" + number1 + "/" + number2); - return httpClient.retrieve(req) - .blockingFirst(); + return Single.fromPublisher(httpClient.retrieve(req)) + .blockingGet(); } public String divide(float number1, float number2) { HttpRequest req = HttpRequest.GET("/math/divide/" + number1 + "/" + number2); - return httpClient.retrieve(req) - .blockingFirst(); + return Single.fromPublisher(httpClient.retrieve(req)) + .blockingGet(); } public String memory() { HttpRequest req = HttpRequest.GET("/math/memory"); - return httpClient.retrieve(req) - .blockingFirst(); + return Single.fromPublisher(httpClient.retrieve(req)) + .blockingGet(); } } diff --git a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/vs/springboot/controller/ArithmeticController.java b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/vs/springboot/controller/ArithmeticController.java index 5bc0e865e1..b774556ece 100644 --- a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/vs/springboot/controller/ArithmeticController.java +++ b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/vs/springboot/controller/ArithmeticController.java @@ -3,7 +3,7 @@ package com.baeldung.micronaut.vs.springboot.controller; import java.lang.management.ManagementFactory; import java.lang.management.MemoryMXBean; -import javax.inject.Inject; +import jakarta.inject.Inject; import com.baeldung.micronaut.vs.springboot.service.ArithmeticService; diff --git a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/vs/springboot/service/ArithmeticService.java b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/vs/springboot/service/ArithmeticService.java index e0e4680495..599a6ee4cf 100644 --- a/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/vs/springboot/service/ArithmeticService.java +++ b/microservices-modules/micronaut/src/main/java/com/baeldung/micronaut/vs/springboot/service/ArithmeticService.java @@ -1,6 +1,6 @@ package com.baeldung.micronaut.vs.springboot.service; -import javax.inject.Singleton; +import jakarta.inject.Singleton; @Singleton public class ArithmeticService { diff --git a/microservices-modules/micronaut/src/main/resources/application.yml b/microservices-modules/micronaut/src/main/resources/application.yml index 32daacd4aa..b265d245aa 100644 --- a/microservices-modules/micronaut/src/main/resources/application.yml +++ b/microservices-modules/micronaut/src/main/resources/application.yml @@ -1,5 +1,19 @@ +context-path: / + micronaut: - application: - name: hello-world-server - server: - port: ${random.port} \ No newline at end of file + router: + versioning: + enabled: true + default-version: 2 + parameter: + enabled: true + names: 'v,api-version' + header: + enabled: true + names: + - 'X-API-VERSION' + + application: + name: hello-world-server + server: + port: ${random.port} diff --git a/microservices-modules/micronaut/src/main/resources/logback.xml b/microservices-modules/micronaut/src/main/resources/logback.xml index afaebf8e17..4db42a7916 100644 --- a/microservices-modules/micronaut/src/main/resources/logback.xml +++ b/microservices-modules/micronaut/src/main/resources/logback.xml @@ -8,6 +8,12 @@ + + + diff --git a/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/apiversioning/custom/client/BirdCountClientUnitTest.java b/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/apiversioning/custom/client/BirdCountClientUnitTest.java new file mode 100644 index 0000000000..a3a547f9e2 --- /dev/null +++ b/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/apiversioning/custom/client/BirdCountClientUnitTest.java @@ -0,0 +1,42 @@ +package com.baeldung.micronaut.apiversioning.custom.client; + +import io.micronaut.context.annotation.Property; +import io.micronaut.http.client.exceptions.HttpClientResponseException; +import io.micronaut.runtime.EmbeddedApplication; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import jakarta.inject.Inject; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +@MicronautTest +@Property(name = "my.router.versioning.enabled", value = "true") +class BirdCountClientUnitTest { + + @Inject + private EmbeddedApplication application; + + @Inject + private BirdCountClient client; + + @Test + void givenTheCountApi_whenUsingV1ViaCustomStrategy_shouldRouteToProperHandler() { + Assertions.assertEquals(10, client.countV1(null).blockingSingle().split(",").length); + Assertions.assertEquals(4, client.countV1(4).blockingSingle().split(",").length); + } + + @Test + void givenTheCountApi_whenUsingV2ViaCustomStrategy_shouldRouteToProperHandler() { + Assertions.assertThrows(HttpClientResponseException.class, + () -> client.countV2(null).count().blockingGet()); + + Assertions.assertEquals(6, client.countV2(6).blockingSingle().split(",").length); + } + + @Test + void givenTheCountApi_whenUsingDefaultVersionViaCustomStrategy_shouldRouteToProperHandler() { + Assertions.assertThrows(HttpClientResponseException.class, + () -> client.countDefault(null).count().blockingGet()); + + Assertions.assertEquals(6, client.countDefault(6).blockingSingle().split(",").length); + } +} \ No newline at end of file diff --git a/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/apiversioning/header/client/DogCountClientUnitTest.java b/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/apiversioning/header/client/DogCountClientUnitTest.java new file mode 100644 index 0000000000..4a47c76943 --- /dev/null +++ b/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/apiversioning/header/client/DogCountClientUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.micronaut.apiversioning.header.client; + +import io.micronaut.http.client.exceptions.HttpClientResponseException; +import io.micronaut.runtime.EmbeddedApplication; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import jakarta.inject.Inject; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +@MicronautTest +class DogCountClientUnitTest { + + @Inject + private EmbeddedApplication application; + + @Inject + private DogCountClient dogCountClient; + + @Test + void givenTheCountApi_whenUsingV1ViaHeaderStrategy_shouldRouteToProperHandler() { + Assertions.assertEquals(10, dogCountClient.countV1(null).blockingSingle().split(",").length); + Assertions.assertEquals(4, dogCountClient.countV1(4).blockingSingle().split(",").length); + } + + @Test + void givenTheCountApi_whenUsingV2ViaHeaderStrategy_shouldRouteToProperHandler() { + Assertions.assertThrows(HttpClientResponseException.class, + () -> dogCountClient.countV2(null).count().blockingGet()); + + Assertions.assertEquals(6, dogCountClient.countV2(6).blockingSingle().split(",").length); + } + + @Test + void givenTheCountApi_whenUsingDefaultVersionViaHeaderStrategy_shouldRouteToProperHandler() { + Assertions.assertThrows(HttpClientResponseException.class, + () -> dogCountClient.countDefault(null).count().blockingGet()); + + Assertions.assertEquals(6, dogCountClient.countDefault(6).blockingSingle().split(",").length); + } +} \ No newline at end of file diff --git a/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/apiversioning/param/client/CatCountClientUnitTest.java b/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/apiversioning/param/client/CatCountClientUnitTest.java new file mode 100644 index 0000000000..266f72eed8 --- /dev/null +++ b/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/apiversioning/param/client/CatCountClientUnitTest.java @@ -0,0 +1,38 @@ +package com.baeldung.micronaut.apiversioning.param.client; + +import io.micronaut.http.client.exceptions.HttpClientResponseException; +import io.micronaut.runtime.EmbeddedApplication; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import jakarta.inject.Inject; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +@MicronautTest +class CatCountClientUnitTest { + + @Inject + private EmbeddedApplication application; + + @Inject + private CatCountClient client; + + @Test + void givenTheCountApi_whenUsingV1ViaParameterStrategy_shouldRouteToProperHandler() { + Assertions.assertEquals(10, client.count(null, 1).blockingSingle().split(",").length); + Assertions.assertEquals(5, client.count(5, 1).blockingSingle().split(",").length); + } + + @Test + void givenTheCountApi_whenUsingV2ViaParameterStrategy_shouldRouteToProperHandler() { + Assertions.assertThrows(HttpClientResponseException.class, + () -> client.count(null, 2).count().blockingGet()); + + Assertions.assertEquals(6, client.count(6, 2).blockingSingle().split(",").length); + } + + @Test + void givenTheCountApi_whenUsingDefaultVersionViaParameterStrategy_shouldRouteToProperHandler() { + Assertions.assertEquals(10, client.count(null, null).blockingSingle().split(",").length); + Assertions.assertEquals(6, client.count(6, null).blockingSingle().split(",").length); + } +} \ No newline at end of file diff --git a/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/apiversioning/url/client/SheepCountClientUnitTest.java b/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/apiversioning/url/client/SheepCountClientUnitTest.java new file mode 100644 index 0000000000..e082793fe1 --- /dev/null +++ b/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/apiversioning/url/client/SheepCountClientUnitTest.java @@ -0,0 +1,44 @@ +package com.baeldung.micronaut.apiversioning.url.client; + +import io.micronaut.http.client.exceptions.HttpClientResponseException; +import io.micronaut.runtime.EmbeddedApplication; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import jakarta.inject.Inject; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.stream.Collectors; + +@MicronautTest +class SheepCountClientUnitTest { + + @Inject + private EmbeddedApplication application; + @Inject + private SheepCountClient client; + + @Test + void givenTheCountApi_whenUsingV1ViaUrlStrategy_shouldRouteToProperHandler() { + Assertions.assertEquals(10, client.countV1(null).blockingSingle().split(",").length); + Assertions.assertEquals(4, client.countV1(4).blockingSingle().split(",").length); + } + + @Test + void givenTheCountApi_whenUsingV2ViaUrlStrategy_shouldRouteToProperHandler() { + Assertions.assertThrows(HttpClientResponseException.class, + () -> client.countV2(null).count().blockingGet()); + + final var actual = client.countV2(4).blockingSingle().split(",").length; + Assertions.assertEquals(4, actual); + } + + @Test + void givenTheCountApi_whenUsingDefaultVersionViaUrlStrategy_shouldRouteToProperHandler() { + Assertions.assertThrows(HttpClientResponseException.class, + () -> client.countDefault(null).count().blockingGet()); + + final var actual = client.countDefault(4).blockingSingle().split(",").length; + Assertions.assertEquals(4, actual); + } +} \ No newline at end of file diff --git a/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/helloworld/client/ConcreteGreetingClientUnitTest.java b/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/helloworld/client/ConcreteGreetingClientUnitTest.java index 336374d5a6..88a9782074 100644 --- a/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/helloworld/client/ConcreteGreetingClientUnitTest.java +++ b/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/helloworld/client/ConcreteGreetingClientUnitTest.java @@ -1,31 +1,19 @@ package com.baeldung.micronaut.helloworld.client; -import io.micronaut.context.ApplicationContext; -import io.micronaut.runtime.server.EmbeddedServer; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import io.micronaut.runtime.EmbeddedApplication; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; -import static junit.framework.TestCase.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; -public class ConcreteGreetingClientUnitTest -{ - private EmbeddedServer server; +@MicronautTest +public class ConcreteGreetingClientUnitTest { + @Inject + private EmbeddedApplication application; + @Inject private ConcreteGreetingClient client; - @Before - public void setup() - { - server = ApplicationContext.run(EmbeddedServer.class); - client = server.getApplicationContext().getBean(ConcreteGreetingClient.class); - } - - @After - public void cleanup() - { - server.stop(); - } - @Test public void testGreeting() { assertEquals(client.greet("Mike"), "Hello Mike"); diff --git a/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/helloworld/client/GreetingClientUnitTest.java b/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/helloworld/client/GreetingClientUnitTest.java index c47fb3a31d..5b269531e7 100644 --- a/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/helloworld/client/GreetingClientUnitTest.java +++ b/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/helloworld/client/GreetingClientUnitTest.java @@ -1,30 +1,21 @@ package com.baeldung.micronaut.helloworld.client; -import io.micronaut.context.ApplicationContext; -import io.micronaut.runtime.server.EmbeddedServer; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import io.micronaut.runtime.EmbeddedApplication; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; -import static junit.framework.TestCase.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +@MicronautTest public class GreetingClientUnitTest { - private EmbeddedServer server; + + @Inject + private EmbeddedApplication application; + + @Inject private GreetingClient client; - @Before - public void setup() - { - server = ApplicationContext.run(EmbeddedServer.class); - client = server.getApplicationContext().getBean(GreetingClient.class); - } - - @After - public void cleanup() - { - server.stop(); - } - @Test public void testGreeting() { assertEquals(client.greet("Mike"), "Hello Mike"); diff --git a/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/vs/springboot/ArithmeticClientUnitTest.java b/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/vs/springboot/ArithmeticClientUnitTest.java index 9a1b095d22..fa191778f5 100644 --- a/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/vs/springboot/ArithmeticClientUnitTest.java +++ b/microservices-modules/micronaut/src/test/java/com/baeldung/micronaut/vs/springboot/ArithmeticClientUnitTest.java @@ -1,34 +1,21 @@ package com.baeldung.micronaut.vs.springboot; -import static org.junit.Assert.assertEquals; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; - -import io.micronaut.context.ApplicationContext; -import io.micronaut.runtime.server.EmbeddedServer; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - import com.baeldung.micronaut.vs.springboot.client.ArithmeticClientImpl; +import io.micronaut.runtime.EmbeddedApplication; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@MicronautTest public class ArithmeticClientUnitTest { - private EmbeddedServer server; + @Inject + private EmbeddedApplication server; + @Inject private ArithmeticClientImpl client; - @Before - public void setup() { - server = ApplicationContext.run(EmbeddedServer.class); - client = server.getApplicationContext() - .getBean(ArithmeticClientImpl.class); - } - - @After - public void cleanup() { - server.stop(); - } - @Test public void givenTwoNumbers_whenAdd_thenCorrectAnswerReturned() { String expected = Float.valueOf(10 + 20).toString(); @@ -56,6 +43,6 @@ public class ArithmeticClientUnitTest { @Test public void whenMemory_thenCorrectAnswerReturned() { String expected = "Initial:"; - assertThat(client.memory(), containsString(expected)); + assertThat(client.memory()).contains(expected); } }