Skip to content

Commit bd94218

Browse files
committed
Kafka quickstart review
1 parent 39cdcb1 commit bd94218

File tree

8 files changed

+60
-25
lines changed

8 files changed

+60
-25
lines changed

kafka-quickstart/README.md

+21-13
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ and in another terminal:
2020
mvn -f processor quarkus:dev
2121
```
2222

23-
_NOTE_: Quarkus Dev Services starts a Kafka broker for you automatically.
23+
_NOTE_: Quarkus Dev Services starts a Kafka broker for you automatically.
2424

25-
Then, open your browser to `http://localhost:8080/quotes.html`.
25+
Then, open your browser at `http://localhost:8080/quotes.html`.
2626
You can send quote requests and observe received quotes.
2727

2828
## Anatomy
@@ -31,7 +31,7 @@ The application is composed of the following components:
3131

3232
#### Producer
3333

34-
The _producer_ application receive requests from the user (via HTTP) and sends data to the Kafka broker.
34+
The _producer_ application receive requests from the user (via HTTP) and sends _quote requests_ to the Kafka broker.
3535
Two main components compose the application:
3636

3737
* `QuoteProducer` generates uniquely identified quote requests and sends them to the Kafka topic `quote-requests`.
@@ -40,26 +40,25 @@ It also consumes the Kafka topic `quotes` and relays received messages to the br
4040

4141
#### Processor
4242

43-
The _processor_ application receives data from Kafka, processes them, and writes the result into the `quotes` Kafka topic.
43+
The _processor_ application receives quote requests from Kafka, processes them, and writes results into the `quotes` Kafka topic.
44+
The application has one main class:
4445

45-
Two main classes compose the application:
46-
47-
* `QuoteProcessor` consumes quote request id's from the `quote-requests` Kafka topic and responds back to the `quotes` topic with a `Quote` object containing a random price.
46+
* `QuoteProcessor` consumes quote request ids from the `quote-requests` Kafka topic and responds back to the `quotes` topic with a `Quote` object containing a random price.
4847

4948
The connection to Kafka is configured in the `src/main/resources/application.properties` file.
5049

5150
## Running the application in Docker
5251

53-
To run the application on Docker:
52+
To run the application in Docker, first make sure that both services are built:
5453

55-
First make sure that both services are packaged:
5654
```bash
5755
mvn package
5856
```
5957

60-
Then launch the Docker compose:
58+
Then launch Docker Compose:
59+
6160
```bash
62-
docker compose up
61+
docker-compose up
6362
```
6463

6564
This will create a single-node Kafka cluster and launch both applications.
@@ -69,10 +68,19 @@ This will create a single-node Kafka cluster and launch both applications.
6968
You can compile the application into a native binary using:
7069

7170
```bash
72-
./mvn package -Pnative
71+
mvn package -Dnative
72+
```
73+
74+
As you are running in _prod_ mode, you need a Kafka cluster.
75+
76+
If you have Docker installed, you can simply run:
77+
78+
```bash
79+
export QUARKUS_MODE=native
80+
docker-compose up --build
7381
```
7482

75-
As you are running in _prod_ mode, you need a Kafka cluster. You can follow the instructions from the [Apache Kafka web site](https://kafka.apache.org/quickstart) or run `docker-compose up` if you have docker installed on your machine.
83+
Alternatively, you can follow the instructions from the [Apache Kafka web site](https://kafka.apache.org/quickstart).
7684

7785
Then run both applications respectively with:
7886

kafka-quickstart/docker-compose.yaml

+6-2
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,12 @@ services:
3434
- kafka-quickstart-network
3535

3636
producer:
37-
image: quarkus-quickstarts/kafka-quickstart-producer:1.0
37+
image: quarkus-quickstarts/kafka-quickstart-producer:1.0-${QUARKUS_MODE:-jvm}
3838
build:
3939
context: producer
4040
dockerfile: src/main/docker/Dockerfile.${QUARKUS_MODE:-jvm}
41+
depends_on:
42+
- kafka
4143
environment:
4244
KAFKA_BOOTSTRAP_SERVERS: kafka:9092
4345
ports:
@@ -46,10 +48,12 @@ services:
4648
- kafka-quickstart-network
4749

4850
processor:
49-
image: quarkus-quickstarts/kafka-quickstart-processor:1.0
51+
image: quarkus-quickstarts/kafka-quickstart-processor:1.0-${QUARKUS_MODE:-jvm}
5052
build:
5153
context: processor
5254
dockerfile: src/main/docker/Dockerfile.${QUARKUS_MODE:-jvm}
55+
depends_on:
56+
- kafka
5357
environment:
5458
KAFKA_BOOTSTRAP_SERVERS: kafka:9092
5559
networks:

kafka-quickstart/processor/src/main/java/org/acme/kafka/model/Quote.java

+10-2
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,20 @@ public class Quote {
66
public int price;
77

88
/**
9-
* Default constructor needed for Jackson serialization
9+
* Default constructor required for Jackson serializer
1010
*/
1111
public Quote() { }
1212

1313
public Quote(String id, int price) {
1414
this.id = id;
1515
this.price = price;
1616
}
17-
}
17+
18+
@Override
19+
public String toString() {
20+
return "Quote{" +
21+
"id='" + id + '\'' +
22+
", price=" + price +
23+
'}';
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
%dev.quarkus.http.port=8081
22

3-
# Configure the incoming Kafka topic quote-requests (we read from it)
3+
# Configure the incoming `quote-requests` Kafka topic
44
mp.messaging.incoming.requests.connector=smallrye-kafka
55
mp.messaging.incoming.requests.topic=quote-requests
66
mp.messaging.incoming.requests.auto.offset.reset=earliest
77

8-
# Configure the outgoing Kafka topic quotes (we write to it)
8+
# Configure the outgoing `quotes` Kafka topic
99
mp.messaging.outgoing.quotes.connector=smallrye-kafka
1010
mp.messaging.outgoing.quotes.value.serializer=io.quarkus.kafka.client.serialization.ObjectMapperSerializer

kafka-quickstart/processor/src/test/java/org/acme/kafka/processor/QuoteProcessorTest.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.apache.kafka.clients.producer.ProducerRecord;
1919
import org.apache.kafka.common.serialization.StringDeserializer;
2020
import org.apache.kafka.common.serialization.StringSerializer;
21+
import org.junit.jupiter.api.AfterEach;
2122
import org.junit.jupiter.api.BeforeEach;
2223
import org.junit.jupiter.api.Test;
2324

@@ -36,12 +37,17 @@ public class QuoteProcessorTest {
3637
KafkaConsumer<String, Quote> quoteConsumer;
3738

3839
@BeforeEach
39-
void beforeAll() {
40-
System.out.println(kafkaConfig);
40+
void setUp() {
4141
quoteConsumer = new KafkaConsumer<>(consumerConfig(), new StringDeserializer(), new ObjectMapperDeserializer<>(Quote.class));
4242
quoteRequestProducer = new KafkaProducer<>(kafkaConfig, new StringSerializer(), new StringSerializer());
4343
}
4444

45+
@AfterEach
46+
void tearDown() {
47+
quoteRequestProducer.close();
48+
quoteConsumer.close();
49+
}
50+
4551
Properties consumerConfig() {
4652
Properties properties = new Properties();
4753
properties.putAll(kafkaConfig);

kafka-quickstart/producer/src/main/java/org/acme/kafka/model/Quote.java

+11-1
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,21 @@ public class Quote {
55
public String id;
66
public int price;
77

8+
/**
9+
* Default constructor required for Jackson serializer
10+
*/
11+
public Quote() { }
12+
13+
public Quote(String id, int price) {
14+
this.id = id;
15+
this.price = price;
16+
}
17+
818
@Override
919
public String toString() {
1020
return "Quote{" +
1121
"id='" + id + '\'' +
1222
", price=" + price +
1323
'}';
1424
}
15-
}
25+
}

kafka-quickstart/producer/src/main/java/org/acme/kafka/model/QuoteDeserializer.java

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
public class QuoteDeserializer extends ObjectMapperDeserializer<Quote> {
66
public QuoteDeserializer() {
7-
// pass the class to the parent.
87
super(Quote.class);
98
}
109
}

kafka-quickstart/producer/src/main/resources/META-INF/resources/quotes.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ <h2 class="card-title">Quotes</h2>
2727
.then(res => res.text())
2828
.then(qid => {
2929
var row = $(`<h4 class='col-md-12' id='${qid}'>Quote # <i>${qid}</i> | <strong>Pending</strong></h4>`);
30-
$(".quotes").append(row);
30+
$(".quotes").prepend(row);
3131
});
3232
});
3333

3434
var source = new EventSource("/quotes");
3535
source.onmessage = (event) => {
3636
var json = JSON.parse(event.data);
37-
$(`#${json.id}`).html(function(index, html) {
37+
$(`#${json.id}`).html((index, html) => {
3838
return html.replace("Pending", `\$\xA0${json.price}`);
3939
});
4040
};

0 commit comments

Comments
 (0)