From bcbda39ed4bb39a2aa2a2f9d25e056a193e065e8 Mon Sep 17 00:00:00 2001 From: TakahashiNguyen Date: Tue, 31 Mar 2026 13:15:39 +0000 Subject: [PATCH] feat(k8s): init (#13) Co-authored-by: TakahashiNg <83152264+TakahashiNguyen@users.noreply.github.com> Reviewed-on: https://git.demonkernel.io.vn/FoodSurf/backend/pulls/13 --- .releaserc.json | 2 +- .../services/AuthenticationService.java | 33 ++--- .../src/main/resources/application.properties | 1 - .../services/AuthenticationServiceTest.java | 17 +-- gateway-service/pom.xml | 8 +- .../com/drinkool/CustomerGatewayResource.java | 19 +-- .../com/drinkool/services/AccountService.java | 17 ++- .../src/main/resources/application.properties | 8 +- k8s.yaml | 116 ++++++++++++++++++ lib/src/main/java/com/drinkool/Url.java | 10 ++ 10 files changed, 179 insertions(+), 52 deletions(-) create mode 100644 k8s.yaml create mode 100644 lib/src/main/java/com/drinkool/Url.java diff --git a/.releaserc.json b/.releaserc.json index 9b65fa2..ce2856c 100644 --- a/.releaserc.json +++ b/.releaserc.json @@ -14,7 +14,7 @@ [ "@semantic-release/exec", { - "prepareCmd": "./mvnw versions:set -DnewVersion=${nextRelease.version}", + "prepareCmd": "./mvnw versions:set -DnewVersion=${nextRelease.version} && sed -i \"s|\\(image: git.demonkernel.io.vn/foodsurf/[^:]*\\):.*|\\1:${nextRelease.version}|g\" k8s.yaml", "publishCmd": "if [ \"${branch.name}\" = \"main\" ]; then ./mvnw package -Dquarkus.container-image.tag=${nextRelease.version} -DskipTests; fi" } ], diff --git a/account-service/src/main/java/com/drinkool/services/AuthenticationService.java b/account-service/src/main/java/com/drinkool/services/AuthenticationService.java index fe2cbdf..70f0bd0 100644 --- a/account-service/src/main/java/com/drinkool/services/AuthenticationService.java +++ b/account-service/src/main/java/com/drinkool/services/AuthenticationService.java @@ -1,5 +1,6 @@ package com.drinkool.services; +import com.drinkool.Url; import com.drinkool.dtos.*; import com.drinkool.entities.CustomerEntity; import jakarta.inject.Inject; @@ -7,14 +8,14 @@ import jakarta.transaction.Transactional; import jakarta.ws.rs.*; import jakarta.ws.rs.core.*; -@Path("/api") +@Path("") public class AuthenticationService { @Inject OtpService otpService; @POST - @Path("/signup") + @Path(Url.Signup) @Transactional public Response signup(Signup input) { CustomerEntity newCustomer = new CustomerEntity(); @@ -25,7 +26,7 @@ public class AuthenticationService { } @POST - @Path("/quickSignup") + @Path(Url.QuickSignup) @Transactional public Response quickSignup(QuickSignup input) { CustomerEntity newCustomer = new CustomerEntity(); @@ -36,7 +37,7 @@ public class AuthenticationService { } @POST - @Path("/login") + @Path(Url.Login) public Response login(Login input) { CustomerEntity customer = CustomerEntity.find( "phone", @@ -53,18 +54,7 @@ public class AuthenticationService { } @POST - @Path("/sms_otp") - public Response smsOtp(SmsOtp input) { - String otp = otpService.generateAndSaveOtp(input.phone); - - // Ở đây bạn sẽ gọi Kafka để gửi SMS thực tế - System.out.println("OTP cho " + input.phone + " là: " + otp); - - return Response.accepted().build(); - } - - @POST - @Path("/quicklogin") + @Path(Url.QuickLogin) public Response quickLogin(QuickLogin input) { if (otpService.verifyOtp(input.phone, input.otp)) { return Response.accepted().build(); @@ -73,4 +63,15 @@ public class AuthenticationService { .entity("InvalidOTP") .build(); } + + @POST + @Path(Url.SmsOtp) + public Response smsOtp(SmsOtp input) { + String otp = otpService.generateAndSaveOtp(input.phone); + + // Ở đây bạn sẽ gọi Kafka để gửi SMS thực tế + System.out.println("OTP cho " + input.phone + " là: " + otp); + + return Response.accepted().build(); + } } diff --git a/account-service/src/main/resources/application.properties b/account-service/src/main/resources/application.properties index 857f702..07c1a35 100644 --- a/account-service/src/main/resources/application.properties +++ b/account-service/src/main/resources/application.properties @@ -7,7 +7,6 @@ quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/postgres quarkus.hibernate-orm.database.generation=update # Docker -## URL của Gitea Registry (thường là gitea.yourdomain.com) quarkus.container-image.registry=git.demonkernel.io.vn quarkus.container-image.group=foodsurf quarkus.container-image.name=account-service diff --git a/account-service/src/test/java/com/drinkool/services/AuthenticationServiceTest.java b/account-service/src/test/java/com/drinkool/services/AuthenticationServiceTest.java index f7d15f5..4925a41 100644 --- a/account-service/src/test/java/com/drinkool/services/AuthenticationServiceTest.java +++ b/account-service/src/test/java/com/drinkool/services/AuthenticationServiceTest.java @@ -3,6 +3,7 @@ package com.drinkool.services; import static io.restassured.RestAssured.given; import static org.junit.jupiter.api.Assertions.*; +import com.drinkool.Url; import com.drinkool.dtos.*; import com.drinkool.entities.CustomerEntity; import io.quarkus.test.junit.QuarkusTest; @@ -31,7 +32,7 @@ public class AuthenticationServiceTest { .contentType(ContentType.JSON) .body(input) .when() - .post("/api/signup") + .post(Url.Signup) .then() .statusCode(201); @@ -49,7 +50,7 @@ public class AuthenticationServiceTest { .contentType(ContentType.JSON) .body(input) .when() - .post("/api/quickSignup") + .post(Url.QuickSignup) .then() .statusCode(201); @@ -68,7 +69,7 @@ public class AuthenticationServiceTest { given() .contentType(ContentType.JSON) .body(signupData) - .post("/api/signup") + .post(Url.Signup) .then() .statusCode(201); @@ -81,7 +82,7 @@ public class AuthenticationServiceTest { .contentType(ContentType.JSON) .body(loginInput) .when() - .post("/api/login") + .post(Url.Login) .then() .statusCode(202); } @@ -97,7 +98,7 @@ public class AuthenticationServiceTest { given() .contentType(ContentType.JSON) .body(signupData) - .post("/api/signup") + .post(Url.Signup) .then() .statusCode(201); @@ -109,7 +110,7 @@ public class AuthenticationServiceTest { .contentType(ContentType.JSON) .body(loginInput) .when() - .post("/api/login") + .post(Url.Login) .then() .statusCode(400); // BadRequestException } @@ -124,7 +125,7 @@ public class AuthenticationServiceTest { .contentType(ContentType.JSON) .body(input) .when() - .post("/api/sms_otp") + .post(Url.SmsOtp) .then() .statusCode(202); @@ -143,7 +144,7 @@ public class AuthenticationServiceTest { .contentType(ContentType.JSON) .body(input) .when() - .post("/api/quicklogin") + .post(Url.QuickLogin) .then() .statusCode(401); } diff --git a/gateway-service/pom.xml b/gateway-service/pom.xml index 592580f..df5aec2 100644 --- a/gateway-service/pom.xml +++ b/gateway-service/pom.xml @@ -48,10 +48,6 @@ lib ${project.version} - - io.quarkus - quarkus-redis-client - io.quarkus quarkus-rest-jackson @@ -64,6 +60,10 @@ io.quarkus quarkus-rest + + io.quarkus + quarkus-container-image-docker + io.quarkus quarkus-rest-client-jackson diff --git a/gateway-service/src/main/java/com/drinkool/CustomerGatewayResource.java b/gateway-service/src/main/java/com/drinkool/CustomerGatewayResource.java index 3e9ad32..28ebcc0 100644 --- a/gateway-service/src/main/java/com/drinkool/CustomerGatewayResource.java +++ b/gateway-service/src/main/java/com/drinkool/CustomerGatewayResource.java @@ -2,7 +2,6 @@ package com.drinkool; import com.drinkool.dtos.*; import com.drinkool.services.AccountService; -import io.quarkus.redis.datasource.RedisDataSource; import io.smallrye.mutiny.Uni; import jakarta.inject.Inject; import jakarta.ws.rs.*; @@ -16,28 +15,14 @@ public class CustomerGatewayResource { @RestClient AccountService accountService; - @Inject - RedisDataSource redisDataSource; - @POST - @Path("/signup") + @Path(Url.Signup) public Uni proxySignup(Signup input) { - String otpVerifiedKey = "otp:verified:" + input.phone; - var valueCmd = redisDataSource.value(String.class); - - if (valueCmd.get(otpVerifiedKey) == null) { - return Uni.createFrom().item( - Response.status(Response.Status.FORBIDDEN) - .entity("Phone not verified") - .build() - ); - } - return accountService.signup(input); } @POST - @Path("/login") + @Path(Url.Login) public Uni proxyLogin(Login input) { return accountService.login(input); } diff --git a/gateway-service/src/main/java/com/drinkool/services/AccountService.java b/gateway-service/src/main/java/com/drinkool/services/AccountService.java index 79befad..b58b552 100644 --- a/gateway-service/src/main/java/com/drinkool/services/AccountService.java +++ b/gateway-service/src/main/java/com/drinkool/services/AccountService.java @@ -1,5 +1,6 @@ package com.drinkool.services; +import com.drinkool.Url; import com.drinkool.dtos.*; import io.smallrye.mutiny.Uni; import jakarta.ws.rs.*; @@ -7,17 +8,25 @@ import jakarta.ws.rs.core.Response; import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; @RegisterRestClient(configKey = "account") -@Path("/api") +@Path("") public interface AccountService { @POST - @Path("/signup") + @Path(Url.Signup) Uni signup(Signup input); @POST - @Path("/quickSignup") + @Path(Url.QuickSignup) Uni quickSignup(QuickSignup input); @POST - @Path("/login") + @Path(Url.Login) Uni login(Login input); + + @POST + @Path(Url.QuickLogin) + Uni quickLogin(QuickSignup input); + + @POST + @Path(Url.SmsOtp) + Uni smsOtp(SmsOtp input); } diff --git a/gateway-service/src/main/resources/application.properties b/gateway-service/src/main/resources/application.properties index 6993984..c52eb42 100644 --- a/gateway-service/src/main/resources/application.properties +++ b/gateway-service/src/main/resources/application.properties @@ -1 +1,7 @@ -quarkus.rest-client.account.url=http://localhost:502 \ No newline at end of file +# Docker +quarkus.container-image.registry=git.demonkernel.io.vn +quarkus.container-image.group=foodsurf +quarkus.container-image.name=gateway-service +quarkus.container-image.push=true +quarkus.container-image.build=true +quarkus.container-image.builder=docker diff --git a/k8s.yaml b/k8s.yaml new file mode 100644 index 0000000..4487135 --- /dev/null +++ b/k8s.yaml @@ -0,0 +1,116 @@ +# 1. ACCOUNT SERVICE +apiVersion: apps/v1 +kind: Deployment +metadata: + name: account-service +spec: + replicas: 1 + selector: + matchLabels: + app: account-service + template: + metadata: + labels: + app: account-service + spec: + containers: + - name: account-service + image: git.demonkernel.io.vn/foodsurf/account-service:latest + ports: + - containerPort: 8080 + env: + - name: QUARKUS_REDIS_HOST + value: "redis-service" +--- +apiVersion: v1 +kind: Service +metadata: + name: account-service +spec: + selector: + app: account-service + ports: + - port: 80 + targetPort: 8080 +--- +# 2. GATEWAY SERVICE +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gateway-deploy +spec: + replicas: 1 + selector: + matchLabels: + app: gateway + template: + metadata: + labels: + app: gateway + spec: + containers: + - name: gateway + image: git.demonkernel.io.vn/foodsurf/gateway-service:latest + ports: + - containerPort: 8080 + env: + - name: QUARKUS_REST_CLIENT_ACCOUNT_URL + value: "http://account-service" +--- +apiVersion: v1 +kind: Service +metadata: + name: gateway-service +spec: + type: NodePort + selector: + app: gateway + ports: + - port: 80 + targetPort: 8080 + nodePort: 39080 +--- +# 3. REDIS +apiVersion: apps/v1 +kind: Deployment +metadata: + name: redis-deploy +spec: + selector: + matchLabels: + app: redis + template: + metadata: + labels: + app: redis + spec: + containers: + - name: redis + image: redis:alpine + ports: + - containerPort: 6379 + resources: + limits: + cpu: "100m" + memory: "128Mi" + requests: + cpu: "20m" + memory: "64Mi" + command: + [ + "redis-server", + "--maxmemory", + "96mb", + "--maxmemory-policy", + "allkeys-lru", + ] +--- +apiVersion: v1 +kind: Service +metadata: + name: redis-service +spec: + selector: + app: redis + ports: + - port: 6379 diff --git a/lib/src/main/java/com/drinkool/Url.java b/lib/src/main/java/com/drinkool/Url.java new file mode 100644 index 0000000..9eb1de6 --- /dev/null +++ b/lib/src/main/java/com/drinkool/Url.java @@ -0,0 +1,10 @@ +package com.drinkool; + +public class Url { + + public static final String Signup = "/signup"; + public static final String QuickSignup = "/quick_signup"; + public static final String Login = "/login"; + public static final String QuickLogin = "/quick_login"; + public static final String SmsOtp = "/sms_otp"; +}