From 30fc547604c59287ab319dafa53fe1037eb34214 Mon Sep 17 00:00:00 2001
From: TakahashiNg <83152264+TakahashiNguyen@users.noreply.github.com>
Date: Tue, 24 Mar 2026 06:56:12 +0000
Subject: [PATCH] chore: update
---
.../src/main/java/com/drinkool/RestAPI.java | 9 +--
.../com/drinkool/entities/CustomerEntity.java | 9 +++
.../java/com/drinkool/models/Customer.java | 7 ---
.../models/{User.java => UserModel.java} | 8 +--
eatery-service/pom.xml | 33 ++++++-----
.../src/main/java/com/drinkool/MyEntity.java | 29 ----------
.../com/drinkool/MyMessagingApplication.java | 48 ----------------
.../main/java/com/drinkool/ReviewService.java | 53 ++++++++++++++++++
.../com/drinkool/entities/ReviewEntity.java | 29 ++++++++++
.../main/java/com/drinkool/models/Review.java | 7 ---
.../utils/SendReviewDeserializer.java | 11 ++++
.../src/main/resources/application.properties | 36 +++++++++++-
.../drinkool/MyMessagingApplicationTest.java | 14 ++---
.../java/com/drinkool/ReviewServiceTest.java | 56 +++++++++++++++++++
.../src/test/resources/application.properties | 15 +++++
.../src/main/resources/application.properties | 4 --
.../java/com/drinkool/dtos/SendReview.java | 11 ++++
.../{BaseReview.java => ReviewModel.java} | 2 +-
18 files changed, 250 insertions(+), 131 deletions(-)
create mode 100644 account-service/src/main/java/com/drinkool/entities/CustomerEntity.java
delete mode 100644 account-service/src/main/java/com/drinkool/models/Customer.java
rename account-service/src/main/java/com/drinkool/models/{User.java => UserModel.java} (89%)
delete mode 100644 eatery-service/src/main/java/com/drinkool/MyEntity.java
delete mode 100644 eatery-service/src/main/java/com/drinkool/MyMessagingApplication.java
create mode 100644 eatery-service/src/main/java/com/drinkool/ReviewService.java
create mode 100644 eatery-service/src/main/java/com/drinkool/entities/ReviewEntity.java
delete mode 100644 eatery-service/src/main/java/com/drinkool/models/Review.java
create mode 100644 eatery-service/src/main/java/com/drinkool/utils/SendReviewDeserializer.java
create mode 100644 eatery-service/src/test/java/com/drinkool/ReviewServiceTest.java
create mode 100644 eatery-service/src/test/resources/application.properties
create mode 100644 lib/src/main/java/com/drinkool/dtos/SendReview.java
rename lib/src/main/java/com/drinkool/models/{BaseReview.java => ReviewModel.java} (88%)
diff --git a/account-service/src/main/java/com/drinkool/RestAPI.java b/account-service/src/main/java/com/drinkool/RestAPI.java
index 899474f..6bb45f0 100644
--- a/account-service/src/main/java/com/drinkool/RestAPI.java
+++ b/account-service/src/main/java/com/drinkool/RestAPI.java
@@ -1,7 +1,8 @@
package com.drinkool;
import com.drinkool.dtos.*;
-import com.drinkool.models.Customer;
+import com.drinkool.entities.CustomerEntity;
+import com.drinkool.entities.CustomerEntity;
import com.drinkool.services.*;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
@@ -18,7 +19,7 @@ public class RestAPI {
@Path("/signup")
@Transactional
public Response signup(Signup input) {
- Customer newCustomer = new Customer();
+ CustomerEntity newCustomer = new CustomerEntity();
newCustomer.signup(input.name, input.phone, input.password);
@@ -29,7 +30,7 @@ public class RestAPI {
@Path("/quickSignup")
@Transactional
public Response quickSignup(QuickSignup input) {
- Customer newCustomer = new Customer();
+ CustomerEntity newCustomer = new CustomerEntity();
newCustomer.signup(input.phone);
@@ -39,7 +40,7 @@ public class RestAPI {
@POST
@Path("/login")
public Response login(Login input) {
- Customer customer = Customer.find("phone", input.phone).firstResult();
+ CustomerEntity customer = CustomerEntity.find("phone", input.phone).firstResult();
if (customer == null) throw new BadRequestException("InvalidPhoneNumber");
diff --git a/account-service/src/main/java/com/drinkool/entities/CustomerEntity.java b/account-service/src/main/java/com/drinkool/entities/CustomerEntity.java
new file mode 100644
index 0000000..98801ed
--- /dev/null
+++ b/account-service/src/main/java/com/drinkool/entities/CustomerEntity.java
@@ -0,0 +1,9 @@
+package com.drinkool.entities;
+
+import com.drinkool.models.UserModel;
+
+import jakarta.persistence.*;
+
+@Entity
+@Table(name = "customer")
+public class CustomerEntity extends UserModel {}
diff --git a/account-service/src/main/java/com/drinkool/models/Customer.java b/account-service/src/main/java/com/drinkool/models/Customer.java
deleted file mode 100644
index 491137f..0000000
--- a/account-service/src/main/java/com/drinkool/models/Customer.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.drinkool.models;
-
-import jakarta.persistence.*;
-
-@Entity
-@Table(name = "customer")
-public class Customer extends User {}
diff --git a/account-service/src/main/java/com/drinkool/models/User.java b/account-service/src/main/java/com/drinkool/models/UserModel.java
similarity index 89%
rename from account-service/src/main/java/com/drinkool/models/User.java
rename to account-service/src/main/java/com/drinkool/models/UserModel.java
index debaf29..d19ed1d 100644
--- a/account-service/src/main/java/com/drinkool/models/User.java
+++ b/account-service/src/main/java/com/drinkool/models/UserModel.java
@@ -11,7 +11,7 @@ import java.util.UUID;
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "users")
-public abstract class User extends PanacheEntity {
+public abstract class UserModel extends PanacheEntity {
@Column(nullable = false)
public String name;
@@ -22,10 +22,6 @@ public abstract class User extends PanacheEntity {
@Column(nullable = false, length = 1024)
public String hashedPassword;
- public User() {
- super();
- }
-
@Transactional
public void signup(String phone) {
this.signup(phone, phone, UUID.randomUUID().toString().substring(0, 32));
@@ -34,7 +30,7 @@ public abstract class User extends PanacheEntity {
@Transactional
public void signup(String name, String phone, String rawPassword) {
// Check existed user
- Customer existedUser = User.find("phone", phone).firstResult();
+ UserModel existedUser = UserModel.find("phone", phone).firstResult();
if (existedUser != null) throw new BadRequestException("ExistedUser");
diff --git a/eatery-service/pom.xml b/eatery-service/pom.xml
index df94b97..006b8e4 100644
--- a/eatery-service/pom.xml
+++ b/eatery-service/pom.xml
@@ -1,9 +1,7 @@
-
-
+
+
4.0.0
@@ -20,11 +18,9 @@
3.15.0
21
UTF-8
- UTF-8
+ UTF-8
quarkus-bom
- io.quarkus.platform
+ io.quarkus.platform
3.32.4
true
3.5.4
@@ -48,6 +44,11 @@
lib
${project.version}
+
+ org.awaitility
+ awaitility
+ test
+
io.quarkus
quarkus-hibernate-orm-panache
@@ -72,6 +73,10 @@
io.quarkus
quarkus-hibernate-orm
+
+ io.quarkus
+ quarkus-rest-jackson
+
io.quarkus
quarkus-junit
@@ -100,8 +105,7 @@
@{argLine}
- org.jboss.logmanager.LogManager
+ org.jboss.logmanager.LogManager
${maven.home}
@@ -122,8 +126,7 @@
${project.build.directory}/${project.build.finalName}-runner
- org.jboss.logmanager.LogManager
+ org.jboss.logmanager.LogManager
${maven.home}
@@ -146,4 +149,4 @@
-
+
\ No newline at end of file
diff --git a/eatery-service/src/main/java/com/drinkool/MyEntity.java b/eatery-service/src/main/java/com/drinkool/MyEntity.java
deleted file mode 100644
index ceb5d4a..0000000
--- a/eatery-service/src/main/java/com/drinkool/MyEntity.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.drinkool;
-
-import io.quarkus.hibernate.orm.panache.PanacheEntity;
-import jakarta.persistence.Entity;
-
-/**
- * Example JPA entity defined as a Panache Entity.
- * An ID field of Long type is provided, if you want to define your own ID field extends PanacheEntityBase instead.
- *
- * This uses the active record pattern, you can also use the repository pattern instead:
- * {@see https://quarkus.io/guides/hibernate-orm-panache#solution-2-using-the-repository-pattern}.
- *
- * Usage:
- *
- * {@code
- * public void doSomething() {
- * MyEntity entity1 = new MyEntity();
- * entity1.field = "field-1";
- * entity1.persist();
- *
- * List entities = MyEntity.listAll();
- * }
- * }
- */
-@Entity
-public class MyEntity extends PanacheEntity {
-
- public String field;
-}
diff --git a/eatery-service/src/main/java/com/drinkool/MyMessagingApplication.java b/eatery-service/src/main/java/com/drinkool/MyMessagingApplication.java
deleted file mode 100644
index a9e0791..0000000
--- a/eatery-service/src/main/java/com/drinkool/MyMessagingApplication.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.drinkool;
-
-import io.quarkus.runtime.StartupEvent;
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.enterprise.event.Observes;
-import java.util.stream.Stream;
-import org.eclipse.microprofile.reactive.messaging.Channel;
-import org.eclipse.microprofile.reactive.messaging.Emitter;
-import org.eclipse.microprofile.reactive.messaging.Incoming;
-import org.eclipse.microprofile.reactive.messaging.Outgoing;
-
-@ApplicationScoped
-public class MyMessagingApplication {
-
- /**
- * Injects an emitter to send messages to the "words-out" channel.
- */
- @Channel("words-out")
- Emitter emitter;
-
- /**
- * Sends message to the "words-out" channel, can be used from a JAX-RS resource or any bean of your application.
- * Messages are sent to the broker.
- **/
- void onStart(@Observes StartupEvent ev) {
- Stream.of("Hello", "with", "Quarkus", "Messaging", "message").forEach(
- string -> emitter.send(string)
- );
- }
-
- /**
- * Consume the message from the "words-in" channel, uppercase it and send it to the uppercase channel.
- * This method is called by the framework when a message is received on the "words-in" channel (from the broker).
- **/
- @Incoming("words-in")
- @Outgoing("uppercase")
- public String toUpperCase(String message) {
- return message.toUpperCase();
- }
-
- /**
- * Consume the uppercase channel (coming from within the application) and print the messages to the console.
- **/
- @Incoming("uppercase")
- public void sink(String word) {
- System.out.println(">> " + word);
- }
-}
diff --git a/eatery-service/src/main/java/com/drinkool/ReviewService.java b/eatery-service/src/main/java/com/drinkool/ReviewService.java
new file mode 100644
index 0000000..ea5d76f
--- /dev/null
+++ b/eatery-service/src/main/java/com/drinkool/ReviewService.java
@@ -0,0 +1,53 @@
+package com.drinkool;
+
+import com.drinkool.dtos.SendReview;
+import com.drinkool.entities.ReviewEntity;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.transaction.Transactional;
+import org.eclipse.microprofile.reactive.messaging.Incoming;
+
+@ApplicationScoped
+public class ReviewService {
+
+ /**
+ * Injects an emitter to send messages to the "words-out" channel.
+ */
+ // @Channel("words-out")
+ // Emitter emitter;
+
+ // /**
+ // * Sends message to the "words-out" channel, can be used from a JAX-RS resource or any bean of your application.
+ // * Messages are sent to the broker.
+ // **/
+ // void onStart(@Observes StartupEvent ev) {
+ // Stream.of("Hello", "with", "Quarkus", "Messaging", "message").forEach(
+ // string -> emitter.send(string)
+ // );
+ // }
+
+ /**
+ * Consume the message from the "words-in" channel, uppercase it and send it to the uppercase channel.
+ * This method is called by the framework when a message is received on the "words-in" channel (from the broker).
+ **/
+ // @Incoming("words-in")
+ // @Outgoing("uppercase")
+ // public String toUpperCase(String message) {
+ // return message.toUpperCase();
+ // }
+
+ /**
+ * Consume the uppercase channel (coming from within the application) and print the messages to the console.
+ **/
+ // @Incoming("uppercase")
+ // public void sink(String word) {
+ // System.out.println(">> " + word);
+ // }
+
+ @Incoming("review")
+ @Transactional
+ public void receiveReview(SendReview input) {
+ ReviewEntity newReview = new ReviewEntity();
+
+ newReview.receive(input.reviewerId, input.orderId, input.review);
+ }
+}
diff --git a/eatery-service/src/main/java/com/drinkool/entities/ReviewEntity.java b/eatery-service/src/main/java/com/drinkool/entities/ReviewEntity.java
new file mode 100644
index 0000000..b0a913b
--- /dev/null
+++ b/eatery-service/src/main/java/com/drinkool/entities/ReviewEntity.java
@@ -0,0 +1,29 @@
+package com.drinkool.entities;
+
+import com.drinkool.models.ReviewModel;
+import jakarta.persistence.*;
+import jakarta.transaction.Transactional;
+
+import java.util.UUID;
+
+@Entity
+@Table(name = "reviews")
+public class ReviewEntity extends ReviewModel {
+
+ public UUID reviewerId;
+
+ public UUID eateryId;
+
+ @Transactional
+ public void receive(UUID reviewerId, UUID eateryId, ReviewModel review) {
+ this.reviewerId = reviewerId;
+
+ this.eateryId = eateryId;
+
+ this.rating = review.rating;
+
+ this.comment = review.comment;
+
+ this.persist();
+ }
+}
diff --git a/eatery-service/src/main/java/com/drinkool/models/Review.java b/eatery-service/src/main/java/com/drinkool/models/Review.java
deleted file mode 100644
index 8c0a227..0000000
--- a/eatery-service/src/main/java/com/drinkool/models/Review.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.drinkool.models;
-
-import jakarta.persistence.*;
-
-@Entity
-@Table(name = "reviews")
-public class Review extends BaseReview {}
diff --git a/eatery-service/src/main/java/com/drinkool/utils/SendReviewDeserializer.java b/eatery-service/src/main/java/com/drinkool/utils/SendReviewDeserializer.java
new file mode 100644
index 0000000..98ca717
--- /dev/null
+++ b/eatery-service/src/main/java/com/drinkool/utils/SendReviewDeserializer.java
@@ -0,0 +1,11 @@
+package com.drinkool.utils;
+
+import com.drinkool.dtos.SendReview;
+
+import io.quarkus.kafka.client.serialization.ObjectMapperDeserializer;
+
+public class SendReviewDeserializer extends ObjectMapperDeserializer {
+ public SendReviewDeserializer() {
+ super(SendReview.class);
+ }
+}
diff --git a/eatery-service/src/main/resources/application.properties b/eatery-service/src/main/resources/application.properties
index 112829f..a7a355d 100644
--- a/eatery-service/src/main/resources/application.properties
+++ b/eatery-service/src/main/resources/application.properties
@@ -1,3 +1,33 @@
-mp.messaging.incoming.words-in.auto.offset.reset=earliest
-mp.messaging.incoming.words-in.topic=words
-mp.messaging.outgoing.words-out.topic=words
+# Cấu hình Database
+
+# Kafka
+# Địa chỉ server Kafka
+kafka.bootstrap.servers=localhost:9092
+
+# --- CẤU HÌNH GỬI TIN (OUTGOING) ---
+# Kênh "eatery-out" sẽ gửi vào topic "eatery-events"
+# mp.messaging.outgoing.eatery-out.connector=smallrye-kafka
+# mp.messaging.outgoing.eatery-out.topic=eatery-events
+# # Tự động biến Object thành JSON
+# mp.messaging.outgoing.eatery-out.value.serializer=io.quarkus.kafka.client.serialization.ObjectMapperSerializer
+
+# --- CẤU HÌNH NHẬN TIN (INCOMING) ---
+# Kênh "review-in" sẽ nhận từ topic "review-topic"
+mp.messaging.incoming.review.connector=smallrye-kafka
+mp.messaging.incoming.review.topic=review-topic
+# Tự động biến JSON thành Object (giả sử là class ReviewModel)
+mp.messaging.incoming.review.value.deserializer=com.drinkool.utils.SendReviewDeserializer
+
+# Postgress
+# Cấu hình Database
+quarkus.datasource.db-kind=postgresql
+quarkus.datasource.username=postgres
+quarkus.datasource.password=password
+quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/eatery
+
+# Tự động tạo bảng từ Entity (chỉ dùng cho môi trường dev)
+quarkus.hibernate-orm.database.generation=update
+
+# Dependency
+quarkus.index-dependency.lib.group-id=com.drinkool
+quarkus.index-dependency.lib.artifact-id=lib
\ No newline at end of file
diff --git a/eatery-service/src/test/java/com/drinkool/MyMessagingApplicationTest.java b/eatery-service/src/test/java/com/drinkool/MyMessagingApplicationTest.java
index 7573d8d..668934e 100644
--- a/eatery-service/src/test/java/com/drinkool/MyMessagingApplicationTest.java
+++ b/eatery-service/src/test/java/com/drinkool/MyMessagingApplicationTest.java
@@ -9,12 +9,12 @@ import org.junit.jupiter.api.Test;
@QuarkusTest
class MyMessagingApplicationTest {
- @Inject
- MyMessagingApplication application;
+ // @Inject
+ // MyMessagingApplication application;
- @Test
- void test() {
- assertEquals("HELLO", application.toUpperCase("Hello"));
- assertEquals("BONJOUR", application.toUpperCase("bonjour"));
- }
+ // @Test
+ // void test() {
+ // assertEquals("HELLO", application.toUpperCase("Hello"));
+ // assertEquals("BONJOUR", application.toUpperCase("bonjour"));
+ // }
}
diff --git a/eatery-service/src/test/java/com/drinkool/ReviewServiceTest.java b/eatery-service/src/test/java/com/drinkool/ReviewServiceTest.java
new file mode 100644
index 0000000..fb4892e
--- /dev/null
+++ b/eatery-service/src/test/java/com/drinkool/ReviewServiceTest.java
@@ -0,0 +1,56 @@
+package com.drinkool;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import com.drinkool.dtos.SendReview;
+import com.drinkool.entities.ReviewEntity;
+import com.drinkool.models.ReviewModel;
+import io.quarkus.narayana.jta.QuarkusTransaction;
+import io.quarkus.test.junit.QuarkusTest;
+import jakarta.inject.Inject;
+import java.util.Random;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import org.awaitility.Awaitility;
+import org.eclipse.microprofile.reactive.messaging.*;
+import org.junit.jupiter.api.Test;
+
+@QuarkusTest
+public class ReviewServiceTest {
+
+ @Inject
+ ReviewService service;
+
+ @Inject
+ @Channel("review-test")
+ Emitter producer;
+
+ @Test
+ void receiveReview() {
+ Random random = new Random();
+
+ UUID reviewerId = UUID.randomUUID();
+ UUID orderId = UUID.randomUUID();
+ String comment = UUID.randomUUID().toString();
+ int rating = random.nextInt();
+
+ SendReview input = new SendReview();
+ input.reviewerId = reviewerId;
+ input.orderId = orderId;
+ ReviewModel reviewModel = new ReviewModel();
+ reviewModel.comment = comment;
+ reviewModel.rating = rating;
+ input.review = reviewModel;
+
+ producer.send(input);
+
+ Awaitility.await()
+ .atMost(5, TimeUnit.SECONDS)
+ .untilAsserted(() -> {
+ ReviewEntity saved = QuarkusTransaction.requiringNew().call(() ->
+ ReviewEntity.find("reviewerId", reviewerId).firstResult()
+ );
+ assertNotNull(saved);
+ });
+ }
+}
diff --git a/eatery-service/src/test/resources/application.properties b/eatery-service/src/test/resources/application.properties
new file mode 100644
index 0000000..8c405bc
--- /dev/null
+++ b/eatery-service/src/test/resources/application.properties
@@ -0,0 +1,15 @@
+# Kafka
+kafka.bootstrap.servers=localhost:9092
+
+# --- CẤU HÌNH GỬI TIN (OUTGOING) ---
+# Kênh "eatery-out" sẽ gửi vào topic "eatery-events"
+# mp.messaging.outgoing.eatery-out.connector=smallrye-kafka
+# mp.messaging.outgoing.eatery-out.topic=eatery-events
+# # Tự động biến Object thành JSON
+# mp.messaging.outgoing.eatery-out.value.serializer=io.quarkus.kafka.client.serialization.ObjectMapperSerializer
+
+# --- CẤU HÌNH NHẬN TIN (INCOMING) ---
+mp.messaging.outgoing.review-test.connector=smallrye-kafka
+mp.messaging.outgoing.review-test.topic=review-topic
+# Sửa serializer cho đúng loại dành cho việc GỬI
+mp.messaging.outgoing.review-test.value.serializer=io.quarkus.kafka.client.serialization.ObjectMapperSerializer
\ No newline at end of file
diff --git a/gateway-service/src/main/resources/application.properties b/gateway-service/src/main/resources/application.properties
index 92a3501..6993984 100644
--- a/gateway-service/src/main/resources/application.properties
+++ b/gateway-service/src/main/resources/application.properties
@@ -1,5 +1 @@
-mp.messaging.incoming.words-in.auto.offset.reset=earliest
-mp.messaging.incoming.words-in.topic=words
-mp.messaging.outgoing.words-out.topic=words
-
quarkus.rest-client.account.url=http://localhost:502
\ No newline at end of file
diff --git a/lib/src/main/java/com/drinkool/dtos/SendReview.java b/lib/src/main/java/com/drinkool/dtos/SendReview.java
new file mode 100644
index 0000000..a887081
--- /dev/null
+++ b/lib/src/main/java/com/drinkool/dtos/SendReview.java
@@ -0,0 +1,11 @@
+package com.drinkool.dtos;
+
+import java.util.UUID;
+
+import com.drinkool.models.ReviewModel;
+
+public class SendReview {
+ public UUID reviewerId;
+ public UUID orderId;
+ public ReviewModel review;
+}
diff --git a/lib/src/main/java/com/drinkool/models/BaseReview.java b/lib/src/main/java/com/drinkool/models/ReviewModel.java
similarity index 88%
rename from lib/src/main/java/com/drinkool/models/BaseReview.java
rename to lib/src/main/java/com/drinkool/models/ReviewModel.java
index 5b83bc8..e7da336 100644
--- a/lib/src/main/java/com/drinkool/models/BaseReview.java
+++ b/lib/src/main/java/com/drinkool/models/ReviewModel.java
@@ -5,7 +5,7 @@ import jakarta.persistence.*;
import java.time.LocalDateTime;
@MappedSuperclass
-public class BaseReview extends PanacheEntity {
+public class ReviewModel extends PanacheEntity {
@Column
public int rating;