diff --git a/documentation/modules/ROOT/pages/14_reactive.adoc b/documentation/modules/ROOT/pages/14_reactive.adoc index c6f0ceb..956562c 100644 --- a/documentation/modules/ROOT/pages/14_reactive.adoc +++ b/documentation/modules/ROOT/pages/14_reactive.adoc @@ -36,6 +36,32 @@ cd {project-name} -- ==== +== Start the app in Dev Mode: + +[tabs%sync] +==== +Maven:: ++ +-- +[.console-input] +[source,bash,subs="+macros,+attributes"] +---- +./mvnw quarkus:dev +---- + +-- +Quarkus CLI:: ++ +-- +[.console-input] +[source,bash,subs="+macros,+attributes"] +---- +quarkus dev +---- +-- +==== + + == Create Beer POJO Create a new `Beer` Java class in `src/main/java` in the `com.redhat.developers` package with the following contents: @@ -117,6 +143,8 @@ public interface BeerService { == Configure REST Client properties +NOTE: The original punkapi.com service is not operational anymore. To reproduce the application, you can deploy the API on an Openshift Sandbox (developers.redhat.com/sandbox). Once you have logged in to the Sandbox, go to the "Developers" perspective in the top left corner, click on +Add in the left menu, and then in the "Git Repository" section click on the "Import from Git". Paste in the Git Repo URL field: "https://github.com/kdubois/punkapi-server.git", scroll down and set "Target port" to `3333`. Wait for the build to complete (this may take a few minutes) and the app to be deployed. Now click on the deployed app circle in the Topology view and copy the URL from the "Routes" section which should be visible on the right side of your screen. Then paste this URL in the application.properties below: + Add the following properties to your `application.properties` in `src/main/resources`: [.console-input] diff --git a/documentation/modules/ROOT/pages/15_reactive-messaging.adoc b/documentation/modules/ROOT/pages/15_reactive-messaging.adoc index e36af5f..9117539 100644 --- a/documentation/modules/ROOT/pages/15_reactive-messaging.adoc +++ b/documentation/modules/ROOT/pages/15_reactive-messaging.adoc @@ -1,20 +1,19 @@ = Reactive Messaging -As a Java developer you are aware that the JMS is the standard when comes to working with messages. -JMS is a blocking API which blocks us from implementing the reactive principles. +As a Java developer you're likely familiar with JMS, which is considered to be the standard when it comes to working with messages. +JMS however is a blocking API, which prevents us from implementing the reactive principles. -Quarkus has SmallRye Reactive Messaging which is an implementation of the Eclipse MicroProfile Reactive Messaging specification. -Quarkus implements version 2.x of this specification but also provides many other extensions. +Quarkus has a "SmallRye Reactive Messaging" extension which is an implementation of the Eclipse MicroProfile Reactive Messaging specification. Reactive Messaging allows us to implement messaging in a non-blocking, reactive way. -In this chapter we're going to use SmallRye Reactive Messaging to generate beers having a price but using messages instead of synchronous calls. +In this chapter we're going to use SmallRye Reactive Messaging to generate beers once again. This time we're going to add a (random) price to the beers. We're going to be using messages instead of synchronous calls to do this. -At this point, we're going to use an inmemory channel which means that messages are sent through the same application using the memory as transport channel of the messages. +To do so, we're going to use an in-memory channel. This means that messages are sent through the application using memory as transport channel of the messages. In the following section, we'll see what we need to change to start using an external broker for sending messages. == Add the Reactive Messaging extension -Just open a new terminal window, and make sure you’re at the root of your `{project-name}` project, then run: +Open a new terminal window, and make sure you’re at the root of your `{project-name}` project, then run: [tabs] ==== @@ -41,9 +40,9 @@ quarkus extension add messaging == Modify BeerResource -Let's create a new endpoint that finds a beer and sends/emits a message to `beers` channel with the beer. +Let's create a new endpoint that finds a beer and sends/emits a message to a `beers` channel. -Open `BeerResource` class and add the following code. +Open the `BeerResource` class and add the following code. In the imports section: @@ -79,9 +78,9 @@ public Response emitBeer(@PathParam("beer") int beerId) { <4> Sends an ack to caller The previous code sends the beer as a `JsonObject` to `beers` channel. -Since we are using a memory channel, let's create a new Java class in the same project capturing the messages sent to the channel. +Since we are using an in-memory channel, let's create a new Java class in the same project capturing the messages sent to the channel. -Moreover this new class, will send another event to a different channel which will be captured by another method. +This new class will send another event to a different channel which will be captured by yet another method. == Create BeerProcessor @@ -90,7 +89,7 @@ Create a new `BeerProcessor` Java class in `src/main/java` in the `org.acme` pac [.console-input] [source,java] ---- -package org.acme; +package com.redhat.developers; import java.util.concurrent.ThreadLocalRandom; @@ -109,7 +108,7 @@ public class BeerProcessor { @Incoming("beers") // <1> @Outgoing("messages") // <2> - public JsonObject processPrize(JsonObject beer) { // <3> + public JsonObject processPrice(JsonObject beer) { // <3> JsonObjectBuilder beerWithPrice = Json.createObjectBuilder(beer).add("price", getPrice()); return beerWithPrice.build(); // <4> } @@ -124,7 +123,7 @@ public class BeerProcessor { } } ---- -<1> Listen events from `beers` channel +<1> Listen to events from `beers` channel <2> Sends/Emits the result of the method call to the `messages` channel <3> Argument is the message of the `beers` channel <4> Return object is sent to the `messages` channel diff --git a/documentation/modules/ROOT/pages/16_kafka-and-streams.adoc b/documentation/modules/ROOT/pages/16_kafka-and-streams.adoc index 647e172..5115756 100644 --- a/documentation/modules/ROOT/pages/16_kafka-and-streams.adoc +++ b/documentation/modules/ROOT/pages/16_kafka-and-streams.adoc @@ -1,12 +1,12 @@ = Apache Kafka with Reactive Streams -Mutiny is just part of the Reactive story. To complement it, we need Reactive Streams too. And an important service that can serve as the underlying implementation for our stream is http://kafka.apache.org[Apache Kafka,window=_blank]. +Mutiny is just one part of the Reactive story. To complement it, we could use Reactive Streams too. An important service that can serve as the underlying implementation for our stream is http://kafka.apache.org[Apache Kafka,window=_blank]. -In this chapter, we'll do a small change, we send beers with a price to a Kafka broker instead of using a memory channel. +In this chapter, we'll make a small change: We will send beers with a price to a Kafka broker instead of using an in-memory channel. == Add the Reactive Messaging Kafka extension -Just open a new terminal window, and make sure you’re at the root of your `{project-name}` project, then run: +Open a new terminal window, and make sure you’re at the root of your `{project-name}` project, then run: [tabs] ==== @@ -65,13 +65,13 @@ TIP: If the channel name is the same as the topic, it's not necessary to set the Because starting a Kafka broker can be long and you need to develop fast in your local environment, Dev Services for Kafka is here to help you! -Since `quarkus-smallrye-reactive-messaging-kafka` extension is present, Dev Services for Kafka automatically starts a Kafka broker in dev mode and when running tests. +Since we have added the `quarkus-messaging-kafka`, Quarkus Dev Services automatically starts a containerized Kafka broker in dev mode and when running tests. TIP: You can disable Dev Services for Kafka by adding `quarkus.kafka.devservices.enabled=false` or configuring `kafka.bootstrap.servers` in `application.properties`. == Invoke the endpoint -With all these changes done, having Docker/Podman running in your computer, and starting the service in dev mode, you can send the same request as in the previous chapter: +There's not really any code to add at this point. Just by having Docker/Podman running on our computer, and starting the service in dev mode, we can now send the same request as in the previous chapter, but it will be sent to a Kafka topic instead of an in-memory channel. Let's try it: [.console-input] [source,bash] @@ -80,6 +80,4 @@ curl -w '\n' localhost:8080/beer/emit/1 ---- -Now, nothing is shown as return or in the Quarkus terminal, because the event is sent to a Kafka topic. - -To check the content of the topic, we can use the Dev UI interfac by pointing your browser to http://localhost:8080/q/dev-ui/io.quarkus.quarkus-kafka-client/topics[window=_blank] \ No newline at end of file +As you can see, nothing is shown in the return message, nor is there anything in the Quarkus terminal, because the event is simply sent to a Kafka topic. We could create some additional code to retrieve the message from Kafka, but in this case we're going to use the Dev UI interface where we can actually find the contents of the Kafka topic in the Kafka by pointing our browser to http://localhost:8080/q/dev-ui/io.quarkus.quarkus-kafka-client/topics[window=_blank] \ No newline at end of file