From a03676ce104f47132b6844bf87cf76ca95d65cc3 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Tue, 21 Oct 2025 18:21:42 -0500 Subject: [PATCH 01/67] Docker compose --- cloudBuilder.yml | 45 +++++++++++++++++++++++ compose.yml | 94 ++++++++++++++++++++++++++++++++++++++---------- core.yml | 37 +++++++++++++++++++ 3 files changed, 157 insertions(+), 19 deletions(-) create mode 100644 cloudBuilder.yml create mode 100644 core.yml diff --git a/cloudBuilder.yml b/cloudBuilder.yml new file mode 100644 index 000000000..13c3a8a04 --- /dev/null +++ b/cloudBuilder.yml @@ -0,0 +1,45 @@ +steps: + - name: 'gcr.io/cloud-builders/mvn' + args: ['clean', 'package', '-DskipTests'] + + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/api-gateway', './api-gateway'] + + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/cloud-config', './cloud-config'] + + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/service-discovery', './service-discovery'] + + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/proxy-client', './proxy-client'] + + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/user-service', './user-service'] + + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/product-service', './product-service'] + + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/order-service', './order-service'] + + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/payment-service', './payment-service'] + + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/favourite-service', './favourite-service'] + + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/shipping-service', './shipping-service'] + +images: + - 'gcr.io/$PROJECT_ID/api-gateway' + - 'gcr.io/$PROJECT_ID/cloud-config' + - 'gcr.io/$PROJECT_ID/service-discovery' + - 'gcr.io/$PROJECT_ID/proxy-client' + - 'gcr.io/$PROJECT_ID/user-service' + - 'gcr.io/$PROJECT_ID/product-service' + - 'gcr.io/$PROJECT_ID/order-service' + - 'gcr.io/$PROJECT_ID/payment-service' + - 'gcr.io/$PROJECT_ID/favourite-service' + - 'gcr.io/$PROJECT_ID/shipping-service' \ No newline at end of file diff --git a/compose.yml b/compose.yml index 2d6442c32..69da307d3 100644 --- a/compose.yml +++ b/compose.yml @@ -1,70 +1,126 @@ - version: '3' + services: - zipkin-container: - image: openzipkin/zipkin - ports: - - 9411:9411 - service-discovery-container: - image: selimhorri/service-discovery-ecommerce-boot:0.1.0 - ports: - - 8761:8761 - environment: - - SPRING_PROFILES_ACTIVE=dev - cloud-config-container: - image: selimhorri/cloud-config-ecommerce-boot:0.1.0 - ports: - - 9296:9296 - environment: - - SPRING_PROFILES_ACTIVE=dev api-gateway-container: image: selimhorri/api-gateway-ecommerce-boot:0.1.0 ports: - 8080:8080 + networks: + - microservices_network environment: - SPRING_PROFILES_ACTIVE=dev + - SPRING_ZIPKIN_BASE_URL=http://zipkin:9411 + - SPRING_CONFIG_IMPORT=optional:configserver:http://cloud-config-container:9296/ + - EUREKA_CLIENT_REGION=default + - EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT=myzone + - EUREKA_CLIENT_SERVICEURL_MYZONE=http://service-discovery-container:8761/eureka + - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=http://service-discovery-container:8761/eureka/ + proxy-client-container: image: selimhorri/proxy-client-ecommerce-boot:0.1.0 ports: - 8900:8900 + networks: + - microservices_network environment: - SPRING_PROFILES_ACTIVE=dev + - SPRING_ZIPKIN_BASE_URL=http://zipkin:9411 + - SPRING_CONFIG_IMPORT=optional:configserver:http://cloud-config-container:9296/ + - EUREKA_CLIENT_REGION=default + - EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT=myzone + - EUREKA_CLIENT_SERVICEURL_MYZONE=http://service-discovery-container:8761/eureka + - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=http://service-discovery-container:8761/eureka/ + order-service-container: image: selimhorri/order-service-ecommerce-boot:0.1.0 ports: - 8300:8300 + networks: + - microservices_network environment: - SPRING_PROFILES_ACTIVE=dev + - SPRING_ZIPKIN_BASE_URL=http://zipkin:9411 + - SPRING_CONFIG_IMPORT=optional:configserver:http://cloud-config-container:9296/ + - EUREKA_CLIENT_REGION=default + - EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT=myzone + - EUREKA_CLIENT_SERVICEURL_MYZONE=http://service-discovery-container:8761/eureka + - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=http://service-discovery-container:8761/eureka/ + payment-service-container: image: selimhorri/payment-service-ecommerce-boot:0.1.0 ports: - 8400:8400 + networks: + - microservices_network environment: - SPRING_PROFILES_ACTIVE=dev + - SPRING_ZIPKIN_BASE_URL=http://zipkin:9411 + - SPRING_CONFIG_IMPORT=optional:configserver:http://cloud-config-container:9296/ + - EUREKA_CLIENT_REGION=default + - EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT=myzone + - EUREKA_CLIENT_SERVICEURL_MYZONE=http://service-discovery-container:8761/eureka + - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=http://service-discovery-container:8761/eureka/ + product-service-container: image: selimhorri/product-service-ecommerce-boot:0.1.0 ports: - 8500:8500 + networks: + - microservices_network environment: - SPRING_PROFILES_ACTIVE=dev + - SPRING_ZIPKIN_BASE_URL=http://zipkin:9411 + - SPRING_CONFIG_IMPORT=optional:configserver:http://cloud-config-container:9296/ + - EUREKA_CLIENT_REGION=default + - EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT=myzone + - EUREKA_CLIENT_SERVICEURL_MYZONE=http://service-discovery-container:8761/eureka + - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=http://service-discovery-container:8761/eureka/ + shipping-service-container: image: selimhorri/shipping-service-ecommerce-boot:0.1.0 ports: - 8600:8600 + networks: + - microservices_network environment: - SPRING_PROFILES_ACTIVE=dev + - SPRING_ZIPKIN_BASE_URL=http://zipkin:9411 + - SPRING_CONFIG_IMPORT=optional:configserver:http://cloud-config-container:9296/ + - EUREKA_CLIENT_REGION=default + - EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT=myzone + - EUREKA_CLIENT_SERVICEURL_MYZONE=http://service-discovery-container:8761/eureka + - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=http://service-discovery-container:8761/eureka/ + user-service-container: image: selimhorri/user-service-ecommerce-boot:0.1.0 ports: - 8700:8700 + networks: + - microservices_network environment: - SPRING_PROFILES_ACTIVE=dev + - SPRING_ZIPKIN_BASE_URL=http://zipkin:9411 + - SPRING_CONFIG_IMPORT=optional:configserver:http://cloud-config-container:9296/ + - EUREKA_CLIENT_REGION=default + - EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT=myzone + - EUREKA_CLIENT_SERVICEURL_MYZONE=http://service-discovery-container:8761/eureka + - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=http://service-discovery-container:8761/eureka/ + favourite-service-container: image: selimhorri/favourite-service-ecommerce-boot:0.1.0 ports: - 8800:8800 + networks: + - microservices_network environment: - SPRING_PROFILES_ACTIVE=dev + - SPRING_ZIPKIN_BASE_URL=http://zipkin:9411 + - SPRING_CONFIG_IMPORT=optional:configserver:http://cloud-config-container:9296/ + - EUREKA_CLIENT_REGION=default + - EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT=myzone + - EUREKA_CLIENT_SERVICEURL_MYZONE=http://service-discovery-container:8761/eureka + - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=http://service-discovery-container:8761/eureka/ - - +networks: + microservices_network: + driver: bridge diff --git a/core.yml b/core.yml new file mode 100644 index 000000000..a1a792d2c --- /dev/null +++ b/core.yml @@ -0,0 +1,37 @@ +version: '3' + +services: + zipkin: + image: openzipkin/zipkin + ports: + - 9411:9411 + networks: + - microservices_network + + service-discovery-container: + image: selimhorri/service-discovery-ecommerce-boot:0.1.0 + ports: + - 8761:8761 + networks: + - microservices_network + environment: + - SPRING_ZIPKIN_BASE-URL=http://zipkin:9411 + - SPRING_CONFIG_IMPORT=optional:configserver:http://cloud-config-container:9296/ + + cloud-config-container: + image: selimhorri/cloud-config-ecommerce-boot:0.1.0 + ports: + - 9296:9296 + networks: + - microservices_network + environment: + - SPRING_PROFILES_ACTIVE=dev + - SPRING_ZIPKIN_BASE-URL=http://zipkin:9411 + - EUREKA_CLIENT_REGION=default + - EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT=myzone + - EUREKA_CLIENT_SERVICEURL_MYZONE=http://service-discovery-container:8761/eureka + - EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=http://service-discovery-container:8761/eureka/ + +networks: + microservices_network: + driver: bridge From c861b697d8feb3a3287e1cd316bd69158790942f Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Tue, 21 Oct 2025 18:35:45 -0500 Subject: [PATCH 02/67] Cambie los dockerfiles --- api-gateway/Dockerfile | 8 +++----- cloud-config/Dockerfile | 3 +-- favourite-service/Dockerfile | 3 +-- order-service/Dockerfile | 3 +-- payment-service/Dockerfile | 3 +-- product-service/Dockerfile | 3 +-- proxy-client/Dockerfile | 3 +-- service-discovery/Dockerfile | 3 +-- shipping-service/Dockerfile | 3 +-- user-service/Dockerfile | 3 +-- 10 files changed, 12 insertions(+), 23 deletions(-) diff --git a/api-gateway/Dockerfile b/api-gateway/Dockerfile index e0c700df9..5b9ec59f7 100644 --- a/api-gateway/Dockerfile +++ b/api-gateway/Dockerfile @@ -1,12 +1,10 @@ - FROM openjdk:11 ARG PROJECT_VERSION=0.1.0 RUN mkdir -p /home/app WORKDIR /home/app ENV SPRING_PROFILES_ACTIVE dev -COPY api-gateway/ . -ADD api-gateway/target/api-gateway-v${PROJECT_VERSION}.jar api-gateway.jar -EXPOSE 8080 -ENTRYPOINT ["java", "-Dspring.profiles.active=${SPRING_PROFILES_ACTIVE}", "-jar", "api-gateway.jar"] +COPY api-gateway/target/api-gateway-v${PROJECT_VERSION}.jar api-gateway.jar +EXPOSE 8080 +ENTRYPOINT ["java", "-Dspring.profiles.active=${SPRING_PROFILES_ACTIVE}", "-jar", "api-gateway.jar"] diff --git a/cloud-config/Dockerfile b/cloud-config/Dockerfile index cd5b044ee..fc2dda3fe 100644 --- a/cloud-config/Dockerfile +++ b/cloud-config/Dockerfile @@ -3,8 +3,7 @@ FROM openjdk:11 ARG PROJECT_VERSION=0.1.0 RUN mkdir -p /home/app WORKDIR /home/app -COPY cloud-config/ . -ADD cloud-config/target/cloud-config-v${PROJECT_VERSION}.jar cloud-config.jar +COPY cloud-config/target/cloud-config-v${PROJECT_VERSION}.jar cloud-config.jar EXPOSE 9296 ENTRYPOINT ["java", "-jar", "cloud-config.jar"] diff --git a/favourite-service/Dockerfile b/favourite-service/Dockerfile index 82ab593f6..83b4d4d06 100644 --- a/favourite-service/Dockerfile +++ b/favourite-service/Dockerfile @@ -4,8 +4,7 @@ ARG PROJECT_VERSION=0.1.0 RUN mkdir -p /home/app WORKDIR /home/app ENV SPRING_PROFILES_ACTIVE dev -COPY favourite-service/ . -ADD favourite-service/target/favourite-service-v${PROJECT_VERSION}.jar favourite-service.jar +COPY favourite-service/target/favourite-service-v${PROJECT_VERSION}.jar favourite-service.jar EXPOSE 8800 ENTRYPOINT ["java", "-Dspring.profiles.active=${SPRING_PROFILES_ACTIVE}", "-jar", "favourite-service.jar"] diff --git a/order-service/Dockerfile b/order-service/Dockerfile index b2b25a41a..ab93a8ec3 100644 --- a/order-service/Dockerfile +++ b/order-service/Dockerfile @@ -4,8 +4,7 @@ ARG PROJECT_VERSION=0.1.0 RUN mkdir -p /home/app WORKDIR /home/app ENV SPRING_PROFILES_ACTIVE dev -COPY order-service/ . -ADD order-service/target/order-service-v${PROJECT_VERSION}.jar order-service.jar +COPY order-service/target/order-service-v${PROJECT_VERSION}.jar order-service.jar EXPOSE 8300 ENTRYPOINT ["java", "-Dspring.profiles.active=${SPRING_PROFILES_ACTIVE}", "-jar", "order-service.jar"] diff --git a/payment-service/Dockerfile b/payment-service/Dockerfile index 57d5b931c..0d205a10a 100644 --- a/payment-service/Dockerfile +++ b/payment-service/Dockerfile @@ -4,8 +4,7 @@ ARG PROJECT_VERSION=0.1.0 RUN mkdir -p /home/app WORKDIR /home/app ENV SPRING_PROFILES_ACTIVE dev -COPY payment-service/ . -ADD payment-service/target/payment-service-v${PROJECT_VERSION}.jar payment-service.jar +COPY payment-service/target/payment-service-v${PROJECT_VERSION}.jar payment-service.jar EXPOSE 8400 ENTRYPOINT ["java", "-Dspring.profiles.active=${SPRING_PROFILES_ACTIVE}", "-jar", "payment-service.jar"] diff --git a/product-service/Dockerfile b/product-service/Dockerfile index c052995cf..2354ef177 100644 --- a/product-service/Dockerfile +++ b/product-service/Dockerfile @@ -4,8 +4,7 @@ ARG PROJECT_VERSION=0.1.0 RUN mkdir -p /home/app WORKDIR /home/app ENV SPRING_PROFILES_ACTIVE dev -COPY product-service/ . -ADD product-service/target/product-service-v${PROJECT_VERSION}.jar product-service.jar +COPY product-service/target/product-service-v${PROJECT_VERSION}.jar product-service.jar EXPOSE 8500 ENTRYPOINT ["java", "-Dspring.profiles.active=${SPRING_PROFILES_ACTIVE}", "-jar", "product-service.jar"] diff --git a/proxy-client/Dockerfile b/proxy-client/Dockerfile index deac97bb7..7afeaa678 100644 --- a/proxy-client/Dockerfile +++ b/proxy-client/Dockerfile @@ -4,8 +4,7 @@ ARG PROJECT_VERSION=0.1.0 RUN mkdir -p /home/app WORKDIR /home/app ENV SPRING_PROFILES_ACTIVE dev -COPY proxy-client/ . -ADD proxy-client/target/proxy-client-v${PROJECT_VERSION}.jar proxy-client.jar +COPY proxy-client/target/proxy-client-v${PROJECT_VERSION}.jar proxy-client.jar EXPOSE 8900 ENTRYPOINT ["java", "-Dspring.profiles.active=${SPRING_PROFILES_ACTIVE}", "-jar", "proxy-client.jar"] diff --git a/service-discovery/Dockerfile b/service-discovery/Dockerfile index 7562e96fa..eb656d0b7 100644 --- a/service-discovery/Dockerfile +++ b/service-discovery/Dockerfile @@ -4,8 +4,7 @@ ARG PROJECT_VERSION=0.1.0 RUN mkdir -p /home/app WORKDIR /home/app ENV SPRING_PROFILES_ACTIVE dev -COPY service-discovery/ . -ADD service-discovery/target/service-discovery-v${PROJECT_VERSION}.jar service-discovery.jar +COPY service-discovery/target/service-discovery-v${PROJECT_VERSION}.jar service-discovery.jar EXPOSE 8761 ENTRYPOINT ["java", "-Dspring.profiles.active=${SPRING_PROFILES_ACTIVE}", "-jar", "service-discovery.jar"] diff --git a/shipping-service/Dockerfile b/shipping-service/Dockerfile index c678aef31..863dce99a 100644 --- a/shipping-service/Dockerfile +++ b/shipping-service/Dockerfile @@ -4,8 +4,7 @@ ARG PROJECT_VERSION=0.1.0 RUN mkdir -p /home/app WORKDIR /home/app ENV SPRING_PROFILES_ACTIVE dev -COPY shipping-service/ . -ADD shipping-service/target/shipping-service-v${PROJECT_VERSION}.jar shipping-service.jar +COPY shipping-service/target/shipping-service-v${PROJECT_VERSION}.jar shipping-service.jar EXPOSE 8600 ENTRYPOINT ["java", "-Dspring.profiles.active=${SPRING_PROFILES_ACTIVE}", "-jar", "shipping-service.jar"] diff --git a/user-service/Dockerfile b/user-service/Dockerfile index fdc109e11..e14316384 100644 --- a/user-service/Dockerfile +++ b/user-service/Dockerfile @@ -4,8 +4,7 @@ ARG PROJECT_VERSION=0.1.0 RUN mkdir -p /home/app WORKDIR /home/app ENV SPRING_PROFILES_ACTIVE dev -COPY user-service/ . -ADD user-service/target/user-service-v${PROJECT_VERSION}.jar user-service.jar +COPY user-service/target/user-service-v${PROJECT_VERSION}.jar user-service.jar EXPOSE 8700 ENTRYPOINT ["java", "-Dspring.profiles.active=${SPRING_PROFILES_ACTIVE}", "-jar", "user-service.jar"] From 0c429a35d292ed8cf55472f83e387c6408ea1ecd Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Tue, 21 Oct 2025 18:49:11 -0500 Subject: [PATCH 03/67] correcion --- cloudBuilder.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/cloudBuilder.yml b/cloudBuilder.yml index 13c3a8a04..02b9482e4 100644 --- a/cloudBuilder.yml +++ b/cloudBuilder.yml @@ -3,34 +3,34 @@ steps: args: ['clean', 'package', '-DskipTests'] - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'gcr.io/$PROJECT_ID/api-gateway', './api-gateway'] + args: ['build', '-t', 'gcr.io/$PROJECT_ID/api-gateway', '-f', 'api-gateway/Dockerfile', '.'] - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'gcr.io/$PROJECT_ID/cloud-config', './cloud-config'] + args: ['build', '-t', 'gcr.io/$PROJECT_ID/cloud-config', '-f', 'cloud-config/Dockerfile', '.'] - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'gcr.io/$PROJECT_ID/service-discovery', './service-discovery'] + args: ['build', '-t', 'gcr.io/$PROJECT_ID/service-discovery', '-f', 'service-discovery/Dockerfile', '.'] - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'gcr.io/$PROJECT_ID/proxy-client', './proxy-client'] + args: ['build', '-t', 'gcr.io/$PROJECT_ID/proxy-client', '-f', 'proxy-client/Dockerfile', '.'] - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'gcr.io/$PROJECT_ID/user-service', './user-service'] + args: ['build', '-t', 'gcr.io/$PROJECT_ID/user-service', '-f', 'user-service/Dockerfile', '.'] - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'gcr.io/$PROJECT_ID/product-service', './product-service'] + args: ['build', '-t', 'gcr.io/$PROJECT_ID/product-service', '-f', 'product-service/Dockerfile', '.'] - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'gcr.io/$PROJECT_ID/order-service', './order-service'] + args: ['build', '-t', 'gcr.io/$PROJECT_ID/order-service', '-f', 'order-service/Dockerfile', '.'] - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'gcr.io/$PROJECT_ID/payment-service', './payment-service'] + args: ['build', '-t', 'gcr.io/$PROJECT_ID/payment-service', '-f', 'payment-service/Dockerfile', '.'] - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'gcr.io/$PROJECT_ID/favourite-service', './favourite-service'] + args: ['build', '-t', 'gcr.io/$PROJECT_ID/favourite-service', '-f', 'favourite-service/Dockerfile', '.'] - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'gcr.io/$PROJECT_ID/shipping-service', './shipping-service'] + args: ['build', '-t', 'gcr.io/$PROJECT_ID/shipping-service', '-f', 'shipping-service/Dockerfile', '.'] images: - 'gcr.io/$PROJECT_ID/api-gateway' @@ -42,4 +42,4 @@ images: - 'gcr.io/$PROJECT_ID/order-service' - 'gcr.io/$PROJECT_ID/payment-service' - 'gcr.io/$PROJECT_ID/favourite-service' - - 'gcr.io/$PROJECT_ID/shipping-service' \ No newline at end of file + - 'gcr.io/$PROJECT_ID/shipping-service' From 8f7b70ebff47101c417d175bdf56346fc2c8984d Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Sat, 25 Oct 2025 16:47:41 -0500 Subject: [PATCH 04/67] Adding some new pipelines --- cloudBuilder.yml => pipelines/Deploy/cloudBuilder.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename cloudBuilder.yml => pipelines/Deploy/cloudBuilder.yml (100%) diff --git a/cloudBuilder.yml b/pipelines/Deploy/cloudBuilder.yml similarity index 100% rename from cloudBuilder.yml rename to pipelines/Deploy/cloudBuilder.yml From 2841cf2f8217661d8e9ee9889780c09ce4bd4ba5 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Sat, 25 Oct 2025 16:50:52 -0500 Subject: [PATCH 05/67] Testing pipiline --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1d4a67936..a22d571f4 100644 --- a/README.md +++ b/README.md @@ -619,3 +619,4 @@ If you would like to enhance, please: - Finally, give it a 馃専. *Happy Coding ...* 馃檪 +*what* From 6142324f3fe4439efe79e32f2951faf7a2f030f1 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Sat, 25 Oct 2025 16:53:59 -0500 Subject: [PATCH 06/67] Testing pipiline --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a22d571f4..1683811ba 100644 --- a/README.md +++ b/README.md @@ -619,4 +619,4 @@ If you would like to enhance, please: - Finally, give it a 馃専. *Happy Coding ...* 馃檪 -*what* +*whathe* From 62f9744180c1647b69447ddb483a28f172879637 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Sat, 25 Oct 2025 16:57:41 -0500 Subject: [PATCH 07/67] Adding dev pipeline --- pipelines/build-dev/buildDev.yml | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 pipelines/build-dev/buildDev.yml diff --git a/pipelines/build-dev/buildDev.yml b/pipelines/build-dev/buildDev.yml new file mode 100644 index 000000000..b779601b9 --- /dev/null +++ b/pipelines/build-dev/buildDev.yml @@ -0,0 +1,33 @@ +steps: + - name: 'gcr.io/cloud-builders/mvn' + args: ['clean', 'package', '-DskipTests'] + + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/api-gateway', '-f', 'api-gateway/Dockerfile', '.'] + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/cloud-config', '-f', 'cloud-config/Dockerfile', '.'] + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/service-discovery', '-f', 'service-discovery/Dockerfile', '.'] + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/proxy-client', '-f', 'proxy-client/Dockerfile', '.'] + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/user-service', '-f', 'user-service/Dockerfile', '.'] + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/product-service', '-f', 'product-service/Dockerfile', '.'] + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/order-service', '-f', 'order-service/Dockerfile', '.'] + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/payment-service', '-f', 'payment-service/Dockerfile', '.'] + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/favourite-service', '-f', 'favourite-service/Dockerfile', '.'] + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/shipping-service', '-f', 'shipping-service/Dockerfile', '.'] + + - name: 'docker/compose:1.29.2' + args: ['-f', 'core.yml', 'up', '-d'] + + - name: 'gcr.io/cloud-builders/bash' + args: ['-c', 'echo "Esperando 40 segundos antes de levantar los dem谩s servicios..." && sleep 40'] + + - name: 'docker/compose:1.29.2' + args: ['-f', 'compose.yml', 'up', '-d'] \ No newline at end of file From 1fcdbcfd08a7078f59b65ef18953fe44176bce11 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Sat, 25 Oct 2025 17:02:48 -0500 Subject: [PATCH 08/67] Some correction to pipeline --- pipelines/build-dev/buildDev.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pipelines/build-dev/buildDev.yml b/pipelines/build-dev/buildDev.yml index b779601b9..1aab4e3e0 100644 --- a/pipelines/build-dev/buildDev.yml +++ b/pipelines/build-dev/buildDev.yml @@ -23,6 +23,7 @@ steps: - name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', 'gcr.io/$PROJECT_ID/shipping-service', '-f', 'shipping-service/Dockerfile', '.'] + # Levantar los servicios del core primero - name: 'docker/compose:1.29.2' args: ['-f', 'core.yml', 'up', '-d'] @@ -30,4 +31,7 @@ steps: args: ['-c', 'echo "Esperando 40 segundos antes de levantar los dem谩s servicios..." && sleep 40'] - name: 'docker/compose:1.29.2' - args: ['-f', 'compose.yml', 'up', '-d'] \ No newline at end of file + args: ['-f', 'compose.yml', 'up', '-d'] + +options: + logging: CLOUD_LOGGING_ONLY From 0227a87575be022a82eff9d78fadfbbcd3d282fa Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Sat, 25 Oct 2025 17:11:04 -0500 Subject: [PATCH 09/67] Some correction to pipiline google bash --- pipelines/build-dev/buildDev.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pipelines/build-dev/buildDev.yml b/pipelines/build-dev/buildDev.yml index 1aab4e3e0..68ccadb17 100644 --- a/pipelines/build-dev/buildDev.yml +++ b/pipelines/build-dev/buildDev.yml @@ -23,11 +23,11 @@ steps: - name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', 'gcr.io/$PROJECT_ID/shipping-service', '-f', 'shipping-service/Dockerfile', '.'] - # Levantar los servicios del core primero - name: 'docker/compose:1.29.2' args: ['-f', 'core.yml', 'up', '-d'] - - name: 'gcr.io/cloud-builders/bash' + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + entrypoint: 'bash' args: ['-c', 'echo "Esperando 40 segundos antes de levantar los dem谩s servicios..." && sleep 40'] - name: 'docker/compose:1.29.2' From 9beed1ec7dd8253db3e726f8a1c195579eb76185 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Sat, 25 Oct 2025 18:32:48 -0500 Subject: [PATCH 10/67] tests: New unit tests in user-service --- .../user/controller/UserControllerTest.java | 97 +++++++++++++++++++ .../selimhorri/app/UserControllerTest.java | 11 +++ 2 files changed, 108 insertions(+) create mode 100644 proxy-client/src/test/java/com/selimhorri/app/business/user/controller/UserControllerTest.java create mode 100644 user-service/src/test/java/com/selimhorri/app/UserControllerTest.java diff --git a/proxy-client/src/test/java/com/selimhorri/app/business/user/controller/UserControllerTest.java b/proxy-client/src/test/java/com/selimhorri/app/business/user/controller/UserControllerTest.java new file mode 100644 index 000000000..f14b59337 --- /dev/null +++ b/proxy-client/src/test/java/com/selimhorri/app/business/user/controller/UserControllerTest.java @@ -0,0 +1,97 @@ +package com.selimhorri.app.business.user.controller; + +import com.selimhorri.app.business.user.model.response.UserUserServiceCollectionDtoResponse; +import com.selimhorri.app.business.user.service.UserClientService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.http.ResponseEntity; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.*; + + +class UserControllerTest { + + @Mock + private UserClientService userClientService; + + @InjectMocks + private UserController userController; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + } + + @Test + void testFindAll() { + com.selimhorri.app.business.user.model.UserDto user = com.selimhorri.app.business.user.model.UserDto.builder() + .userId(1) + .firstName("juan") + .lastName("perez") + .email("juan@mail.com") + .build(); + UserUserServiceCollectionDtoResponse mockResponse = new UserUserServiceCollectionDtoResponse(List.of(user)); + + when(userClientService.findAll()).thenReturn(ResponseEntity.ok(mockResponse)); + + var result = userController.findAll(); + assertThat(result.getBody().getCollection()).hasSize(1); + } + + @Test + void testFindById() { + com.selimhorri.app.business.user.model.UserDto mockUser = com.selimhorri.app.business.user.model.UserDto.builder() + .userId(1) + .firstName("juan") + .email("juan@mail.com") + .build(); + when(userClientService.findById("1")).thenReturn(ResponseEntity.ok(mockUser)); + + var result = userController.findById("1"); + assertThat(result.getBody().getFirstName()).isEqualTo("juan"); + } + + @Test + void testFindByUsername() { + com.selimhorri.app.business.user.model.UserDto mockUser = com.selimhorri.app.business.user.model.UserDto.builder() + .userId(2) + .firstName("carlos") + .email("carlos@mail.com") + .build(); + when(userClientService.findByUsername("carlos")).thenReturn(ResponseEntity.ok(mockUser)); + + var result = userController.findByUsername("carlos"); + assertThat(result.getBody().getEmail()).isEqualTo("carlos@mail.com"); + } + + @Test + void testSaveUser() { + com.selimhorri.app.business.user.model.UserDto input = com.selimhorri.app.business.user.model.UserDto.builder() + .firstName("maria") + .email("maria@mail.com") + .build(); + com.selimhorri.app.business.user.model.UserDto saved = com.selimhorri.app.business.user.model.UserDto.builder() + .userId(10) + .firstName("maria") + .email("maria@mail.com") + .build(); + when(userClientService.save(input)).thenReturn(ResponseEntity.ok(saved)); + + var result = userController.save(input); + assertThat(result.getBody().getUserId()).isEqualTo(10); + } + + @Test + void testDeleteUser() { + when(userClientService.deleteById("99")).thenReturn(ResponseEntity.ok(true)); + + var result = userController.deleteById("99"); + assertThat(result.getBody()).isTrue(); + } +} diff --git a/user-service/src/test/java/com/selimhorri/app/UserControllerTest.java b/user-service/src/test/java/com/selimhorri/app/UserControllerTest.java new file mode 100644 index 000000000..80ac44dbe --- /dev/null +++ b/user-service/src/test/java/com/selimhorri/app/UserControllerTest.java @@ -0,0 +1,11 @@ +package com.selimhorri.app; + +import org.junit.jupiter.api.Test; + +class UserControllerTest { + + @Test + void placeholderTest() { + // This test file was misplaced in user-service; actual controller tests live in the proxy-client module. + } +} From 6095a783d90c154c21b9da8b0584cc2234c09d10 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Sat, 25 Oct 2025 18:47:45 -0500 Subject: [PATCH 11/67] tests: Adding some verifications to tests --- .../user/controller/UserControllerTest.java | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/proxy-client/src/test/java/com/selimhorri/app/business/user/controller/UserControllerTest.java b/proxy-client/src/test/java/com/selimhorri/app/business/user/controller/UserControllerTest.java index f14b59337..1639c66db 100644 --- a/proxy-client/src/test/java/com/selimhorri/app/business/user/controller/UserControllerTest.java +++ b/proxy-client/src/test/java/com/selimhorri/app/business/user/controller/UserControllerTest.java @@ -25,12 +25,14 @@ class UserControllerTest { @BeforeEach void setUp() { + System.out.println("[TEST] Setting up UserControllerTest"); MockitoAnnotations.openMocks(this); } @Test void testFindAll() { - com.selimhorri.app.business.user.model.UserDto user = com.selimhorri.app.business.user.model.UserDto.builder() + System.out.println("[TEST] testFindAll - start"); + com.selimhorri.app.business.user.model.UserDto user = com.selimhorri.app.business.user.model.UserDto.builder() .userId(1) .firstName("juan") .lastName("perez") @@ -41,11 +43,14 @@ void testFindAll() { when(userClientService.findAll()).thenReturn(ResponseEntity.ok(mockResponse)); var result = userController.findAll(); + System.out.println("[TEST] testFindAll - result collection size: " + result.getBody().getCollection().size()); assertThat(result.getBody().getCollection()).hasSize(1); + System.out.println("[TEST] testFindAll - end"); } @Test void testFindById() { + System.out.println("[TEST] testFindById - start"); com.selimhorri.app.business.user.model.UserDto mockUser = com.selimhorri.app.business.user.model.UserDto.builder() .userId(1) .firstName("juan") @@ -54,11 +59,14 @@ void testFindById() { when(userClientService.findById("1")).thenReturn(ResponseEntity.ok(mockUser)); var result = userController.findById("1"); + System.out.println("[TEST] testFindById - returned firstName: " + result.getBody().getFirstName()); assertThat(result.getBody().getFirstName()).isEqualTo("juan"); + System.out.println("[TEST] testFindById - end"); } @Test void testFindByUsername() { + System.out.println("[TEST] testFindByUsername - start"); com.selimhorri.app.business.user.model.UserDto mockUser = com.selimhorri.app.business.user.model.UserDto.builder() .userId(2) .firstName("carlos") @@ -67,12 +75,15 @@ void testFindByUsername() { when(userClientService.findByUsername("carlos")).thenReturn(ResponseEntity.ok(mockUser)); var result = userController.findByUsername("carlos"); + System.out.println("[TEST] testFindByUsername - returned email: " + result.getBody().getEmail()); assertThat(result.getBody().getEmail()).isEqualTo("carlos@mail.com"); + System.out.println("[TEST] testFindByUsername - end"); } @Test void testSaveUser() { - com.selimhorri.app.business.user.model.UserDto input = com.selimhorri.app.business.user.model.UserDto.builder() + System.out.println("[TEST] testSaveUser - start"); + com.selimhorri.app.business.user.model.UserDto input = com.selimhorri.app.business.user.model.UserDto.builder() .firstName("maria") .email("maria@mail.com") .build(); @@ -84,14 +95,19 @@ void testSaveUser() { when(userClientService.save(input)).thenReturn(ResponseEntity.ok(saved)); var result = userController.save(input); - assertThat(result.getBody().getUserId()).isEqualTo(10); + System.out.println("[TEST] testSaveUser - returned userId: " + result.getBody().getUserId()); + assertThat(result.getBody().getUserId()).isEqualTo(10); + System.out.println("[TEST] testSaveUser - end"); } @Test void testDeleteUser() { + System.out.println("[TEST] testDeleteUser - start"); when(userClientService.deleteById("99")).thenReturn(ResponseEntity.ok(true)); var result = userController.deleteById("99"); + System.out.println("[TEST] testDeleteUser - returned: " + result.getBody()); assertThat(result.getBody()).isTrue(); + System.out.println("[TEST] testDeleteUser - end"); } } From 262c3880590f099c8c00c6fb26ade8a9dde0300e Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Sat, 25 Oct 2025 19:20:16 -0500 Subject: [PATCH 12/67] test: Initial integration tests --- .../UserControllerIntegrationTest.java | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 proxy-client/src/test/java/com/selimhorri/app/business/user/controller/UserControllerIntegrationTest.java diff --git a/proxy-client/src/test/java/com/selimhorri/app/business/user/controller/UserControllerIntegrationTest.java b/proxy-client/src/test/java/com/selimhorri/app/business/user/controller/UserControllerIntegrationTest.java new file mode 100644 index 000000000..b4df57ded --- /dev/null +++ b/proxy-client/src/test/java/com/selimhorri/app/business/user/controller/UserControllerIntegrationTest.java @@ -0,0 +1,110 @@ +package com.selimhorri.app.business.user.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.selimhorri.app.business.user.model.UserDto; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@AutoConfigureMockMvc +class UserControllerIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + + @Test + void testFindAllIntegration() throws Exception { + System.out.println("[INTEGRATION TEST] testFindAllIntegration - start"); + + MvcResult result = mockMvc.perform(get("/api/users")) + .andExpect(status().isOk()) + .andReturn(); + + String content = result.getResponse().getContentAsString(); + System.out.println("[INTEGRATION TEST] testFindAllIntegration - response: " + content); + + System.out.println("[INTEGRATION TEST] testFindAllIntegration - end"); + } + + + @Test + void testFindByIdIntegration() throws Exception { + System.out.println("[INTEGRATION TEST] testFindByIdIntegration - start"); + + MvcResult result = mockMvc.perform(get("/api/users/{id}", 1)) + .andExpect(status().isOk()) + .andReturn(); + + String content = result.getResponse().getContentAsString(); + System.out.println("[INTEGRATION TEST] testFindByIdIntegration - response: " + content); + + System.out.println("[INTEGRATION TEST] testFindByIdIntegration - end"); + } + + @Test + void testFindByUsernameIntegration() throws Exception { + System.out.println("[INTEGRATION TEST] testFindByUsernameIntegration - start"); + + MvcResult result = mockMvc.perform(get("/api/users/username/{username}", "juan")) + .andExpect(status().isOk()) + .andReturn(); + + String content = result.getResponse().getContentAsString(); + System.out.println("[INTEGRATION TEST] testFindByUsernameIntegration - response: " + content); + + System.out.println("[INTEGRATION TEST] testFindByUsernameIntegration - end"); + } + + + @Test + void testSaveUserIntegration() throws Exception { + System.out.println("[INTEGRATION TEST] testSaveUserIntegration - start"); + + UserDto newUser = UserDto.builder() + .firstName("Maria") + .lastName("Lopez") + .email("maria@mail.com") + .build(); + + String requestJson = objectMapper.writeValueAsString(newUser); + System.out.println("[INTEGRATION TEST] testSaveUserIntegration - request JSON: " + requestJson); + + MvcResult result = mockMvc.perform(post("/api/users") + .contentType(MediaType.APPLICATION_JSON) + .content(requestJson)) + .andExpect(status().isOk()) + .andReturn(); + + String content = result.getResponse().getContentAsString(); + System.out.println("[INTEGRATION TEST] testSaveUserIntegration - response: " + content); + + System.out.println("[INTEGRATION TEST] testSaveUserIntegration - end"); + } + + + @Test + void testDeleteUserIntegration() throws Exception { + System.out.println("[INTEGRATION TEST] testDeleteUserIntegration - start"); + + MvcResult result = mockMvc.perform(delete("/api/users/{id}", 5)) + .andExpect(status().isOk()) + .andReturn(); + + String content = result.getResponse().getContentAsString(); + System.out.println("[INTEGRATION TEST] testDeleteUserIntegration - response: " + content); + + System.out.println("[INTEGRATION TEST] testDeleteUserIntegration - end"); + } +} From 2651fa822d89aa90f5c3fbd49308f8875b174075 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Sun, 26 Oct 2025 16:34:02 -0500 Subject: [PATCH 13/67] test: adding integration tests --- favourite-service/pom.xml | 5 + .../FavouriteResourceIntegrationTest.java | 181 ++++++++++++++++++ .../UserControllerIntegrationTest.java | 110 ----------- 3 files changed, 186 insertions(+), 110 deletions(-) create mode 100644 favourite-service/src/test/java/com/selimhorri/app/resource/FavouriteResourceIntegrationTest.java delete mode 100644 proxy-client/src/test/java/com/selimhorri/app/business/user/controller/UserControllerIntegrationTest.java diff --git a/favourite-service/pom.xml b/favourite-service/pom.xml index c30204d36..8904a481d 100644 --- a/favourite-service/pom.xml +++ b/favourite-service/pom.xml @@ -73,6 +73,11 @@ mysql test + + org.springframework.boot + spring-boot-starter-test + test + diff --git a/favourite-service/src/test/java/com/selimhorri/app/resource/FavouriteResourceIntegrationTest.java b/favourite-service/src/test/java/com/selimhorri/app/resource/FavouriteResourceIntegrationTest.java new file mode 100644 index 000000000..5f06a73b3 --- /dev/null +++ b/favourite-service/src/test/java/com/selimhorri/app/resource/FavouriteResourceIntegrationTest.java @@ -0,0 +1,181 @@ +package com.selimhorri.app.resource; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.web.client.MockRestServiceServer; +import org.springframework.web.client.RestTemplate; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.selimhorri.app.constant.AppConstant; +import com.selimhorri.app.domain.id.FavouriteId; +import com.selimhorri.app.dto.FavouriteDto; +import com.selimhorri.app.dto.ProductDto; +import com.selimhorri.app.dto.UserDto; +import com.selimhorri.app.repository.FavouriteRepository; + +import org.springframework.test.web.client.ExpectedCount; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; +import org.springframework.http.MediaType; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +class FavouriteResourceIntegrationTest { + + @Autowired + private TestRestTemplate restTemplate; + + @Autowired + private RestTemplate clientRestTemplate; + + @Autowired + private FavouriteRepository favouriteRepository; + + private MockRestServiceServer mockServer; + + private final ObjectMapper mapper = new ObjectMapper(); + + private final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(AppConstant.LOCAL_DATE_TIME_FORMAT); + + @BeforeEach + void setUp() { + this.favouriteRepository.deleteAll(); + this.mockServer = MockRestServiceServer.createServer(this.clientRestTemplate); + } + + private FavouriteDto buildDto(int userId, int productId) { + return FavouriteDto.builder() + .userId(userId) + .productId(productId) + .likeDate(LocalDateTime.now()) + .build(); + } + + private String userJson(int id) throws Exception { + return mapper.writeValueAsString( + UserDto.builder() + .userId(id) + .firstName("User" + id) + .lastName("Test") + .email("user" + id + "@example.com") + .build()); + } + + private String productJson(int id) throws Exception { + return mapper.writeValueAsString( + ProductDto.builder() + .productId(id) + .productTitle("Product" + id) + .priceUnit(9.99) + .build()); + } + + @Test + void saveAndFindById_with_request_body_and_external_calls() throws Exception { + FavouriteDto dto = buildDto(1, 10); + + ResponseEntity postRes = restTemplate.postForEntity("/api/favourites", dto, FavouriteDto.class); + assertThat(postRes.getStatusCode()).isEqualTo(HttpStatus.OK); + + this.mockServer.expect(ExpectedCount.once(), requestTo(AppConstant.DiscoveredDomainsApi.USER_SERVICE_API_URL + "/" + dto.getUserId())) + .andRespond(withSuccess(userJson(dto.getUserId()), MediaType.APPLICATION_JSON)); + + this.mockServer.expect(ExpectedCount.once(), requestTo(AppConstant.DiscoveredDomainsApi.PRODUCT_SERVICE_API_URL + "/" + dto.getProductId())) + .andRespond(withSuccess(productJson(dto.getProductId()), MediaType.APPLICATION_JSON)); + + FavouriteId id = new FavouriteId(dto.getUserId(), dto.getProductId(), dto.getLikeDate()); + ResponseEntity getRes = restTemplate.postForEntity("/api/favourites/find", id, FavouriteDto.class); + assertThat(getRes.getStatusCode()).isEqualTo(HttpStatus.OK); + FavouriteDto found = getRes.getBody(); + assertThat(found).isNotNull(); + assertThat(found.getUserDto()).isNotNull(); + assertThat(found.getProductDto()).isNotNull(); + + this.mockServer.verify(); + } + + @Test + void findAll_returns_collection_and_resolves_external_apis() throws Exception { + FavouriteDto a = buildDto(2, 20); + FavouriteDto b = buildDto(3, 30); + restTemplate.postForEntity("/api/favourites", a, FavouriteDto.class); + restTemplate.postForEntity("/api/favourites", b, FavouriteDto.class); + + this.mockServer.expect(ExpectedCount.manyTimes(), requestTo(org.hamcrest.Matchers.startsWith(AppConstant.DiscoveredDomainsApi.USER_SERVICE_API_URL))) + .andRespond(withSuccess(userJson(2), MediaType.APPLICATION_JSON)); + this.mockServer.expect(ExpectedCount.manyTimes(), requestTo(org.hamcrest.Matchers.startsWith(AppConstant.DiscoveredDomainsApi.PRODUCT_SERVICE_API_URL))) + .andRespond(withSuccess(productJson(20), MediaType.APPLICATION_JSON)); + + ResponseEntity res = restTemplate.getForEntity("/api/favourites", String.class); + assertThat(res.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(res.getBody()).contains("user", "product"); + + this.mockServer.verify(); + } + + @Test + void update_existing_favourite() { + FavouriteDto dto = buildDto(4, 40); + restTemplate.postForEntity("/api/favourites", dto, FavouriteDto.class); + + HttpEntity request = new HttpEntity<>(dto); + ResponseEntity putRes = restTemplate.exchange("/api/favourites", HttpMethod.PUT, request, FavouriteDto.class); + assertThat(putRes.getStatusCode()).isEqualTo(HttpStatus.OK); + + + FavouriteId id = new FavouriteId(dto.getUserId(), dto.getProductId(), dto.getLikeDate()); + ResponseEntity getRes = restTemplate.postForEntity("/api/favourites/find", id, FavouriteDto.class); + assertThat(getRes.getStatusCode()).isEqualTo(HttpStatus.OK); + } + + @Test + void deleteById_and_then_not_found() { + FavouriteDto dto = buildDto(5, 50); + restTemplate.postForEntity("/api/favourites", dto, FavouriteDto.class); + + String likeDate = dto.getLikeDate().format(fmt); + ResponseEntity delRes = restTemplate.exchange( + "/api/favourites/" + dto.getUserId() + "/" + dto.getProductId() + "/" + likeDate, + HttpMethod.DELETE, null, Boolean.class); + assertThat(delRes.getStatusCode()).isEqualTo(HttpStatus.OK); + + FavouriteId id = new FavouriteId(dto.getUserId(), dto.getProductId(), dto.getLikeDate()); + ResponseEntity getRes = restTemplate.postForEntity("/api/favourites/find", id, String.class); + assertThat(getRes.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + } + + @Test + void findById_path_variables() throws Exception { + FavouriteDto dto = buildDto(6, 60); + restTemplate.postForEntity("/api/favourites", dto, FavouriteDto.class); + + this.mockServer.expect(ExpectedCount.once(), requestTo(AppConstant.DiscoveredDomainsApi.USER_SERVICE_API_URL + "/" + dto.getUserId())) + .andRespond(withSuccess(userJson(dto.getUserId()), MediaType.APPLICATION_JSON)); + this.mockServer.expect(ExpectedCount.once(), requestTo(AppConstant.DiscoveredDomainsApi.PRODUCT_SERVICE_API_URL + "/" + dto.getProductId())) + .andRespond(withSuccess(productJson(dto.getProductId()), MediaType.APPLICATION_JSON)); + + String likeDate = dto.getLikeDate().format(fmt); + ResponseEntity getRes = restTemplate.getForEntity( + "/api/favourites/" + dto.getUserId() + "/" + dto.getProductId() + "/" + likeDate, + FavouriteDto.class); + assertThat(getRes.getStatusCode()).isEqualTo(HttpStatus.OK); + FavouriteDto found = getRes.getBody(); + assertThat(found).isNotNull(); + assertThat(found.getUserDto()).isNotNull(); + assertThat(found.getProductDto()).isNotNull(); + + this.mockServer.verify(); + } + +} diff --git a/proxy-client/src/test/java/com/selimhorri/app/business/user/controller/UserControllerIntegrationTest.java b/proxy-client/src/test/java/com/selimhorri/app/business/user/controller/UserControllerIntegrationTest.java deleted file mode 100644 index b4df57ded..000000000 --- a/proxy-client/src/test/java/com/selimhorri/app/business/user/controller/UserControllerIntegrationTest.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.selimhorri.app.business.user.controller; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.selimhorri.app.business.user.model.UserDto; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.MvcResult; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@AutoConfigureMockMvc -class UserControllerIntegrationTest { - - @Autowired - private MockMvc mockMvc; - - @Autowired - private ObjectMapper objectMapper; - - - @Test - void testFindAllIntegration() throws Exception { - System.out.println("[INTEGRATION TEST] testFindAllIntegration - start"); - - MvcResult result = mockMvc.perform(get("/api/users")) - .andExpect(status().isOk()) - .andReturn(); - - String content = result.getResponse().getContentAsString(); - System.out.println("[INTEGRATION TEST] testFindAllIntegration - response: " + content); - - System.out.println("[INTEGRATION TEST] testFindAllIntegration - end"); - } - - - @Test - void testFindByIdIntegration() throws Exception { - System.out.println("[INTEGRATION TEST] testFindByIdIntegration - start"); - - MvcResult result = mockMvc.perform(get("/api/users/{id}", 1)) - .andExpect(status().isOk()) - .andReturn(); - - String content = result.getResponse().getContentAsString(); - System.out.println("[INTEGRATION TEST] testFindByIdIntegration - response: " + content); - - System.out.println("[INTEGRATION TEST] testFindByIdIntegration - end"); - } - - @Test - void testFindByUsernameIntegration() throws Exception { - System.out.println("[INTEGRATION TEST] testFindByUsernameIntegration - start"); - - MvcResult result = mockMvc.perform(get("/api/users/username/{username}", "juan")) - .andExpect(status().isOk()) - .andReturn(); - - String content = result.getResponse().getContentAsString(); - System.out.println("[INTEGRATION TEST] testFindByUsernameIntegration - response: " + content); - - System.out.println("[INTEGRATION TEST] testFindByUsernameIntegration - end"); - } - - - @Test - void testSaveUserIntegration() throws Exception { - System.out.println("[INTEGRATION TEST] testSaveUserIntegration - start"); - - UserDto newUser = UserDto.builder() - .firstName("Maria") - .lastName("Lopez") - .email("maria@mail.com") - .build(); - - String requestJson = objectMapper.writeValueAsString(newUser); - System.out.println("[INTEGRATION TEST] testSaveUserIntegration - request JSON: " + requestJson); - - MvcResult result = mockMvc.perform(post("/api/users") - .contentType(MediaType.APPLICATION_JSON) - .content(requestJson)) - .andExpect(status().isOk()) - .andReturn(); - - String content = result.getResponse().getContentAsString(); - System.out.println("[INTEGRATION TEST] testSaveUserIntegration - response: " + content); - - System.out.println("[INTEGRATION TEST] testSaveUserIntegration - end"); - } - - - @Test - void testDeleteUserIntegration() throws Exception { - System.out.println("[INTEGRATION TEST] testDeleteUserIntegration - start"); - - MvcResult result = mockMvc.perform(delete("/api/users/{id}", 5)) - .andExpect(status().isOk()) - .andReturn(); - - String content = result.getResponse().getContentAsString(); - System.out.println("[INTEGRATION TEST] testDeleteUserIntegration - response: " + content); - - System.out.println("[INTEGRATION TEST] testDeleteUserIntegration - end"); - } -} From 1b82c0f4fa4c5b409b996282e86ef7e977beb4df Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Sun, 26 Oct 2025 17:02:06 -0500 Subject: [PATCH 14/67] tests: Integration tests, traying other things --- .../FavouriteResourceIntegrationTest.java | 39 +++++++++++++++---- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/favourite-service/src/test/java/com/selimhorri/app/resource/FavouriteResourceIntegrationTest.java b/favourite-service/src/test/java/com/selimhorri/app/resource/FavouriteResourceIntegrationTest.java index 5f06a73b3..a7b657a0c 100644 --- a/favourite-service/src/test/java/com/selimhorri/app/resource/FavouriteResourceIntegrationTest.java +++ b/favourite-service/src/test/java/com/selimhorri/app/resource/FavouriteResourceIntegrationTest.java @@ -26,6 +26,11 @@ import com.selimhorri.app.repository.FavouriteRepository; import org.springframework.test.web.client.ExpectedCount; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; import org.springframework.http.MediaType; @@ -33,6 +38,16 @@ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class FavouriteResourceIntegrationTest { + @TestConfiguration + static class TestRestConfig { + // Provide a plain RestTemplate bean for tests so MockRestServiceServer can intercept calls + @Bean + @Primary + public RestTemplate restTemplate() { + return new RestTemplate(); + } + } + @Autowired private TestRestTemplate restTemplate; @@ -48,6 +63,14 @@ class FavouriteResourceIntegrationTest { private final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(AppConstant.LOCAL_DATE_TIME_FORMAT); + private String encode(final String s) { + try { + return URLEncoder.encode(s, StandardCharsets.UTF_8.toString()); + } catch (final Exception e) { + throw new RuntimeException(e); + } + } + @BeforeEach void setUp() { this.favouriteRepository.deleteAll(); @@ -144,10 +167,10 @@ void deleteById_and_then_not_found() { FavouriteDto dto = buildDto(5, 50); restTemplate.postForEntity("/api/favourites", dto, FavouriteDto.class); - String likeDate = dto.getLikeDate().format(fmt); - ResponseEntity delRes = restTemplate.exchange( - "/api/favourites/" + dto.getUserId() + "/" + dto.getProductId() + "/" + likeDate, - HttpMethod.DELETE, null, Boolean.class); + String likeDate = encode(dto.getLikeDate().format(fmt)); + ResponseEntity delRes = restTemplate.exchange( + "/api/favourites/" + dto.getUserId() + "/" + dto.getProductId() + "/" + likeDate, + HttpMethod.DELETE, null, Boolean.class); assertThat(delRes.getStatusCode()).isEqualTo(HttpStatus.OK); FavouriteId id = new FavouriteId(dto.getUserId(), dto.getProductId(), dto.getLikeDate()); @@ -165,10 +188,10 @@ void findById_path_variables() throws Exception { this.mockServer.expect(ExpectedCount.once(), requestTo(AppConstant.DiscoveredDomainsApi.PRODUCT_SERVICE_API_URL + "/" + dto.getProductId())) .andRespond(withSuccess(productJson(dto.getProductId()), MediaType.APPLICATION_JSON)); - String likeDate = dto.getLikeDate().format(fmt); - ResponseEntity getRes = restTemplate.getForEntity( - "/api/favourites/" + dto.getUserId() + "/" + dto.getProductId() + "/" + likeDate, - FavouriteDto.class); + String likeDate = encode(dto.getLikeDate().format(fmt)); + ResponseEntity getRes = restTemplate.getForEntity( + "/api/favourites/" + dto.getUserId() + "/" + dto.getProductId() + "/" + likeDate, + FavouriteDto.class); assertThat(getRes.getStatusCode()).isEqualTo(HttpStatus.OK); FavouriteDto found = getRes.getBody(); assertThat(found).isNotNull(); From 1af4b9faf438566e10dafc865b0277c5c5da0ea2 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Sun, 26 Oct 2025 17:09:30 -0500 Subject: [PATCH 15/67] Test: another thing change --- .../FavouriteResourceIntegrationTest.java | 49 ++++++++++--------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/favourite-service/src/test/java/com/selimhorri/app/resource/FavouriteResourceIntegrationTest.java b/favourite-service/src/test/java/com/selimhorri/app/resource/FavouriteResourceIntegrationTest.java index a7b657a0c..47f9aaa36 100644 --- a/favourite-service/src/test/java/com/selimhorri/app/resource/FavouriteResourceIntegrationTest.java +++ b/favourite-service/src/test/java/com/selimhorri/app/resource/FavouriteResourceIntegrationTest.java @@ -108,8 +108,10 @@ private String productJson(int id) throws Exception { void saveAndFindById_with_request_body_and_external_calls() throws Exception { FavouriteDto dto = buildDto(1, 10); - ResponseEntity postRes = restTemplate.postForEntity("/api/favourites", dto, FavouriteDto.class); - assertThat(postRes.getStatusCode()).isEqualTo(HttpStatus.OK); + ResponseEntity postRes = restTemplate.postForEntity("/api/favourites", dto, String.class); + assertThat(postRes.getStatusCode()).isEqualTo(HttpStatus.OK); + FavouriteDto saved = mapper.readValue(postRes.getBody(), FavouriteDto.class); + assertThat(saved).isNotNull(); this.mockServer.expect(ExpectedCount.once(), requestTo(AppConstant.DiscoveredDomainsApi.USER_SERVICE_API_URL + "/" + dto.getUserId())) .andRespond(withSuccess(userJson(dto.getUserId()), MediaType.APPLICATION_JSON)); @@ -117,13 +119,13 @@ void saveAndFindById_with_request_body_and_external_calls() throws Exception { this.mockServer.expect(ExpectedCount.once(), requestTo(AppConstant.DiscoveredDomainsApi.PRODUCT_SERVICE_API_URL + "/" + dto.getProductId())) .andRespond(withSuccess(productJson(dto.getProductId()), MediaType.APPLICATION_JSON)); - FavouriteId id = new FavouriteId(dto.getUserId(), dto.getProductId(), dto.getLikeDate()); - ResponseEntity getRes = restTemplate.postForEntity("/api/favourites/find", id, FavouriteDto.class); - assertThat(getRes.getStatusCode()).isEqualTo(HttpStatus.OK); - FavouriteDto found = getRes.getBody(); - assertThat(found).isNotNull(); - assertThat(found.getUserDto()).isNotNull(); - assertThat(found.getProductDto()).isNotNull(); + FavouriteId id = new FavouriteId(dto.getUserId(), dto.getProductId(), dto.getLikeDate()); + ResponseEntity getRes = restTemplate.postForEntity("/api/favourites/find", id, String.class); + assertThat(getRes.getStatusCode()).isEqualTo(HttpStatus.OK); + FavouriteDto found = mapper.readValue(getRes.getBody(), FavouriteDto.class); + assertThat(found).isNotNull(); + assertThat(found.getUserDto()).isNotNull(); + assertThat(found.getProductDto()).isNotNull(); this.mockServer.verify(); } @@ -132,8 +134,8 @@ void saveAndFindById_with_request_body_and_external_calls() throws Exception { void findAll_returns_collection_and_resolves_external_apis() throws Exception { FavouriteDto a = buildDto(2, 20); FavouriteDto b = buildDto(3, 30); - restTemplate.postForEntity("/api/favourites", a, FavouriteDto.class); - restTemplate.postForEntity("/api/favourites", b, FavouriteDto.class); + restTemplate.postForEntity("/api/favourites", a, String.class); + restTemplate.postForEntity("/api/favourites", b, String.class); this.mockServer.expect(ExpectedCount.manyTimes(), requestTo(org.hamcrest.Matchers.startsWith(AppConstant.DiscoveredDomainsApi.USER_SERVICE_API_URL))) .andRespond(withSuccess(userJson(2), MediaType.APPLICATION_JSON)); @@ -148,30 +150,31 @@ void findAll_returns_collection_and_resolves_external_apis() throws Exception { } @Test - void update_existing_favourite() { + void update_existing_favourite() throws Exception { FavouriteDto dto = buildDto(4, 40); - restTemplate.postForEntity("/api/favourites", dto, FavouriteDto.class); + restTemplate.postForEntity("/api/favourites", dto, String.class); - HttpEntity request = new HttpEntity<>(dto); - ResponseEntity putRes = restTemplate.exchange("/api/favourites", HttpMethod.PUT, request, FavouriteDto.class); - assertThat(putRes.getStatusCode()).isEqualTo(HttpStatus.OK); + HttpEntity request = new HttpEntity<>(dto); + ResponseEntity putRes = restTemplate.exchange("/api/favourites", HttpMethod.PUT, request, String.class); + assertThat(putRes.getStatusCode()).isEqualTo(HttpStatus.OK); - - FavouriteId id = new FavouriteId(dto.getUserId(), dto.getProductId(), dto.getLikeDate()); - ResponseEntity getRes = restTemplate.postForEntity("/api/favourites/find", id, FavouriteDto.class); - assertThat(getRes.getStatusCode()).isEqualTo(HttpStatus.OK); + FavouriteId id = new FavouriteId(dto.getUserId(), dto.getProductId(), dto.getLikeDate()); + ResponseEntity getRes = restTemplate.postForEntity("/api/favourites/find", id, String.class); + assertThat(getRes.getStatusCode()).isEqualTo(HttpStatus.OK); } @Test - void deleteById_and_then_not_found() { + void deleteById_and_then_not_found() throws Exception { FavouriteDto dto = buildDto(5, 50); restTemplate.postForEntity("/api/favourites", dto, FavouriteDto.class); String likeDate = encode(dto.getLikeDate().format(fmt)); - ResponseEntity delRes = restTemplate.exchange( + ResponseEntity delRes = restTemplate.exchange( "/api/favourites/" + dto.getUserId() + "/" + dto.getProductId() + "/" + likeDate, - HttpMethod.DELETE, null, Boolean.class); + HttpMethod.DELETE, null, String.class); assertThat(delRes.getStatusCode()).isEqualTo(HttpStatus.OK); + Boolean deleted = mapper.readValue(delRes.getBody(), Boolean.class); + assertThat(deleted).isTrue(); FavouriteId id = new FavouriteId(dto.getUserId(), dto.getProductId(), dto.getLikeDate()); ResponseEntity getRes = restTemplate.postForEntity("/api/favourites/find", id, String.class); From 1c592777c0376e936dac44951a955ba9fd570cf6 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Sun, 26 Oct 2025 17:33:41 -0500 Subject: [PATCH 16/67] tests: doing some changes in tests --- .../FavouriteResourceIntegrationTest.java | 97 +++---------------- 1 file changed, 13 insertions(+), 84 deletions(-) diff --git a/favourite-service/src/test/java/com/selimhorri/app/resource/FavouriteResourceIntegrationTest.java b/favourite-service/src/test/java/com/selimhorri/app/resource/FavouriteResourceIntegrationTest.java index 47f9aaa36..bdf5760c6 100644 --- a/favourite-service/src/test/java/com/selimhorri/app/resource/FavouriteResourceIntegrationTest.java +++ b/favourite-service/src/test/java/com/selimhorri/app/resource/FavouriteResourceIntegrationTest.java @@ -14,67 +14,34 @@ import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.test.web.client.MockRestServiceServer; -import org.springframework.web.client.RestTemplate; + import com.fasterxml.jackson.databind.ObjectMapper; import com.selimhorri.app.constant.AppConstant; import com.selimhorri.app.domain.id.FavouriteId; import com.selimhorri.app.dto.FavouriteDto; -import com.selimhorri.app.dto.ProductDto; -import com.selimhorri.app.dto.UserDto; + import com.selimhorri.app.repository.FavouriteRepository; -import org.springframework.test.web.client.ExpectedCount; -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Primary; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; -import org.springframework.http.MediaType; + @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class FavouriteResourceIntegrationTest { - @TestConfiguration - static class TestRestConfig { - // Provide a plain RestTemplate bean for tests so MockRestServiceServer can intercept calls - @Bean - @Primary - public RestTemplate restTemplate() { - return new RestTemplate(); - } - } - @Autowired private TestRestTemplate restTemplate; - @Autowired - private RestTemplate clientRestTemplate; - @Autowired private FavouriteRepository favouriteRepository; - private MockRestServiceServer mockServer; - private final ObjectMapper mapper = new ObjectMapper(); private final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(AppConstant.LOCAL_DATE_TIME_FORMAT); - private String encode(final String s) { - try { - return URLEncoder.encode(s, StandardCharsets.UTF_8.toString()); - } catch (final Exception e) { - throw new RuntimeException(e); - } - } @BeforeEach void setUp() { this.favouriteRepository.deleteAll(); - this.mockServer = MockRestServiceServer.createServer(this.clientRestTemplate); } private FavouriteDto buildDto(int userId, int productId) { @@ -85,24 +52,6 @@ private FavouriteDto buildDto(int userId, int productId) { .build(); } - private String userJson(int id) throws Exception { - return mapper.writeValueAsString( - UserDto.builder() - .userId(id) - .firstName("User" + id) - .lastName("Test") - .email("user" + id + "@example.com") - .build()); - } - - private String productJson(int id) throws Exception { - return mapper.writeValueAsString( - ProductDto.builder() - .productId(id) - .productTitle("Product" + id) - .priceUnit(9.99) - .build()); - } @Test void saveAndFindById_with_request_body_and_external_calls() throws Exception { @@ -113,12 +62,6 @@ void saveAndFindById_with_request_body_and_external_calls() throws Exception { FavouriteDto saved = mapper.readValue(postRes.getBody(), FavouriteDto.class); assertThat(saved).isNotNull(); - this.mockServer.expect(ExpectedCount.once(), requestTo(AppConstant.DiscoveredDomainsApi.USER_SERVICE_API_URL + "/" + dto.getUserId())) - .andRespond(withSuccess(userJson(dto.getUserId()), MediaType.APPLICATION_JSON)); - - this.mockServer.expect(ExpectedCount.once(), requestTo(AppConstant.DiscoveredDomainsApi.PRODUCT_SERVICE_API_URL + "/" + dto.getProductId())) - .andRespond(withSuccess(productJson(dto.getProductId()), MediaType.APPLICATION_JSON)); - FavouriteId id = new FavouriteId(dto.getUserId(), dto.getProductId(), dto.getLikeDate()); ResponseEntity getRes = restTemplate.postForEntity("/api/favourites/find", id, String.class); assertThat(getRes.getStatusCode()).isEqualTo(HttpStatus.OK); @@ -127,7 +70,6 @@ void saveAndFindById_with_request_body_and_external_calls() throws Exception { assertThat(found.getUserDto()).isNotNull(); assertThat(found.getProductDto()).isNotNull(); - this.mockServer.verify(); } @Test @@ -137,16 +79,10 @@ void findAll_returns_collection_and_resolves_external_apis() throws Exception { restTemplate.postForEntity("/api/favourites", a, String.class); restTemplate.postForEntity("/api/favourites", b, String.class); - this.mockServer.expect(ExpectedCount.manyTimes(), requestTo(org.hamcrest.Matchers.startsWith(AppConstant.DiscoveredDomainsApi.USER_SERVICE_API_URL))) - .andRespond(withSuccess(userJson(2), MediaType.APPLICATION_JSON)); - this.mockServer.expect(ExpectedCount.manyTimes(), requestTo(org.hamcrest.Matchers.startsWith(AppConstant.DiscoveredDomainsApi.PRODUCT_SERVICE_API_URL))) - .andRespond(withSuccess(productJson(20), MediaType.APPLICATION_JSON)); - ResponseEntity res = restTemplate.getForEntity("/api/favourites", String.class); assertThat(res.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(res.getBody()).contains("user", "product"); - this.mockServer.verify(); } @Test @@ -158,7 +94,7 @@ void update_existing_favourite() throws Exception { ResponseEntity putRes = restTemplate.exchange("/api/favourites", HttpMethod.PUT, request, String.class); assertThat(putRes.getStatusCode()).isEqualTo(HttpStatus.OK); - FavouriteId id = new FavouriteId(dto.getUserId(), dto.getProductId(), dto.getLikeDate()); + FavouriteId id = new FavouriteId(dto.getUserId(), dto.getProductId(), dto.getLikeDate()); ResponseEntity getRes = restTemplate.postForEntity("/api/favourites/find", id, String.class); assertThat(getRes.getStatusCode()).isEqualTo(HttpStatus.OK); } @@ -168,12 +104,12 @@ void deleteById_and_then_not_found() throws Exception { FavouriteDto dto = buildDto(5, 50); restTemplate.postForEntity("/api/favourites", dto, FavouriteDto.class); - String likeDate = encode(dto.getLikeDate().format(fmt)); + String likeDate = dto.getLikeDate().format(fmt); ResponseEntity delRes = restTemplate.exchange( - "/api/favourites/" + dto.getUserId() + "/" + dto.getProductId() + "/" + likeDate, - HttpMethod.DELETE, null, String.class); + "/api/favourites/{userId}/{productId}/{likeDate}", HttpMethod.DELETE, null, String.class, + dto.getUserId(), dto.getProductId(), likeDate); assertThat(delRes.getStatusCode()).isEqualTo(HttpStatus.OK); - Boolean deleted = mapper.readValue(delRes.getBody(), Boolean.class); + Boolean deleted = Boolean.valueOf(delRes.getBody()); assertThat(deleted).isTrue(); FavouriteId id = new FavouriteId(dto.getUserId(), dto.getProductId(), dto.getLikeDate()); @@ -186,22 +122,15 @@ void findById_path_variables() throws Exception { FavouriteDto dto = buildDto(6, 60); restTemplate.postForEntity("/api/favourites", dto, FavouriteDto.class); - this.mockServer.expect(ExpectedCount.once(), requestTo(AppConstant.DiscoveredDomainsApi.USER_SERVICE_API_URL + "/" + dto.getUserId())) - .andRespond(withSuccess(userJson(dto.getUserId()), MediaType.APPLICATION_JSON)); - this.mockServer.expect(ExpectedCount.once(), requestTo(AppConstant.DiscoveredDomainsApi.PRODUCT_SERVICE_API_URL + "/" + dto.getProductId())) - .andRespond(withSuccess(productJson(dto.getProductId()), MediaType.APPLICATION_JSON)); - - String likeDate = encode(dto.getLikeDate().format(fmt)); - ResponseEntity getRes = restTemplate.getForEntity( - "/api/favourites/" + dto.getUserId() + "/" + dto.getProductId() + "/" + likeDate, - FavouriteDto.class); + String likeDate = dto.getLikeDate().format(fmt); + ResponseEntity getRes = restTemplate.getForEntity( + "/api/favourites/{userId}/{productId}/{likeDate}", String.class, + dto.getUserId(), dto.getProductId(), likeDate); assertThat(getRes.getStatusCode()).isEqualTo(HttpStatus.OK); - FavouriteDto found = getRes.getBody(); + FavouriteDto found = mapper.readValue(getRes.getBody(), FavouriteDto.class); assertThat(found).isNotNull(); assertThat(found.getUserDto()).isNotNull(); assertThat(found.getProductDto()).isNotNull(); - - this.mockServer.verify(); } } From 4329b5eea1b0ccf041ed4e8e8f8bd13749aa709c Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Sun, 26 Oct 2025 18:01:35 -0500 Subject: [PATCH 17/67] tests: New tests --- .../FavouriteServiceIntegrationTest.java | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 favourite-service/src/test/java/com/selimhorri/app/service/FavouriteServiceIntegrationTest.java diff --git a/favourite-service/src/test/java/com/selimhorri/app/service/FavouriteServiceIntegrationTest.java b/favourite-service/src/test/java/com/selimhorri/app/service/FavouriteServiceIntegrationTest.java new file mode 100644 index 000000000..b43f3cb16 --- /dev/null +++ b/favourite-service/src/test/java/com/selimhorri/app/service/FavouriteServiceIntegrationTest.java @@ -0,0 +1,140 @@ +package com.selimhorri.app.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; + +import com.selimhorri.app.constant.AppConstant; +import com.selimhorri.app.domain.Favourite; +import com.selimhorri.app.domain.id.FavouriteId; +import com.selimhorri.app.dto.FavouriteDto; +import com.selimhorri.app.dto.ProductDto; +import com.selimhorri.app.dto.UserDto; +import com.selimhorri.app.repository.FavouriteRepository; + +@SpringBootTest(properties = { + "spring.jpa.hibernate.ddl-auto=create-drop", + "spring.datasource.url=jdbc:h2:mem:favourite_integration_db;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE", + "spring.datasource.username=sa", + "spring.datasource.password=", + "spring.jpa.show-sql=false", + "spring.flyway.enabled=false", + "spring.sql.init.mode=never", + "spring.config.import=optional:file:./", + "SPRING_CONFIG_IMPORT=optional:file:./", + "eureka.client.enabled=false", + "spring.cloud.config.enabled=false", + "spring.cloud.discovery.enabled=false", + "server.servlet.context-path=" +}) +class FavouriteServiceIntegrationTest { + + private static final LocalDateTime EXISTING_LIKE_DATE = LocalDateTime.of(2024, 1, 15, 10, 15, 30, 123_000_000); + + @Autowired + private FavouriteService favouriteService; + + @Autowired + private FavouriteRepository favouriteRepository; + + @MockBean + private org.springframework.web.client.RestTemplate restTemplate; + + private FavouriteId existingId; + + @BeforeEach + void setUp() { + this.favouriteRepository.deleteAll(); + Favourite favourite = Favourite.builder() + .userId(101) + .productId(202) + .likeDate(EXISTING_LIKE_DATE) + .build(); + this.favouriteRepository.save(favourite); + this.existingId = new FavouriteId(101, 202, EXISTING_LIKE_DATE); + } + + @Test + void findAllShouldReturnPersistedFavouritesWithRemoteDetails() { + mockRemoteUser(existingId.getUserId(), "Alice"); + mockRemoteProduct(existingId.getProductId(), "Camera"); + + List favourites = this.favouriteService.findAll(); + + assertThat(favourites).hasSize(1); + FavouriteDto favouriteDto = favourites.get(0); + assertThat(favouriteDto.getUserId()).isEqualTo(existingId.getUserId()); + assertThat(favouriteDto.getProductId()).isEqualTo(existingId.getProductId()); + assertThat(favouriteDto.getLikeDate()).isEqualTo(existingId.getLikeDate()); + assertThat(favouriteDto.getUserDto().getFirstName()).isEqualTo("Alice"); + assertThat(favouriteDto.getProductDto().getProductTitle()).isEqualTo("Camera"); + + verify(this.restTemplate).getForObject(userUrl(existingId.getUserId()), UserDto.class); + verify(this.restTemplate).getForObject(productUrl(existingId.getProductId()), ProductDto.class); + } + + @Test + void findByIdShouldReturnFavouriteWhenPresent() { + mockRemoteUser(existingId.getUserId(), "Bob"); + mockRemoteProduct(existingId.getProductId(), "Laptop"); + + FavouriteDto favouriteDto = this.favouriteService.findById(existingId); + + assertThat(favouriteDto.getUserId()).isEqualTo(existingId.getUserId()); + assertThat(favouriteDto.getProductId()).isEqualTo(existingId.getProductId()); + assertThat(favouriteDto.getLikeDate()).isEqualTo(existingId.getLikeDate()); + assertThat(favouriteDto.getUserDto().getFirstName()).isEqualTo("Bob"); + assertThat(favouriteDto.getProductDto().getProductTitle()).isEqualTo("Laptop"); + } + + @Test + void saveShouldPersistFavourite() { + FavouriteDto payload = FavouriteDto.builder() + .userId(303) + .productId(404) + .likeDate(EXISTING_LIKE_DATE.plusDays(1)) + .build(); + + FavouriteDto saved = this.favouriteService.save(payload); + + Optional persisted = this.favouriteRepository.findById(new FavouriteId(303, 404, payload.getLikeDate())); + assertThat(persisted).isPresent(); + assertThat(saved.getUserId()).isEqualTo(payload.getUserId()); + assertThat(saved.getProductId()).isEqualTo(payload.getProductId()); + } + + @Test + void deleteByIdShouldRemoveFavourite() { + this.favouriteService.deleteById(existingId); + + assertThat(this.favouriteRepository.findAll()).isEmpty(); + } + + private void mockRemoteUser(int userId, String firstName) { + when(this.restTemplate.getForObject(userUrl(userId), UserDto.class)) + .thenReturn(UserDto.builder().userId(userId).firstName(firstName).build()); + } + + private void mockRemoteProduct(int productId, String title) { + when(this.restTemplate.getForObject(productUrl(productId), ProductDto.class)) + .thenReturn(ProductDto.builder().productId(productId).productTitle(title).build()); + } + + private static String userUrl(int userId) { + return AppConstant.DiscoveredDomainsApi.USER_SERVICE_API_URL + "/" + userId; + } + + private static String productUrl(int productId) { + return AppConstant.DiscoveredDomainsApi.PRODUCT_SERVICE_API_URL + "/" + productId; + } +} From 652dd82c3950cf2352c9aa7dfc799cbe643515a8 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Sun, 26 Oct 2025 20:33:29 -0500 Subject: [PATCH 18/67] test: changing the integration tests --- .../FavouriteServiceIntegrationTest.java | 3 +- .../FavouriteResourceIntegrationTest.java | 136 ------------------ 2 files changed, 2 insertions(+), 137 deletions(-) rename favourite-service/src/test/java/com/selimhorri/app/{service => }/FavouriteServiceIntegrationTest.java (98%) delete mode 100644 favourite-service/src/test/java/com/selimhorri/app/resource/FavouriteResourceIntegrationTest.java diff --git a/favourite-service/src/test/java/com/selimhorri/app/service/FavouriteServiceIntegrationTest.java b/favourite-service/src/test/java/com/selimhorri/app/FavouriteServiceIntegrationTest.java similarity index 98% rename from favourite-service/src/test/java/com/selimhorri/app/service/FavouriteServiceIntegrationTest.java rename to favourite-service/src/test/java/com/selimhorri/app/FavouriteServiceIntegrationTest.java index b43f3cb16..24158c7c9 100644 --- a/favourite-service/src/test/java/com/selimhorri/app/service/FavouriteServiceIntegrationTest.java +++ b/favourite-service/src/test/java/com/selimhorri/app/FavouriteServiceIntegrationTest.java @@ -1,4 +1,4 @@ -package com.selimhorri.app.service; +package com.selimhorri.app; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.verify; @@ -21,6 +21,7 @@ import com.selimhorri.app.dto.ProductDto; import com.selimhorri.app.dto.UserDto; import com.selimhorri.app.repository.FavouriteRepository; +import com.selimhorri.app.service.FavouriteService; @SpringBootTest(properties = { "spring.jpa.hibernate.ddl-auto=create-drop", diff --git a/favourite-service/src/test/java/com/selimhorri/app/resource/FavouriteResourceIntegrationTest.java b/favourite-service/src/test/java/com/selimhorri/app/resource/FavouriteResourceIntegrationTest.java deleted file mode 100644 index bdf5760c6..000000000 --- a/favourite-service/src/test/java/com/selimhorri/app/resource/FavouriteResourceIntegrationTest.java +++ /dev/null @@ -1,136 +0,0 @@ -package com.selimhorri.app.resource; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; - - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.selimhorri.app.constant.AppConstant; -import com.selimhorri.app.domain.id.FavouriteId; -import com.selimhorri.app.dto.FavouriteDto; - -import com.selimhorri.app.repository.FavouriteRepository; - - - -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -class FavouriteResourceIntegrationTest { - - @Autowired - private TestRestTemplate restTemplate; - - @Autowired - private FavouriteRepository favouriteRepository; - - private final ObjectMapper mapper = new ObjectMapper(); - - private final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(AppConstant.LOCAL_DATE_TIME_FORMAT); - - - @BeforeEach - void setUp() { - this.favouriteRepository.deleteAll(); - } - - private FavouriteDto buildDto(int userId, int productId) { - return FavouriteDto.builder() - .userId(userId) - .productId(productId) - .likeDate(LocalDateTime.now()) - .build(); - } - - - @Test - void saveAndFindById_with_request_body_and_external_calls() throws Exception { - FavouriteDto dto = buildDto(1, 10); - - ResponseEntity postRes = restTemplate.postForEntity("/api/favourites", dto, String.class); - assertThat(postRes.getStatusCode()).isEqualTo(HttpStatus.OK); - FavouriteDto saved = mapper.readValue(postRes.getBody(), FavouriteDto.class); - assertThat(saved).isNotNull(); - - FavouriteId id = new FavouriteId(dto.getUserId(), dto.getProductId(), dto.getLikeDate()); - ResponseEntity getRes = restTemplate.postForEntity("/api/favourites/find", id, String.class); - assertThat(getRes.getStatusCode()).isEqualTo(HttpStatus.OK); - FavouriteDto found = mapper.readValue(getRes.getBody(), FavouriteDto.class); - assertThat(found).isNotNull(); - assertThat(found.getUserDto()).isNotNull(); - assertThat(found.getProductDto()).isNotNull(); - - } - - @Test - void findAll_returns_collection_and_resolves_external_apis() throws Exception { - FavouriteDto a = buildDto(2, 20); - FavouriteDto b = buildDto(3, 30); - restTemplate.postForEntity("/api/favourites", a, String.class); - restTemplate.postForEntity("/api/favourites", b, String.class); - - ResponseEntity res = restTemplate.getForEntity("/api/favourites", String.class); - assertThat(res.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(res.getBody()).contains("user", "product"); - - } - - @Test - void update_existing_favourite() throws Exception { - FavouriteDto dto = buildDto(4, 40); - restTemplate.postForEntity("/api/favourites", dto, String.class); - - HttpEntity request = new HttpEntity<>(dto); - ResponseEntity putRes = restTemplate.exchange("/api/favourites", HttpMethod.PUT, request, String.class); - assertThat(putRes.getStatusCode()).isEqualTo(HttpStatus.OK); - - FavouriteId id = new FavouriteId(dto.getUserId(), dto.getProductId(), dto.getLikeDate()); - ResponseEntity getRes = restTemplate.postForEntity("/api/favourites/find", id, String.class); - assertThat(getRes.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Test - void deleteById_and_then_not_found() throws Exception { - FavouriteDto dto = buildDto(5, 50); - restTemplate.postForEntity("/api/favourites", dto, FavouriteDto.class); - - String likeDate = dto.getLikeDate().format(fmt); - ResponseEntity delRes = restTemplate.exchange( - "/api/favourites/{userId}/{productId}/{likeDate}", HttpMethod.DELETE, null, String.class, - dto.getUserId(), dto.getProductId(), likeDate); - assertThat(delRes.getStatusCode()).isEqualTo(HttpStatus.OK); - Boolean deleted = Boolean.valueOf(delRes.getBody()); - assertThat(deleted).isTrue(); - - FavouriteId id = new FavouriteId(dto.getUserId(), dto.getProductId(), dto.getLikeDate()); - ResponseEntity getRes = restTemplate.postForEntity("/api/favourites/find", id, String.class); - assertThat(getRes.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); - } - - @Test - void findById_path_variables() throws Exception { - FavouriteDto dto = buildDto(6, 60); - restTemplate.postForEntity("/api/favourites", dto, FavouriteDto.class); - - String likeDate = dto.getLikeDate().format(fmt); - ResponseEntity getRes = restTemplate.getForEntity( - "/api/favourites/{userId}/{productId}/{likeDate}", String.class, - dto.getUserId(), dto.getProductId(), likeDate); - assertThat(getRes.getStatusCode()).isEqualTo(HttpStatus.OK); - FavouriteDto found = mapper.readValue(getRes.getBody(), FavouriteDto.class); - assertThat(found).isNotNull(); - assertThat(found.getUserDto()).isNotNull(); - assertThat(found.getProductDto()).isNotNull(); - } - -} From 61684406740658f1b25a57634586464f456bf55d Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Sun, 26 Oct 2025 21:17:07 -0500 Subject: [PATCH 19/67] test: now theres integration test for order service --- .../app/FavouriteServiceIntegrationTest.java | 8 ++ .../app/OrderServiceIntegrationTest.java | 108 ++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 order-service/src/test/java/com/selimhorri/app/OrderServiceIntegrationTest.java diff --git a/favourite-service/src/test/java/com/selimhorri/app/FavouriteServiceIntegrationTest.java b/favourite-service/src/test/java/com/selimhorri/app/FavouriteServiceIntegrationTest.java index 24158c7c9..db049fa5e 100644 --- a/favourite-service/src/test/java/com/selimhorri/app/FavouriteServiceIntegrationTest.java +++ b/favourite-service/src/test/java/com/selimhorri/app/FavouriteServiceIntegrationTest.java @@ -21,6 +21,8 @@ import com.selimhorri.app.dto.ProductDto; import com.selimhorri.app.dto.UserDto; import com.selimhorri.app.repository.FavouriteRepository; +import com.selimhorri.app.exception.wrapper.FavouriteNotFoundException; +import static org.junit.jupiter.api.Assertions.assertThrows; import com.selimhorri.app.service.FavouriteService; @SpringBootTest(properties = { @@ -121,6 +123,12 @@ void deleteByIdShouldRemoveFavourite() { assertThat(this.favouriteRepository.findAll()).isEmpty(); } + @Test + void findByIdShouldThrowWhenNotPresent() { + FavouriteId missingId = new FavouriteId(9999, 8888, EXISTING_LIKE_DATE.plusDays(5)); + assertThrows(FavouriteNotFoundException.class, () -> this.favouriteService.findById(missingId)); + } + private void mockRemoteUser(int userId, String firstName) { when(this.restTemplate.getForObject(userUrl(userId), UserDto.class)) .thenReturn(UserDto.builder().userId(userId).firstName(firstName).build()); diff --git a/order-service/src/test/java/com/selimhorri/app/OrderServiceIntegrationTest.java b/order-service/src/test/java/com/selimhorri/app/OrderServiceIntegrationTest.java new file mode 100644 index 000000000..35f8e631c --- /dev/null +++ b/order-service/src/test/java/com/selimhorri/app/OrderServiceIntegrationTest.java @@ -0,0 +1,108 @@ +package com.selimhorri.app; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; + +import com.selimhorri.app.domain.Order; +import com.selimhorri.app.dto.OrderDto; +import com.selimhorri.app.exception.wrapper.OrderNotFoundException; +import com.selimhorri.app.repository.OrderRepository; +import com.selimhorri.app.service.OrderService; + +@SpringBootTest(properties = { + "spring.jpa.hibernate.ddl-auto=create-drop", + "spring.datasource.url=jdbc:h2:mem:order_integration_db;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE", + "spring.datasource.username=sa", + "spring.datasource.password=", + "spring.jpa.show-sql=false", + "spring.flyway.enabled=false", + "spring.sql.init.mode=never", + "spring.config.import=optional:file:./", + "SPRING_CONFIG_IMPORT=optional:file:./", + "eureka.client.enabled=false", + "spring.cloud.config.enabled=false", + "spring.cloud.discovery.enabled=false", + "server.servlet.context-path=" +}) +class OrderServiceIntegrationTest { + + private static final LocalDateTime EXISTING_ORDER_DATE = LocalDateTime.of(2024, 3, 10, 9, 0, 0); + + @Autowired + private OrderService orderService; + + @Autowired + private OrderRepository orderRepository; + + @MockBean + private org.springframework.web.client.RestTemplate restTemplate; + + private Integer existingId; + + @BeforeEach + void setUp() { + this.orderRepository.deleteAll(); + Order order = Order.builder() + .orderDate(EXISTING_ORDER_DATE) + .orderDesc("Initial order") + .orderFee(12.5) + .build(); + Order saved = this.orderRepository.save(order); + this.existingId = saved.getOrderId(); + } + + @Test + void findAllShouldReturnPersistedOrders() { + List orders = this.orderService.findAll(); + assertThat(orders).isNotEmpty(); + OrderDto dto = orders.get(0); + assertThat(dto.getOrderDate()).isEqualTo(EXISTING_ORDER_DATE); + assertThat(dto.getOrderDesc()).isEqualTo("Initial order"); + assertThat(dto.getOrderFee()).isEqualTo(12.5); + } + + @Test + void findByIdShouldReturnOrderWhenPresent() { + OrderDto dto = this.orderService.findById(this.existingId); + assertThat(dto).isNotNull(); + assertThat(dto.getOrderId()).isEqualTo(this.existingId); + assertThat(dto.getOrderDate()).isEqualTo(EXISTING_ORDER_DATE); + } + + @Test + void saveShouldPersistOrder() { + OrderDto payload = OrderDto.builder() + .orderDate(EXISTING_ORDER_DATE.plusDays(1)) + .orderDesc("New order") + .orderFee(5.0) + .build(); + + OrderDto saved = this.orderService.save(payload); + + Optional persisted = this.orderRepository.findById(saved.getOrderId()); + assertThat(persisted).isPresent(); + assertThat(saved.getOrderDesc()).isEqualTo("New order"); + } + + @Test + void deleteByIdShouldRemoveOrder() { + this.orderService.deleteById(this.existingId); + assertThat(this.orderRepository.findAll()).isEmpty(); + } + + @Test + void findByIdShouldThrowWhenNotPresent() { + assertThrows(OrderNotFoundException.class, () -> this.orderService.findById(99999)); + } + +} From dd49004aeee2b91a8a35119a6ef02696727d1370 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Sun, 26 Oct 2025 21:29:27 -0500 Subject: [PATCH 20/67] test: i change the test for order service --- .../app/OrderServiceIntegrationTest.java | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/order-service/src/test/java/com/selimhorri/app/OrderServiceIntegrationTest.java b/order-service/src/test/java/com/selimhorri/app/OrderServiceIntegrationTest.java index 35f8e631c..52c47410a 100644 --- a/order-service/src/test/java/com/selimhorri/app/OrderServiceIntegrationTest.java +++ b/order-service/src/test/java/com/selimhorri/app/OrderServiceIntegrationTest.java @@ -14,7 +14,9 @@ import org.springframework.boot.test.mock.mockito.MockBean; import com.selimhorri.app.domain.Order; +import com.selimhorri.app.domain.Cart; import com.selimhorri.app.dto.OrderDto; +import com.selimhorri.app.dto.CartDto; import com.selimhorri.app.exception.wrapper.OrderNotFoundException; import com.selimhorri.app.repository.OrderRepository; import com.selimhorri.app.service.OrderService; @@ -44,6 +46,9 @@ class OrderServiceIntegrationTest { @Autowired private OrderRepository orderRepository; + @Autowired + private com.selimhorri.app.repository.CartRepository cartRepository; + @MockBean private org.springframework.web.client.RestTemplate restTemplate; @@ -52,10 +57,14 @@ class OrderServiceIntegrationTest { @BeforeEach void setUp() { this.orderRepository.deleteAll(); + this.cartRepository.deleteAll(); + Cart cart = Cart.builder().userId(555).build(); + Cart savedCart = this.cartRepository.save(cart); Order order = Order.builder() .orderDate(EXISTING_ORDER_DATE) .orderDesc("Initial order") .orderFee(12.5) + .cart(savedCart) .build(); Order saved = this.orderRepository.save(order); this.existingId = saved.getOrderId(); @@ -81,13 +90,18 @@ void findByIdShouldReturnOrderWhenPresent() { @Test void saveShouldPersistOrder() { - OrderDto payload = OrderDto.builder() - .orderDate(EXISTING_ORDER_DATE.plusDays(1)) - .orderDesc("New order") - .orderFee(5.0) - .build(); - - OrderDto saved = this.orderService.save(payload); + // create a cart to associate with saved order so mapping doesn't NPE + Cart cart = Cart.builder().userId(777).build(); + Cart savedCart = this.cartRepository.save(cart); + + OrderDto payload = OrderDto.builder() + .orderDate(EXISTING_ORDER_DATE.plusDays(1)) + .orderDesc("New order") + .orderFee(5.0) + .cartDto(CartDto.builder().cartId(savedCart.getCartId()).build()) + .build(); + + OrderDto saved = this.orderService.save(payload); Optional persisted = this.orderRepository.findById(saved.getOrderId()); assertThat(persisted).isPresent(); From 047d8e32744d889d74c81b31c8631a0e746739f1 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Sun, 26 Oct 2025 22:21:44 -0500 Subject: [PATCH 21/67] test: Initial e2e tests, i have to develop more things --- .../java/com/selimhorri/app/UserE2ETest.java | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 user-service/src/test/java/com/selimhorri/app/UserE2ETest.java diff --git a/user-service/src/test/java/com/selimhorri/app/UserE2ETest.java b/user-service/src/test/java/com/selimhorri/app/UserE2ETest.java new file mode 100644 index 000000000..01fb6d7c1 --- /dev/null +++ b/user-service/src/test/java/com/selimhorri/app/UserE2ETest.java @@ -0,0 +1,131 @@ +package com.selimhorri.app; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Optional; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; + +import com.selimhorri.app.dto.CredentialDto; +import com.selimhorri.app.dto.UserDto; +import com.selimhorri.app.repository.UserRepository; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = { + "spring.jpa.hibernate.ddl-auto=create-drop", + "spring.datasource.url=jdbc:h2:mem:user_e2e_db;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE", + "spring.datasource.username=sa", + "spring.datasource.password=", + "spring.jpa.show-sql=false", + "spring.flyway.enabled=false", + "spring.sql.init.mode=never", + "spring.config.import=optional:file:./", + "SPRING_CONFIG_IMPORT=optional:file:./", + "eureka.client.enabled=false", + "spring.cloud.config.enabled=false", + "spring.cloud.discovery.enabled=false", + "server.servlet.context-path=" +}) +class UserE2ETest { + + @Autowired + private TestRestTemplate restTemplate; + + @Autowired + private UserRepository userRepository; + + @BeforeEach + void setUp() { + this.userRepository.deleteAll(); + } + + private UserDto buildUser(String username, String firstName, String lastName) { + CredentialDto cred = CredentialDto.builder() + .username(username) + .password("secret") + .build(); + return UserDto.builder() + .firstName(firstName) + .lastName(lastName) + .credentialDto(cred) + .build(); + } + + @Test + void createUser_thenGetById() { + UserDto payload = buildUser("alice1", "Alice", "Smith"); + ResponseEntity postResp = this.restTemplate.postForEntity("/api/users", payload, UserDto.class); + assertThat(postResp.getStatusCode().is2xxSuccessful()).isTrue(); + UserDto created = postResp.getBody(); + assertThat(created).isNotNull(); + assertThat(created.getUserId()).isNotNull(); + + ResponseEntity getResp = this.restTemplate.getForEntity("/api/users/{id}", UserDto.class, created.getUserId()); + assertThat(getResp.getStatusCode().is2xxSuccessful()).isTrue(); + UserDto fetched = getResp.getBody(); + assertThat(fetched.getFirstName()).isEqualTo("Alice"); + } + + @Test + void createUser_thenFindByUsername() { + UserDto payload = buildUser("bob1", "Bob", "Jones"); + UserDto created = this.restTemplate.postForEntity("/api/users", payload, UserDto.class).getBody(); + assertThat(created).isNotNull(); + + ResponseEntity resp = this.restTemplate.getForEntity("/api/users/username/{username}", UserDto.class, "bob1"); + assertThat(resp.getStatusCode().is2xxSuccessful()).isTrue(); + UserDto found = resp.getBody(); + assertThat(found.getUserId()).isEqualTo(created.getUserId()); + } + + @Test + void updateUser_viaPut_bodyAndById() { + UserDto payload = buildUser("carol1", "Carol", "White"); + UserDto created = this.restTemplate.postForEntity("/api/users", payload, UserDto.class).getBody(); + assertThat(created).isNotNull(); + + created.setFirstName("Caroline"); + ResponseEntity putResp = this.restTemplate.exchange("/api/users", HttpMethod.PUT, new HttpEntity<>(created), UserDto.class); + assertThat(putResp.getStatusCode().is2xxSuccessful()).isTrue(); + UserDto updated = putResp.getBody(); + assertThat(updated.getFirstName()).isEqualTo("Caroline"); + + updated.setLastName("Black"); + ResponseEntity putById = this.restTemplate.exchange("/api/users/{id}", HttpMethod.PUT, new HttpEntity<>(updated), UserDto.class, updated.getUserId()); + assertThat(putById.getStatusCode().is2xxSuccessful()).isTrue(); + assertThat(putById.getBody().getLastName()).isEqualTo("Black"); + } + + @Test + void deleteUser_shouldRemoveAndNotFind() { + UserDto payload = buildUser("dan1", "Dan", "Brown"); + UserDto created = this.restTemplate.postForEntity("/api/users", payload, UserDto.class).getBody(); + Integer id = created.getUserId(); + + ResponseEntity del = this.restTemplate.exchange("/api/users/{id}", HttpMethod.DELETE, HttpEntity.EMPTY, Boolean.class, id); + assertThat(del.getStatusCode().is2xxSuccessful()).isTrue(); + assertThat(del.getBody()).isTrue(); + + Optional maybe = this.userRepository.findById(id); + assertThat(maybe).isNotPresent(); + } + + @Test + void createMultiple_thenFindAll() { + this.restTemplate.postForEntity("/api/users", buildUser("u1", "U", "One"), UserDto.class); + this.restTemplate.postForEntity("/api/users", buildUser("u2", "V", "Two"), UserDto.class); + + ResponseEntity> resp = this.restTemplate.getForEntity("/api/users", (Class) com.selimhorri.app.dto.response.collection.DtoCollectionResponse.class); + assertThat(resp.getStatusCode().is2xxSuccessful()).isTrue(); + com.selimhorri.app.dto.response.collection.DtoCollectionResponse body = resp.getBody(); + assertThat(body).isNotNull(); + assertThat(body.getCollection()).asList().hasSizeGreaterThanOrEqualTo(2); + } + +} From 09b9733cacc888528bd1414cd0527a4f1d6da8d4 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Mon, 27 Oct 2025 20:49:02 -0500 Subject: [PATCH 22/67] test: new E2E test for users --- .../java/com/selimhorri/app/UserE2ETest.java | 222 ++++++++++++++---- 1 file changed, 171 insertions(+), 51 deletions(-) diff --git a/user-service/src/test/java/com/selimhorri/app/UserE2ETest.java b/user-service/src/test/java/com/selimhorri/app/UserE2ETest.java index 01fb6d7c1..7e848f835 100644 --- a/user-service/src/test/java/com/selimhorri/app/UserE2ETest.java +++ b/user-service/src/test/java/com/selimhorri/app/UserE2ETest.java @@ -57,75 +57,195 @@ private UserDto buildUser(String username, String firstName, String lastName) { .build(); } + @Test - void createUser_thenGetById() { - UserDto payload = buildUser("alice1", "Alice", "Smith"); - ResponseEntity postResp = this.restTemplate.postForEntity("/api/users", payload, UserDto.class); - assertThat(postResp.getStatusCode().is2xxSuccessful()).isTrue(); - UserDto created = postResp.getBody(); + void createUserWithCompleteProfile_thenUpdate_thenVerifyAllChanges() { + UserDto payload = UserDto.builder() + .firstName("Juan") + .lastName("P茅rez") + .email("juan.perez@example.com") + .phone("+1234567890") + .imageUrl("https://example.com/avatar.jpg") + .credentialDto(CredentialDto.builder() + .username("juanperez") + .password("securePass123") + .build()) + .build(); + + ResponseEntity createResp = this.restTemplate.postForEntity("/api/users", payload, UserDto.class); + assertThat(createResp.getStatusCode().is2xxSuccessful()).isTrue(); + UserDto created = createResp.getBody(); assertThat(created).isNotNull(); assertThat(created.getUserId()).isNotNull(); - - ResponseEntity getResp = this.restTemplate.getForEntity("/api/users/{id}", UserDto.class, created.getUserId()); - assertThat(getResp.getStatusCode().is2xxSuccessful()).isTrue(); - UserDto fetched = getResp.getBody(); - assertThat(fetched.getFirstName()).isEqualTo("Alice"); + assertThat(created.getEmail()).isEqualTo("juan.perez@example.com"); + assertThat(created.getPhone()).isEqualTo("+1234567890"); + + created.setFirstName("Juan Carlos"); + created.setLastName("P茅rez Garc铆a"); + created.setEmail("juancarlos.perez@example.com"); + created.setPhone("+0987654321"); + + ResponseEntity updateResp = this.restTemplate.exchange( + "/api/users", + HttpMethod.PUT, + new HttpEntity<>(created), + UserDto.class); + assertThat(updateResp.getStatusCode().is2xxSuccessful()).isTrue(); + UserDto updated = updateResp.getBody(); + + assertThat(updated.getFirstName()).isEqualTo("Juan Carlos"); + assertThat(updated.getLastName()).isEqualTo("P茅rez Garc铆a"); + assertThat(updated.getEmail()).isEqualTo("juancarlos.perez@example.com"); + assertThat(updated.getPhone()).isEqualTo("+0987654321"); } @Test - void createUser_thenFindByUsername() { - UserDto payload = buildUser("bob1", "Bob", "Jones"); - UserDto created = this.restTemplate.postForEntity("/api/users", payload, UserDto.class).getBody(); + void createUser_thenGetById_thenDelete_thenVerifyNotFound() { + UserDto payload = buildUser("testuser", "Test", "User"); + ResponseEntity createResp = this.restTemplate.postForEntity("/api/users", payload, UserDto.class); + assertThat(createResp.getStatusCode().is2xxSuccessful()).isTrue(); + UserDto created = createResp.getBody(); assertThat(created).isNotNull(); + Integer userId = created.getUserId(); - ResponseEntity resp = this.restTemplate.getForEntity("/api/users/username/{username}", UserDto.class, "bob1"); - assertThat(resp.getStatusCode().is2xxSuccessful()).isTrue(); - UserDto found = resp.getBody(); - assertThat(found.getUserId()).isEqualTo(created.getUserId()); + ResponseEntity getResp = this.restTemplate.getForEntity("/api/users/{id}", UserDto.class, userId); + assertThat(getResp.getStatusCode().is2xxSuccessful()).isTrue(); + assertThat(getResp.getBody().getUserId()).isEqualTo(userId); + + ResponseEntity delResp = this.restTemplate.exchange( + "/api/users/{id}", + HttpMethod.DELETE, + HttpEntity.EMPTY, + Boolean.class, + userId); + assertThat(delResp.getStatusCode().is2xxSuccessful()).isTrue(); + assertThat(delResp.getBody()).isTrue(); + + // Verificar que ya no existe en BD + Optional deleted = this.userRepository.findById(userId); + assertThat(deleted).isNotPresent(); } @Test - void updateUser_viaPut_bodyAndById() { - UserDto payload = buildUser("carol1", "Carol", "White"); - UserDto created = this.restTemplate.postForEntity("/api/users", payload, UserDto.class).getBody(); - assertThat(created).isNotNull(); - - created.setFirstName("Caroline"); - ResponseEntity putResp = this.restTemplate.exchange("/api/users", HttpMethod.PUT, new HttpEntity<>(created), UserDto.class); - assertThat(putResp.getStatusCode().is2xxSuccessful()).isTrue(); - UserDto updated = putResp.getBody(); - assertThat(updated.getFirstName()).isEqualTo("Caroline"); - - updated.setLastName("Black"); - ResponseEntity putById = this.restTemplate.exchange("/api/users/{id}", HttpMethod.PUT, new HttpEntity<>(updated), UserDto.class, updated.getUserId()); - assertThat(putById.getStatusCode().is2xxSuccessful()).isTrue(); - assertThat(putById.getBody().getLastName()).isEqualTo("Black"); + void createMultipleUsers_thenFindAll_thenFindByUsername_thenUpdateOne() { + UserDto user1 = this.restTemplate.postForEntity("/api/users", + buildUser("alice_2024", "Alice", "Wonderland"), UserDto.class).getBody(); + UserDto user2 = this.restTemplate.postForEntity("/api/users", + buildUser("bob_2024", "Bob", "Builder"), UserDto.class).getBody(); + UserDto user3 = this.restTemplate.postForEntity("/api/users", + buildUser("charlie_2024", "Charlie", "Brown"), UserDto.class).getBody(); + + assertThat(user1).isNotNull(); + assertThat(user2).isNotNull(); + assertThat(user3).isNotNull(); + + ResponseEntity> getAllResp = + this.restTemplate.getForEntity("/api/users", + (Class>) + (Class) com.selimhorri.app.dto.response.collection.DtoCollectionResponse.class); + assertThat(getAllResp.getStatusCode().is2xxSuccessful()).isTrue(); + assertThat(getAllResp.getBody().getCollection()).asList().hasSizeGreaterThanOrEqualTo(3); + + ResponseEntity findByUsernameResp = this.restTemplate.getForEntity( + "/api/users/username/{username}", + UserDto.class, + "bob_2024"); + assertThat(findByUsernameResp.getStatusCode().is2xxSuccessful()).isTrue(); + UserDto found = findByUsernameResp.getBody(); + assertThat(found.getFirstName()).isEqualTo("Bob"); + assertThat(found.getLastName()).isEqualTo("Builder"); + + user2.setFirstName("Robert"); + user2.setLastName("The Builder"); + ResponseEntity updateResp = this.restTemplate.exchange( + "/api/users/" + user2.getUserId(), + HttpMethod.PUT, + new HttpEntity<>(user2), + UserDto.class); + assertThat(updateResp.getStatusCode().is2xxSuccessful()).isTrue(); + assertThat(updateResp.getBody().getFirstName()).isEqualTo("Robert"); } @Test - void deleteUser_shouldRemoveAndNotFind() { - UserDto payload = buildUser("dan1", "Dan", "Brown"); - UserDto created = this.restTemplate.postForEntity("/api/users", payload, UserDto.class).getBody(); - Integer id = created.getUserId(); - - ResponseEntity del = this.restTemplate.exchange("/api/users/{id}", HttpMethod.DELETE, HttpEntity.EMPTY, Boolean.class, id); - assertThat(del.getStatusCode().is2xxSuccessful()).isTrue(); - assertThat(del.getBody()).isTrue(); + void createUser_thenUpdatePartialFields_thenVerifyDatabaseState() { + UserDto initialUser = UserDto.builder() + .firstName("Mar铆a") + .lastName("Gonz谩lez") + .email("maria.gonzalez@example.com") + .phone("555-0001") + .credentialDto(CredentialDto.builder() + .username("mariagonz") + .password("password123") + .build()) + .build(); - Optional maybe = this.userRepository.findById(id); - assertThat(maybe).isNotPresent(); + ResponseEntity createResp = this.restTemplate.postForEntity("/api/users", initialUser, UserDto.class); + UserDto created = createResp.getBody(); + assertThat(created).isNotNull(); + Integer userId = created.getUserId(); + + created.setLastName("Gonz谩lez Rodr铆guez"); + created.setImageUrl("https://example.com/new-avatar.jpg"); + + ResponseEntity updateResp = this.restTemplate.exchange( + "/api/users/{userId}", + HttpMethod.PUT, + new HttpEntity<>(created), + UserDto.class, + userId); + assertThat(updateResp.getStatusCode().is2xxSuccessful()).isTrue(); + + UserDto updated = updateResp.getBody(); + assertThat(updated.getFirstName()).isEqualTo("Mar铆a"); + assertThat(updated.getLastName()).isEqualTo("Gonz谩lez Rodr铆guez"); + assertThat(updated.getEmail()).isEqualTo("maria.gonzalez@example.com"); + assertThat(updated.getPhone()).isEqualTo("555-0001"); + assertThat(updated.getImageUrl()).isEqualTo("https://example.com/new-avatar.jpg"); } @Test - void createMultiple_thenFindAll() { - this.restTemplate.postForEntity("/api/users", buildUser("u1", "U", "One"), UserDto.class); - this.restTemplate.postForEntity("/api/users", buildUser("u2", "V", "Two"), UserDto.class); - - ResponseEntity> resp = this.restTemplate.getForEntity("/api/users", (Class) com.selimhorri.app.dto.response.collection.DtoCollectionResponse.class); - assertThat(resp.getStatusCode().is2xxSuccessful()).isTrue(); - com.selimhorri.app.dto.response.collection.DtoCollectionResponse body = resp.getBody(); - assertThat(body).isNotNull(); - assertThat(body.getCollection()).asList().hasSizeGreaterThanOrEqualTo(2); + void createUser_thenRetrieve_thenUpdateByPath_thenRetrieveAgain() { + UserDto newUser = UserDto.builder() + .firstName("Pedro") + .lastName("Mart铆nez") + .email("pedro.martinez@example.com") + .phone("+555-1234") + .credentialDto(CredentialDto.builder() + .username("pedromart") + .password("secret123") + .build()) + .build(); + + ResponseEntity create = this.restTemplate.postForEntity("/api/users", newUser, UserDto.class); + assertThat(create.getStatusCode().is2xxSuccessful()).isTrue(); + UserDto created = create.getBody(); + assertThat(created.getUserId()).isNotNull(); + + ResponseEntity getById = this.restTemplate.getForEntity( + "/api/users/{id}", + UserDto.class, + created.getUserId()); + assertThat(getById.getStatusCode().is2xxSuccessful()).isTrue(); + assertThat(getById.getBody().getFirstName()).isEqualTo("Pedro"); + + created.setFirstName("Pedro Luis"); + created.setEmail("pedroluis.martinez@example.com"); + + ResponseEntity updateById = this.restTemplate.exchange( + "/api/users/{userId}", + HttpMethod.PUT, + new HttpEntity<>(created), + UserDto.class, + created.getUserId()); + assertThat(updateById.getStatusCode().is2xxSuccessful()).isTrue(); + + ResponseEntity getAgain = this.restTemplate.getForEntity( + "/api/users/{id}", + UserDto.class, + created.getUserId()); + assertThat(getAgain.getStatusCode().is2xxSuccessful()).isTrue(); + assertThat(getAgain.getBody().getFirstName()).isEqualTo("Pedro Luis"); + assertThat(getAgain.getBody().getEmail()).isEqualTo("pedroluis.martinez@example.com"); } } From 6562dc0abeac7bef89d58e4e24cb9d2345950f9d Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Mon, 27 Oct 2025 21:21:43 -0500 Subject: [PATCH 23/67] test: Some changes in E2E tests --- user-service/src/main/java/com/selimhorri/app/dto/UserDto.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/user-service/src/main/java/com/selimhorri/app/dto/UserDto.java b/user-service/src/main/java/com/selimhorri/app/dto/UserDto.java index 3987d6d3e..7a834c5ae 100644 --- a/user-service/src/main/java/com/selimhorri/app/dto/UserDto.java +++ b/user-service/src/main/java/com/selimhorri/app/dto/UserDto.java @@ -3,6 +3,7 @@ import java.io.Serializable; import java.util.Set; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; @@ -16,6 +17,7 @@ @AllArgsConstructor @Data @Builder +@JsonIgnoreProperties(ignoreUnknown = true) public class UserDto implements Serializable { private static final long serialVersionUID = 1L; From b0ada8943a6bbc492ea4929bf06316b3f336c92f Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Mon, 27 Oct 2025 21:47:41 -0500 Subject: [PATCH 24/67] test:new changes to E2E tests --- .../java/com/selimhorri/app/UserE2ETest.java | 62 ++++++++++--------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/user-service/src/test/java/com/selimhorri/app/UserE2ETest.java b/user-service/src/test/java/com/selimhorri/app/UserE2ETest.java index 7e848f835..7115f0172 100644 --- a/user-service/src/test/java/com/selimhorri/app/UserE2ETest.java +++ b/user-service/src/test/java/com/selimhorri/app/UserE2ETest.java @@ -57,7 +57,6 @@ private UserDto buildUser(String username, String firstName, String lastName) { .build(); } - @Test void createUserWithCompleteProfile_thenUpdate_thenVerifyAllChanges() { UserDto payload = UserDto.builder() @@ -86,10 +85,11 @@ void createUserWithCompleteProfile_thenUpdate_thenVerifyAllChanges() { created.setPhone("+0987654321"); ResponseEntity updateResp = this.restTemplate.exchange( - "/api/users", - HttpMethod.PUT, - new HttpEntity<>(created), - UserDto.class); + "/api/users/{userId}", + HttpMethod.PUT, + new HttpEntity<>(created), + UserDto.class, + created.getUserId()); assertThat(updateResp.getStatusCode().is2xxSuccessful()).isTrue(); UserDto updated = updateResp.getBody(); @@ -113,20 +113,20 @@ void createUser_thenGetById_thenDelete_thenVerifyNotFound() { assertThat(getResp.getBody().getUserId()).isEqualTo(userId); ResponseEntity delResp = this.restTemplate.exchange( - "/api/users/{id}", - HttpMethod.DELETE, - HttpEntity.EMPTY, - Boolean.class, + "/api/users/{id}", + HttpMethod.DELETE, + HttpEntity.EMPTY, + Boolean.class, userId); assertThat(delResp.getStatusCode().is2xxSuccessful()).isTrue(); assertThat(delResp.getBody()).isTrue(); - // Verificar que ya no existe en BD Optional deleted = this.userRepository.findById(userId); assertThat(deleted).isNotPresent(); } @Test + @SuppressWarnings("unchecked") void createMultipleUsers_thenFindAll_thenFindByUsername_thenUpdateOne() { UserDto user1 = this.restTemplate.postForEntity("/api/users", buildUser("alice_2024", "Alice", "Wonderland"), UserDto.class).getBody(); @@ -140,15 +140,15 @@ void createMultipleUsers_thenFindAll_thenFindByUsername_thenUpdateOne() { assertThat(user3).isNotNull(); ResponseEntity> getAllResp = - this.restTemplate.getForEntity("/api/users", + this.restTemplate.getForEntity("/api/users", (Class>) (Class) com.selimhorri.app.dto.response.collection.DtoCollectionResponse.class); assertThat(getAllResp.getStatusCode().is2xxSuccessful()).isTrue(); assertThat(getAllResp.getBody().getCollection()).asList().hasSizeGreaterThanOrEqualTo(3); ResponseEntity findByUsernameResp = this.restTemplate.getForEntity( - "/api/users/username/{username}", - UserDto.class, + "/api/users/username/{username}", + UserDto.class, "bob_2024"); assertThat(findByUsernameResp.getStatusCode().is2xxSuccessful()).isTrue(); UserDto found = findByUsernameResp.getBody(); @@ -157,11 +157,13 @@ void createMultipleUsers_thenFindAll_thenFindByUsername_thenUpdateOne() { user2.setFirstName("Robert"); user2.setLastName("The Builder"); + ResponseEntity updateResp = this.restTemplate.exchange( - "/api/users/" + user2.getUserId(), - HttpMethod.PUT, - new HttpEntity<>(user2), - UserDto.class); + "/api/users/{userId}", + HttpMethod.PUT, + new HttpEntity<>(user2), + UserDto.class, + user2.getUserId()); assertThat(updateResp.getStatusCode().is2xxSuccessful()).isTrue(); assertThat(updateResp.getBody().getFirstName()).isEqualTo("Robert"); } @@ -188,10 +190,10 @@ void createUser_thenUpdatePartialFields_thenVerifyDatabaseState() { created.setImageUrl("https://example.com/new-avatar.jpg"); ResponseEntity updateResp = this.restTemplate.exchange( - "/api/users/{userId}", - HttpMethod.PUT, - new HttpEntity<>(created), - UserDto.class, + "/api/users/{userId}", + HttpMethod.PUT, + new HttpEntity<>(created), + UserDto.class, userId); assertThat(updateResp.getStatusCode().is2xxSuccessful()).isTrue(); @@ -222,26 +224,26 @@ void createUser_thenRetrieve_thenUpdateByPath_thenRetrieveAgain() { assertThat(created.getUserId()).isNotNull(); ResponseEntity getById = this.restTemplate.getForEntity( - "/api/users/{id}", - UserDto.class, + "/api/users/{id}", + UserDto.class, created.getUserId()); assertThat(getById.getStatusCode().is2xxSuccessful()).isTrue(); assertThat(getById.getBody().getFirstName()).isEqualTo("Pedro"); created.setFirstName("Pedro Luis"); created.setEmail("pedroluis.martinez@example.com"); - + ResponseEntity updateById = this.restTemplate.exchange( - "/api/users/{userId}", - HttpMethod.PUT, - new HttpEntity<>(created), - UserDto.class, + "/api/users/{userId}", + HttpMethod.PUT, + new HttpEntity<>(created), + UserDto.class, created.getUserId()); assertThat(updateById.getStatusCode().is2xxSuccessful()).isTrue(); ResponseEntity getAgain = this.restTemplate.getForEntity( - "/api/users/{id}", - UserDto.class, + "/api/users/{id}", + UserDto.class, created.getUserId()); assertThat(getAgain.getStatusCode().is2xxSuccessful()).isTrue(); assertThat(getAgain.getBody().getFirstName()).isEqualTo("Pedro Luis"); From e48ae7fa731ff18ca38a0a247fed718940c1bd94 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Tue, 28 Oct 2025 09:54:37 -0500 Subject: [PATCH 25/67] test: doing some changes in DTOs --- .../app/helper/UserMappingHelper.java | 75 +++++++++++-------- .../app/service/impl/UserServiceImpl.java | 4 +- 2 files changed, 44 insertions(+), 35 deletions(-) diff --git a/user-service/src/main/java/com/selimhorri/app/helper/UserMappingHelper.java b/user-service/src/main/java/com/selimhorri/app/helper/UserMappingHelper.java index 1bb02c2d6..923e6316b 100644 --- a/user-service/src/main/java/com/selimhorri/app/helper/UserMappingHelper.java +++ b/user-service/src/main/java/com/selimhorri/app/helper/UserMappingHelper.java @@ -7,48 +7,57 @@ public interface UserMappingHelper { - public static UserDto map(final User user) { - return UserDto.builder() - .userId(user.getUserId()) - .firstName(user.getFirstName()) - .lastName(user.getLastName()) - .imageUrl(user.getImageUrl()) - .email(user.getEmail()) - .phone(user.getPhone()) - .credentialDto( - CredentialDto.builder() - .credentialId(user.getCredential().getCredentialId()) - .username(user.getCredential().getUsername()) - .password(user.getCredential().getPassword()) - .roleBasedAuthority(user.getCredential().getRoleBasedAuthority()) - .isEnabled(user.getCredential().getIsEnabled()) - .isAccountNonExpired(user.getCredential().getIsAccountNonExpired()) - .isAccountNonLocked(user.getCredential().getIsAccountNonLocked()) - .isCredentialsNonExpired(user.getCredential().getIsCredentialsNonExpired()) - .build()) - .build(); - } + public static UserDto map(final User user) { + final Credential cred = user.getCredential(); + final CredentialDto credDto = cred == null ? null : CredentialDto.builder() + .credentialId(cred.getCredentialId()) + .username(cred.getUsername()) + .password(cred.getPassword()) + .roleBasedAuthority(cred.getRoleBasedAuthority()) + .isEnabled(cred.getIsEnabled()) + .isAccountNonExpired(cred.getIsAccountNonExpired()) + .isAccountNonLocked(cred.getIsAccountNonLocked()) + .isCredentialsNonExpired(cred.getIsCredentialsNonExpired()) + .build(); + + return UserDto.builder() + .userId(user.getUserId()) + .firstName(user.getFirstName()) + .lastName(user.getLastName()) + .imageUrl(user.getImageUrl()) + .email(user.getEmail()) + .phone(user.getPhone()) + .credentialDto(credDto) + .build(); + } public static User map(final UserDto userDto) { - return User.builder() + final User user = User.builder() .userId(userDto.getUserId()) .firstName(userDto.getFirstName()) .lastName(userDto.getLastName()) .imageUrl(userDto.getImageUrl()) .email(userDto.getEmail()) .phone(userDto.getPhone()) - .credential( - Credential.builder() - .credentialId(userDto.getCredentialDto().getCredentialId()) - .username(userDto.getCredentialDto().getUsername()) - .password(userDto.getCredentialDto().getPassword()) - .roleBasedAuthority(userDto.getCredentialDto().getRoleBasedAuthority()) - .isEnabled(userDto.getCredentialDto().getIsEnabled()) - .isAccountNonExpired(userDto.getCredentialDto().getIsAccountNonExpired()) - .isAccountNonLocked(userDto.getCredentialDto().getIsAccountNonLocked()) - .isCredentialsNonExpired(userDto.getCredentialDto().getIsCredentialsNonExpired()) - .build()) .build(); + + if (userDto.getCredentialDto() != null) { + final Credential cred = Credential.builder() + .credentialId(userDto.getCredentialDto().getCredentialId()) + .username(userDto.getCredentialDto().getUsername()) + .password(userDto.getCredentialDto().getPassword()) + .roleBasedAuthority(userDto.getCredentialDto().getRoleBasedAuthority()) + .isEnabled(userDto.getCredentialDto().getIsEnabled()) + .isAccountNonExpired(userDto.getCredentialDto().getIsAccountNonExpired()) + .isAccountNonLocked(userDto.getCredentialDto().getIsAccountNonLocked()) + .isCredentialsNonExpired(userDto.getCredentialDto().getIsCredentialsNonExpired()) + .build(); + + cred.setUser(user); + user.setCredential(cred); + } + + return user; } diff --git a/user-service/src/main/java/com/selimhorri/app/service/impl/UserServiceImpl.java b/user-service/src/main/java/com/selimhorri/app/service/impl/UserServiceImpl.java index 436599baa..bfe04e182 100644 --- a/user-service/src/main/java/com/selimhorri/app/service/impl/UserServiceImpl.java +++ b/user-service/src/main/java/com/selimhorri/app/service/impl/UserServiceImpl.java @@ -57,8 +57,8 @@ public UserDto update(final UserDto userDto) { @Override public UserDto update(final Integer userId, final UserDto userDto) { log.info("*** UserDto, service; update user with userId *"); - return UserMappingHelper.map(this.userRepository.save( - UserMappingHelper.map(this.findById(userId)))); + userDto.setUserId(userId); + return UserMappingHelper.map(this.userRepository.save(UserMappingHelper.map(userDto))); } @Override From a05eb5493ea4063ff65d9dc591c11bde73d9bbec Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Tue, 28 Oct 2025 10:25:31 -0500 Subject: [PATCH 26/67] test: testing the locus tests thing --- loadtest-compose.yml | 22 +++++ user-service/loadtest/Dockerfile | 13 +++ user-service/loadtest/locustfile.py | 122 +++++++++++++++++++++++++ user-service/loadtest/requirements.txt | 4 + 4 files changed, 161 insertions(+) create mode 100644 loadtest-compose.yml create mode 100644 user-service/loadtest/Dockerfile create mode 100644 user-service/loadtest/locustfile.py create mode 100644 user-service/loadtest/requirements.txt diff --git a/loadtest-compose.yml b/loadtest-compose.yml new file mode 100644 index 000000000..bd003ba1c --- /dev/null +++ b/loadtest-compose.yml @@ -0,0 +1,22 @@ +version: '3' + +services: + locust: + build: + context: ./user-service/loadtest + ports: + - 8089:8089 + networks: + - microservices_network + depends_on: + - api-gateway-container + environment: + - LOCUST_USERS=100 + - LOCUST_SPAWN_RATE=10 + - LOCUST_RUN_TIME=5m + - TARGET_HOST=http://api-gateway-container:8080 + command: sh -c "locust -f locustfile.py --host ${TARGET_HOST} --web-host 0.0.0.0 --web-port 8089" + +networks: + microservices_network: + driver: bridge diff --git a/user-service/loadtest/Dockerfile b/user-service/loadtest/Dockerfile new file mode 100644 index 000000000..53584b37a --- /dev/null +++ b/user-service/loadtest/Dockerfile @@ -0,0 +1,13 @@ +FROM python:3.11-slim +WORKDIR /loadtest + +COPY requirements.txt ./ +RUN pip install --no-cache-dir -r requirements.txt + +COPY locustfile.py ./ + +ENV LOCUSTFILE=locustfile.py +EXPOSE 8089 + +ENTRYPOINT ["locust"] +CMD ["-f", "locustfile.py", "--host", "http://api-gateway-container:8080", "--web-host", "0.0.0.0", "--web-port", "8089"] diff --git a/user-service/loadtest/locustfile.py b/user-service/loadtest/locustfile.py new file mode 100644 index 000000000..81e79af7d --- /dev/null +++ b/user-service/loadtest/locustfile.py @@ -0,0 +1,122 @@ +from locust import HttpUser, task, between, events +import random +import string +import json +import time + + +def rand_username(): + return "user_" + ''.join(random.choices(string.ascii_lowercase + string.digits, k=8)) + +def rand_name(): + return ''.join(random.choices(string.ascii_letters, k=6)) + + +class UserBehavior(HttpUser): + wait_time = between(0.5, 2.0) + + def on_start(self): + self.my_users = [] + + @task(15) + def list_users(self): + with self.client.get('/api/users', catch_response=True, name="GET /api/users") as resp: + if resp.status_code == 200: + try: + data = resp.json() + # expects the API to return a DTO collection with 'collection' property + if isinstance(data, dict) and 'collection' in data: + pass + except Exception: + pass + + @task(25) + def create_user(self): + username = rand_username() + payload = { + "firstName": rand_name(), + "lastName": rand_name(), + "email": f"{username}@example.com", + "phone": "+1-555-0123", + "imageUrl": "https://example.com/avatar.png", + "credential": { + "username": username, + "password": "LocustPass!23" + } + } + with self.client.post('/api/users', json=payload, catch_response=True, name="POST /api/users") as resp: + if resp.status_code == 200 or resp.status_code == 201: + try: + u = resp.json() + if u and 'userId' in u: + self.my_users.append(u['userId']) + except Exception: + pass + else: + resp.failure(f"Unexpected status: {resp.status_code}") + + @task(20) + def get_user_by_id(self): + if not self.my_users: + r = self.client.get('/api/users') + try: + data = r.json() + coll = data.get('collection', []) if isinstance(data, dict) else [] + if coll: + uid = coll[0].get('userId') + if uid: + self.client.get(f'/api/users/{uid}', name="GET /api/users/:id") + except Exception: + pass + return + + user_id = random.choice(self.my_users) + self.client.get(f'/api/users/{user_id}', name="GET /api/users/:id") + + @task(10) + def find_by_username(self): + if not self.my_users: + return + r = self.client.get('/api/users') + try: + data = r.json() + coll = data.get('collection', []) if isinstance(data, dict) else [] + if coll: + candidate = random.choice(coll) + cred = candidate.get('credential') or candidate.get('credentialDto') + if cred and 'username' in cred: + self.client.get(f"/api/users/username/{cred['username']}", name="GET /api/users/username/:username") + except Exception: + pass + + @task(10) + def update_user(self): + if not self.my_users: + return + user_id = random.choice(self.my_users) + payload = { + "userId": user_id, + "firstName": "Updated_" + rand_name(), + "lastName": rand_name(), + "email": f"updated_{user_id}@example.com", + "phone": "+1-999-9999", + } + with self.client.put(f'/api/users/{user_id}', json=payload, catch_response=True, name="PUT /api/users/:id") as resp: + if not (200 <= resp.status_code < 300): + resp.failure(f"Unexpected status: {resp.status_code}") + + @task(5) + def delete_user(self): + if not self.my_users: + return + user_id = self.my_users.pop(0) + with self.client.delete(f'/api/users/{user_id}', catch_response=True, name="DELETE /api/users/:id") as resp: + if not (200 <= resp.status_code < 300): + resp.failure(f"Unexpected status: {resp.status_code}") + + +@events.quitting.add_listener +def _(environment, **kw): + print("Quitting. Summary:") + if environment.stats.total: + print(environment.stats.total) diff --git a/user-service/loadtest/requirements.txt b/user-service/loadtest/requirements.txt new file mode 100644 index 000000000..d74505ba6 --- /dev/null +++ b/user-service/loadtest/requirements.txt @@ -0,0 +1,4 @@ +locust +locust==2.21.0 +requests==2.31.0 +python-dotenv==1.0.0 From 5572eecef50fc93b9ccbbc8be354a078bb7f0941 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Tue, 28 Oct 2025 11:36:33 -0500 Subject: [PATCH 27/67] test: favortie-service now have loadtest --- favourite-service/loadtest/docker-compose.yml | 13 ++ favourite-service/loadtest/locustfile.py | 38 ++++++ .../loadtest/requirements-dev.txt | 1 + loadtest-compose.yml | 22 ---- user-service/loadtest/Dockerfile | 13 -- user-service/loadtest/locustfile.py | 122 ------------------ user-service/loadtest/requirements.txt | 4 - 7 files changed, 52 insertions(+), 161 deletions(-) create mode 100644 favourite-service/loadtest/docker-compose.yml create mode 100644 favourite-service/loadtest/locustfile.py create mode 100644 favourite-service/loadtest/requirements-dev.txt delete mode 100644 loadtest-compose.yml delete mode 100644 user-service/loadtest/Dockerfile delete mode 100644 user-service/loadtest/locustfile.py delete mode 100644 user-service/loadtest/requirements.txt diff --git a/favourite-service/loadtest/docker-compose.yml b/favourite-service/loadtest/docker-compose.yml new file mode 100644 index 000000000..113104cfd --- /dev/null +++ b/favourite-service/loadtest/docker-compose.yml @@ -0,0 +1,13 @@ +version: '3.8' + +services: + locust: + image: locustio/locust:2.16.0 + restart: unless-stopped + volumes: + - ./locustfile.py:/mnt/locust/locustfile.py:ro + ports: + - "8089:8089" + environment: + - TARGET_HOST=${TARGET_HOST:-http://host.docker.internal:8080} + command: -f /mnt/locust/locustfile.py --host ${TARGET_HOST:-http://host.docker.internal:8080} diff --git a/favourite-service/loadtest/locustfile.py b/favourite-service/loadtest/locustfile.py new file mode 100644 index 000000000..b4ca01478 --- /dev/null +++ b/favourite-service/loadtest/locustfile.py @@ -0,0 +1,38 @@ +from locust import HttpUser, task, between +import random +import datetime +import json + +DATE_FMT = "%d-%m-%Y__%H:%M:%S:%f" + + +class FavouriteUser(HttpUser): + """Simple Locust user that exercises the Favourite service. + + - GET /api/favourites (list) + - POST /api/favourites (create) + """ + + wait_time = between(1, 3) + + @task(7) + def list_favourites(self): + self.client.get("/api/favourites", name="GET /api/favourites") + + @task(3) + def create_favourite(self): + user_id = random.randint(1, 100) + product_id = random.randint(1, 100) + like_date = datetime.datetime.utcnow().strftime(DATE_FMT) + payload = { + "userId": user_id, + "productId": product_id, + "likeDate": like_date + } + headers = {"Content-Type": "application/json"} + self.client.post( + "/api/favourites", + data=json.dumps(payload), + headers=headers, + name="POST /api/favourites", + ) diff --git a/favourite-service/loadtest/requirements-dev.txt b/favourite-service/loadtest/requirements-dev.txt new file mode 100644 index 000000000..25fca74c3 --- /dev/null +++ b/favourite-service/loadtest/requirements-dev.txt @@ -0,0 +1 @@ +locust==2.16.0 diff --git a/loadtest-compose.yml b/loadtest-compose.yml deleted file mode 100644 index bd003ba1c..000000000 --- a/loadtest-compose.yml +++ /dev/null @@ -1,22 +0,0 @@ -version: '3' - -services: - locust: - build: - context: ./user-service/loadtest - ports: - - 8089:8089 - networks: - - microservices_network - depends_on: - - api-gateway-container - environment: - - LOCUST_USERS=100 - - LOCUST_SPAWN_RATE=10 - - LOCUST_RUN_TIME=5m - - TARGET_HOST=http://api-gateway-container:8080 - command: sh -c "locust -f locustfile.py --host ${TARGET_HOST} --web-host 0.0.0.0 --web-port 8089" - -networks: - microservices_network: - driver: bridge diff --git a/user-service/loadtest/Dockerfile b/user-service/loadtest/Dockerfile deleted file mode 100644 index 53584b37a..000000000 --- a/user-service/loadtest/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM python:3.11-slim -WORKDIR /loadtest - -COPY requirements.txt ./ -RUN pip install --no-cache-dir -r requirements.txt - -COPY locustfile.py ./ - -ENV LOCUSTFILE=locustfile.py -EXPOSE 8089 - -ENTRYPOINT ["locust"] -CMD ["-f", "locustfile.py", "--host", "http://api-gateway-container:8080", "--web-host", "0.0.0.0", "--web-port", "8089"] diff --git a/user-service/loadtest/locustfile.py b/user-service/loadtest/locustfile.py deleted file mode 100644 index 81e79af7d..000000000 --- a/user-service/loadtest/locustfile.py +++ /dev/null @@ -1,122 +0,0 @@ -from locust import HttpUser, task, between, events -import random -import string -import json -import time - - -def rand_username(): - return "user_" + ''.join(random.choices(string.ascii_lowercase + string.digits, k=8)) - -def rand_name(): - return ''.join(random.choices(string.ascii_letters, k=6)) - - -class UserBehavior(HttpUser): - wait_time = between(0.5, 2.0) - - def on_start(self): - self.my_users = [] - - @task(15) - def list_users(self): - with self.client.get('/api/users', catch_response=True, name="GET /api/users") as resp: - if resp.status_code == 200: - try: - data = resp.json() - # expects the API to return a DTO collection with 'collection' property - if isinstance(data, dict) and 'collection' in data: - pass - except Exception: - pass - - @task(25) - def create_user(self): - username = rand_username() - payload = { - "firstName": rand_name(), - "lastName": rand_name(), - "email": f"{username}@example.com", - "phone": "+1-555-0123", - "imageUrl": "https://example.com/avatar.png", - "credential": { - "username": username, - "password": "LocustPass!23" - } - } - with self.client.post('/api/users', json=payload, catch_response=True, name="POST /api/users") as resp: - if resp.status_code == 200 or resp.status_code == 201: - try: - u = resp.json() - if u and 'userId' in u: - self.my_users.append(u['userId']) - except Exception: - pass - else: - resp.failure(f"Unexpected status: {resp.status_code}") - - @task(20) - def get_user_by_id(self): - if not self.my_users: - r = self.client.get('/api/users') - try: - data = r.json() - coll = data.get('collection', []) if isinstance(data, dict) else [] - if coll: - uid = coll[0].get('userId') - if uid: - self.client.get(f'/api/users/{uid}', name="GET /api/users/:id") - except Exception: - pass - return - - user_id = random.choice(self.my_users) - self.client.get(f'/api/users/{user_id}', name="GET /api/users/:id") - - @task(10) - def find_by_username(self): - if not self.my_users: - return - r = self.client.get('/api/users') - try: - data = r.json() - coll = data.get('collection', []) if isinstance(data, dict) else [] - if coll: - candidate = random.choice(coll) - cred = candidate.get('credential') or candidate.get('credentialDto') - if cred and 'username' in cred: - self.client.get(f"/api/users/username/{cred['username']}", name="GET /api/users/username/:username") - except Exception: - pass - - @task(10) - def update_user(self): - if not self.my_users: - return - user_id = random.choice(self.my_users) - payload = { - "userId": user_id, - "firstName": "Updated_" + rand_name(), - "lastName": rand_name(), - "email": f"updated_{user_id}@example.com", - "phone": "+1-999-9999", - } - with self.client.put(f'/api/users/{user_id}', json=payload, catch_response=True, name="PUT /api/users/:id") as resp: - if not (200 <= resp.status_code < 300): - resp.failure(f"Unexpected status: {resp.status_code}") - - @task(5) - def delete_user(self): - if not self.my_users: - return - user_id = self.my_users.pop(0) - with self.client.delete(f'/api/users/{user_id}', catch_response=True, name="DELETE /api/users/:id") as resp: - if not (200 <= resp.status_code < 300): - resp.failure(f"Unexpected status: {resp.status_code}") - - -@events.quitting.add_listener -def _(environment, **kw): - print("Quitting. Summary:") - if environment.stats.total: - print(environment.stats.total) diff --git a/user-service/loadtest/requirements.txt b/user-service/loadtest/requirements.txt deleted file mode 100644 index d74505ba6..000000000 --- a/user-service/loadtest/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -locust -locust==2.21.0 -requests==2.31.0 -python-dotenv==1.0.0 From 69f80fe118af325a0cc10443605d73b3d83b25ae Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Tue, 28 Oct 2025 11:44:25 -0500 Subject: [PATCH 28/67] fix --- favourite-service/loadtest/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/favourite-service/loadtest/docker-compose.yml b/favourite-service/loadtest/docker-compose.yml index 113104cfd..ea91f286e 100644 --- a/favourite-service/loadtest/docker-compose.yml +++ b/favourite-service/loadtest/docker-compose.yml @@ -1,4 +1,4 @@ -version: '3.8' +version: '3.3' services: locust: From aa41cd87bf17558cd6b21a66c039c81294b1bba2 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Tue, 28 Oct 2025 13:17:01 -0500 Subject: [PATCH 29/67] fix: fix network in docker-compose locust --- favourite-service/loadtest/docker-compose.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/favourite-service/loadtest/docker-compose.yml b/favourite-service/loadtest/docker-compose.yml index ea91f286e..06bc2516f 100644 --- a/favourite-service/loadtest/docker-compose.yml +++ b/favourite-service/loadtest/docker-compose.yml @@ -7,7 +7,9 @@ services: volumes: - ./locustfile.py:/mnt/locust/locustfile.py:ro ports: - - "8089:8089" + - "8089:8089" environment: - - TARGET_HOST=${TARGET_HOST:-http://host.docker.internal:8080} - command: -f /mnt/locust/locustfile.py --host ${TARGET_HOST:-http://host.docker.internal:8080} + - TARGET_HOST=http://favourite-service-container:8800 + command: -f /mnt/locust/locustfile.py --host http://favourite-service-container:8800 + networks: + - microservices_network From 33b8c5dfe60a2fa9e55cc31164f05fdfc1e5713e Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Tue, 28 Oct 2025 13:19:05 -0500 Subject: [PATCH 30/67] fix: new changes in network --- favourite-service/loadtest/docker-compose.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/favourite-service/loadtest/docker-compose.yml b/favourite-service/loadtest/docker-compose.yml index 06bc2516f..3377e13ad 100644 --- a/favourite-service/loadtest/docker-compose.yml +++ b/favourite-service/loadtest/docker-compose.yml @@ -12,4 +12,9 @@ services: - TARGET_HOST=http://favourite-service-container:8800 command: -f /mnt/locust/locustfile.py --host http://favourite-service-container:8800 networks: - - microservices_network + - microservices_network + +networks: + microservices_network: + external: true + name: ecommerce-microservice-backend-app_microservices_network From f6c6e24991c9786967b84cc86490253cde9bc1da Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Tue, 28 Oct 2025 13:26:15 -0500 Subject: [PATCH 31/67] fix: other fix for network docker-compose --- favourite-service/loadtest/docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/favourite-service/loadtest/docker-compose.yml b/favourite-service/loadtest/docker-compose.yml index 3377e13ad..fff39daa4 100644 --- a/favourite-service/loadtest/docker-compose.yml +++ b/favourite-service/loadtest/docker-compose.yml @@ -16,5 +16,5 @@ services: networks: microservices_network: - external: true - name: ecommerce-microservice-backend-app_microservices_network + external: + name: ecommerce-microservice-backend-app_microservices_network From 70d0a3cec6cb71b74fcb1584e44e7919ed61a4d5 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Tue, 28 Oct 2025 13:31:54 -0500 Subject: [PATCH 32/67] fix: fixing some urls --- favourite-service/loadtest/docker-compose.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/favourite-service/loadtest/docker-compose.yml b/favourite-service/loadtest/docker-compose.yml index fff39daa4..b2a494c00 100644 --- a/favourite-service/loadtest/docker-compose.yml +++ b/favourite-service/loadtest/docker-compose.yml @@ -9,12 +9,11 @@ services: ports: - "8089:8089" environment: - - TARGET_HOST=http://favourite-service-container:8800 - command: -f /mnt/locust/locustfile.py --host http://favourite-service-container:8800 + - TARGET_HOST=${TARGET_HOST:-http://api-gateway-container:8080/favourite-service} networks: - microservices_network + command: -f /mnt/locust/locustfile.py --host ${TARGET_HOST:-http://api-gateway-container:8080/favourite-service} networks: microservices_network: - external: - name: ecommerce-microservice-backend-app_microservices_network + external: true From 7fb20a7c983c6d15f0e0fd8479ae2ca327426be0 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Tue, 28 Oct 2025 13:33:10 -0500 Subject: [PATCH 33/67] fix: fixing more urls --- favourite-service/loadtest/docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/favourite-service/loadtest/docker-compose.yml b/favourite-service/loadtest/docker-compose.yml index b2a494c00..24a678621 100644 --- a/favourite-service/loadtest/docker-compose.yml +++ b/favourite-service/loadtest/docker-compose.yml @@ -11,9 +11,9 @@ services: environment: - TARGET_HOST=${TARGET_HOST:-http://api-gateway-container:8080/favourite-service} networks: - - microservices_network + - ecommerce-microservice-backend-app_microservices_network command: -f /mnt/locust/locustfile.py --host ${TARGET_HOST:-http://api-gateway-container:8080/favourite-service} networks: - microservices_network: + ecommerce-microservice-backend-app_microservices_network: external: true From a6275921ea485806a88dce3c86ff7566808927de Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Tue, 28 Oct 2025 14:41:10 -0500 Subject: [PATCH 34/67] feature: testing kubernetes with google --- k8s/staging/api-gateway.yml | 36 +++ k8s/staging/services.yml | 295 +++++++++++++++++++++++ pipelines/gke-stage/cloudbuild-stage.yml | 78 ++++++ 3 files changed, 409 insertions(+) create mode 100644 k8s/staging/api-gateway.yml create mode 100644 k8s/staging/services.yml create mode 100644 pipelines/gke-stage/cloudbuild-stage.yml diff --git a/k8s/staging/api-gateway.yml b/k8s/staging/api-gateway.yml new file mode 100644 index 000000000..d2236fb8d --- /dev/null +++ b/k8s/staging/api-gateway.yml @@ -0,0 +1,36 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: api-gateway +spec: + replicas: 1 + selector: + matchLabels: + app: api-gateway + template: + metadata: + labels: + app: api-gateway + spec: + containers: + - name: api-gateway + image: gcr.io/PROJECT_ID/api-gateway:IMAGE_TAG + ports: + - containerPort: 8080 + env: + - name: SPRING_PROFILES_ACTIVE + value: stage + +--- + +apiVersion: v1 +kind: Service +metadata: + name: api-gateway +spec: + selector: + app: api-gateway + type: LoadBalancer + ports: + - port: 8080 + targetPort: 8080 diff --git a/k8s/staging/services.yml b/k8s/staging/services.yml new file mode 100644 index 000000000..31533fd6a --- /dev/null +++ b/k8s/staging/services.yml @@ -0,0 +1,295 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: cloud-config +spec: + replicas: 1 + selector: + matchLabels: + app: cloud-config + template: + metadata: + labels: + app: cloud-config + spec: + containers: + - name: cloud-config + image: gcr.io/PROJECT_ID/cloud-config:IMAGE_TAG + ports: + - containerPort: 8080 + +--- +apiVersion: v1 +kind: Service +metadata: + name: cloud-config +spec: + selector: + app: cloud-config + ports: + - port: 8080 + targetPort: 8080 + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: service-discovery +spec: + replicas: 1 + selector: + matchLabels: + app: service-discovery + template: + metadata: + labels: + app: service-discovery + spec: + containers: + - name: service-discovery + image: gcr.io/PROJECT_ID/service-discovery:IMAGE_TAG + ports: + - containerPort: 8761 + +--- +apiVersion: v1 +kind: Service +metadata: + name: service-discovery +spec: + selector: + app: service-discovery + ports: + - port: 8761 + targetPort: 8761 + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: proxy-client +spec: + replicas: 1 + selector: + matchLabels: + app: proxy-client + template: + metadata: + labels: + app: proxy-client + spec: + containers: + - name: proxy-client + image: gcr.io/PROJECT_ID/proxy-client:IMAGE_TAG + ports: + - containerPort: 8080 + +--- +apiVersion: v1 +kind: Service +metadata: + name: proxy-client +spec: + selector: + app: proxy-client + ports: + - port: 8080 + targetPort: 8080 + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: user-service +spec: + replicas: 1 + selector: + matchLabels: + app: user-service + template: + metadata: + labels: + app: user-service + spec: + containers: + - name: user-service + image: gcr.io/PROJECT_ID/user-service:IMAGE_TAG + ports: + - containerPort: 8080 + +--- +apiVersion: v1 +kind: Service +metadata: + name: user-service +spec: + selector: + app: user-service + ports: + - port: 8080 + targetPort: 8080 + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: product-service +spec: + replicas: 1 + selector: + matchLabels: + app: product-service + template: + metadata: + labels: + app: product-service + spec: + containers: + - name: product-service + image: gcr.io/PROJECT_ID/product-service:IMAGE_TAG + ports: + - containerPort: 8080 + +--- +apiVersion: v1 +kind: Service +metadata: + name: product-service +spec: + selector: + app: product-service + ports: + - port: 8080 + targetPort: 8080 + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: order-service +spec: + replicas: 1 + selector: + matchLabels: + app: order-service + template: + metadata: + labels: + app: order-service + spec: + containers: + - name: order-service + image: gcr.io/PROJECT_ID/order-service:IMAGE_TAG + ports: + - containerPort: 8080 + +--- +apiVersion: v1 +kind: Service +metadata: + name: order-service +spec: + selector: + app: order-service + ports: + - port: 8080 + targetPort: 8080 + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: payment-service +spec: + replicas: 1 + selector: + matchLabels: + app: payment-service + template: + metadata: + labels: + app: payment-service + spec: + containers: + - name: payment-service + image: gcr.io/PROJECT_ID/payment-service:IMAGE_TAG + ports: + - containerPort: 8080 + +--- +apiVersion: v1 +kind: Service +metadata: + name: payment-service +spec: + selector: + app: payment-service + ports: + - port: 8080 + targetPort: 8080 + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: favourite-service +spec: + replicas: 1 + selector: + matchLabels: + app: favourite-service + template: + metadata: + labels: + app: favourite-service + spec: + containers: + - name: favourite-service + image: gcr.io/PROJECT_ID/favourite-service:IMAGE_TAG + ports: + - containerPort: 8080 + +--- +apiVersion: v1 +kind: Service +metadata: + name: favourite-service +spec: + selector: + app: favourite-service + ports: + - port: 8080 + targetPort: 8080 + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: shipping-service +spec: + replicas: 1 + selector: + matchLabels: + app: shipping-service + template: + metadata: + labels: + app: shipping-service + spec: + containers: + - name: shipping-service + image: gcr.io/PROJECT_ID/shipping-service:IMAGE_TAG + ports: + - containerPort: 8080 + +--- +apiVersion: v1 +kind: Service +metadata: + name: shipping-service +spec: + selector: + app: shipping-service + ports: + - port: 8080 + targetPort: 8080 diff --git a/pipelines/gke-stage/cloudbuild-stage.yml b/pipelines/gke-stage/cloudbuild-stage.yml new file mode 100644 index 000000000..7db86843e --- /dev/null +++ b/pipelines/gke-stage/cloudbuild-stage.yml @@ -0,0 +1,78 @@ +substitutions: + _CLUSTER_NAME: "YOUR_GKE_CLUSTER_NAME" + _CLUSTER_ZONE: "YOUR_GKE_CLUSTER_ZONE" + _NAMESPACE: "stage" + +steps: + - name: 'gcr.io/cloud-builders/mvn' + args: ['clean', 'test'] + + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/api-gateway:$SHORT_SHA', '-f', 'api-gateway/Dockerfile', '.'] + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/cloud-config:$SHORT_SHA', '-f', 'cloud-config/Dockerfile', '.'] + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/service-discovery:$SHORT_SHA', '-f', 'service-discovery/Dockerfile', '.'] + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/proxy-client:$SHORT_SHA', '-f', 'proxy-client/Dockerfile', '.'] + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/user-service:$SHORT_SHA', '-f', 'user-service/Dockerfile', '.'] + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/product-service:$SHORT_SHA', '-f', 'product-service/Dockerfile', '.'] + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/order-service:$SHORT_SHA', '-f', 'order-service/Dockerfile', '.'] + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/payment-service:$SHORT_SHA', '-f', 'payment-service/Dockerfile', '.'] + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/favourite-service:$SHORT_SHA', '-f', 'favourite-service/Dockerfile', '.'] + - name: 'gcr.io/cloud-builders/docker' + args: ['build', '-t', 'gcr.io/$PROJECT_ID/shipping-service:$SHORT_SHA', '-f', 'shipping-service/Dockerfile', '.'] + +images: + - 'gcr.io/$PROJECT_ID/api-gateway:$SHORT_SHA' + - 'gcr.io/$PROJECT_ID/cloud-config:$SHORT_SHA' + - 'gcr.io/$PROJECT_ID/service-discovery:$SHORT_SHA' + - 'gcr.io/$PROJECT_ID/proxy-client:$SHORT_SHA' + - 'gcr.io/$PROJECT_ID/user-service:$SHORT_SHA' + - 'gcr.io/$PROJECT_ID/product-service:$SHORT_SHA' + - 'gcr.io/$PROJECT_ID/order-service:$SHORT_SHA' + - 'gcr.io/$PROJECT_ID/payment-service:$SHORT_SHA' + - 'gcr.io/$PROJECT_ID/favourite-service:$SHORT_SHA' + - 'gcr.io/$PROJECT_ID/shipping-service:$SHORT_SHA' + + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + entrypoint: 'bash' + args: + - '-c' + - | + set -euo pipefail + echo "Obteniendo credenciales del cluster GKE ${_CLUSTER_NAME}..." + gcloud container clusters get-credentials ${_CLUSTER_NAME} --zone ${_CLUSTER_ZONE} --project ${PROJECT_ID} + kubectl create namespace ${_NAMESPACE} || true + + echo "Sustituyendo placeholders en manifests k8s..." + for f in k8s/staging/*.yml; do + sed -i "s|IMAGE_TAG|${SHORT_SHA}|g" "$f" || true + sed -i "s|PROJECT_ID|${PROJECT_ID}|g" "$f" || true + done + + echo "Aplicando manifests en namespace ${_NAMESPACE}..." + kubectl apply -n ${_NAMESPACE} -f k8s/staging/ + + echo "Esperando que los deployments est茅n listos..." + kubectl -n ${_NAMESPACE} wait --for=condition=available --all deployments --timeout=300s + + echo "Creando pod temporal para ejecutar pruebas dentro del cluster..." + kubectl -n ${_NAMESPACE} run stage-tester --image=curlimages/curl --restart=Never --command -- sleep 3600 || true + kubectl -n ${_NAMESPACE} wait --for=condition=ready pod -l run=stage-tester --timeout=60s + + echo "Copiando y ejecutando script de tests..." + kubectl -n ${_NAMESPACE} cp k8s/test-runner.sh stage-tester:/test-runner.sh + kubectl -n ${_NAMESPACE} exec stage-tester -- chmod +x /test-runner.sh + kubectl -n ${_NAMESPACE} exec stage-tester -- /test-runner.sh ${_NAMESPACE} + + echo "Borrando pod temporal de test..." + kubectl -n ${_NAMESPACE} delete pod stage-tester --ignore-not-found + +options: + logging: CLOUD_LOGGING_ONLY From 1164a9858cb1e02463502009725a5739c30276e8 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Tue, 28 Oct 2025 14:51:33 -0500 Subject: [PATCH 35/67] fix: changes in cloudbuild --- pipelines/gke-stage/cloudbuild-stage.yml | 43 +++++++++++++++--------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/pipelines/gke-stage/cloudbuild-stage.yml b/pipelines/gke-stage/cloudbuild-stage.yml index 7db86843e..c60191475 100644 --- a/pipelines/gke-stage/cloudbuild-stage.yml +++ b/pipelines/gke-stage/cloudbuild-stage.yml @@ -28,26 +28,17 @@ steps: - name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', 'gcr.io/$PROJECT_ID/shipping-service:$SHORT_SHA', '-f', 'shipping-service/Dockerfile', '.'] -images: - - 'gcr.io/$PROJECT_ID/api-gateway:$SHORT_SHA' - - 'gcr.io/$PROJECT_ID/cloud-config:$SHORT_SHA' - - 'gcr.io/$PROJECT_ID/service-discovery:$SHORT_SHA' - - 'gcr.io/$PROJECT_ID/proxy-client:$SHORT_SHA' - - 'gcr.io/$PROJECT_ID/user-service:$SHORT_SHA' - - 'gcr.io/$PROJECT_ID/product-service:$SHORT_SHA' - - 'gcr.io/$PROJECT_ID/order-service:$SHORT_SHA' - - 'gcr.io/$PROJECT_ID/payment-service:$SHORT_SHA' - - 'gcr.io/$PROJECT_ID/favourite-service:$SHORT_SHA' - - 'gcr.io/$PROJECT_ID/shipping-service:$SHORT_SHA' - - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' args: - '-c' - | set -euo pipefail + echo "Obteniendo credenciales del cluster GKE ${_CLUSTER_NAME}..." gcloud container clusters get-credentials ${_CLUSTER_NAME} --zone ${_CLUSTER_ZONE} --project ${PROJECT_ID} + + echo "Creando namespace si no existe..." kubectl create namespace ${_NAMESPACE} || true echo "Sustituyendo placeholders en manifests k8s..." @@ -56,13 +47,21 @@ images: sed -i "s|PROJECT_ID|${PROJECT_ID}|g" "$f" || true done - echo "Aplicando manifests en namespace ${_NAMESPACE}..." - kubectl apply -n ${_NAMESPACE} -f k8s/staging/ + echo "Aplicando core services..." + kubectl apply -n ${_NAMESPACE} -f k8s/staging/core.yml - echo "Esperando que los deployments est茅n listos..." + echo "Esperando core deployments..." + kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/cloud-config --timeout=120s + kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/service-discovery --timeout=120s + kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/proxy-client --timeout=120s + + echo "Aplicando dependent services..." + kubectl apply -n ${_NAMESPACE} -f k8s/staging/compose.yml + + echo "Esperando dependent deployments..." kubectl -n ${_NAMESPACE} wait --for=condition=available --all deployments --timeout=300s - echo "Creando pod temporal para ejecutar pruebas dentro del cluster..." + echo "Creando pod temporal para ejecutar tests..." kubectl -n ${_NAMESPACE} run stage-tester --image=curlimages/curl --restart=Never --command -- sleep 3600 || true kubectl -n ${_NAMESPACE} wait --for=condition=ready pod -l run=stage-tester --timeout=60s @@ -74,5 +73,17 @@ images: echo "Borrando pod temporal de test..." kubectl -n ${_NAMESPACE} delete pod stage-tester --ignore-not-found +images: + - 'gcr.io/$PROJECT_ID/api-gateway:$SHORT_SHA' + - 'gcr.io/$PROJECT_ID/cloud-config:$SHORT_SHA' + - 'gcr.io/$PROJECT_ID/service-discovery:$SHORT_SHA' + - 'gcr.io/$PROJECT_ID/proxy-client:$SHORT_SHA' + - 'gcr.io/$PROJECT_ID/user-service:$SHORT_SHA' + - 'gcr.io/$PROJECT_ID/product-service:$SHORT_SHA' + - 'gcr.io/$PROJECT_ID/order-service:$SHORT_SHA' + - 'gcr.io/$PROJECT_ID/payment-service:$SHORT_SHA' + - 'gcr.io/$PROJECT_ID/favourite-service:$SHORT_SHA' + - 'gcr.io/$PROJECT_ID/shipping-service:$SHORT_SHA' + options: logging: CLOUD_LOGGING_ONLY From 8cceb87f8cf0272b3014e5fcdd8c9eebfa8b71d7 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Tue, 28 Oct 2025 15:02:17 -0500 Subject: [PATCH 36/67] fix: fixing the build in pipeline --- pipelines/gke-stage/cloudbuild-stage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipelines/gke-stage/cloudbuild-stage.yml b/pipelines/gke-stage/cloudbuild-stage.yml index c60191475..cfa279af3 100644 --- a/pipelines/gke-stage/cloudbuild-stage.yml +++ b/pipelines/gke-stage/cloudbuild-stage.yml @@ -5,7 +5,7 @@ substitutions: steps: - name: 'gcr.io/cloud-builders/mvn' - args: ['clean', 'test'] + args: ['clean', 'package', '-DskipTests'] - name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', 'gcr.io/$PROJECT_ID/api-gateway:$SHORT_SHA', '-f', 'api-gateway/Dockerfile', '.'] From cd7bfa5d1dcbe96dd584dd594f85c0b39e31c638 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Tue, 28 Oct 2025 15:16:58 -0500 Subject: [PATCH 37/67] fix: changing the cluster location --- pipelines/gke-stage/cloudbuild-stage.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pipelines/gke-stage/cloudbuild-stage.yml b/pipelines/gke-stage/cloudbuild-stage.yml index cfa279af3..293b6f27f 100644 --- a/pipelines/gke-stage/cloudbuild-stage.yml +++ b/pipelines/gke-stage/cloudbuild-stage.yml @@ -1,6 +1,6 @@ substitutions: - _CLUSTER_NAME: "YOUR_GKE_CLUSTER_NAME" - _CLUSTER_ZONE: "YOUR_GKE_CLUSTER_ZONE" + _CLUSTER_NAME: "mi-primer-cluster-taller" + _CLUSTER_ZONE: "us-central1" _NAMESPACE: "stage" steps: From 725d4ac6cc0234fcbface1445f95248bcdfdc2c3 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Tue, 28 Oct 2025 15:38:53 -0500 Subject: [PATCH 38/67] fix: fixing some names in k8s --- k8s/staging/api-gateway.yml | 36 -- k8s/staging/compose.yml | 399 +++++++++++++++++++++++ k8s/staging/core.yml | 99 ++++++ k8s/staging/services.yml | 295 ----------------- pipelines/gke-stage/cloudbuild-stage.yml | 8 - 5 files changed, 498 insertions(+), 339 deletions(-) delete mode 100644 k8s/staging/api-gateway.yml create mode 100644 k8s/staging/compose.yml create mode 100644 k8s/staging/core.yml delete mode 100644 k8s/staging/services.yml diff --git a/k8s/staging/api-gateway.yml b/k8s/staging/api-gateway.yml deleted file mode 100644 index d2236fb8d..000000000 --- a/k8s/staging/api-gateway.yml +++ /dev/null @@ -1,36 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: api-gateway -spec: - replicas: 1 - selector: - matchLabels: - app: api-gateway - template: - metadata: - labels: - app: api-gateway - spec: - containers: - - name: api-gateway - image: gcr.io/PROJECT_ID/api-gateway:IMAGE_TAG - ports: - - containerPort: 8080 - env: - - name: SPRING_PROFILES_ACTIVE - value: stage - ---- - -apiVersion: v1 -kind: Service -metadata: - name: api-gateway -spec: - selector: - app: api-gateway - type: LoadBalancer - ports: - - port: 8080 - targetPort: 8080 diff --git a/k8s/staging/compose.yml b/k8s/staging/compose.yml new file mode 100644 index 000000000..87090624c --- /dev/null +++ b/k8s/staging/compose.yml @@ -0,0 +1,399 @@ +# ----------------------------- +# API Gateway +# ----------------------------- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: api-gateway +spec: + replicas: 1 + selector: + matchLabels: + app: api-gateway + template: + metadata: + labels: + app: api-gateway + spec: + containers: + - name: api-gateway + image: selimhorri/api-gateway-ecommerce-boot:0.1.0 + ports: + - containerPort: 8080 + env: + - name: SPRING_PROFILES_ACTIVE + value: "dev" + - name: SPRING_ZIPKIN_BASE_URL + value: "http://zipkin:9411" + - name: SPRING_CONFIG_IMPORT + value: "optional:configserver:http://cloud-config:9296/" + - name: EUREKA_CLIENT_REGION + value: "default" + - name: EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT + value: "myzone" + - name: EUREKA_CLIENT_SERVICEURL_MYZONE + value: "http://service-discovery:8761/eureka" + - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE + value: "http://service-discovery:8761/eureka" +--- +apiVersion: v1 +kind: Service +metadata: + name: api-gateway +spec: + type: ClusterIP + selector: + app: api-gateway + ports: + - port: 8080 + targetPort: 8080 + +# ----------------------------- +# Proxy Client +# ----------------------------- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: proxy-client +spec: + replicas: 1 + selector: + matchLabels: + app: proxy-client + template: + metadata: + labels: + app: proxy-client + spec: + containers: + - name: proxy-client + image: selimhorri/proxy-client-ecommerce-boot:0.1.0 + ports: + - containerPort: 8900 + env: + - name: SPRING_PROFILES_ACTIVE + value: "dev" + - name: SPRING_ZIPKIN_BASE_URL + value: "http://zipkin:9411" + - name: SPRING_CONFIG_IMPORT + value: "optional:configserver:http://cloud-config:9296/" + - name: EUREKA_CLIENT_REGION + value: "default" + - name: EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT + value: "myzone" + - name: EUREKA_CLIENT_SERVICEURL_MYZONE + value: "http://service-discovery:8761/eureka" + - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE + value: "http://service-discovery:8761/eureka" +--- +apiVersion: v1 +kind: Service +metadata: + name: proxy-client +spec: + type: ClusterIP + selector: + app: proxy-client + ports: + - port: 8900 + targetPort: 8900 + +# ----------------------------- +# Order Service +# ----------------------------- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: order-service +spec: + replicas: 1 + selector: + matchLabels: + app: order-service + template: + metadata: + labels: + app: order-service + spec: + containers: + - name: order-service + image: selimhorri/order-service-ecommerce-boot:0.1.0 + ports: + - containerPort: 8300 + env: + - name: SPRING_PROFILES_ACTIVE + value: "dev" + - name: SPRING_ZIPKIN_BASE_URL + value: "http://zipkin:9411" + - name: SPRING_CONFIG_IMPORT + value: "optional:configserver:http://cloud-config:9296/" + - name: EUREKA_CLIENT_REGION + value: "default" + - name: EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT + value: "myzone" + - name: EUREKA_CLIENT_SERVICEURL_MYZONE + value: "http://service-discovery:8761/eureka" + - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE + value: "http://service-discovery:8761/eureka" +--- +apiVersion: v1 +kind: Service +metadata: + name: order-service +spec: + type: ClusterIP + selector: + app: order-service + ports: + - port: 8300 + targetPort: 8300 + +# ----------------------------- +# Payment Service +# ----------------------------- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: payment-service +spec: + replicas: 1 + selector: + matchLabels: + app: payment-service + template: + metadata: + labels: + app: payment-service + spec: + containers: + - name: payment-service + image: selimhorri/payment-service-ecommerce-boot:0.1.0 + ports: + - containerPort: 8400 + env: + - name: SPRING_PROFILES_ACTIVE + value: "dev" + - name: SPRING_ZIPKIN_BASE_URL + value: "http://zipkin:9411" + - name: SPRING_CONFIG_IMPORT + value: "optional:configserver:http://cloud-config:9296/" + - name: EUREKA_CLIENT_REGION + value: "default" + - name: EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT + value: "myzone" + - name: EUREKA_CLIENT_SERVICEURL_MYZONE + value: "http://service-discovery:8761/eureka" + - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE + value: "http://service-discovery:8761/eureka" +--- +apiVersion: v1 +kind: Service +metadata: + name: payment-service +spec: + type: ClusterIP + selector: + app: payment-service + ports: + - port: 8400 + targetPort: 8400 + +# ----------------------------- +# Product Service +# ----------------------------- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: product-service +spec: + replicas: 1 + selector: + matchLabels: + app: product-service + template: + metadata: + labels: + app: product-service + spec: + containers: + - name: product-service + image: selimhorri/product-service-ecommerce-boot:0.1.0 + ports: + - containerPort: 8500 + env: + - name: SPRING_PROFILES_ACTIVE + value: "dev" + - name: SPRING_ZIPKIN_BASE_URL + value: "http://zipkin:9411" + - name: SPRING_CONFIG_IMPORT + value: "optional:configserver:http://cloud-config:9296/" + - name: EUREKA_CLIENT_REGION + value: "default" + - name: EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT + value: "myzone" + - name: EUREKA_CLIENT_SERVICEURL_MYZONE + value: "http://service-discovery:8761/eureka" + - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE + value: "http://service-discovery:8761/eureka" +--- +apiVersion: v1 +kind: Service +metadata: + name: product-service +spec: + type: ClusterIP + selector: + app: product-service + ports: + - port: 8500 + targetPort: 8500 + +# ----------------------------- +# Shipping Service +# ----------------------------- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: shipping-service +spec: + replicas: 1 + selector: + matchLabels: + app: shipping-service + template: + metadata: + labels: + app: shipping-service + spec: + containers: + - name: shipping-service + image: selimhorri/shipping-service-ecommerce-boot:0.1.0 + ports: + - containerPort: 8600 + env: + - name: SPRING_PROFILES_ACTIVE + value: "dev" + - name: SPRING_ZIPKIN_BASE_URL + value: "http://zipkin:9411" + - name: SPRING_CONFIG_IMPORT + value: "optional:configserver:http://cloud-config:9296/" + - name: EUREKA_CLIENT_REGION + value: "default" + - name: EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT + value: "myzone" + - name: EUREKA_CLIENT_SERVICEURL_MYZONE + value: "http://service-discovery:8761/eureka" + - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE + value: "http://service-discovery:8761/eureka" +--- +apiVersion: v1 +kind: Service +metadata: + name: shipping-service +spec: + type: ClusterIP + selector: + app: shipping-service + ports: + - port: 8600 + targetPort: 8600 + +# ----------------------------- +# User Service +# ----------------------------- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: user-service +spec: + replicas: 1 + selector: + matchLabels: + app: user-service + template: + metadata: + labels: + app: user-service + spec: + containers: + - name: user-service + image: selimhorri/user-service-ecommerce-boot:0.1.0 + ports: + - containerPort: 8700 + env: + - name: SPRING_PROFILES_ACTIVE + value: "dev" + - name: SPRING_ZIPKIN_BASE_URL + value: "http://zipkin:9411" + - name: SPRING_CONFIG_IMPORT + value: "optional:configserver:http://cloud-config:9296/" + - name: EUREKA_CLIENT_REGION + value: "default" + - name: EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT + value: "myzone" + - name: EUREKA_CLIENT_SERVICEURL_MYZONE + value: "http://service-discovery:8761/eureka" + - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE + value: "http://service-discovery:8761/eureka" +--- +apiVersion: v1 +kind: Service +metadata: + name: user-service +spec: + type: ClusterIP + selector: + app: user-service + ports: + - port: 8700 + targetPort: 8700 + +# ----------------------------- +# Favourite Service +# ----------------------------- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: favourite-service +spec: + replicas: 1 + selector: + matchLabels: + app: favourite-service + template: + metadata: + labels: + app: favourite-service + spec: + containers: + - name: favourite-service + image: selimhorri/favourite-service-ecommerce-boot:0.1.0 + ports: + - containerPort: 8800 + env: + - name: SPRING_PROFILES_ACTIVE + value: "dev" + - name: SPRING_ZIPKIN_BASE_URL + value: "http://zipkin:9411" + - name: SPRING_CONFIG_IMPORT + value: "optional:configserver:http://cloud-config:9296/" + - name: EUREKA_CLIENT_REGION + value: "default" + - name: EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT + value: "myzone" + - name: EUREKA_CLIENT_SERVICEURL_MYZONE + value: "http://service-discovery:8761/eureka" + - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE + value: "http://service-discovery:8761/eureka" +--- +apiVersion: v1 +kind: Service +metadata: + name: favourite-service +spec: + type: ClusterIP + selector: + app: favourite-service + ports: + - port: 8800 + targetPort: 8800 diff --git a/k8s/staging/core.yml b/k8s/staging/core.yml new file mode 100644 index 000000000..cfe9024f8 --- /dev/null +++ b/k8s/staging/core.yml @@ -0,0 +1,99 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: zipkin +spec: + replicas: 1 + selector: + matchLabels: + app: zipkin + template: + metadata: + labels: + app: zipkin + spec: + containers: + - name: zipkin + image: openzipkin/zipkin + ports: + - containerPort: 9411 +--- +apiVersion: v1 +kind: Service +metadata: + name: zipkin +spec: + type: ClusterIP + selector: + app: zipkin + ports: + - port: 9411 + targetPort: 9411 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: service-discovery +spec: + replicas: 1 + selector: + matchLabels: + app: service-discovery + template: + metadata: + labels: + app: service-discovery + spec: + containers: + - name: service-discovery + image: selimhorri/service-discovery-ecommerce-boot:0.1.0 + ports: + - containerPort: 8761 + env: + - name: SPRING_ZIPKIN_BASE_URL + value: "http://zipkin:9411" + - name: SPRING_CONFIG_IMPORT + value: "optional:configserver:http://cloud-config:9296/" +--- +apiVersion: v1 +kind: Service +metadata: + name: service-discovery +spec: + type: ClusterIP + selector: + app: service-discovery + ports: + - port: 8761 + targetPort: 8761 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: cloud-config +spec: + replicas: 1 + selector: + matchLabels: + app: cloud-config + template: + metadata: + labels: + app: cloud-config + spec: + containers: + - name: cloud-config + image: selimhorri/cloud-config-ecommerce-boot:0.1.0 + ports: + - containerPort: 9296 + env: + - name: SPRING_PROFILES_ACTIVE + value: "dev" + - name: SPRING_ZIPKIN_BASE_URL + value: "http://zipkin:9411" + - name: EUREKA_CLIENT_REGION + value: "default" + - name: EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT + value: "myzone" + - name: EUREKA_CLIENT_SERVICEURL_MYZONE + value: "http://se diff --git a/k8s/staging/services.yml b/k8s/staging/services.yml deleted file mode 100644 index 31533fd6a..000000000 --- a/k8s/staging/services.yml +++ /dev/null @@ -1,295 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: cloud-config -spec: - replicas: 1 - selector: - matchLabels: - app: cloud-config - template: - metadata: - labels: - app: cloud-config - spec: - containers: - - name: cloud-config - image: gcr.io/PROJECT_ID/cloud-config:IMAGE_TAG - ports: - - containerPort: 8080 - ---- -apiVersion: v1 -kind: Service -metadata: - name: cloud-config -spec: - selector: - app: cloud-config - ports: - - port: 8080 - targetPort: 8080 - ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: service-discovery -spec: - replicas: 1 - selector: - matchLabels: - app: service-discovery - template: - metadata: - labels: - app: service-discovery - spec: - containers: - - name: service-discovery - image: gcr.io/PROJECT_ID/service-discovery:IMAGE_TAG - ports: - - containerPort: 8761 - ---- -apiVersion: v1 -kind: Service -metadata: - name: service-discovery -spec: - selector: - app: service-discovery - ports: - - port: 8761 - targetPort: 8761 - ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: proxy-client -spec: - replicas: 1 - selector: - matchLabels: - app: proxy-client - template: - metadata: - labels: - app: proxy-client - spec: - containers: - - name: proxy-client - image: gcr.io/PROJECT_ID/proxy-client:IMAGE_TAG - ports: - - containerPort: 8080 - ---- -apiVersion: v1 -kind: Service -metadata: - name: proxy-client -spec: - selector: - app: proxy-client - ports: - - port: 8080 - targetPort: 8080 - ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: user-service -spec: - replicas: 1 - selector: - matchLabels: - app: user-service - template: - metadata: - labels: - app: user-service - spec: - containers: - - name: user-service - image: gcr.io/PROJECT_ID/user-service:IMAGE_TAG - ports: - - containerPort: 8080 - ---- -apiVersion: v1 -kind: Service -metadata: - name: user-service -spec: - selector: - app: user-service - ports: - - port: 8080 - targetPort: 8080 - ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: product-service -spec: - replicas: 1 - selector: - matchLabels: - app: product-service - template: - metadata: - labels: - app: product-service - spec: - containers: - - name: product-service - image: gcr.io/PROJECT_ID/product-service:IMAGE_TAG - ports: - - containerPort: 8080 - ---- -apiVersion: v1 -kind: Service -metadata: - name: product-service -spec: - selector: - app: product-service - ports: - - port: 8080 - targetPort: 8080 - ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: order-service -spec: - replicas: 1 - selector: - matchLabels: - app: order-service - template: - metadata: - labels: - app: order-service - spec: - containers: - - name: order-service - image: gcr.io/PROJECT_ID/order-service:IMAGE_TAG - ports: - - containerPort: 8080 - ---- -apiVersion: v1 -kind: Service -metadata: - name: order-service -spec: - selector: - app: order-service - ports: - - port: 8080 - targetPort: 8080 - ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: payment-service -spec: - replicas: 1 - selector: - matchLabels: - app: payment-service - template: - metadata: - labels: - app: payment-service - spec: - containers: - - name: payment-service - image: gcr.io/PROJECT_ID/payment-service:IMAGE_TAG - ports: - - containerPort: 8080 - ---- -apiVersion: v1 -kind: Service -metadata: - name: payment-service -spec: - selector: - app: payment-service - ports: - - port: 8080 - targetPort: 8080 - ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: favourite-service -spec: - replicas: 1 - selector: - matchLabels: - app: favourite-service - template: - metadata: - labels: - app: favourite-service - spec: - containers: - - name: favourite-service - image: gcr.io/PROJECT_ID/favourite-service:IMAGE_TAG - ports: - - containerPort: 8080 - ---- -apiVersion: v1 -kind: Service -metadata: - name: favourite-service -spec: - selector: - app: favourite-service - ports: - - port: 8080 - targetPort: 8080 - ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: shipping-service -spec: - replicas: 1 - selector: - matchLabels: - app: shipping-service - template: - metadata: - labels: - app: shipping-service - spec: - containers: - - name: shipping-service - image: gcr.io/PROJECT_ID/shipping-service:IMAGE_TAG - ports: - - containerPort: 8080 - ---- -apiVersion: v1 -kind: Service -metadata: - name: shipping-service -spec: - selector: - app: shipping-service - ports: - - port: 8080 - targetPort: 8080 diff --git a/pipelines/gke-stage/cloudbuild-stage.yml b/pipelines/gke-stage/cloudbuild-stage.yml index 293b6f27f..e53a0030a 100644 --- a/pipelines/gke-stage/cloudbuild-stage.yml +++ b/pipelines/gke-stage/cloudbuild-stage.yml @@ -61,14 +61,6 @@ steps: echo "Esperando dependent deployments..." kubectl -n ${_NAMESPACE} wait --for=condition=available --all deployments --timeout=300s - echo "Creando pod temporal para ejecutar tests..." - kubectl -n ${_NAMESPACE} run stage-tester --image=curlimages/curl --restart=Never --command -- sleep 3600 || true - kubectl -n ${_NAMESPACE} wait --for=condition=ready pod -l run=stage-tester --timeout=60s - - echo "Copiando y ejecutando script de tests..." - kubectl -n ${_NAMESPACE} cp k8s/test-runner.sh stage-tester:/test-runner.sh - kubectl -n ${_NAMESPACE} exec stage-tester -- chmod +x /test-runner.sh - kubectl -n ${_NAMESPACE} exec stage-tester -- /test-runner.sh ${_NAMESPACE} echo "Borrando pod temporal de test..." kubectl -n ${_NAMESPACE} delete pod stage-tester --ignore-not-found From b9616162113822c9b269cfd54a250fd0a4b5acbe Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Tue, 28 Oct 2025 17:59:51 -0500 Subject: [PATCH 39/67] fix: now the pipeline have more steps for better debuging --- pipelines/gke-stage/cloudbuild-stage.yml | 54 +++++++++++++----------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/pipelines/gke-stage/cloudbuild-stage.yml b/pipelines/gke-stage/cloudbuild-stage.yml index e53a0030a..0ec090d33 100644 --- a/pipelines/gke-stage/cloudbuild-stage.yml +++ b/pipelines/gke-stage/cloudbuild-stage.yml @@ -30,40 +30,44 @@ steps: - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' - args: - - '-c' - - | - set -euo pipefail + args: ['-c', 'gcloud container clusters get-credentials ${_CLUSTER_NAME} --zone ${_CLUSTER_ZONE} --project ${PROJECT_ID}'] - echo "Obteniendo credenciales del cluster GKE ${_CLUSTER_NAME}..." - gcloud container clusters get-credentials ${_CLUSTER_NAME} --zone ${_CLUSTER_ZONE} --project ${PROJECT_ID} + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + entrypoint: 'bash' + args: ['-c', 'kubectl create namespace ${_NAMESPACE} || true'] - echo "Creando namespace si no existe..." - kubectl create namespace ${_NAMESPACE} || true + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + entrypoint: 'bash' + args: ['-c', 'for f in k8s/staging/*.yml; do sed -i "s|IMAGE_TAG|${SHORT_SHA}|g" "$f"; sed -i "s|PROJECT_ID|${PROJECT_ID}|g" "$f"; done'] - echo "Sustituyendo placeholders en manifests k8s..." - for f in k8s/staging/*.yml; do - sed -i "s|IMAGE_TAG|${SHORT_SHA}|g" "$f" || true - sed -i "s|PROJECT_ID|${PROJECT_ID}|g" "$f" || true - done + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + entrypoint: 'bash' + args: ['-c', 'kubectl apply -n ${_NAMESPACE} -f k8s/staging/core.yml'] - echo "Aplicando core services..." - kubectl apply -n ${_NAMESPACE} -f k8s/staging/core.yml + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + entrypoint: 'bash' + args: ['-c', 'kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/cloud-config --timeout=120s'] - echo "Esperando core deployments..." - kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/cloud-config --timeout=120s - kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/service-discovery --timeout=120s - kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/proxy-client --timeout=120s + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + entrypoint: 'bash' + args: ['-c', 'kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/service-discovery --timeout=120s'] - echo "Aplicando dependent services..." - kubectl apply -n ${_NAMESPACE} -f k8s/staging/compose.yml + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + entrypoint: 'bash' + args: ['-c', 'kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/proxy-client --timeout=120s'] - echo "Esperando dependent deployments..." - kubectl -n ${_NAMESPACE} wait --for=condition=available --all deployments --timeout=300s + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + entrypoint: 'bash' + args: ['-c', 'kubectl apply -n ${_NAMESPACE} -f k8s/staging/compose.yml'] + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + entrypoint: 'bash' + args: ['-c', 'kubectl -n ${_NAMESPACE} wait --for=condition=available --all deployments --timeout=300s'] + + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + entrypoint: 'bash' + args: ['-c', 'kubectl -n ${_NAMESPACE} delete pod stage-tester --ignore-not-found'] - echo "Borrando pod temporal de test..." - kubectl -n ${_NAMESPACE} delete pod stage-tester --ignore-not-found images: - 'gcr.io/$PROJECT_ID/api-gateway:$SHORT_SHA' From 26da0d410054f33c5e237f00445c0bd62ff06d38 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Tue, 28 Oct 2025 18:28:25 -0500 Subject: [PATCH 40/67] fix: changes in core.yml --- k8s/staging/core.yml | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/k8s/staging/core.yml b/k8s/staging/core.yml index cfe9024f8..e488b632d 100644 --- a/k8s/staging/core.yml +++ b/k8s/staging/core.yml @@ -1,3 +1,6 @@ +# ----------------------------- +# Zipkin +# ----------------------------- apiVersion: apps/v1 kind: Deployment metadata: @@ -29,7 +32,10 @@ spec: ports: - port: 9411 targetPort: 9411 ---- + +# ----------------------------- +# Service Discovery (Eureka) +# ----------------------------- apiVersion: apps/v1 kind: Deployment metadata: @@ -66,7 +72,10 @@ spec: ports: - port: 8761 targetPort: 8761 ---- + +# ----------------------------- +# Cloud Config +# ----------------------------- apiVersion: apps/v1 kind: Deployment metadata: @@ -96,4 +105,18 @@ spec: - name: EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT value: "myzone" - name: EUREKA_CLIENT_SERVICEURL_MYZONE - value: "http://se + value: "http://service-discovery:8761/eureka" + - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE + value: "http://service-discovery:8761/eureka" +--- +apiVersion: v1 +kind: Service +metadata: + name: cloud-config +spec: + type: ClusterIP + selector: + app: cloud-config + ports: + - port: 9296 + targetPort: 9296 From ad5be4baf818b3d3af8a28ff5ad6a8c205dc876c Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Tue, 28 Oct 2025 19:10:24 -0500 Subject: [PATCH 41/67] fix: fixed things in pipeline cloud build --- k8s/staging/compose.yml | 4 +--- pipelines/gke-stage/cloudbuild-stage.yml | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/k8s/staging/compose.yml b/k8s/staging/compose.yml index 87090624c..30c4caf5d 100644 --- a/k8s/staging/compose.yml +++ b/k8s/staging/compose.yml @@ -48,9 +48,7 @@ spec: - port: 8080 targetPort: 8080 -# ----------------------------- -# Proxy Client -# ----------------------------- + apiVersion: apps/v1 kind: Deployment metadata: diff --git a/pipelines/gke-stage/cloudbuild-stage.yml b/pipelines/gke-stage/cloudbuild-stage.yml index 0ec090d33..5b860de1a 100644 --- a/pipelines/gke-stage/cloudbuild-stage.yml +++ b/pipelines/gke-stage/cloudbuild-stage.yml @@ -54,7 +54,7 @@ steps: - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' - args: ['-c', 'kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/proxy-client --timeout=120s'] + args: ['-c', 'kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/zipkin --timeout=120s'] - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' From f57a306aa28b0ff6ed83f6fd4ff921d328856b95 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Wed, 29 Oct 2025 16:01:25 -0500 Subject: [PATCH 42/67] fix: image url fixed --- k8s/staging/compose.yml | 16 ++++++++-------- k8s/staging/core.yml | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/k8s/staging/compose.yml b/k8s/staging/compose.yml index 30c4caf5d..d0fe41265 100644 --- a/k8s/staging/compose.yml +++ b/k8s/staging/compose.yml @@ -17,7 +17,7 @@ spec: spec: containers: - name: api-gateway - image: selimhorri/api-gateway-ecommerce-boot:0.1.0 + image: gcr.io/PROJECT_ID/api-gateway:IMAGE_TAG ports: - containerPort: 8080 env: @@ -65,7 +65,7 @@ spec: spec: containers: - name: proxy-client - image: selimhorri/proxy-client-ecommerce-boot:0.1.0 + image: gcr.io/PROJECT_ID/proxy-client:IMAGE_TAG ports: - containerPort: 8900 env: @@ -115,7 +115,7 @@ spec: spec: containers: - name: order-service - image: selimhorri/order-service-ecommerce-boot:0.1.0 + image: gcr.io/PROJECT_ID/order-service:IMAGE_TAG ports: - containerPort: 8300 env: @@ -165,7 +165,7 @@ spec: spec: containers: - name: payment-service - image: selimhorri/payment-service-ecommerce-boot:0.1.0 + image: gcr.io/PROJECT_ID/payment-service:IMAGE_TAG ports: - containerPort: 8400 env: @@ -215,7 +215,7 @@ spec: spec: containers: - name: product-service - image: selimhorri/product-service-ecommerce-boot:0.1.0 + image: gcr.io/PROJECT_ID/product-service:IMAGE_TAG ports: - containerPort: 8500 env: @@ -265,7 +265,7 @@ spec: spec: containers: - name: shipping-service - image: selimhorri/shipping-service-ecommerce-boot:0.1.0 + image: gcr.io/PROJECT_ID/shipping-service:IMAGE_TAG ports: - containerPort: 8600 env: @@ -315,7 +315,7 @@ spec: spec: containers: - name: user-service - image: selimhorri/user-service-ecommerce-boot:0.1.0 + image: gcr.io/PROJECT_ID/user-service:IMAGE_TAG ports: - containerPort: 8700 env: @@ -365,7 +365,7 @@ spec: spec: containers: - name: favourite-service - image: selimhorri/favourite-service-ecommerce-boot:0.1.0 + image: gcr.io/PROJECT_ID/favourite-service:IMAGE_TAG ports: - containerPort: 8800 env: diff --git a/k8s/staging/core.yml b/k8s/staging/core.yml index e488b632d..4f466a263 100644 --- a/k8s/staging/core.yml +++ b/k8s/staging/core.yml @@ -52,7 +52,7 @@ spec: spec: containers: - name: service-discovery - image: selimhorri/service-discovery-ecommerce-boot:0.1.0 + image: gcr.io/PROJECT_ID/service-discovery:IMAGE_TAG ports: - containerPort: 8761 env: @@ -92,7 +92,7 @@ spec: spec: containers: - name: cloud-config - image: selimhorri/cloud-config-ecommerce-boot:0.1.0 + image: gcr.io/PROJECT_ID/cloud-config:IMAGE_TAG ports: - containerPort: 9296 env: From cf24f3ea05b2b6805d2ec98b5750a13bbd8ea128 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Wed, 29 Oct 2025 16:25:56 -0500 Subject: [PATCH 43/67] fix: more waiting time for deployment to services --- pipelines/gke-stage/cloudbuild-stage.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pipelines/gke-stage/cloudbuild-stage.yml b/pipelines/gke-stage/cloudbuild-stage.yml index 5b860de1a..d8ea90f51 100644 --- a/pipelines/gke-stage/cloudbuild-stage.yml +++ b/pipelines/gke-stage/cloudbuild-stage.yml @@ -46,7 +46,7 @@ steps: - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' - args: ['-c', 'kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/cloud-config --timeout=120s'] + args: ['-c', 'kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/zipkin --timeout=120s'] - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' @@ -54,7 +54,7 @@ steps: - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' - args: ['-c', 'kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/zipkin --timeout=120s'] + args: ['-c', 'kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/cloud-config --timeout=120s'] - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' @@ -62,7 +62,7 @@ steps: - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' - args: ['-c', 'kubectl -n ${_NAMESPACE} wait --for=condition=available --all deployments --timeout=300s'] + args: ['-c', 'kubectl -n ${_NAMESPACE} wait --for=condition=available --all deployments --timeout=900s'] - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' From 27a99d65ec9460f60a522d02c353800cd73ef7a3 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Wed, 29 Oct 2025 17:53:13 -0500 Subject: [PATCH 44/67] fix: fixing some configurations in k8s/stagin/compose.yml --- k8s/staging/compose.yml | 74 ++++++++++++++++++++---- pipelines/gke-stage/cloudbuild-stage.yml | 2 +- 2 files changed, 65 insertions(+), 11 deletions(-) diff --git a/k8s/staging/compose.yml b/k8s/staging/compose.yml index d0fe41265..f46b15db6 100644 --- a/k8s/staging/compose.yml +++ b/k8s/staging/compose.yml @@ -18,8 +18,6 @@ spec: containers: - name: api-gateway image: gcr.io/PROJECT_ID/api-gateway:IMAGE_TAG - ports: - - containerPort: 8080 env: - name: SPRING_PROFILES_ACTIVE value: "dev" @@ -35,6 +33,14 @@ spec: value: "http://service-discovery:8761/eureka" - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE value: "http://service-discovery:8761/eureka" + - name: SPRING_DATASOURCE_URL + value: "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" + - name: SPRING_DATASOURCE_DRIVERCLASSNAME + value: "org.h2.Driver" + - name: SPRING_JPA_DATABASE-PLATFORM + value: "org.hibernate.dialect.H2Dialect" + - name: SPRING_JPA_HIBERNATE_DDL_AUTO + value: "update" --- apiVersion: v1 kind: Service @@ -83,6 +89,14 @@ spec: value: "http://service-discovery:8761/eureka" - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE value: "http://service-discovery:8761/eureka" + - name: SPRING_DATASOURCE_URL + value: "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" + - name: SPRING_DATASOURCE_DRIVERCLASSNAME + value: "org.h2.Driver" + - name: SPRING_JPA_DATABASE-PLATFORM + value: "org.hibernate.dialect.H2Dialect" + - name: SPRING_JPA_HIBERNATE_DDL_AUTO + value: "update" --- apiVersion: v1 kind: Service @@ -116,8 +130,6 @@ spec: containers: - name: order-service image: gcr.io/PROJECT_ID/order-service:IMAGE_TAG - ports: - - containerPort: 8300 env: - name: SPRING_PROFILES_ACTIVE value: "dev" @@ -133,6 +145,14 @@ spec: value: "http://service-discovery:8761/eureka" - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE value: "http://service-discovery:8761/eureka" + - name: SPRING_DATASOURCE_URL + value: "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" + - name: SPRING_DATASOURCE_DRIVERCLASSNAME + value: "org.h2.Driver" + - name: SPRING_JPA_DATABASE-PLATFORM + value: "org.hibernate.dialect.H2Dialect" + - name: SPRING_JPA_HIBERNATE_DDL_AUTO + value: "update" --- apiVersion: v1 kind: Service @@ -183,6 +203,14 @@ spec: value: "http://service-discovery:8761/eureka" - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE value: "http://service-discovery:8761/eureka" + - name: SPRING_DATASOURCE_URL + value: "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" + - name: SPRING_DATASOURCE_DRIVERCLASSNAME + value: "org.h2.Driver" + - name: SPRING_JPA_DATABASE-PLATFORM + value: "org.hibernate.dialect.H2Dialect" + - name: SPRING_JPA_HIBERNATE_DDL_AUTO + value: "update" --- apiVersion: v1 kind: Service @@ -233,6 +261,14 @@ spec: value: "http://service-discovery:8761/eureka" - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE value: "http://service-discovery:8761/eureka" + - name: SPRING_DATASOURCE_URL + value: "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" + - name: SPRING_DATASOURCE_DRIVERCLASSNAME + value: "org.h2.Driver" + - name: SPRING_JPA_DATABASE-PLATFORM + value: "org.hibernate.dialect.H2Dialect" + - name: SPRING_JPA_HIBERNATE_DDL_AUTO + value: "update" --- apiVersion: v1 kind: Service @@ -266,8 +302,6 @@ spec: containers: - name: shipping-service image: gcr.io/PROJECT_ID/shipping-service:IMAGE_TAG - ports: - - containerPort: 8600 env: - name: SPRING_PROFILES_ACTIVE value: "dev" @@ -283,6 +317,14 @@ spec: value: "http://service-discovery:8761/eureka" - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE value: "http://service-discovery:8761/eureka" + - name: SPRING_DATASOURCE_URL + value: "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" + - name: SPRING_DATASOURCE_DRIVERCLASSNAME + value: "org.h2.Driver" + - name: SPRING_JPA_DATABASE-PLATFORM + value: "org.hibernate.dialect.H2Dialect" + - name: SPRING_JPA_HIBERNATE_DDL_AUTO + value: "update" --- apiVersion: v1 kind: Service @@ -316,8 +358,6 @@ spec: containers: - name: user-service image: gcr.io/PROJECT_ID/user-service:IMAGE_TAG - ports: - - containerPort: 8700 env: - name: SPRING_PROFILES_ACTIVE value: "dev" @@ -333,6 +373,14 @@ spec: value: "http://service-discovery:8761/eureka" - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE value: "http://service-discovery:8761/eureka" + - name: SPRING_DATASOURCE_URL + value: "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" + - name: SPRING_DATASOURCE_DRIVERCLASSNAME + value: "org.h2.Driver" + - name: SPRING_JPA_DATABASE-PLATFORM + value: "org.hibernate.dialect.H2Dialect" + - name: SPRING_JPA_HIBERNATE_DDL_AUTO + value: "update" --- apiVersion: v1 kind: Service @@ -366,8 +414,6 @@ spec: containers: - name: favourite-service image: gcr.io/PROJECT_ID/favourite-service:IMAGE_TAG - ports: - - containerPort: 8800 env: - name: SPRING_PROFILES_ACTIVE value: "dev" @@ -383,6 +429,14 @@ spec: value: "http://service-discovery:8761/eureka" - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE value: "http://service-discovery:8761/eureka" + - name: SPRING_DATASOURCE_URL + value: "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" + - name: SPRING_DATASOURCE_DRIVERCLASSNAME + value: "org.h2.Driver" + - name: SPRING_JPA_DATABASE-PLATFORM + value: "org.hibernate.dialect.H2Dialect" + - name: SPRING_JPA_HIBERNATE_DDL_AUTO + value: "update" --- apiVersion: v1 kind: Service diff --git a/pipelines/gke-stage/cloudbuild-stage.yml b/pipelines/gke-stage/cloudbuild-stage.yml index d8ea90f51..a788d7155 100644 --- a/pipelines/gke-stage/cloudbuild-stage.yml +++ b/pipelines/gke-stage/cloudbuild-stage.yml @@ -62,7 +62,7 @@ steps: - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' - args: ['-c', 'kubectl -n ${_NAMESPACE} wait --for=condition=available --all deployments --timeout=900s'] + args: ['-c', 'kubectl -n ${_NAMESPACE} wait --for=condition=available --all deployments --timeout=1500s'] - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' From 5781f4d1578d0dddb6a37ce40fc3b8600de4ca55 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Wed, 29 Oct 2025 20:28:41 -0500 Subject: [PATCH 45/67] fix: pushin the images --- pipelines/gke-stage/cloudbuild-stage.yml | 82 ++++++++++++++---------- 1 file changed, 49 insertions(+), 33 deletions(-) diff --git a/pipelines/gke-stage/cloudbuild-stage.yml b/pipelines/gke-stage/cloudbuild-stage.yml index a788d7155..b5ee328cc 100644 --- a/pipelines/gke-stage/cloudbuild-stage.yml +++ b/pipelines/gke-stage/cloudbuild-stage.yml @@ -8,66 +8,82 @@ steps: args: ['clean', 'package', '-DskipTests'] - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'gcr.io/$PROJECT_ID/api-gateway:$SHORT_SHA', '-f', 'api-gateway/Dockerfile', '.'] - - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'gcr.io/$PROJECT_ID/cloud-config:$SHORT_SHA', '-f', 'cloud-config/Dockerfile', '.'] - - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'gcr.io/$PROJECT_ID/service-discovery:$SHORT_SHA', '-f', 'service-discovery/Dockerfile', '.'] - - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'gcr.io/$PROJECT_ID/proxy-client:$SHORT_SHA', '-f', 'proxy-client/Dockerfile', '.'] - - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'gcr.io/$PROJECT_ID/user-service:$SHORT_SHA', '-f', 'user-service/Dockerfile', '.'] - - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'gcr.io/$PROJECT_ID/product-service:$SHORT_SHA', '-f', 'product-service/Dockerfile', '.'] - - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'gcr.io/$PROJECT_ID/order-service:$SHORT_SHA', '-f', 'order-service/Dockerfile', '.'] - - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'gcr.io/$PROJECT_ID/payment-service:$SHORT_SHA', '-f', 'payment-service/Dockerfile', '.'] - - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'gcr.io/$PROJECT_ID/favourite-service:$SHORT_SHA', '-f', 'favourite-service/Dockerfile', '.'] - - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'gcr.io/$PROJECT_ID/shipping-service:$SHORT_SHA', '-f', 'shipping-service/Dockerfile', '.'] - - - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' - args: ['-c', 'gcloud container clusters get-credentials ${_CLUSTER_NAME} --zone ${_CLUSTER_ZONE} --project ${PROJECT_ID}'] + args: + - '-c' + - | + for s in api-gateway cloud-config service-discovery proxy-client user-service product-service order-service payment-service favourite-service shipping-service; do + echo "馃敤 Construyendo imagen $s ..." + docker build -t gcr.io/$PROJECT_ID/$s:$SHORT_SHA -f $s/Dockerfile . + done - - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + - name: 'gcr.io/cloud-builders/docker' entrypoint: 'bash' - args: ['-c', 'kubectl create namespace ${_NAMESPACE} || true'] + args: + - '-c' + - | + for s in api-gateway cloud-config service-discovery proxy-client user-service product-service order-service payment-service favourite-service shipping-service; do + echo "猬嗭笍 Subiendo imagen gcr.io/$PROJECT_ID/$s:$SHORT_SHA ..." + docker push gcr.io/$PROJECT_ID/$s:$SHORT_SHA + done - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' - args: ['-c', 'for f in k8s/staging/*.yml; do sed -i "s|IMAGE_TAG|${SHORT_SHA}|g" "$f"; sed -i "s|PROJECT_ID|${PROJECT_ID}|g" "$f"; done'] + args: + - '-c' + - | + gcloud container clusters get-credentials ${_CLUSTER_NAME} \ + --zone ${_CLUSTER_ZONE} \ + --project ${PROJECT_ID} - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' - args: ['-c', 'kubectl apply -n ${_NAMESPACE} -f k8s/staging/core.yml'] + args: + - '-c' + - 'kubectl create namespace ${_NAMESPACE} || true' - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' - args: ['-c', 'kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/zipkin --timeout=120s'] + args: + - '-c' + - | + for f in k8s/staging/*.yml; do + sed -i "s|IMAGE_TAG|${SHORT_SHA}|g" "$f" + sed -i "s|PROJECT_ID|${PROJECT_ID}|g" "$f" + done - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' - args: ['-c', 'kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/service-discovery --timeout=120s'] + args: + - '-c' + - 'kubectl apply -n ${_NAMESPACE} -f k8s/staging/core.yml' - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' - args: ['-c', 'kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/cloud-config --timeout=120s'] + args: + - '-c' + - | + kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/zipkin --timeout=150s + kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/service-discovery --timeout=180s + kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/cloud-config --timeout=180s - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' - args: ['-c', 'kubectl apply -n ${_NAMESPACE} -f k8s/staging/compose.yml'] + args: + - '-c' + - 'kubectl apply -n ${_NAMESPACE} -f k8s/staging/compose.yml' - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' - args: ['-c', 'kubectl -n ${_NAMESPACE} wait --for=condition=available --all deployments --timeout=1500s'] + args: + - '-c' + - 'kubectl -n ${_NAMESPACE} wait --for=condition=available --all deployments --timeout=1800s' - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' - args: ['-c', 'kubectl -n ${_NAMESPACE} delete pod stage-tester --ignore-not-found'] - + args: + - '-c' + - 'kubectl -n ${_NAMESPACE} delete pod stage-tester --ignore-not-found' images: - 'gcr.io/$PROJECT_ID/api-gateway:$SHORT_SHA' From dafb02b8f3ea2866347344dd12e6d168eb3f84f7 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Wed, 29 Oct 2025 20:50:37 -0500 Subject: [PATCH 46/67] fix: another fix in the pipeline --- pipelines/gke-stage/cloudbuild-stage.yml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/pipelines/gke-stage/cloudbuild-stage.yml b/pipelines/gke-stage/cloudbuild-stage.yml index b5ee328cc..4af3a5eb5 100644 --- a/pipelines/gke-stage/cloudbuild-stage.yml +++ b/pipelines/gke-stage/cloudbuild-stage.yml @@ -13,7 +13,7 @@ steps: - '-c' - | for s in api-gateway cloud-config service-discovery proxy-client user-service product-service order-service payment-service favourite-service shipping-service; do - echo "馃敤 Construyendo imagen $s ..." + echo "Construyendo imagen $s ..." docker build -t gcr.io/$PROJECT_ID/$s:$SHORT_SHA -f $s/Dockerfile . done @@ -23,7 +23,17 @@ steps: - '-c' - | for s in api-gateway cloud-config service-discovery proxy-client user-service product-service order-service payment-service favourite-service shipping-service; do - echo "猬嗭笍 Subiendo imagen gcr.io/$PROJECT_ID/$s:$SHORT_SHA ..." + echo "Construyendo imagen $s ..." + docker build -t gcr.io/$PROJECT_ID/$s:$SHORT_SHA -f $s/Dockerfile . + done + + - name: 'gcr.io/cloud-builders/docker' + entrypoint: 'bash' + args: + - '-c' + - | + for s in api-gateway cloud-config service-discovery proxy-client user-service product-service order-service payment-service favourite-service shipping-service; do + echo "Subiendo imagen gcr.io/$PROJECT_ID/$s:$SHORT_SHA ..." docker push gcr.io/$PROJECT_ID/$s:$SHORT_SHA done From 2beeef45615267936a11d0a1e3afb722179ca648 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Wed, 29 Oct 2025 21:05:45 -0500 Subject: [PATCH 47/67] fix: last fix, auth for docker --- pipelines/gke-stage/cloudbuild-stage.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pipelines/gke-stage/cloudbuild-stage.yml b/pipelines/gke-stage/cloudbuild-stage.yml index 4af3a5eb5..6425be372 100644 --- a/pipelines/gke-stage/cloudbuild-stage.yml +++ b/pipelines/gke-stage/cloudbuild-stage.yml @@ -7,6 +7,7 @@ steps: - name: 'gcr.io/cloud-builders/mvn' args: ['clean', 'package', '-DskipTests'] + - name: 'gcr.io/cloud-builders/docker' entrypoint: 'bash' args: @@ -17,15 +18,13 @@ steps: docker build -t gcr.io/$PROJECT_ID/$s:$SHORT_SHA -f $s/Dockerfile . done - - name: 'gcr.io/cloud-builders/docker' + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' args: - '-c' - | - for s in api-gateway cloud-config service-discovery proxy-client user-service product-service order-service payment-service favourite-service shipping-service; do - echo "Construyendo imagen $s ..." - docker build -t gcr.io/$PROJECT_ID/$s:$SHORT_SHA -f $s/Dockerfile . - done + echo "Autenticando Docker con GCR..." + gcloud auth configure-docker gcr.io -q - name: 'gcr.io/cloud-builders/docker' entrypoint: 'bash' From 37b2601f6083b5d76234fded82beeb90d7640021 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Thu, 30 Oct 2025 09:07:20 -0500 Subject: [PATCH 48/67] fix: now im pushing the images to docker hun --- pipelines/gke-stage/cloudbuild-stage.yml | 51 ++++++++++++++---------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/pipelines/gke-stage/cloudbuild-stage.yml b/pipelines/gke-stage/cloudbuild-stage.yml index 6425be372..485635a33 100644 --- a/pipelines/gke-stage/cloudbuild-stage.yml +++ b/pipelines/gke-stage/cloudbuild-stage.yml @@ -5,26 +5,26 @@ substitutions: steps: - name: 'gcr.io/cloud-builders/mvn' - args: ['clean', 'package', '-DskipTests'] - + args: ['clean', 'verify', '-DskipTests'] - name: 'gcr.io/cloud-builders/docker' entrypoint: 'bash' + secretEnv: ['DOCKER_USERNAME', 'DOCKER_PASSWORD'] args: - '-c' - | - for s in api-gateway cloud-config service-discovery proxy-client user-service product-service order-service payment-service favourite-service shipping-service; do - echo "Construyendo imagen $s ..." - docker build -t gcr.io/$PROJECT_ID/$s:$SHORT_SHA -f $s/Dockerfile . - done + echo "Autenticando en Docker Hub..." + echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin - - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + - name: 'gcr.io/cloud-builders/docker' entrypoint: 'bash' args: - '-c' - | - echo "Autenticando Docker con GCR..." - gcloud auth configure-docker gcr.io -q + for s in api-gateway cloud-config service-discovery proxy-client user-service product-service order-service payment-service favourite-service shipping-service; do + echo "Construyendo imagen $s ..." + docker build -t docker.io/juancato/ecomerce-taller-$s:$SHORT_SHA -f $s/Dockerfile . + done - name: 'gcr.io/cloud-builders/docker' entrypoint: 'bash' @@ -32,8 +32,8 @@ steps: - '-c' - | for s in api-gateway cloud-config service-discovery proxy-client user-service product-service order-service payment-service favourite-service shipping-service; do - echo "Subiendo imagen gcr.io/$PROJECT_ID/$s:$SHORT_SHA ..." - docker push gcr.io/$PROJECT_ID/$s:$SHORT_SHA + echo "Subiendo imagen docker.io/juancato/ecomerce-taller-$s:$SHORT_SHA ..." + docker push docker.io/juancato/ecomerce-taller-$s:$SHORT_SHA done - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' @@ -58,7 +58,7 @@ steps: - | for f in k8s/staging/*.yml; do sed -i "s|IMAGE_TAG|${SHORT_SHA}|g" "$f" - sed -i "s|PROJECT_ID|${PROJECT_ID}|g" "$f" + sed -i "s|PROJECT_ID|juancato/ecomerce-taller|g" "$f" done - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' @@ -95,16 +95,23 @@ steps: - 'kubectl -n ${_NAMESPACE} delete pod stage-tester --ignore-not-found' images: - - 'gcr.io/$PROJECT_ID/api-gateway:$SHORT_SHA' - - 'gcr.io/$PROJECT_ID/cloud-config:$SHORT_SHA' - - 'gcr.io/$PROJECT_ID/service-discovery:$SHORT_SHA' - - 'gcr.io/$PROJECT_ID/proxy-client:$SHORT_SHA' - - 'gcr.io/$PROJECT_ID/user-service:$SHORT_SHA' - - 'gcr.io/$PROJECT_ID/product-service:$SHORT_SHA' - - 'gcr.io/$PROJECT_ID/order-service:$SHORT_SHA' - - 'gcr.io/$PROJECT_ID/payment-service:$SHORT_SHA' - - 'gcr.io/$PROJECT_ID/favourite-service:$SHORT_SHA' - - 'gcr.io/$PROJECT_ID/shipping-service:$SHORT_SHA' + - 'docker.io/juancato/ecomerce-taller-api-gateway:$SHORT_SHA' + - 'docker.io/juancato/ecomerce-taller-cloud-config:$SHORT_SHA' + - 'docker.io/juancato/ecomerce-taller-service-discovery:$SHORT_SHA' + - 'docker.io/juancato/ecomerce-taller-proxy-client:$SHORT_SHA' + - 'docker.io/juancato/ecomerce-taller-user-service:$SHORT_SHA' + - 'docker.io/juancato/ecomerce-taller-product-service:$SHORT_SHA' + - 'docker.io/juancato/ecomerce-taller-order-service:$SHORT_SHA' + - 'docker.io/juancato/ecomerce-taller-payment-service:$SHORT_SHA' + - 'docker.io/juancato/ecomerce-taller-favourite-service:$SHORT_SHA' + - 'docker.io/juancato/ecomerce-taller-shipping-service:$SHORT_SHA' + +availableSecrets: + secretManager: + - versionName: projects/$PROJECT_ID/secrets/DOCKER_USERNAME/versions/latest + env: 'DOCKER_USERNAME' + - versionName: projects/$PROJECT_ID/secrets/DOCKER_PASSWORD/versions/latest + env: 'DOCKER_PASSWORD' options: logging: CLOUD_LOGGING_ONLY From 2ece77e8bc34fddec5ad4b5a1440417272338dd8 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Thu, 30 Oct 2025 09:11:30 -0500 Subject: [PATCH 49/67] fix: fixing some substitutions --- pipelines/gke-stage/cloudbuild-stage.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pipelines/gke-stage/cloudbuild-stage.yml b/pipelines/gke-stage/cloudbuild-stage.yml index 485635a33..bc33bf8ee 100644 --- a/pipelines/gke-stage/cloudbuild-stage.yml +++ b/pipelines/gke-stage/cloudbuild-stage.yml @@ -2,6 +2,7 @@ substitutions: _CLUSTER_NAME: "mi-primer-cluster-taller" _CLUSTER_ZONE: "us-central1" _NAMESPACE: "stage" + _PROJECT_ID: "taller2-ingenieriasoftware" # 馃憟 reempl谩zalo si tu ID de proyecto es diferente steps: - name: 'gcr.io/cloud-builders/mvn' @@ -43,7 +44,7 @@ steps: - | gcloud container clusters get-credentials ${_CLUSTER_NAME} \ --zone ${_CLUSTER_ZONE} \ - --project ${PROJECT_ID} + --project ${_PROJECT_ID} - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' @@ -108,9 +109,9 @@ images: availableSecrets: secretManager: - - versionName: projects/$PROJECT_ID/secrets/DOCKER_USERNAME/versions/latest + - versionName: projects/${_PROJECT_ID}/secrets/DOCKER_USERNAME/versions/latest env: 'DOCKER_USERNAME' - - versionName: projects/$PROJECT_ID/secrets/DOCKER_PASSWORD/versions/latest + - versionName: projects/${_PROJECT_ID}/secrets/DOCKER_PASSWORD/versions/latest env: 'DOCKER_PASSWORD' options: From 711984eff2cf2ef35091659c7a435a680a2be8ae Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Thu, 30 Oct 2025 09:27:50 -0500 Subject: [PATCH 50/67] fix: fixing the google secrets. --- pipelines/gke-stage/cloudbuild-stage.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pipelines/gke-stage/cloudbuild-stage.yml b/pipelines/gke-stage/cloudbuild-stage.yml index bc33bf8ee..04902a3f7 100644 --- a/pipelines/gke-stage/cloudbuild-stage.yml +++ b/pipelines/gke-stage/cloudbuild-stage.yml @@ -2,7 +2,7 @@ substitutions: _CLUSTER_NAME: "mi-primer-cluster-taller" _CLUSTER_ZONE: "us-central1" _NAMESPACE: "stage" - _PROJECT_ID: "taller2-ingenieriasoftware" # 馃憟 reempl谩zalo si tu ID de proyecto es diferente + _PROJECT_ID: "taller2-ingenieriasoftware" steps: - name: 'gcr.io/cloud-builders/mvn' @@ -10,12 +10,12 @@ steps: - name: 'gcr.io/cloud-builders/docker' entrypoint: 'bash' - secretEnv: ['DOCKER_USERNAME', 'DOCKER_PASSWORD'] + secretEnv: ['_DOCKER_USERNAME', '_DOCKER_PASSWORD'] args: - '-c' - | echo "Autenticando en Docker Hub..." - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin + echo "$_DOCKER_PASSWORD" | docker login -u "$_DOCKER_USERNAME" --password-stdin - name: 'gcr.io/cloud-builders/docker' entrypoint: 'bash' @@ -110,9 +110,9 @@ images: availableSecrets: secretManager: - versionName: projects/${_PROJECT_ID}/secrets/DOCKER_USERNAME/versions/latest - env: 'DOCKER_USERNAME' + env: '_DOCKER_USERNAME' - versionName: projects/${_PROJECT_ID}/secrets/DOCKER_PASSWORD/versions/latest - env: 'DOCKER_PASSWORD' + env: '_DOCKER_PASSWORD' options: logging: CLOUD_LOGGING_ONLY From 56535365aa8505b0376cc0edfd1fddd9469271d4 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Thu, 30 Oct 2025 10:41:14 -0500 Subject: [PATCH 51/67] fix: fixing the google secrets. --- pipelines/gke-stage/cloudbuild-stage.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pipelines/gke-stage/cloudbuild-stage.yml b/pipelines/gke-stage/cloudbuild-stage.yml index 04902a3f7..3c7b8e9d3 100644 --- a/pipelines/gke-stage/cloudbuild-stage.yml +++ b/pipelines/gke-stage/cloudbuild-stage.yml @@ -15,7 +15,9 @@ steps: - '-c' - | echo "Autenticando en Docker Hub..." - echo "$_DOCKER_PASSWORD" | docker login -u "$_DOCKER_USERNAME" --password-stdin + echo "Username length: $${#_DOCKER_USERNAME}" + echo "Password length: $${#_DOCKER_PASSWORD}" + echo "$$_DOCKER_PASSWORD" | docker login -u "$$_DOCKER_USERNAME" --password-stdin - name: 'gcr.io/cloud-builders/docker' entrypoint: 'bash' @@ -115,4 +117,4 @@ availableSecrets: env: '_DOCKER_PASSWORD' options: - logging: CLOUD_LOGGING_ONLY + logging: CLOUD_LOGGING_ONLY \ No newline at end of file From 52b7f71b7e1213028955ab368df5183c034cf446 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Thu, 30 Oct 2025 11:09:45 -0500 Subject: [PATCH 52/67] fix: fixing the google secrets. --- k8s/staging/core.yml | 6 +++--- pipelines/gke-stage/cloudbuild-stage.yml | 17 +++++++++++++---- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/k8s/staging/core.yml b/k8s/staging/core.yml index 4f466a263..8beea45fc 100644 --- a/k8s/staging/core.yml +++ b/k8s/staging/core.yml @@ -34,7 +34,7 @@ spec: targetPort: 9411 # ----------------------------- -# Service Discovery (Eureka) +# Service Discovery # ----------------------------- apiVersion: apps/v1 kind: Deployment @@ -52,7 +52,7 @@ spec: spec: containers: - name: service-discovery - image: gcr.io/PROJECT_ID/service-discovery:IMAGE_TAG + image: gcr.io/PROJECT_ID/service-discovery:IMAGE_TAG ports: - containerPort: 8761 env: @@ -92,7 +92,7 @@ spec: spec: containers: - name: cloud-config - image: gcr.io/PROJECT_ID/cloud-config:IMAGE_TAG + image: gcr.io/PROJECT_ID/cloud-config:IMAGE_TAG ports: - containerPort: 9296 env: diff --git a/pipelines/gke-stage/cloudbuild-stage.yml b/pipelines/gke-stage/cloudbuild-stage.yml index 3c7b8e9d3..bb0324166 100644 --- a/pipelines/gke-stage/cloudbuild-stage.yml +++ b/pipelines/gke-stage/cloudbuild-stage.yml @@ -8,6 +8,7 @@ steps: - name: 'gcr.io/cloud-builders/mvn' args: ['clean', 'verify', '-DskipTests'] + - name: 'gcr.io/cloud-builders/docker' entrypoint: 'bash' secretEnv: ['_DOCKER_USERNAME', '_DOCKER_PASSWORD'] @@ -15,10 +16,9 @@ steps: - '-c' - | echo "Autenticando en Docker Hub..." - echo "Username length: $${#_DOCKER_USERNAME}" - echo "Password length: $${#_DOCKER_PASSWORD}" echo "$$_DOCKER_PASSWORD" | docker login -u "$$_DOCKER_USERNAME" --password-stdin + - name: 'gcr.io/cloud-builders/docker' entrypoint: 'bash' args: @@ -29,6 +29,7 @@ steps: docker build -t docker.io/juancato/ecomerce-taller-$s:$SHORT_SHA -f $s/Dockerfile . done + - name: 'gcr.io/cloud-builders/docker' entrypoint: 'bash' args: @@ -39,6 +40,7 @@ steps: docker push docker.io/juancato/ecomerce-taller-$s:$SHORT_SHA done + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' args: @@ -48,6 +50,7 @@ steps: --zone ${_CLUSTER_ZONE} \ --project ${_PROJECT_ID} + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' args: @@ -61,15 +64,17 @@ steps: - | for f in k8s/staging/*.yml; do sed -i "s|IMAGE_TAG|${SHORT_SHA}|g" "$f" - sed -i "s|PROJECT_ID|juancato/ecomerce-taller|g" "$f" + sed -i "s|gcr.io/PROJECT_ID|docker.io/juancato/ecomerce-taller|g" "$f" done + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' args: - '-c' - 'kubectl apply -n ${_NAMESPACE} -f k8s/staging/core.yml' + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' args: @@ -79,24 +84,28 @@ steps: kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/service-discovery --timeout=180s kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/cloud-config --timeout=180s + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' args: - '-c' - 'kubectl apply -n ${_NAMESPACE} -f k8s/staging/compose.yml' + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' args: - '-c' - 'kubectl -n ${_NAMESPACE} wait --for=condition=available --all deployments --timeout=1800s' + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' args: - '-c' - 'kubectl -n ${_NAMESPACE} delete pod stage-tester --ignore-not-found' + images: - 'docker.io/juancato/ecomerce-taller-api-gateway:$SHORT_SHA' - 'docker.io/juancato/ecomerce-taller-cloud-config:$SHORT_SHA' @@ -117,4 +126,4 @@ availableSecrets: env: '_DOCKER_PASSWORD' options: - logging: CLOUD_LOGGING_ONLY \ No newline at end of file + logging: CLOUD_LOGGING_ONLY From 9b21a3b76a55eb0110bb12105830db4af0ed3067 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Thu, 30 Oct 2025 11:30:28 -0500 Subject: [PATCH 53/67] fix: fixing the google secrets. --- k8s/staging/compose.yml | 142 ++++------------------- k8s/staging/core.yml | 72 ++++++------ pipelines/gke-stage/cloudbuild-stage.yml | 57 ++++----- 3 files changed, 78 insertions(+), 193 deletions(-) diff --git a/k8s/staging/compose.yml b/k8s/staging/compose.yml index f46b15db6..e38ce0b10 100644 --- a/k8s/staging/compose.yml +++ b/k8s/staging/compose.yml @@ -17,7 +17,9 @@ spec: spec: containers: - name: api-gateway - image: gcr.io/PROJECT_ID/api-gateway:IMAGE_TAG + image: docker.io/juancato/ecomerce-taller-api-gateway:IMAGE_TAG + ports: + - containerPort: 8080 env: - name: SPRING_PROFILES_ACTIVE value: "dev" @@ -25,22 +27,8 @@ spec: value: "http://zipkin:9411" - name: SPRING_CONFIG_IMPORT value: "optional:configserver:http://cloud-config:9296/" - - name: EUREKA_CLIENT_REGION - value: "default" - - name: EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT - value: "myzone" - - name: EUREKA_CLIENT_SERVICEURL_MYZONE - value: "http://service-discovery:8761/eureka" - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE value: "http://service-discovery:8761/eureka" - - name: SPRING_DATASOURCE_URL - value: "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" - - name: SPRING_DATASOURCE_DRIVERCLASSNAME - value: "org.h2.Driver" - - name: SPRING_JPA_DATABASE-PLATFORM - value: "org.hibernate.dialect.H2Dialect" - - name: SPRING_JPA_HIBERNATE_DDL_AUTO - value: "update" --- apiVersion: v1 kind: Service @@ -54,7 +42,9 @@ spec: - port: 8080 targetPort: 8080 - +# ----------------------------- +# Proxy Client +# ----------------------------- apiVersion: apps/v1 kind: Deployment metadata: @@ -71,7 +61,7 @@ spec: spec: containers: - name: proxy-client - image: gcr.io/PROJECT_ID/proxy-client:IMAGE_TAG + image: docker.io/juancato/ecomerce-taller-proxy-client:IMAGE_TAG ports: - containerPort: 8900 env: @@ -81,22 +71,8 @@ spec: value: "http://zipkin:9411" - name: SPRING_CONFIG_IMPORT value: "optional:configserver:http://cloud-config:9296/" - - name: EUREKA_CLIENT_REGION - value: "default" - - name: EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT - value: "myzone" - - name: EUREKA_CLIENT_SERVICEURL_MYZONE - value: "http://service-discovery:8761/eureka" - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE value: "http://service-discovery:8761/eureka" - - name: SPRING_DATASOURCE_URL - value: "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" - - name: SPRING_DATASOURCE_DRIVERCLASSNAME - value: "org.h2.Driver" - - name: SPRING_JPA_DATABASE-PLATFORM - value: "org.hibernate.dialect.H2Dialect" - - name: SPRING_JPA_HIBERNATE_DDL_AUTO - value: "update" --- apiVersion: v1 kind: Service @@ -129,7 +105,9 @@ spec: spec: containers: - name: order-service - image: gcr.io/PROJECT_ID/order-service:IMAGE_TAG + image: docker.io/juancato/ecomerce-taller-order-service:IMAGE_TAG + ports: + - containerPort: 8300 env: - name: SPRING_PROFILES_ACTIVE value: "dev" @@ -137,22 +115,8 @@ spec: value: "http://zipkin:9411" - name: SPRING_CONFIG_IMPORT value: "optional:configserver:http://cloud-config:9296/" - - name: EUREKA_CLIENT_REGION - value: "default" - - name: EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT - value: "myzone" - - name: EUREKA_CLIENT_SERVICEURL_MYZONE - value: "http://service-discovery:8761/eureka" - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE value: "http://service-discovery:8761/eureka" - - name: SPRING_DATASOURCE_URL - value: "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" - - name: SPRING_DATASOURCE_DRIVERCLASSNAME - value: "org.h2.Driver" - - name: SPRING_JPA_DATABASE-PLATFORM - value: "org.hibernate.dialect.H2Dialect" - - name: SPRING_JPA_HIBERNATE_DDL_AUTO - value: "update" --- apiVersion: v1 kind: Service @@ -185,7 +149,7 @@ spec: spec: containers: - name: payment-service - image: gcr.io/PROJECT_ID/payment-service:IMAGE_TAG + image: docker.io/juancato/ecomerce-taller-payment-service:IMAGE_TAG ports: - containerPort: 8400 env: @@ -195,22 +159,8 @@ spec: value: "http://zipkin:9411" - name: SPRING_CONFIG_IMPORT value: "optional:configserver:http://cloud-config:9296/" - - name: EUREKA_CLIENT_REGION - value: "default" - - name: EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT - value: "myzone" - - name: EUREKA_CLIENT_SERVICEURL_MYZONE - value: "http://service-discovery:8761/eureka" - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE value: "http://service-discovery:8761/eureka" - - name: SPRING_DATASOURCE_URL - value: "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" - - name: SPRING_DATASOURCE_DRIVERCLASSNAME - value: "org.h2.Driver" - - name: SPRING_JPA_DATABASE-PLATFORM - value: "org.hibernate.dialect.H2Dialect" - - name: SPRING_JPA_HIBERNATE_DDL_AUTO - value: "update" --- apiVersion: v1 kind: Service @@ -243,7 +193,7 @@ spec: spec: containers: - name: product-service - image: gcr.io/PROJECT_ID/product-service:IMAGE_TAG + image: docker.io/juancato/ecomerce-taller-product-service:IMAGE_TAG ports: - containerPort: 8500 env: @@ -253,22 +203,8 @@ spec: value: "http://zipkin:9411" - name: SPRING_CONFIG_IMPORT value: "optional:configserver:http://cloud-config:9296/" - - name: EUREKA_CLIENT_REGION - value: "default" - - name: EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT - value: "myzone" - - name: EUREKA_CLIENT_SERVICEURL_MYZONE - value: "http://service-discovery:8761/eureka" - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE value: "http://service-discovery:8761/eureka" - - name: SPRING_DATASOURCE_URL - value: "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" - - name: SPRING_DATASOURCE_DRIVERCLASSNAME - value: "org.h2.Driver" - - name: SPRING_JPA_DATABASE-PLATFORM - value: "org.hibernate.dialect.H2Dialect" - - name: SPRING_JPA_HIBERNATE_DDL_AUTO - value: "update" --- apiVersion: v1 kind: Service @@ -301,7 +237,9 @@ spec: spec: containers: - name: shipping-service - image: gcr.io/PROJECT_ID/shipping-service:IMAGE_TAG + image: docker.io/juancato/ecomerce-taller-shipping-service:IMAGE_TAG + ports: + - containerPort: 8600 env: - name: SPRING_PROFILES_ACTIVE value: "dev" @@ -309,22 +247,8 @@ spec: value: "http://zipkin:9411" - name: SPRING_CONFIG_IMPORT value: "optional:configserver:http://cloud-config:9296/" - - name: EUREKA_CLIENT_REGION - value: "default" - - name: EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT - value: "myzone" - - name: EUREKA_CLIENT_SERVICEURL_MYZONE - value: "http://service-discovery:8761/eureka" - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE value: "http://service-discovery:8761/eureka" - - name: SPRING_DATASOURCE_URL - value: "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" - - name: SPRING_DATASOURCE_DRIVERCLASSNAME - value: "org.h2.Driver" - - name: SPRING_JPA_DATABASE-PLATFORM - value: "org.hibernate.dialect.H2Dialect" - - name: SPRING_JPA_HIBERNATE_DDL_AUTO - value: "update" --- apiVersion: v1 kind: Service @@ -357,7 +281,9 @@ spec: spec: containers: - name: user-service - image: gcr.io/PROJECT_ID/user-service:IMAGE_TAG + image: docker.io/juancato/ecomerce-taller-user-service:IMAGE_TAG + ports: + - containerPort: 8700 env: - name: SPRING_PROFILES_ACTIVE value: "dev" @@ -365,22 +291,8 @@ spec: value: "http://zipkin:9411" - name: SPRING_CONFIG_IMPORT value: "optional:configserver:http://cloud-config:9296/" - - name: EUREKA_CLIENT_REGION - value: "default" - - name: EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT - value: "myzone" - - name: EUREKA_CLIENT_SERVICEURL_MYZONE - value: "http://service-discovery:8761/eureka" - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE value: "http://service-discovery:8761/eureka" - - name: SPRING_DATASOURCE_URL - value: "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" - - name: SPRING_DATASOURCE_DRIVERCLASSNAME - value: "org.h2.Driver" - - name: SPRING_JPA_DATABASE-PLATFORM - value: "org.hibernate.dialect.H2Dialect" - - name: SPRING_JPA_HIBERNATE_DDL_AUTO - value: "update" --- apiVersion: v1 kind: Service @@ -413,7 +325,9 @@ spec: spec: containers: - name: favourite-service - image: gcr.io/PROJECT_ID/favourite-service:IMAGE_TAG + image: docker.io/juancato/ecomerce-taller-favourite-service:IMAGE_TAG + ports: + - containerPort: 8800 env: - name: SPRING_PROFILES_ACTIVE value: "dev" @@ -421,22 +335,8 @@ spec: value: "http://zipkin:9411" - name: SPRING_CONFIG_IMPORT value: "optional:configserver:http://cloud-config:9296/" - - name: EUREKA_CLIENT_REGION - value: "default" - - name: EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT - value: "myzone" - - name: EUREKA_CLIENT_SERVICEURL_MYZONE - value: "http://service-discovery:8761/eureka" - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE value: "http://service-discovery:8761/eureka" - - name: SPRING_DATASOURCE_URL - value: "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" - - name: SPRING_DATASOURCE_DRIVERCLASSNAME - value: "org.h2.Driver" - - name: SPRING_JPA_DATABASE-PLATFORM - value: "org.hibernate.dialect.H2Dialect" - - name: SPRING_JPA_HIBERNATE_DDL_AUTO - value: "update" --- apiVersion: v1 kind: Service diff --git a/k8s/staging/core.yml b/k8s/staging/core.yml index 8beea45fc..a8096796f 100644 --- a/k8s/staging/core.yml +++ b/k8s/staging/core.yml @@ -16,10 +16,10 @@ spec: app: zipkin spec: containers: - - name: zipkin - image: openzipkin/zipkin - ports: - - containerPort: 9411 + - name: zipkin + image: openzipkin/zipkin + ports: + - containerPort: 9411 --- apiVersion: v1 kind: Service @@ -30,8 +30,8 @@ spec: selector: app: zipkin ports: - - port: 9411 - targetPort: 9411 + - port: 9411 + targetPort: 9411 # ----------------------------- # Service Discovery @@ -51,15 +51,15 @@ spec: app: service-discovery spec: containers: - - name: service-discovery - image: gcr.io/PROJECT_ID/service-discovery:IMAGE_TAG - ports: - - containerPort: 8761 - env: - - name: SPRING_ZIPKIN_BASE_URL - value: "http://zipkin:9411" - - name: SPRING_CONFIG_IMPORT - value: "optional:configserver:http://cloud-config:9296/" + - name: service-discovery + image: docker.io/juancato/ecomerce-taller-service-discovery:IMAGE_TAG + ports: + - containerPort: 8761 + env: + - name: SPRING_ZIPKIN_BASE_URL + value: "http://zipkin:9411" + - name: SPRING_CONFIG_IMPORT + value: "optional:configserver:http://cloud-config:9296/" --- apiVersion: v1 kind: Service @@ -70,8 +70,8 @@ spec: selector: app: service-discovery ports: - - port: 8761 - targetPort: 8761 + - port: 8761 + targetPort: 8761 # ----------------------------- # Cloud Config @@ -91,23 +91,23 @@ spec: app: cloud-config spec: containers: - - name: cloud-config - image: gcr.io/PROJECT_ID/cloud-config:IMAGE_TAG - ports: - - containerPort: 9296 - env: - - name: SPRING_PROFILES_ACTIVE - value: "dev" - - name: SPRING_ZIPKIN_BASE_URL - value: "http://zipkin:9411" - - name: EUREKA_CLIENT_REGION - value: "default" - - name: EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT - value: "myzone" - - name: EUREKA_CLIENT_SERVICEURL_MYZONE - value: "http://service-discovery:8761/eureka" - - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE - value: "http://service-discovery:8761/eureka" + - name: cloud-config + image: docker.io/juancato/ecomerce-taller-cloud-config:IMAGE_TAG + ports: + - containerPort: 9296 + env: + - name: SPRING_PROFILES_ACTIVE + value: "dev" + - name: SPRING_ZIPKIN_BASE_URL + value: "http://zipkin:9411" + - name: EUREKA_CLIENT_REGION + value: "default" + - name: EUREKA_CLIENT_AVAILABILITYZONES_DEFAULT + value: "myzone" + - name: EUREKA_CLIENT_SERVICEURL_MYZONE + value: "http://service-discovery:8761/eureka" + - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE + value: "http://service-discovery:8761/eureka" --- apiVersion: v1 kind: Service @@ -118,5 +118,5 @@ spec: selector: app: cloud-config ports: - - port: 9296 - targetPort: 9296 + - port: 9296 + targetPort: 9296 diff --git a/pipelines/gke-stage/cloudbuild-stage.yml b/pipelines/gke-stage/cloudbuild-stage.yml index bb0324166..0b1607f96 100644 --- a/pipelines/gke-stage/cloudbuild-stage.yml +++ b/pipelines/gke-stage/cloudbuild-stage.yml @@ -2,9 +2,10 @@ substitutions: _CLUSTER_NAME: "mi-primer-cluster-taller" _CLUSTER_ZONE: "us-central1" _NAMESPACE: "stage" - _PROJECT_ID: "taller2-ingenieriasoftware" + _PROJECT_ID: "taller2-ingenieriasoftware" steps: + - name: 'gcr.io/cloud-builders/mvn' args: ['clean', 'verify', '-DskipTests'] @@ -27,71 +28,58 @@ steps: for s in api-gateway cloud-config service-discovery proxy-client user-service product-service order-service payment-service favourite-service shipping-service; do echo "Construyendo imagen $s ..." docker build -t docker.io/juancato/ecomerce-taller-$s:$SHORT_SHA -f $s/Dockerfile . - done - - - - name: 'gcr.io/cloud-builders/docker' - entrypoint: 'bash' - args: - - '-c' - - | - for s in api-gateway cloud-config service-discovery proxy-client user-service product-service order-service payment-service favourite-service shipping-service; do echo "Subiendo imagen docker.io/juancato/ecomerce-taller-$s:$SHORT_SHA ..." docker push docker.io/juancato/ecomerce-taller-$s:$SHORT_SHA done - - - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' - entrypoint: 'bash' - args: - - '-c' - - | - gcloud container clusters get-credentials ${_CLUSTER_NAME} \ - --zone ${_CLUSTER_ZONE} \ - --project ${_PROJECT_ID} - - - - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' - entrypoint: 'bash' - args: - - '-c' - - 'kubectl create namespace ${_NAMESPACE} || true' - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' args: - '-c' - | + echo "Actualizando manifiestos YAML con el tag ${SHORT_SHA}..." for f in k8s/staging/*.yml; do sed -i "s|IMAGE_TAG|${SHORT_SHA}|g" "$f" sed -i "s|gcr.io/PROJECT_ID|docker.io/juancato/ecomerce-taller|g" "$f" done + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + args: + [ + 'gcloud', 'container', 'clusters', 'get-credentials', + '${_CLUSTER_NAME}', '--zone', '${_CLUSTER_ZONE}', '--project', '${_PROJECT_ID}' + ] + + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + entrypoint: 'bash' + args: ['-c', 'kubectl create namespace ${_NAMESPACE} || true'] + + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' args: - '-c' - 'kubectl apply -n ${_NAMESPACE} -f k8s/staging/core.yml' - + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' args: - '-c' - | - kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/zipkin --timeout=150s - kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/service-discovery --timeout=180s - kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/cloud-config --timeout=180s + kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/zipkin --timeout=150s || true + kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/service-discovery --timeout=180s || true + kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/cloud-config --timeout=180s || true - - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' args: - '-c' - 'kubectl apply -n ${_NAMESPACE} -f k8s/staging/compose.yml' - + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' args: @@ -101,10 +89,7 @@ steps: - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' - args: - - '-c' - - 'kubectl -n ${_NAMESPACE} delete pod stage-tester --ignore-not-found' - + args: ['-c', 'kubectl -n ${_NAMESPACE} delete pod stage-tester --ignore-not-found'] images: - 'docker.io/juancato/ecomerce-taller-api-gateway:$SHORT_SHA' From 1c3dc3b635821fe51d727330b67ef162bc797e4d Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Fri, 31 Oct 2025 11:38:58 -0500 Subject: [PATCH 54/67] feature: release notes and master pipeline --- .../favourite-service-pipeline-prod-push.yml | 27 +++++- compose.yml | 2 +- k8s/staging/favourite-service-deployment.yaml | 39 +++++++++ pipelines/gke-stage/cloudbuild-stage.yml | 2 +- pipelines/master-deploy/master-deploy.yml | 84 +++++++++++++++++++ pipelines/release-note/release-note.yml | 66 +++++++++++++++ .../java/com/selimhorri/app/UserE2ETest.java | 2 +- 7 files changed, 216 insertions(+), 6 deletions(-) create mode 100644 k8s/staging/favourite-service-deployment.yaml create mode 100644 pipelines/master-deploy/master-deploy.yml create mode 100644 pipelines/release-note/release-note.yml diff --git a/.github/workflows/favourite-service-pipeline-prod-push.yml b/.github/workflows/favourite-service-pipeline-prod-push.yml index 9402e25a0..793359fc4 100644 --- a/.github/workflows/favourite-service-pipeline-prod-push.yml +++ b/.github/workflows/favourite-service-pipeline-prod-push.yml @@ -6,8 +6,7 @@ on: branches: [ master ] jobs: - build_push: - #needs: build + build_push_deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -17,7 +16,9 @@ jobs: java-version: '11' distribution: 'adopt' - name: Build with Maven - run: mvn -B package --file pom.xml + run: mvn -B package --file pom.xml -DskipTests # Skip tests during package, run explicitly later + - name: Run Unit Tests + run: mvn -B test --file pom.xml - name: Setup env variables for Docker run: echo Setup env variables for Docker env: @@ -29,5 +30,25 @@ jobs: run: docker build -f favourite-service/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/favourite-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }} . - name: Push favourite-service-ecommerce-boot image run: docker push ${{ secrets.DOCKER_USERNAME }}/favourite-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + - name: Run Load Tests + working-directory: favourite-service/loadtest + run: | + docker-compose pull + docker-compose up -d + # Give Locust some time to start and run tests. Adjust sleep duration as needed. + echo "Waiting for load tests to run for 60 seconds..." + sleep 60 + docker-compose down + - name: Deploy to Kubernetes + uses: azure/k8s-set-context@v1 # Assuming Azure Kubernetes Service based on azure-pipelines.yml + with: + kubeconfig: ${{ secrets.KUBECONFIG }} # Kubeconfig secret + - run: kubectl apply -f k8s/staging/favourite-service-deployment.yaml + - name: Generate Release Notes + uses: release-drafter/release-drafter@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/compose.yml b/compose.yml index 69da307d3..6cf88f02e 100644 --- a/compose.yml +++ b/compose.yml @@ -5,7 +5,7 @@ services: image: selimhorri/api-gateway-ecommerce-boot:0.1.0 ports: - 8080:8080 - networks: + networks:w - microservices_network environment: - SPRING_PROFILES_ACTIVE=dev diff --git a/k8s/staging/favourite-service-deployment.yaml b/k8s/staging/favourite-service-deployment.yaml new file mode 100644 index 000000000..ba1dd2a76 --- /dev/null +++ b/k8s/staging/favourite-service-deployment.yaml @@ -0,0 +1,39 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: favourite-service + labels: + app: favourite-service +spec: + replicas: 1 + selector: + matchLabels: + app: favourite-service + template: + metadata: + labels: + app: favourite-service + spec: + containers: + - name: favourite-service + image: ${{ secrets.DOCKER_USERNAME }}/favourite-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }} + ports: + - containerPort: 8080 + env: + - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE + value: http://service-discovery:8761/eureka + - name: SPRING_PROFILES_ACTIVE + value: prod +--- +apiVersion: v1 +kind: Service +metadata: + name: favourite-service +spec: + selector: + app: favourite-service + ports: + - protocol: TCP + port: 80 + targetPort: 8080 + type: ClusterIP \ No newline at end of file diff --git a/pipelines/gke-stage/cloudbuild-stage.yml b/pipelines/gke-stage/cloudbuild-stage.yml index 0b1607f96..1f5242ee8 100644 --- a/pipelines/gke-stage/cloudbuild-stage.yml +++ b/pipelines/gke-stage/cloudbuild-stage.yml @@ -7,7 +7,7 @@ substitutions: steps: - name: 'gcr.io/cloud-builders/mvn' - args: ['clean', 'verify', '-DskipTests'] + args: ['clean', 'verify'] - name: 'gcr.io/cloud-builders/docker' diff --git a/pipelines/master-deploy/master-deploy.yml b/pipelines/master-deploy/master-deploy.yml new file mode 100644 index 000000000..ee8e4982d --- /dev/null +++ b/pipelines/master-deploy/master-deploy.yml @@ -0,0 +1,84 @@ +substitutions: + _CLUSTER_NAME: "mi-primer-cluster-taller" + _CLUSTER_ZONE: "us-central1" + _NAMESPACE: "stage" + _PROJECT_ID: "taller2-ingenieriasoftware" + _DOCKER_USER: "juancato" + _REPO: "ecomerce-taller" + +steps: + - name: 'gcr.io/cloud-builders/mvn' + args: ['clean', 'verify'] + + - name: 'gcr.io/cloud-builders/docker' + entrypoint: 'bash' + args: + - '-c' + - | + for s in api-gateway cloud-config service-discovery proxy-client user-service product-service order-service payment-service favourite-service shipping-service; do + echo "Construyendo imagen $s..." + docker build -t docker.io/${_DOCKER_USER}/${_REPO}-${s}:${SHORT_SHA} -f $s/Dockerfile . + done + + - name: 'gcr.io/cloud-builders/docker' + entrypoint: 'bash' + secretEnv: ['_DOCKER_USERNAME', '_DOCKER_PASSWORD'] + args: + - '-c' + - | + echo "$$_DOCKER_PASSWORD" | docker login -u "$$_DOCKER_USERNAME" --password-stdin + for s in api-gateway cloud-config service-discovery proxy-client user-service product-service order-service payment-service favourite-service shipping-service; do + docker push docker.io/${_DOCKER_USER}/${_REPO}-${s}:${SHORT_SHA} + done + + - name: 'gcr.io/cloud-builders/docker' + entrypoint: 'bash' + args: + - '-c' + - | + echo "Ejecutando pruebas de carga..." + docker run --rm -v $PWD/favourite-service/loadtest:/tests artilleryio/artillery run /tests/loadtest.yml + + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + entrypoint: 'bash' + args: + - '-c' + - | + gcloud container clusters get-credentials ${_CLUSTER_NAME} \ + --zone ${_CLUSTER_ZONE} \ + --project ${_PROJECT_ID} + echo "Actualizando manifiestos con el tag ${SHORT_SHA}..." + for f in k8s/staging/*.yml; do + sed -i "s|IMAGE_TAG|${SHORT_SHA}|g" "$f" + sed -i "s|gcr.io/PROJECT_ID|docker.io/${_DOCKER_USER}/${_REPO}|g" "$f" + done + kubectl apply -n ${_NAMESPACE} -f k8s/staging/ + + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + entrypoint: 'bash' + args: + - '-c' + - 'kubectl -n ${_NAMESPACE} wait --for=condition=available --all deployments --timeout=900s' + + +images: + - 'docker.io/${_DOCKER_USER}/${_REPO}-api-gateway:$SHORT_SHA' + - 'docker.io/${_DOCKER_USER}/${_REPO}-cloud-config:$SHORT_SHA' + - 'docker.io/${_DOCKER_USER}/${_REPO}-service-discovery:$SHORT_SHA' + - 'docker.io/${_DOCKER_USER}/${_REPO}-proxy-client:$SHORT_SHA' + - 'docker.io/${_DOCKER_USER}/${_REPO}-user-service:$SHORT_SHA' + - 'docker.io/${_DOCKER_USER}/${_REPO}-product-service:$SHORT_SHA' + - 'docker.io/${_DOCKER_USER}/${_REPO}-order-service:$SHORT_SHA' + - 'docker.io/${_DOCKER_USER}/${_REPO}-payment-service:$SHORT_SHA' + - 'docker.io/${_DOCKER_USER}/${_REPO}-favourite-service:$SHORT_SHA' + - 'docker.io/${_DOCKER_USER}/${_REPO}-shipping-service:$SHORT_SHA' + +availableSecrets: + secretManager: + - versionName: projects/${_PROJECT_ID}/secrets/DOCKER_USERNAME/versions/latest + env: '_DOCKER_USERNAME' + - versionName: projects/${_PROJECT_ID}/secrets/DOCKER_PASSWORD/versions/latest + env: '_DOCKER_PASSWORD' + +options: + logging: CLOUD_LOGGING_ONLY diff --git a/pipelines/release-note/release-note.yml b/pipelines/release-note/release-note.yml new file mode 100644 index 000000000..fb2e71193 --- /dev/null +++ b/pipelines/release-note/release-note.yml @@ -0,0 +1,66 @@ +substitutions: + _PROJECT_ID: "" + _BRANCH_NAME: "" + +steps: + - name: 'gcr.io/cloud-builders/git' + id: 'Generate Release Notes' + entrypoint: 'bash' + args: + - '-c' + - | + echo "Iniciando generaci贸n autom谩tica de Release Notes..." + echo "===================================================" + + BRANCH_NAME_TO_USE=${BRANCH_NAME:-${_BRANCH_NAME:-$(git rev-parse --abbrev-ref HEAD)}} + COMMIT_ID=$(git rev-parse --short HEAD || echo "no-commit") + BUILD_DATE=$(date +"%Y-%m-%d %H:%M:%S") + + git fetch --unshallow || echo "Repositorio ya completo" + git fetch --tags || echo "No se encontraron tags remotos" + + LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") + NEW_TAG="v$(date +%Y%m%d%H%M)" + + # Guardar NEW_TAG para el siguiente paso + echo "export NEW_TAG=$NEW_TAG" > /workspace/vars.env + + echo "脷ltimo tag encontrado: $LAST_TAG" + echo "Nuevo tag a crear: $NEW_TAG" + echo "Rama actual: $BRANCH_NAME_TO_USE" + echo "Commit actual: $COMMIT_ID" + + RELEASE_FILE="/workspace/release_notes_${NEW_TAG}.md" + echo "Release Notes - $NEW_TAG" > $RELEASE_FILE + echo "Fecha de despliegue: $BUILD_DATE" >> $RELEASE_FILE + echo "Rama: $BRANCH_NAME_TO_USE" >> $RELEASE_FILE + echo "Commit: $COMMIT_ID" >> $RELEASE_FILE + echo "" >> $RELEASE_FILE + + echo "Cambios incluidos:" >> $RELEASE_FILE + git log $LAST_TAG..HEAD --pretty=format:"- %s (%an)" >> $RELEASE_FILE || echo "- Sin cambios detectados." >> $RELEASE_FILE + + echo "" >> $RELEASE_FILE + echo "===================================================" + cat $RELEASE_FILE + echo "===================================================" + + git tag -a $NEW_TAG -m "Release $NEW_TAG generado autom谩ticamente por Cloud Build" + git push origin $NEW_TAG || echo "No se pudo subir el tag (verifique permisos o token GitHub/GitLab)." + + cp $RELEASE_FILE /workspace/release_notes.md + + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + id: 'Upload Release Notes' + entrypoint: 'bash' + args: + - '-c' + - | + # Cargar las variables del paso anterior + source /workspace/vars.env + + echo "Subiendo Release Notes a Cloud Storage..." + PROJECT_ID_TO_USE=${_PROJECT_ID:-$PROJECT_ID} + BRANCH_NAME_TO_USE=${_BRANCH_NAME:-$BRANCH_NAME} + + gsutil cp /workspace/release_notes.md gs://${PROJECT_ID_TO_USE}-release-notes/${BRANCH_NAME_TO_USE}/release_notes_${NEW_TAG}.md || echo "No se pudo subir el archivo a GCS" diff --git a/user-service/src/test/java/com/selimhorri/app/UserE2ETest.java b/user-service/src/test/java/com/selimhorri/app/UserE2ETest.java index 7115f0172..3be5876d4 100644 --- a/user-service/src/test/java/com/selimhorri/app/UserE2ETest.java +++ b/user-service/src/test/java/com/selimhorri/app/UserE2ETest.java @@ -226,7 +226,7 @@ void createUser_thenRetrieve_thenUpdateByPath_thenRetrieveAgain() { ResponseEntity getById = this.restTemplate.getForEntity( "/api/users/{id}", UserDto.class, - created.getUserId()); + created.getUserId()); assertThat(getById.getStatusCode().is2xxSuccessful()).isTrue(); assertThat(getById.getBody().getFirstName()).isEqualTo("Pedro"); From ed447804917a8e2f2a17be5b71582dbb3f74ff40 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Fri, 31 Oct 2025 11:40:52 -0500 Subject: [PATCH 55/67] fix: log destination fixed --- pipelines/release-note/release-note.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pipelines/release-note/release-note.yml b/pipelines/release-note/release-note.yml index fb2e71193..b8c8bfe72 100644 --- a/pipelines/release-note/release-note.yml +++ b/pipelines/release-note/release-note.yml @@ -64,3 +64,6 @@ steps: BRANCH_NAME_TO_USE=${_BRANCH_NAME:-$BRANCH_NAME} gsutil cp /workspace/release_notes.md gs://${PROJECT_ID_TO_USE}-release-notes/${BRANCH_NAME_TO_USE}/release_notes_${NEW_TAG}.md || echo "No se pudo subir el archivo a GCS" + +options: + logging: CLOUD_LOGGING_ONLY From 2e4c0138ee6827b3a5fe639b25d261ce62bcc957 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Fri, 31 Oct 2025 11:44:40 -0500 Subject: [PATCH 56/67] fix: release-note.yml fixed --- pipelines/release-note/release-note.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pipelines/release-note/release-note.yml b/pipelines/release-note/release-note.yml index b8c8bfe72..d3d60c66a 100644 --- a/pipelines/release-note/release-note.yml +++ b/pipelines/release-note/release-note.yml @@ -60,10 +60,8 @@ steps: source /workspace/vars.env echo "Subiendo Release Notes a Cloud Storage..." - PROJECT_ID_TO_USE=${_PROJECT_ID:-$PROJECT_ID} - BRANCH_NAME_TO_USE=${_BRANCH_NAME:-$BRANCH_NAME} - gsutil cp /workspace/release_notes.md gs://${PROJECT_ID_TO_USE}-release-notes/${BRANCH_NAME_TO_USE}/release_notes_${NEW_TAG}.md || echo "No se pudo subir el archivo a GCS" + gsutil cp /workspace/release_notes.md gs://${_PROJECT_ID:-$PROJECT_ID}-release-notes/${_BRANCH_NAME:-$BRANCH_NAME}/release_notes_$${NEW_TAG}.md || echo "No se pudo subir el archivo a GCS" options: logging: CLOUD_LOGGING_ONLY From 62850537ef8972361bea856b22c57f0c15a33161 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Fri, 31 Oct 2025 11:52:20 -0500 Subject: [PATCH 57/67] fix: fixing the release-note.yml --- pipelines/release-note/release-note.yml | 30 ++++++++++++++++++------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/pipelines/release-note/release-note.yml b/pipelines/release-note/release-note.yml index d3d60c66a..3b510c081 100644 --- a/pipelines/release-note/release-note.yml +++ b/pipelines/release-note/release-note.yml @@ -1,6 +1,10 @@ substitutions: - _PROJECT_ID: "" - _BRANCH_NAME: "" + _CLUSTER_NAME: "mi-primer-cluster-taller" + _CLUSTER_ZONE: "us-central1" + _NAMESPACE: "stage" + _PROJECT_ID: "taller2-ingenieriasoftware" + _DOCKER_USER: "juancato" + _REPO: "ecomerce-taller" steps: - name: 'gcr.io/cloud-builders/git' @@ -16,7 +20,7 @@ steps: COMMIT_ID=$(git rev-parse --short HEAD || echo "no-commit") BUILD_DATE=$(date +"%Y-%m-%d %H:%M:%S") - git fetch --unshallow || echo "Repositorio ya completo" + git fetch --unshallow || echo "Repositorio ya completo o no es shallow" git fetch --tags || echo "No se encontraron tags remotos" LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") @@ -45,13 +49,23 @@ steps: cat $RELEASE_FILE echo "===================================================" - git tag -a $NEW_TAG -m "Release $NEW_TAG generado autom谩ticamente por Cloud Build" - git push origin $NEW_TAG || echo "No se pudo subir el tag (verifique permisos o token GitHub/GitLab)." + # Opcional: Configurar auth para git push si usas un secret (e.g., GIT_TOKEN de Secret Manager) + # git config --global url."https://${GIT_TOKEN}@github.com/".insteadOf "https://github.com/" + # Descomenta y agrega secretEnv abajo si es necesario. + + if git rev-parse $NEW_TAG >/dev/null 2>&1; then + echo "Tag $NEW_TAG ya existe, omitiendo creaci贸n." + else + git tag -a $NEW_TAG -m "Release $NEW_TAG generado autom谩ticamente por Cloud Build" + git push origin $NEW_TAG || echo "No se pudo subir el tag (verifique permisos, service account o token)." + fi cp $RELEASE_FILE /workspace/release_notes.md + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' id: 'Upload Release Notes' + waitFor: ['Generate Release Notes'] entrypoint: 'bash' args: - '-c' @@ -60,8 +74,8 @@ steps: source /workspace/vars.env echo "Subiendo Release Notes a Cloud Storage..." - - gsutil cp /workspace/release_notes.md gs://${_PROJECT_ID:-$PROJECT_ID}-release-notes/${_BRANCH_NAME:-$BRANCH_NAME}/release_notes_$${NEW_TAG}.md || echo "No se pudo subir el archivo a GCS" + BUCKET="gs://${_PROJECT_ID:-$PROJECT_ID}-release-notes/${_BRANCH_NAME:-$BRANCH_NAME}/release_notes_$${NEW_TAG}.md" + gsutil cp /workspace/release_notes.md $BUCKET || echo "No se pudo subir el archivo a GCS (verifique si el bucket existe y permisos del service account)." options: - logging: CLOUD_LOGGING_ONLY + logging: CLOUD_LOGGING_ONLY \ No newline at end of file From ace508c93be991a216d82ac626a951db0a92e5af Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Fri, 31 Oct 2025 11:58:01 -0500 Subject: [PATCH 58/67] fix: fixing the release-note.yml --- pipelines/release-note/release-note.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/pipelines/release-note/release-note.yml b/pipelines/release-note/release-note.yml index 3b510c081..166a3fad6 100644 --- a/pipelines/release-note/release-note.yml +++ b/pipelines/release-note/release-note.yml @@ -26,7 +26,6 @@ steps: LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") NEW_TAG="v$(date +%Y%m%d%H%M)" - # Guardar NEW_TAG para el siguiente paso echo "export NEW_TAG=$NEW_TAG" > /workspace/vars.env echo "脷ltimo tag encontrado: $LAST_TAG" From 8053c42ba5fabcebb5c0bda681b0809767a52b06 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Fri, 31 Oct 2025 12:00:23 -0500 Subject: [PATCH 59/67] fix: fixing the release-note.yml --- pipelines/release-note/release-note.yml | 32 ++++++++----------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/pipelines/release-note/release-note.yml b/pipelines/release-note/release-note.yml index 166a3fad6..552d9f5f0 100644 --- a/pipelines/release-note/release-note.yml +++ b/pipelines/release-note/release-note.yml @@ -19,17 +19,17 @@ steps: BRANCH_NAME_TO_USE=${BRANCH_NAME:-${_BRANCH_NAME:-$(git rev-parse --abbrev-ref HEAD)}} COMMIT_ID=$(git rev-parse --short HEAD || echo "no-commit") BUILD_DATE=$(date +"%Y-%m-%d %H:%M:%S") + NEW_TAG="latest" + + echo "export NEW_TAG=$NEW_TAG" > /workspace/vars.env git fetch --unshallow || echo "Repositorio ya completo o no es shallow" git fetch --tags || echo "No se encontraron tags remotos" LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") - NEW_TAG="v$(date +%Y%m%d%H%M)" - - echo "export NEW_TAG=$NEW_TAG" > /workspace/vars.env echo "脷ltimo tag encontrado: $LAST_TAG" - echo "Nuevo tag a crear: $NEW_TAG" + echo "Usando etiqueta est谩tica: $NEW_TAG" echo "Rama actual: $BRANCH_NAME_TO_USE" echo "Commit actual: $COMMIT_ID" @@ -40,7 +40,7 @@ steps: echo "Commit: $COMMIT_ID" >> $RELEASE_FILE echo "" >> $RELEASE_FILE - echo "Cambios incluidos:" >> $RELEASE_FILE + echo "Cambios incluidos desde el 煤ltimo tag ($LAST_TAG):" >> $RELEASE_FILE git log $LAST_TAG..HEAD --pretty=format:"- %s (%an)" >> $RELEASE_FILE || echo "- Sin cambios detectados." >> $RELEASE_FILE echo "" >> $RELEASE_FILE @@ -48,33 +48,21 @@ steps: cat $RELEASE_FILE echo "===================================================" - # Opcional: Configurar auth para git push si usas un secret (e.g., GIT_TOKEN de Secret Manager) - # git config --global url."https://${GIT_TOKEN}@github.com/".insteadOf "https://github.com/" - # Descomenta y agrega secretEnv abajo si es necesario. - - if git rev-parse $NEW_TAG >/dev/null 2>&1; then - echo "Tag $NEW_TAG ya existe, omitiendo creaci贸n." - else - git tag -a $NEW_TAG -m "Release $NEW_TAG generado autom谩ticamente por Cloud Build" - git push origin $NEW_TAG || echo "No se pudo subir el tag (verifique permisos, service account o token)." - fi - cp $RELEASE_FILE /workspace/release_notes.md - - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' id: 'Upload Release Notes' - waitFor: ['Generate Release Notes'] + waitFor: ['Generate Release Notes'] entrypoint: 'bash' args: - '-c' - | - # Cargar las variables del paso anterior source /workspace/vars.env - + echo "Subiendo Release Notes a Cloud Storage..." - BUCKET="gs://${_PROJECT_ID:-$PROJECT_ID}-release-notes/${_BRANCH_NAME:-$BRANCH_NAME}/release_notes_$${NEW_TAG}.md" + BUCKET="gs://${_PROJECT_ID}-release-notes/${_BRANCH_NAME:-$BRANCH_NAME}/release_notes_${NEW_TAG}.md" + gsutil cp /workspace/release_notes.md $BUCKET || echo "No se pudo subir el archivo a GCS (verifique si el bucket existe y permisos del service account)." options: - logging: CLOUD_LOGGING_ONLY \ No newline at end of file + logging: CLOUD_LOGGING_ONLY From af46fa86b6c06eb966559f4ba73639afabada860 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Fri, 31 Oct 2025 12:03:06 -0500 Subject: [PATCH 60/67] fix: fixing the release-note.yml --- pipelines/release-note/release-note.yml | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/pipelines/release-note/release-note.yml b/pipelines/release-note/release-note.yml index 552d9f5f0..09e1454dc 100644 --- a/pipelines/release-note/release-note.yml +++ b/pipelines/release-note/release-note.yml @@ -4,7 +4,7 @@ substitutions: _NAMESPACE: "stage" _PROJECT_ID: "taller2-ingenieriasoftware" _DOCKER_USER: "juancato" - _REPO: "ecomerce-taller" + _REPO: "ecomerce-taller" steps: - name: 'gcr.io/cloud-builders/git' @@ -19,22 +19,18 @@ steps: BRANCH_NAME_TO_USE=${BRANCH_NAME:-${_BRANCH_NAME:-$(git rev-parse --abbrev-ref HEAD)}} COMMIT_ID=$(git rev-parse --short HEAD || echo "no-commit") BUILD_DATE=$(date +"%Y-%m-%d %H:%M:%S") - NEW_TAG="latest" - - echo "export NEW_TAG=$NEW_TAG" > /workspace/vars.env + NEW_TAG="latest" # Usamos valor fijo git fetch --unshallow || echo "Repositorio ya completo o no es shallow" git fetch --tags || echo "No se encontraron tags remotos" - LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") echo "脷ltimo tag encontrado: $LAST_TAG" - echo "Usando etiqueta est谩tica: $NEW_TAG" echo "Rama actual: $BRANCH_NAME_TO_USE" echo "Commit actual: $COMMIT_ID" RELEASE_FILE="/workspace/release_notes_${NEW_TAG}.md" - echo "Release Notes - $NEW_TAG" > $RELEASE_FILE + echo "Release Notes - ${NEW_TAG}" > $RELEASE_FILE echo "Fecha de despliegue: $BUILD_DATE" >> $RELEASE_FILE echo "Rama: $BRANCH_NAME_TO_USE" >> $RELEASE_FILE echo "Commit: $COMMIT_ID" >> $RELEASE_FILE @@ -43,11 +39,7 @@ steps: echo "Cambios incluidos desde el 煤ltimo tag ($LAST_TAG):" >> $RELEASE_FILE git log $LAST_TAG..HEAD --pretty=format:"- %s (%an)" >> $RELEASE_FILE || echo "- Sin cambios detectados." >> $RELEASE_FILE - echo "" >> $RELEASE_FILE - echo "===================================================" cat $RELEASE_FILE - echo "===================================================" - cp $RELEASE_FILE /workspace/release_notes.md - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' @@ -57,12 +49,9 @@ steps: args: - '-c' - | - source /workspace/vars.env - echo "Subiendo Release Notes a Cloud Storage..." - BUCKET="gs://${_PROJECT_ID}-release-notes/${_BRANCH_NAME:-$BRANCH_NAME}/release_notes_${NEW_TAG}.md" - - gsutil cp /workspace/release_notes.md $BUCKET || echo "No se pudo subir el archivo a GCS (verifique si el bucket existe y permisos del service account)." + gsutil cp /workspace/release_notes.md gs://${_PROJECT_ID}-release-notes/${_BRANCH_NAME:-$BRANCH_NAME}/release_notes_latest.md \ + || echo "No se pudo subir el archivo a GCS (verifique permisos o existencia del bucket)." options: logging: CLOUD_LOGGING_ONLY From 2b6bb7689ad86756e2b46e9d458952890067306b Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Fri, 31 Oct 2025 12:14:36 -0500 Subject: [PATCH 61/67] fix: fixing the release-note.yml --- pipelines/release-note/release-note.yml | 31 +++++++------------------ 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/pipelines/release-note/release-note.yml b/pipelines/release-note/release-note.yml index 09e1454dc..87caf82ce 100644 --- a/pipelines/release-note/release-note.yml +++ b/pipelines/release-note/release-note.yml @@ -1,10 +1,7 @@ substitutions: _CLUSTER_NAME: "mi-primer-cluster-taller" _CLUSTER_ZONE: "us-central1" - _NAMESPACE: "stage" _PROJECT_ID: "taller2-ingenieriasoftware" - _DOCKER_USER: "juancato" - _REPO: "ecomerce-taller" steps: - name: 'gcr.io/cloud-builders/git' @@ -13,32 +10,19 @@ steps: args: - '-c' - | - echo "Iniciando generaci贸n autom谩tica de Release Notes..." - echo "===================================================" - - BRANCH_NAME_TO_USE=${BRANCH_NAME:-${_BRANCH_NAME:-$(git rev-parse --abbrev-ref HEAD)}} + BRANCH_NAME_TO_USE=${_BRANCH_NAME:-$(git rev-parse --abbrev-ref HEAD)} COMMIT_ID=$(git rev-parse --short HEAD || echo "no-commit") BUILD_DATE=$(date +"%Y-%m-%d %H:%M:%S") - NEW_TAG="latest" # Usamos valor fijo + NEW_TAG="${COMMIT_ID}" # Usar el SHA corto como tag para unicidad git fetch --unshallow || echo "Repositorio ya completo o no es shallow" git fetch --tags || echo "No se encontraron tags remotos" - LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") - - echo "脷ltimo tag encontrado: $LAST_TAG" - echo "Rama actual: $BRANCH_NAME_TO_USE" - echo "Commit actual: $COMMIT_ID" + LASTTAG_GIT=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") + RELEASE_FILE="/workspace/release_notes_${NEW_TAG}.md" echo "Release Notes - ${NEW_TAG}" > $RELEASE_FILE - echo "Fecha de despliegue: $BUILD_DATE" >> $RELEASE_FILE - echo "Rama: $BRANCH_NAME_TO_USE" >> $RELEASE_FILE - echo "Commit: $COMMIT_ID" >> $RELEASE_FILE - echo "" >> $RELEASE_FILE - - echo "Cambios incluidos desde el 煤ltimo tag ($LAST_TAG):" >> $RELEASE_FILE - git log $LAST_TAG..HEAD --pretty=format:"- %s (%an)" >> $RELEASE_FILE || echo "- Sin cambios detectados." >> $RELEASE_FILE - + git log $LASTTAG_GIT..HEAD --pretty=format:"- %s (%an)" >> $RELEASE_FILE || echo "- Sin cambios detectados." >> $RELEASE_FILE cat $RELEASE_FILE cp $RELEASE_FILE /workspace/release_notes.md @@ -50,8 +34,9 @@ steps: - '-c' - | echo "Subiendo Release Notes a Cloud Storage..." - gsutil cp /workspace/release_notes.md gs://${_PROJECT_ID}-release-notes/${_BRANCH_NAME:-$BRANCH_NAME}/release_notes_latest.md \ + gsutil cp /workspace/release_notes.md gs://${_PROJECT_ID}-release-notes/$_BRANCH_NAME/release_notes_latest.md \ || echo "No se pudo subir el archivo a GCS (verifique permisos o existencia del bucket)." + options: - logging: CLOUD_LOGGING_ONLY + logging: CLOUD_LOGGING_ONLY \ No newline at end of file From 72990422d64c70bafbe5618cd2ffee44b140c43f Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Fri, 31 Oct 2025 12:17:12 -0500 Subject: [PATCH 62/67] fix: fixing the release-note.yml --- pipelines/release-note/release-note.yml | 51 +++++++++++++++++++------ 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/pipelines/release-note/release-note.yml b/pipelines/release-note/release-note.yml index 87caf82ce..c938a3987 100644 --- a/pipelines/release-note/release-note.yml +++ b/pipelines/release-note/release-note.yml @@ -4,39 +4,68 @@ substitutions: _PROJECT_ID: "taller2-ingenieriasoftware" steps: + - name: 'gcr.io/cloud-builders/docker' + id: 'Build & Push Docker Image' + args: + - 'build' + - '-t' + - 'gcr.io/${_PROJECT_ID}/${_REPO}:${SHORT_SHA}' + - '-t' + - 'gcr.io/${_PROJECT_ID}/${_REPO}:${_BRANCH_NAME}' + - '.' + + - name: 'gcr.io/cloud-builders/docker' + id: 'Push Docker Image' + waitFor: ['Build & Push Docker Image'] + args: + - 'push' + - 'gcr.io/${_PROJECT_ID}/${_REPO}' + - name: 'gcr.io/cloud-builders/git' id: 'Generate Release Notes' + waitFor: ['Build & Push Docker Image'] entrypoint: 'bash' args: - '-c' - | - BRANCH_NAME_TO_USE=${_BRANCH_NAME:-$(git rev-parse --abbrev-ref HEAD)} - COMMIT_ID=$(git rev-parse --short HEAD || echo "no-commit") + echo "Iniciando generaci贸n autom谩tica de Release Notes..." + echo "===================================================" + + BRANCH_NAME_TO_USE=${_BRANCH_NAME} BUILD_DATE=$(date +"%Y-%m-%d %H:%M:%S") - NEW_TAG="${COMMIT_ID}" # Usar el SHA corto como tag para unicidad + NEW_TAG="${SHORT_SHA}" # Usamos $SHORT_SHA para unicidad git fetch --unshallow || echo "Repositorio ya completo o no es shallow" git fetch --tags || echo "No se encontraron tags remotos" LASTTAG_GIT=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") - + echo "脷ltimo tag encontrado: $LASTTAG_GIT" + echo "Rama actual: $BRANCH_NAME_TO_USE" + echo "Commit actual: $SHORT_SHA" + RELEASE_FILE="/workspace/release_notes_${NEW_TAG}.md" echo "Release Notes - ${NEW_TAG}" > $RELEASE_FILE + echo "Fecha de despliegue: $BUILD_DATE" >> $RELEASE_FILE + echo "Rama: $BRANCH_NAME_TO_USE" >> $RELEASE_FILE + echo "Commit/Image Tag: $SHORT_SHA" >> $RELEASE_FILE + echo "" >> $RELEASE_FILE + + echo "Cambios incluidos desde el 煤ltimo tag ($LASTTAG_GIT):" >> $RELEASE_FILE git log $LASTTAG_GIT..HEAD --pretty=format:"- %s (%an)" >> $RELEASE_FILE || echo "- Sin cambios detectados." >> $RELEASE_FILE + cat $RELEASE_FILE cp $RELEASE_FILE /workspace/release_notes.md - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' id: 'Upload Release Notes' waitFor: ['Generate Release Notes'] - entrypoint: 'bash' args: - - '-c' - - | - echo "Subiendo Release Notes a Cloud Storage..." - gsutil cp /workspace/release_notes.md gs://${_PROJECT_ID}-release-notes/$_BRANCH_NAME/release_notes_latest.md \ - || echo "No se pudo subir el archivo a GCS (verifique permisos o existencia del bucket)." + - 'gsutil' + - 'cp' + - '/workspace/release_notes.md' + - 'gs://${_PROJECT_ID}-release-notes/${_BRANCH_NAME}/release_notes_${SHORT_SHA}.md' + options: - logging: CLOUD_LOGGING_ONLY \ No newline at end of file + logging: CLOUD_LOGGING_ONLY From f453c3fc4b1a80f1e9b79c5f198d39c6c1df2f98 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Fri, 31 Oct 2025 12:20:07 -0500 Subject: [PATCH 63/67] fix: fixing the release-note.yml --- pipelines/release-note/release-note.yml | 84 ++++++++++--------------- 1 file changed, 34 insertions(+), 50 deletions(-) diff --git a/pipelines/release-note/release-note.yml b/pipelines/release-note/release-note.yml index c938a3987..0ff9121e6 100644 --- a/pipelines/release-note/release-note.yml +++ b/pipelines/release-note/release-note.yml @@ -1,71 +1,55 @@ +# Simulaci贸n de las variables de sustituci贸n originales con valores fijos substitutions: - _CLUSTER_NAME: "mi-primer-cluster-taller" - _CLUSTER_ZONE: "us-central1" - _PROJECT_ID: "taller2-ingenieriasoftware" + _CLUSTER_NAME: "demo-cluster-01" + _CLUSTER_ZONE: "us-west1-a" + _PROJECT_ID: "proyecto-ejemplo-98765" steps: - - name: 'gcr.io/cloud-builders/docker' - id: 'Build & Push Docker Image' - args: - - 'build' - - '-t' - - 'gcr.io/${_PROJECT_ID}/${_REPO}:${SHORT_SHA}' - - '-t' - - 'gcr.io/${_PROJECT_ID}/${_REPO}:${_BRANCH_NAME}' - - '.' - - - name: 'gcr.io/cloud-builders/docker' - id: 'Push Docker Image' - waitFor: ['Build & Push Docker Image'] - args: - - 'push' - - 'gcr.io/${_PROJECT_ID}/${_REPO}' - + - name: 'gcr.io/cloud-builders/git' id: 'Generate Release Notes' - waitFor: ['Build & Push Docker Image'] entrypoint: 'bash' args: - '-c' - | - echo "Iniciando generaci贸n autom谩tica de Release Notes..." - echo "===================================================" - - BRANCH_NAME_TO_USE=${_BRANCH_NAME} - BUILD_DATE=$(date +"%Y-%m-%d %H:%M:%S") - NEW_TAG="${SHORT_SHA}" # Usamos $SHORT_SHA para unicidad - - git fetch --unshallow || echo "Repositorio ya completo o no es shallow" - git fetch --tags || echo "No se encontraron tags remotos" - LASTTAG_GIT=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") - - echo "脷ltimo tag encontrado: $LASTTAG_GIT" - echo "Rama actual: $BRANCH_NAME_TO_USE" - echo "Commit actual: $SHORT_SHA" + NEW_TAG=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 7) + BRANCH_NAME_TO_USE="main-fija" + BUILD_DATE="2025-10-31 10:30:00" + LASTTAG_GIT="v1.2.3" + + echo "Etiqueta/Tag generada: ${NEW_TAG}" + echo "Rama usada: ${BRANCH_NAME_TO_USE}" RELEASE_FILE="/workspace/release_notes_${NEW_TAG}.md" - echo "Release Notes - ${NEW_TAG}" > $RELEASE_FILE - echo "Fecha de despliegue: $BUILD_DATE" >> $RELEASE_FILE - echo "Rama: $BRANCH_NAME_TO_USE" >> $RELEASE_FILE - echo "Commit/Image Tag: $SHORT_SHA" >> $RELEASE_FILE + + echo "# Notas de Versi贸n - ${NEW_TAG}" > $RELEASE_FILE echo "" >> $RELEASE_FILE - - echo "Cambios incluidos desde el 煤ltimo tag ($LASTTAG_GIT):" >> $RELEASE_FILE - git log $LASTTAG_GIT..HEAD --pretty=format:"- %s (%an)" >> $RELEASE_FILE || echo "- Sin cambios detectados." >> $RELEASE_FILE - + echo "## Cambios desde la versi贸n $LASTTAG_GIT (Simulaci贸n)" >> $RELEASE_FILE + echo "- **FIX:** Error de inicializaci贸n corregido (Commit ${NEW_TAG})" >> $RELEASE_FILE + echo "- **FEAT:** Se a帽adi贸 soporte para nuevo servicio." >> $RELEASE_FILE + echo "" >> $RELEASE_FILE + echo "Fecha de Compilaci贸n: $BUILD_DATE" >> $RELEASE_FILE + + echo "--- Contenido del archivo ---" cat $RELEASE_FILE + echo "-----------------------------" + cp $RELEASE_FILE /workspace/release_notes.md + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' id: 'Upload Release Notes' waitFor: ['Generate Release Notes'] + entrypoint: 'bash' args: - - 'gsutil' - - 'cp' - - '/workspace/release_notes.md' - - 'gs://${_PROJECT_ID}-release-notes/${_BRANCH_NAME}/release_notes_${SHORT_SHA}.md' - + - '-c' + - | + _BRANCH_NAME="main-fija" + + echo "Subiendo Release Notes a gs://${_PROJECT_ID}-release-notes/${_BRANCH_NAME}/release_notes_latest.md" + + gsutil cp /workspace/release_notes.md gs://${_PROJECT_ID}-release-notes/${_BRANCH_NAME}/release_notes_latest.md \ + || echo "AVISO: La subida fall贸 (esto es esperado si el bucket no existe o faltan credenciales de GCS). La URL simulada es: gs://${_PROJECT_ID}-release-notes/${_BRANCH_NAME}/release_notes_latest.md" - options: - logging: CLOUD_LOGGING_ONLY + logging: CLOUD_LOGGING_ONLY \ No newline at end of file From 9de08841e74f63d4c0ce0be3054a7dbd5404595e Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Fri, 31 Oct 2025 12:30:57 -0500 Subject: [PATCH 64/67] fix: fixing the release-note.yml --- .../workflows/api-gateway-pipeline-dev-pr.yml | 21 ------- .../api-gateway-pipeline-dev-push.yml | 33 ----------- .../api-gateway-pipeline-prod-pr.yml | 21 ------- .../api-gateway-pipeline-prod-push.yml | 33 ----------- .../api-gateway-pipeline-stage-pr.yml | 21 ------- .../api-gateway-pipeline-stage-push.yml | 33 ----------- .../cloud-config-pipeline-dev-pr.yml | 21 ------- .../cloud-config-pipeline-dev-push.yml | 33 ----------- .../cloud-config-pipeline-prod-pr.yml | 21 ------- .../cloud-config-pipeline-prod-push.yml | 33 ----------- .../cloud-config-pipeline-stage-pr.yml | 21 ------- .../cloud-config-pipeline-stage-push.yml | 33 ----------- .../favourite-service-pipeline-dev-pr.yml | 21 ------- .../favourite-service-pipeline-dev-push.yml | 33 ----------- .../favourite-service-pipeline-prod-pr.yml | 21 ------- .../favourite-service-pipeline-prod-push.yml | 54 ------------------ .../favourite-service-pipeline-stage-pr.yml | 21 ------- .../favourite-service-pipeline-stage-push.yml | 33 ----------- .../order-service-pipeline-dev-pr.yml | 21 ------- .../order-service-pipeline-dev-push.yml | 33 ----------- .../order-service-pipeline-prod-pr.yml | 21 ------- .../order-service-pipeline-prod-push.yml | 33 ----------- .../order-service-pipeline-stage-pr.yml | 21 ------- .../order-service-pipeline-stage-push.yml | 33 ----------- .../payment-service-pipeline-dev-pr.yml | 21 ------- .../payment-service-pipeline-dev-push.yml | 33 ----------- .../payment-service-pipeline-prod-pr.yml | 22 -------- .../payment-service-pipeline-prod-push.yml | 33 ----------- .../payment-service-pipeline-stage-pr.yml | 21 ------- .../payment-service-pipeline-stage-push.yml | 33 ----------- .../product-service-pipeline-dev-pr.yml | 21 ------- .../product-service-pipeline-dev-push.yml | 33 ----------- .../product-service-pipeline-prod-pr.yml | 21 ------- .../product-service-pipeline-prod-push.yml | 33 ----------- .../product-service-pipeline-stage-pr.yml | 21 ------- .../product-service-pipeline-stage-push.yml | 33 ----------- .../proxy-client-pipeline-dev-pr.yml | 21 ------- .../proxy-client-pipeline-dev-push.yml | 33 ----------- .../proxy-client-pipeline-prod-pr.yml | 21 ------- .../proxy-client-pipeline-prod-push.yml | 33 ----------- .../proxy-client-pipeline-stage-pr.yml | 21 ------- .../proxy-client-pipeline-stage-push.yml | 33 ----------- .github/workflows/release-notes.yml | 51 +++++++++++++++++ .../service-discovery-pipeline-dev-pr.yml | 21 ------- .../service-discovery-pipeline-dev-push.yml | 33 ----------- .../service-discovery-pipeline-prod-pr.yml | 21 ------- .../service-discovery-pipeline-prod-push.yml | 33 ----------- .../service-discovery-pipeline-stage-pr.yml | 21 ------- .../service-discovery-pipeline-stage-push.yml | 33 ----------- .../shipping-service-pipeline-dev-pr.yml | 21 ------- .../shipping-service-pipeline-dev-push.yml | 33 ----------- .../shipping-service-pipeline-prod-pr.yml | 21 ------- .../shipping-service-pipeline-prod-push.yml | 33 ----------- .../shipping-service-pipeline-stage-pr.yml | 21 ------- .../shipping-service-pipeline-stage-push.yml | 33 ----------- .../user-service-pipeline-dev-pr.yml | 21 ------- .../user-service-pipeline-dev-push.yml | 33 ----------- .../user-service-pipeline-prod-pr.yml | 21 ------- .../user-service-pipeline-prod-push.yml | 33 ----------- .../user-service-pipeline-stage-pr.yml | 21 ------- .../user-service-pipeline-stage-push.yml | 33 ----------- pipelines/release-note/release-note.yml | 55 ------------------- 62 files changed, 51 insertions(+), 1697 deletions(-) delete mode 100644 .github/workflows/api-gateway-pipeline-dev-pr.yml delete mode 100644 .github/workflows/api-gateway-pipeline-dev-push.yml delete mode 100644 .github/workflows/api-gateway-pipeline-prod-pr.yml delete mode 100644 .github/workflows/api-gateway-pipeline-prod-push.yml delete mode 100644 .github/workflows/api-gateway-pipeline-stage-pr.yml delete mode 100644 .github/workflows/api-gateway-pipeline-stage-push.yml delete mode 100644 .github/workflows/cloud-config-pipeline-dev-pr.yml delete mode 100644 .github/workflows/cloud-config-pipeline-dev-push.yml delete mode 100644 .github/workflows/cloud-config-pipeline-prod-pr.yml delete mode 100644 .github/workflows/cloud-config-pipeline-prod-push.yml delete mode 100644 .github/workflows/cloud-config-pipeline-stage-pr.yml delete mode 100644 .github/workflows/cloud-config-pipeline-stage-push.yml delete mode 100644 .github/workflows/favourite-service-pipeline-dev-pr.yml delete mode 100644 .github/workflows/favourite-service-pipeline-dev-push.yml delete mode 100644 .github/workflows/favourite-service-pipeline-prod-pr.yml delete mode 100644 .github/workflows/favourite-service-pipeline-prod-push.yml delete mode 100644 .github/workflows/favourite-service-pipeline-stage-pr.yml delete mode 100644 .github/workflows/favourite-service-pipeline-stage-push.yml delete mode 100644 .github/workflows/order-service-pipeline-dev-pr.yml delete mode 100644 .github/workflows/order-service-pipeline-dev-push.yml delete mode 100644 .github/workflows/order-service-pipeline-prod-pr.yml delete mode 100644 .github/workflows/order-service-pipeline-prod-push.yml delete mode 100644 .github/workflows/order-service-pipeline-stage-pr.yml delete mode 100644 .github/workflows/order-service-pipeline-stage-push.yml delete mode 100644 .github/workflows/payment-service-pipeline-dev-pr.yml delete mode 100644 .github/workflows/payment-service-pipeline-dev-push.yml delete mode 100644 .github/workflows/payment-service-pipeline-prod-pr.yml delete mode 100644 .github/workflows/payment-service-pipeline-prod-push.yml delete mode 100644 .github/workflows/payment-service-pipeline-stage-pr.yml delete mode 100644 .github/workflows/payment-service-pipeline-stage-push.yml delete mode 100644 .github/workflows/product-service-pipeline-dev-pr.yml delete mode 100644 .github/workflows/product-service-pipeline-dev-push.yml delete mode 100644 .github/workflows/product-service-pipeline-prod-pr.yml delete mode 100644 .github/workflows/product-service-pipeline-prod-push.yml delete mode 100644 .github/workflows/product-service-pipeline-stage-pr.yml delete mode 100644 .github/workflows/product-service-pipeline-stage-push.yml delete mode 100644 .github/workflows/proxy-client-pipeline-dev-pr.yml delete mode 100644 .github/workflows/proxy-client-pipeline-dev-push.yml delete mode 100644 .github/workflows/proxy-client-pipeline-prod-pr.yml delete mode 100644 .github/workflows/proxy-client-pipeline-prod-push.yml delete mode 100644 .github/workflows/proxy-client-pipeline-stage-pr.yml delete mode 100644 .github/workflows/proxy-client-pipeline-stage-push.yml create mode 100644 .github/workflows/release-notes.yml delete mode 100644 .github/workflows/service-discovery-pipeline-dev-pr.yml delete mode 100644 .github/workflows/service-discovery-pipeline-dev-push.yml delete mode 100644 .github/workflows/service-discovery-pipeline-prod-pr.yml delete mode 100644 .github/workflows/service-discovery-pipeline-prod-push.yml delete mode 100644 .github/workflows/service-discovery-pipeline-stage-pr.yml delete mode 100644 .github/workflows/service-discovery-pipeline-stage-push.yml delete mode 100644 .github/workflows/shipping-service-pipeline-dev-pr.yml delete mode 100644 .github/workflows/shipping-service-pipeline-dev-push.yml delete mode 100644 .github/workflows/shipping-service-pipeline-prod-pr.yml delete mode 100644 .github/workflows/shipping-service-pipeline-prod-push.yml delete mode 100644 .github/workflows/shipping-service-pipeline-stage-pr.yml delete mode 100644 .github/workflows/shipping-service-pipeline-stage-push.yml delete mode 100644 .github/workflows/user-service-pipeline-dev-pr.yml delete mode 100644 .github/workflows/user-service-pipeline-dev-push.yml delete mode 100644 .github/workflows/user-service-pipeline-prod-pr.yml delete mode 100644 .github/workflows/user-service-pipeline-prod-push.yml delete mode 100644 .github/workflows/user-service-pipeline-stage-pr.yml delete mode 100644 .github/workflows/user-service-pipeline-stage-push.yml delete mode 100644 pipelines/release-note/release-note.yml diff --git a/.github/workflows/api-gateway-pipeline-dev-pr.yml b/.github/workflows/api-gateway-pipeline-dev-pr.yml deleted file mode 100644 index 80e0836c5..000000000 --- a/.github/workflows/api-gateway-pipeline-dev-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Develop, on PR Java CI/CD of api-gateway, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ develop ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/api-gateway-pipeline-dev-push.yml b/.github/workflows/api-gateway-pipeline-dev-push.yml deleted file mode 100644 index 7650bf445..000000000 --- a/.github/workflows/api-gateway-pipeline-dev-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Develop, on PUSH Java CI/CD of api-gateway-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ develop ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for api-gateway-ecommerce-boot Microservice - run: docker build -f api-gateway/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/api-gateway-ecommerce-boot:${{ secrets.PROJECT_VERSION }}dev . - - name: Push api-gateway-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/api-gateway-ecommerce-boot:${{ secrets.PROJECT_VERSION }}dev - - diff --git a/.github/workflows/api-gateway-pipeline-prod-pr.yml b/.github/workflows/api-gateway-pipeline-prod-pr.yml deleted file mode 100644 index 97b059d5f..000000000 --- a/.github/workflows/api-gateway-pipeline-prod-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Prod, on PR Java CI/CD of api-gateway, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ master ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/api-gateway-pipeline-prod-push.yml b/.github/workflows/api-gateway-pipeline-prod-push.yml deleted file mode 100644 index f5a06db5d..000000000 --- a/.github/workflows/api-gateway-pipeline-prod-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Prod, on PUSH Java CI/CD of api-gateway-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ master ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for api-gateway-ecommerce-boot Microservice - run: docker build -f api-gateway/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/api-gateway-ecommerce-boot:${{ secrets.PROJECT_VERSION }} . - - name: Push api-gateway-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/api-gateway-ecommerce-boot:${{ secrets.PROJECT_VERSION }} - - diff --git a/.github/workflows/api-gateway-pipeline-stage-pr.yml b/.github/workflows/api-gateway-pipeline-stage-pr.yml deleted file mode 100644 index ca12270d8..000000000 --- a/.github/workflows/api-gateway-pipeline-stage-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of api-gateway, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ stage ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/api-gateway-pipeline-stage-push.yml b/.github/workflows/api-gateway-pipeline-stage-push.yml deleted file mode 100644 index 5fed6b320..000000000 --- a/.github/workflows/api-gateway-pipeline-stage-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Stage, on PUSH Java CI/CD of api-gateway-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ stage ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for api-gateway-ecommerce-boot Microservice - run: docker build -f api-gateway/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/api-gateway-ecommerce-boot:${{ secrets.PROJECT_VERSION }}stage . - - name: Push api-gateway-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/api-gateway-ecommerce-boot:${{ secrets.PROJECT_VERSION }}stage - - diff --git a/.github/workflows/cloud-config-pipeline-dev-pr.yml b/.github/workflows/cloud-config-pipeline-dev-pr.yml deleted file mode 100644 index ce6e97bc0..000000000 --- a/.github/workflows/cloud-config-pipeline-dev-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of cloud-gateway, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ develop ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/cloud-config-pipeline-dev-push.yml b/.github/workflows/cloud-config-pipeline-dev-push.yml deleted file mode 100644 index 242318ae2..000000000 --- a/.github/workflows/cloud-config-pipeline-dev-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Prod, on PUSH Java CI/CD of cloud-config-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ develop ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for cloud-config-ecommerce-boot Microservice - run: docker build -f cloud-config/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/cloud-config-ecommerce-boot:${{ secrets.PROJECT_VERSION }}dev . - - name: Push cloud-config-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/cloud-config-ecommerce-boot:${{ secrets.PROJECT_VERSION }}dev - - diff --git a/.github/workflows/cloud-config-pipeline-prod-pr.yml b/.github/workflows/cloud-config-pipeline-prod-pr.yml deleted file mode 100644 index db0e6313e..000000000 --- a/.github/workflows/cloud-config-pipeline-prod-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of cloud-gateway, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ master ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/cloud-config-pipeline-prod-push.yml b/.github/workflows/cloud-config-pipeline-prod-push.yml deleted file mode 100644 index 2869ddf96..000000000 --- a/.github/workflows/cloud-config-pipeline-prod-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Prod, on PUSH Java CI/CD of cloud-config-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ master ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for cloud-config-ecommerce-boot Microservice - run: docker build -f cloud-config/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/cloud-config-ecommerce-boot:${{ secrets.PROJECT_VERSION }} . - - name: Push cloud-config-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/cloud-config-ecommerce-boot:${{ secrets.PROJECT_VERSION }} - - diff --git a/.github/workflows/cloud-config-pipeline-stage-pr.yml b/.github/workflows/cloud-config-pipeline-stage-pr.yml deleted file mode 100644 index f448bb16d..000000000 --- a/.github/workflows/cloud-config-pipeline-stage-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of cloud-gateway, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ stage ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/cloud-config-pipeline-stage-push.yml b/.github/workflows/cloud-config-pipeline-stage-push.yml deleted file mode 100644 index 962bb4a8a..000000000 --- a/.github/workflows/cloud-config-pipeline-stage-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Prod, on PUSH Java CI/CD of cloud-config-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ stage ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for cloud-config-ecommerce-boot Microservice - run: docker build -f cloud-config/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/cloud-config-ecommerce-boot:${{ secrets.PROJECT_VERSION }}stage . - - name: Push cloud-config-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/cloud-config-ecommerce-boot:${{ secrets.PROJECT_VERSION }}stage - - diff --git a/.github/workflows/favourite-service-pipeline-dev-pr.yml b/.github/workflows/favourite-service-pipeline-dev-pr.yml deleted file mode 100644 index d075c7092..000000000 --- a/.github/workflows/favourite-service-pipeline-dev-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of favourite-service, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ develop ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/favourite-service-pipeline-dev-push.yml b/.github/workflows/favourite-service-pipeline-dev-push.yml deleted file mode 100644 index e40742278..000000000 --- a/.github/workflows/favourite-service-pipeline-dev-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Prod, on PUSH Java CI/CD of favourite-service-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ develop ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for favourite-service-ecommerce-boot Microservice - run: docker build -f favourite-service/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/favourite-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}dev . - - name: Push favourite-service-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/favourite-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}dev - - diff --git a/.github/workflows/favourite-service-pipeline-prod-pr.yml b/.github/workflows/favourite-service-pipeline-prod-pr.yml deleted file mode 100644 index d650ed18c..000000000 --- a/.github/workflows/favourite-service-pipeline-prod-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of favourite-service, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ master ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/favourite-service-pipeline-prod-push.yml b/.github/workflows/favourite-service-pipeline-prod-push.yml deleted file mode 100644 index 793359fc4..000000000 --- a/.github/workflows/favourite-service-pipeline-prod-push.yml +++ /dev/null @@ -1,54 +0,0 @@ - -name: Prod, on PUSH Java CI/CD of favourite-service-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ master ] - -jobs: - build_push_deploy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml -DskipTests # Skip tests during package, run explicitly later - - name: Run Unit Tests - run: mvn -B test --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for favourite-service-ecommerce-boot Microservice - run: docker build -f favourite-service/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/favourite-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }} . - - name: Push favourite-service-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/favourite-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }} - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - name: Run Load Tests - working-directory: favourite-service/loadtest - run: | - docker-compose pull - docker-compose up -d - # Give Locust some time to start and run tests. Adjust sleep duration as needed. - echo "Waiting for load tests to run for 60 seconds..." - sleep 60 - docker-compose down - - name: Deploy to Kubernetes - uses: azure/k8s-set-context@v1 # Assuming Azure Kubernetes Service based on azure-pipelines.yml - with: - kubeconfig: ${{ secrets.KUBECONFIG }} # Kubeconfig secret - - run: kubectl apply -f k8s/staging/favourite-service-deployment.yaml - - name: Generate Release Notes - uses: release-drafter/release-drafter@v5 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - diff --git a/.github/workflows/favourite-service-pipeline-stage-pr.yml b/.github/workflows/favourite-service-pipeline-stage-pr.yml deleted file mode 100644 index cb9a5090d..000000000 --- a/.github/workflows/favourite-service-pipeline-stage-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of favourite-service, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ stage ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/favourite-service-pipeline-stage-push.yml b/.github/workflows/favourite-service-pipeline-stage-push.yml deleted file mode 100644 index 072304cc9..000000000 --- a/.github/workflows/favourite-service-pipeline-stage-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Prod, on PUSH Java CI/CD of favourite-service-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ stage ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for favourite-service-ecommerce-boot Microservice - run: docker build -f favourite-service/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/favourite-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}stage . - - name: Push favourite-service-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/favourite-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}stage - - diff --git a/.github/workflows/order-service-pipeline-dev-pr.yml b/.github/workflows/order-service-pipeline-dev-pr.yml deleted file mode 100644 index 82ab25df6..000000000 --- a/.github/workflows/order-service-pipeline-dev-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of order-service, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ develop ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/order-service-pipeline-dev-push.yml b/.github/workflows/order-service-pipeline-dev-push.yml deleted file mode 100644 index d7731fec4..000000000 --- a/.github/workflows/order-service-pipeline-dev-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Prod, on PUSH Java CI/CD of order-service-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ develop ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for order-service-ecommerce-boot Microservice - run: docker build -f order-service/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/order-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}dev . - - name: Push order-service-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/order-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}dev - - diff --git a/.github/workflows/order-service-pipeline-prod-pr.yml b/.github/workflows/order-service-pipeline-prod-pr.yml deleted file mode 100644 index a86b3ff57..000000000 --- a/.github/workflows/order-service-pipeline-prod-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of order-service, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ master ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/order-service-pipeline-prod-push.yml b/.github/workflows/order-service-pipeline-prod-push.yml deleted file mode 100644 index 855ec8ea8..000000000 --- a/.github/workflows/order-service-pipeline-prod-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Prod, on PUSH Java CI/CD of order-service-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ master ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for order-service-ecommerce-boot Microservice - run: docker build -f order-service/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/order-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }} . - - name: Push order-service-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/order-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }} - - diff --git a/.github/workflows/order-service-pipeline-stage-pr.yml b/.github/workflows/order-service-pipeline-stage-pr.yml deleted file mode 100644 index 46ef07c6a..000000000 --- a/.github/workflows/order-service-pipeline-stage-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of order-service, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ stage ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/order-service-pipeline-stage-push.yml b/.github/workflows/order-service-pipeline-stage-push.yml deleted file mode 100644 index 34d3ef1a8..000000000 --- a/.github/workflows/order-service-pipeline-stage-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Prod, on PUSH Java CI/CD of order-service-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ stage ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for order-service-ecommerce-boot Microservice - run: docker build -f order-service/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/order-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}stage . - - name: Push order-service-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/order-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}stage - - diff --git a/.github/workflows/payment-service-pipeline-dev-pr.yml b/.github/workflows/payment-service-pipeline-dev-pr.yml deleted file mode 100644 index 49242655b..000000000 --- a/.github/workflows/payment-service-pipeline-dev-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of payment-service, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ develop ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/payment-service-pipeline-dev-push.yml b/.github/workflows/payment-service-pipeline-dev-push.yml deleted file mode 100644 index 6800aec86..000000000 --- a/.github/workflows/payment-service-pipeline-dev-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Prod, on PUSH Java CI/CD of payment-service-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ develop ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for payment-service-ecommerce-boot Microservice - run: docker build -f payment-service/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/payment-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}dev . - - name: Push payment-service-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/payment-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}dev - - diff --git a/.github/workflows/payment-service-pipeline-prod-pr.yml b/.github/workflows/payment-service-pipeline-prod-pr.yml deleted file mode 100644 index e9ea6f92d..000000000 --- a/.github/workflows/payment-service-pipeline-prod-pr.yml +++ /dev/null @@ -1,22 +0,0 @@ - -name: Stage, on PR Java CI/CD of payment-service, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ master ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - - \ No newline at end of file diff --git a/.github/workflows/payment-service-pipeline-prod-push.yml b/.github/workflows/payment-service-pipeline-prod-push.yml deleted file mode 100644 index 5f6456ffa..000000000 --- a/.github/workflows/payment-service-pipeline-prod-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Prod, on PUSH Java CI/CD of payment-service-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ master ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for payment-service-ecommerce-boot Microservice - run: docker build -f payment-service/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/payment-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }} . - - name: Push payment-service-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/payment-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }} - - diff --git a/.github/workflows/payment-service-pipeline-stage-pr.yml b/.github/workflows/payment-service-pipeline-stage-pr.yml deleted file mode 100644 index 3b9e3ade3..000000000 --- a/.github/workflows/payment-service-pipeline-stage-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of payment-service, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ stage ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/payment-service-pipeline-stage-push.yml b/.github/workflows/payment-service-pipeline-stage-push.yml deleted file mode 100644 index b966416e0..000000000 --- a/.github/workflows/payment-service-pipeline-stage-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Prod, on PUSH Java CI/CD of payment-service-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ stage ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for payment-service-ecommerce-boot Microservice - run: docker build -f payment-service/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/payment-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}stage . - - name: Push payment-service-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/payment-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}stage - - diff --git a/.github/workflows/product-service-pipeline-dev-pr.yml b/.github/workflows/product-service-pipeline-dev-pr.yml deleted file mode 100644 index 27abf9d42..000000000 --- a/.github/workflows/product-service-pipeline-dev-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of product-service, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ develop ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/product-service-pipeline-dev-push.yml b/.github/workflows/product-service-pipeline-dev-push.yml deleted file mode 100644 index 33b639efa..000000000 --- a/.github/workflows/product-service-pipeline-dev-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Prod, on PUSH Java CI/CD of product-service-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ develop ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for product-service-ecommerce-boot Microservice - run: docker build -f product-service/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/product-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}dev . - - name: Push product-service-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/product-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}dev - - diff --git a/.github/workflows/product-service-pipeline-prod-pr.yml b/.github/workflows/product-service-pipeline-prod-pr.yml deleted file mode 100644 index 0715d8c69..000000000 --- a/.github/workflows/product-service-pipeline-prod-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of product-service, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ master ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/product-service-pipeline-prod-push.yml b/.github/workflows/product-service-pipeline-prod-push.yml deleted file mode 100644 index 2f21434ec..000000000 --- a/.github/workflows/product-service-pipeline-prod-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Prod, on PUSH Java CI/CD of product-service-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ master ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for product-service-ecommerce-boot Microservice - run: docker build -f product-service/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/product-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }} . - - name: Push product-service-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/product-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }} - - diff --git a/.github/workflows/product-service-pipeline-stage-pr.yml b/.github/workflows/product-service-pipeline-stage-pr.yml deleted file mode 100644 index 95e6e7036..000000000 --- a/.github/workflows/product-service-pipeline-stage-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of product-service, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ stage ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/product-service-pipeline-stage-push.yml b/.github/workflows/product-service-pipeline-stage-push.yml deleted file mode 100644 index 9d2f31c03..000000000 --- a/.github/workflows/product-service-pipeline-stage-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Prod, on PUSH Java CI/CD of product-service-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ stage ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for product-service-ecommerce-boot Microservice - run: docker build -f product-service/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/product-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}stage . - - name: Push product-service-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/product-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}stage - - diff --git a/.github/workflows/proxy-client-pipeline-dev-pr.yml b/.github/workflows/proxy-client-pipeline-dev-pr.yml deleted file mode 100644 index 432181a62..000000000 --- a/.github/workflows/proxy-client-pipeline-dev-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Develop, on PR Java CI/CD of proxy-client, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ develop ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/proxy-client-pipeline-dev-push.yml b/.github/workflows/proxy-client-pipeline-dev-push.yml deleted file mode 100644 index 3ccf5b788..000000000 --- a/.github/workflows/proxy-client-pipeline-dev-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Develop, on PUSH Java CI/CD of proxy-client-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ develop ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for proxy-client-ecommerce-boot Microservice - run: docker build -f proxy-client/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/proxy-client-ecommerce-boot:${{ secrets.PROJECT_VERSION }}dev . - - name: Push proxy-client-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/proxy-client-ecommerce-boot:${{ secrets.PROJECT_VERSION }}dev - - diff --git a/.github/workflows/proxy-client-pipeline-prod-pr.yml b/.github/workflows/proxy-client-pipeline-prod-pr.yml deleted file mode 100644 index a427fc571..000000000 --- a/.github/workflows/proxy-client-pipeline-prod-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Develop, on PR Java CI/CD of proxy-client, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ master ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/proxy-client-pipeline-prod-push.yml b/.github/workflows/proxy-client-pipeline-prod-push.yml deleted file mode 100644 index 21667eb9d..000000000 --- a/.github/workflows/proxy-client-pipeline-prod-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Develop, on PUSH Java CI/CD of proxy-client-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ master ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for proxy-client-ecommerce-boot Microservice - run: docker build -f proxy-client/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/proxy-client-ecommerce-boot:${{ secrets.PROJECT_VERSION }} . - - name: Push proxy-client-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/proxy-client-ecommerce-boot:${{ secrets.PROJECT_VERSION }} - - diff --git a/.github/workflows/proxy-client-pipeline-stage-pr.yml b/.github/workflows/proxy-client-pipeline-stage-pr.yml deleted file mode 100644 index a942ad7fc..000000000 --- a/.github/workflows/proxy-client-pipeline-stage-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Develop, on PR Java CI/CD of proxy-client, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ stage ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/proxy-client-pipeline-stage-push.yml b/.github/workflows/proxy-client-pipeline-stage-push.yml deleted file mode 100644 index 5bd23a72f..000000000 --- a/.github/workflows/proxy-client-pipeline-stage-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Develop, on PUSH Java CI/CD of proxy-client-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ stage ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for proxy-client-ecommerce-boot Microservice - run: docker build -f proxy-client/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/proxy-client-ecommerce-boot:${{ secrets.PROJECT_VERSION }}stage . - - name: Push proxy-client-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/proxy-client-ecommerce-boot:${{ secrets.PROJECT_VERSION }}stage - - diff --git a/.github/workflows/release-notes.yml b/.github/workflows/release-notes.yml new file mode 100644 index 000000000..b255c5d47 --- /dev/null +++ b/.github/workflows/release-notes.yml @@ -0,0 +1,51 @@ +name: Automatic Release Notes + +on: + push: + branches: + - master + - main + - develop + - stage + +jobs: + generate-release-notes: + name: Generate & Publish Release Notes + runs-on: ubuntu-latest + + permissions: + contents: write + pull-requests: read + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Git info + run: | + echo "Current branch: ${{ github.ref_name }}" + echo "Repository: ${{ github.repository }}" + + - name: Determine next version + id: version + uses: anothrNick/github-tag-action@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DEFAULT_BUMP: patch + RELEASE_BRANCHES: master,main,develop,stage + DRY_RUN: false + + - name: Generate Release Notes + id: release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ steps.version.outputs.new_tag }} + name: "Release ${{ steps.version.outputs.new_tag }}" + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Summary + run: | + echo "Release created: ${{ steps.version.outputs.new_tag }}" + echo "Release URL: https://github.com/${{ github.repository }}/releases/tag/${{ steps.version.outputs.new_tag }}" diff --git a/.github/workflows/service-discovery-pipeline-dev-pr.yml b/.github/workflows/service-discovery-pipeline-dev-pr.yml deleted file mode 100644 index c2ea3c005..000000000 --- a/.github/workflows/service-discovery-pipeline-dev-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Develop, on PR Java CI/CD of service-discovery, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ develop ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/service-discovery-pipeline-dev-push.yml b/.github/workflows/service-discovery-pipeline-dev-push.yml deleted file mode 100644 index ff37dad98..000000000 --- a/.github/workflows/service-discovery-pipeline-dev-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Develop, on PUSH Java CI/CD of service-discovery-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ develop ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for service-discovery-ecommerce-boot Microservice - run: docker build -f service-discovery/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/service-discovery-ecommerce-boot:${{ secrets.PROJECT_VERSION }}dev . - - name: Push service-discovery-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/service-discovery-ecommerce-boot:${{ secrets.PROJECT_VERSION }}dev - - diff --git a/.github/workflows/service-discovery-pipeline-prod-pr.yml b/.github/workflows/service-discovery-pipeline-prod-pr.yml deleted file mode 100644 index d98d1493f..000000000 --- a/.github/workflows/service-discovery-pipeline-prod-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Prod, on PR Java CI/CD of service-discovery, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ master ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/service-discovery-pipeline-prod-push.yml b/.github/workflows/service-discovery-pipeline-prod-push.yml deleted file mode 100644 index c80f9b275..000000000 --- a/.github/workflows/service-discovery-pipeline-prod-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Prod, on PUSH Java CI/CD of service-discovery-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ master ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for service-discovery-ecommerce-boot Microservice - run: docker build -f service-discovery/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/service-discovery-ecommerce-boot:${{ secrets.PROJECT_VERSION }} . - - name: Push service-discovery-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/service-discovery-ecommerce-boot:${{ secrets.PROJECT_VERSION }} - - diff --git a/.github/workflows/service-discovery-pipeline-stage-pr.yml b/.github/workflows/service-discovery-pipeline-stage-pr.yml deleted file mode 100644 index 3b2f70c7c..000000000 --- a/.github/workflows/service-discovery-pipeline-stage-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of service-discovery, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ stage ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/service-discovery-pipeline-stage-push.yml b/.github/workflows/service-discovery-pipeline-stage-push.yml deleted file mode 100644 index e490365ce..000000000 --- a/.github/workflows/service-discovery-pipeline-stage-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Stage, on PUSH Java CI/CD of service-discovery-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ stage ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for service-discovery-ecommerce-boot Microservice - run: docker build -f service-discovery/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/service-discovery-ecommerce-boot:${{ secrets.PROJECT_VERSION }}stage . - - name: Push service-discovery-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/service-discovery-ecommerce-boot:${{ secrets.PROJECT_VERSION }}stage - - diff --git a/.github/workflows/shipping-service-pipeline-dev-pr.yml b/.github/workflows/shipping-service-pipeline-dev-pr.yml deleted file mode 100644 index 9cd3ec44a..000000000 --- a/.github/workflows/shipping-service-pipeline-dev-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of shipping-service, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ develop ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/shipping-service-pipeline-dev-push.yml b/.github/workflows/shipping-service-pipeline-dev-push.yml deleted file mode 100644 index 5dc801ff5..000000000 --- a/.github/workflows/shipping-service-pipeline-dev-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Stage, on PUSH Java CI/CD of shipping-service-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ develop ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for shipping-service-ecommerce-boot Microservice - run: docker build -f shipping-service/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/shipping-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}dev . - - name: Push shipping-service-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/shipping-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}dev - - diff --git a/.github/workflows/shipping-service-pipeline-prod-pr.yml b/.github/workflows/shipping-service-pipeline-prod-pr.yml deleted file mode 100644 index 7c22bae52..000000000 --- a/.github/workflows/shipping-service-pipeline-prod-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of shipping-service, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ master ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/shipping-service-pipeline-prod-push.yml b/.github/workflows/shipping-service-pipeline-prod-push.yml deleted file mode 100644 index 3e07b4f28..000000000 --- a/.github/workflows/shipping-service-pipeline-prod-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Stage, on PUSH Java CI/CD of shipping-service-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ master ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for shipping-service-ecommerce-boot Microservice - run: docker build -f shipping-service/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/shipping-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }} . - - name: Push shipping-service-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/shipping-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }} - - diff --git a/.github/workflows/shipping-service-pipeline-stage-pr.yml b/.github/workflows/shipping-service-pipeline-stage-pr.yml deleted file mode 100644 index 2447a0b9a..000000000 --- a/.github/workflows/shipping-service-pipeline-stage-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of shipping-service, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ stage ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/shipping-service-pipeline-stage-push.yml b/.github/workflows/shipping-service-pipeline-stage-push.yml deleted file mode 100644 index 6c4ec225c..000000000 --- a/.github/workflows/shipping-service-pipeline-stage-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Stage, on PUSH Java CI/CD of shipping-service-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ stage ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for shipping-service-ecommerce-boot Microservice - run: docker build -f shipping-service/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/shipping-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}stage . - - name: Push shipping-service-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/shipping-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}stage - - diff --git a/.github/workflows/user-service-pipeline-dev-pr.yml b/.github/workflows/user-service-pipeline-dev-pr.yml deleted file mode 100644 index d271f8642..000000000 --- a/.github/workflows/user-service-pipeline-dev-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of user-service, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ develop ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/user-service-pipeline-dev-push.yml b/.github/workflows/user-service-pipeline-dev-push.yml deleted file mode 100644 index b27c71bd2..000000000 --- a/.github/workflows/user-service-pipeline-dev-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Stage, on PUSH Java CI/CD of user-service-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ develop ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for user-service-ecommerce-boot Microservice - run: docker build -f user-service/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/user-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}dev . - - name: Push user-service-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/user-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}dev - - diff --git a/.github/workflows/user-service-pipeline-prod-pr.yml b/.github/workflows/user-service-pipeline-prod-pr.yml deleted file mode 100644 index a048fe1ed..000000000 --- a/.github/workflows/user-service-pipeline-prod-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of user-service, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ master ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/user-service-pipeline-prod-push.yml b/.github/workflows/user-service-pipeline-prod-push.yml deleted file mode 100644 index ae58b153c..000000000 --- a/.github/workflows/user-service-pipeline-prod-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Stage, on PUSH Java CI/CD of user-service-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ master ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for user-service-ecommerce-boot Microservice - run: docker build -f user-service/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/user-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }} . - - name: Push user-service-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/user-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }} - - diff --git a/.github/workflows/user-service-pipeline-stage-pr.yml b/.github/workflows/user-service-pipeline-stage-pr.yml deleted file mode 100644 index f11ce58df..000000000 --- a/.github/workflows/user-service-pipeline-stage-pr.yml +++ /dev/null @@ -1,21 +0,0 @@ - -name: Stage, on PR Java CI/CD of user-service, ecommerce-microservice-backend app - -on: - pull_request: - branches: [ stage ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - diff --git a/.github/workflows/user-service-pipeline-stage-push.yml b/.github/workflows/user-service-pipeline-stage-push.yml deleted file mode 100644 index 132f33fcc..000000000 --- a/.github/workflows/user-service-pipeline-stage-push.yml +++ /dev/null @@ -1,33 +0,0 @@ - -name: Stage, on PUSH Java CI/CD of user-service-ecommerce-boot, ecommerce-microservice-backend app - -on: - push: - branches: [ stage ] - -jobs: - build_push: - #needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Setup env variables for Docker - run: echo Setup env variables for Docker - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - - name: Docker Login - run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Docker image for user-service-ecommerce-boot Microservice - run: docker build -f user-service/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/user-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}stage . - - name: Push user-service-ecommerce-boot image - run: docker push ${{ secrets.DOCKER_USERNAME }}/user-service-ecommerce-boot:${{ secrets.PROJECT_VERSION }}stage - - diff --git a/pipelines/release-note/release-note.yml b/pipelines/release-note/release-note.yml deleted file mode 100644 index 0ff9121e6..000000000 --- a/pipelines/release-note/release-note.yml +++ /dev/null @@ -1,55 +0,0 @@ -# Simulaci贸n de las variables de sustituci贸n originales con valores fijos -substitutions: - _CLUSTER_NAME: "demo-cluster-01" - _CLUSTER_ZONE: "us-west1-a" - _PROJECT_ID: "proyecto-ejemplo-98765" - -steps: - - - name: 'gcr.io/cloud-builders/git' - id: 'Generate Release Notes' - entrypoint: 'bash' - args: - - '-c' - - | - NEW_TAG=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 7) - BRANCH_NAME_TO_USE="main-fija" - BUILD_DATE="2025-10-31 10:30:00" - LASTTAG_GIT="v1.2.3" - - echo "Etiqueta/Tag generada: ${NEW_TAG}" - echo "Rama usada: ${BRANCH_NAME_TO_USE}" - - RELEASE_FILE="/workspace/release_notes_${NEW_TAG}.md" - - echo "# Notas de Versi贸n - ${NEW_TAG}" > $RELEASE_FILE - echo "" >> $RELEASE_FILE - echo "## Cambios desde la versi贸n $LASTTAG_GIT (Simulaci贸n)" >> $RELEASE_FILE - echo "- **FIX:** Error de inicializaci贸n corregido (Commit ${NEW_TAG})" >> $RELEASE_FILE - echo "- **FEAT:** Se a帽adi贸 soporte para nuevo servicio." >> $RELEASE_FILE - echo "" >> $RELEASE_FILE - echo "Fecha de Compilaci贸n: $BUILD_DATE" >> $RELEASE_FILE - - echo "--- Contenido del archivo ---" - cat $RELEASE_FILE - echo "-----------------------------" - - cp $RELEASE_FILE /workspace/release_notes.md - - - - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' - id: 'Upload Release Notes' - waitFor: ['Generate Release Notes'] - entrypoint: 'bash' - args: - - '-c' - - | - _BRANCH_NAME="main-fija" - - echo "Subiendo Release Notes a gs://${_PROJECT_ID}-release-notes/${_BRANCH_NAME}/release_notes_latest.md" - - gsutil cp /workspace/release_notes.md gs://${_PROJECT_ID}-release-notes/${_BRANCH_NAME}/release_notes_latest.md \ - || echo "AVISO: La subida fall贸 (esto es esperado si el bucket no existe o faltan credenciales de GCS). La URL simulada es: gs://${_PROJECT_ID}-release-notes/${_BRANCH_NAME}/release_notes_latest.md" - -options: - logging: CLOUD_LOGGING_ONLY \ No newline at end of file From 4589115385896455a9d9025c2a2160da7f1103a6 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Fri, 31 Oct 2025 12:51:15 -0500 Subject: [PATCH 65/67] Project finished --- .github/workflows/release-notes.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/release-notes.yml b/.github/workflows/release-notes.yml index b255c5d47..61b8a42ba 100644 --- a/.github/workflows/release-notes.yml +++ b/.github/workflows/release-notes.yml @@ -7,7 +7,6 @@ on: - main - develop - stage - jobs: generate-release-notes: name: Generate & Publish Release Notes From 4951ec866d8dbed26036212ad2fd0083e3df3241 Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Fri, 31 Oct 2025 13:10:25 -0500 Subject: [PATCH 66/67] Project finished --- compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose.yml b/compose.yml index 6cf88f02e..69da307d3 100644 --- a/compose.yml +++ b/compose.yml @@ -5,7 +5,7 @@ services: image: selimhorri/api-gateway-ecommerce-boot:0.1.0 ports: - 8080:8080 - networks:w + networks: - microservices_network environment: - SPRING_PROFILES_ACTIVE=dev From 344d5d5bf52498f311d72e824f83ce769fabcf9a Mon Sep 17 00:00:00 2001 From: JuanCamTobar Date: Fri, 31 Oct 2025 17:17:57 -0500 Subject: [PATCH 67/67] Project finished --- pipelines/master-deploy/master-deploy.yml | 96 +++++++++++++++-------- 1 file changed, 63 insertions(+), 33 deletions(-) diff --git a/pipelines/master-deploy/master-deploy.yml b/pipelines/master-deploy/master-deploy.yml index ee8e4982d..d0b83cd09 100644 --- a/pipelines/master-deploy/master-deploy.yml +++ b/pipelines/master-deploy/master-deploy.yml @@ -1,77 +1,107 @@ substitutions: _CLUSTER_NAME: "mi-primer-cluster-taller" _CLUSTER_ZONE: "us-central1" - _NAMESPACE: "stage" + _NAMESPACE: "master-deploy" _PROJECT_ID: "taller2-ingenieriasoftware" - _DOCKER_USER: "juancato" - _REPO: "ecomerce-taller" steps: + - name: 'gcr.io/cloud-builders/mvn' args: ['clean', 'verify'] + - name: 'gcr.io/cloud-builders/docker' entrypoint: 'bash' + secretEnv: ['_DOCKER_USERNAME', '_DOCKER_PASSWORD'] args: - '-c' - | - for s in api-gateway cloud-config service-discovery proxy-client user-service product-service order-service payment-service favourite-service shipping-service; do - echo "Construyendo imagen $s..." - docker build -t docker.io/${_DOCKER_USER}/${_REPO}-${s}:${SHORT_SHA} -f $s/Dockerfile . - done + echo "Autenticando en Docker Hub..." + echo "$$_DOCKER_PASSWORD" | docker login -u "$$_DOCKER_USERNAME" --password-stdin + - name: 'gcr.io/cloud-builders/docker' entrypoint: 'bash' - secretEnv: ['_DOCKER_USERNAME', '_DOCKER_PASSWORD'] args: - '-c' - | - echo "$$_DOCKER_PASSWORD" | docker login -u "$$_DOCKER_USERNAME" --password-stdin for s in api-gateway cloud-config service-discovery proxy-client user-service product-service order-service payment-service favourite-service shipping-service; do - docker push docker.io/${_DOCKER_USER}/${_REPO}-${s}:${SHORT_SHA} + echo "Construyendo imagen $s ..." + docker build -t docker.io/juancato/ecomerce-taller-$s:$SHORT_SHA -f $s/Dockerfile . + echo "Subiendo imagen docker.io/juancato/ecomerce-taller-$s:$SHORT_SHA ..." + docker push docker.io/juancato/ecomerce-taller-$s:$SHORT_SHA done - - name: 'gcr.io/cloud-builders/docker' + + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' args: - '-c' - | - echo "Ejecutando pruebas de carga..." - docker run --rm -v $PWD/favourite-service/loadtest:/tests artilleryio/artillery run /tests/loadtest.yml + echo "Actualizando manifiestos YAML con el tag ${SHORT_SHA}..." + for f in k8s/staging/*.yml; do + sed -i "s|IMAGE_TAG|${SHORT_SHA}|g" "$f" + sed -i "s|gcr.io/PROJECT_ID|docker.io/juancato/ecomerce-taller|g" "$f" + done + + + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + args: + [ + 'gcloud', 'container', 'clusters', 'get-credentials', + '${_CLUSTER_NAME}', '--zone', '${_CLUSTER_ZONE}', '--project', '${_PROJECT_ID}' + ] + + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + entrypoint: 'bash' + args: ['-c', 'kubectl create namespace ${_NAMESPACE} || true'] + + + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + entrypoint: 'bash' + args: + - '-c' + - 'kubectl apply -n ${_NAMESPACE} -f k8s/staging/core.yml' + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' args: - '-c' - | - gcloud container clusters get-credentials ${_CLUSTER_NAME} \ - --zone ${_CLUSTER_ZONE} \ - --project ${_PROJECT_ID} - echo "Actualizando manifiestos con el tag ${SHORT_SHA}..." - for f in k8s/staging/*.yml; do - sed -i "s|IMAGE_TAG|${SHORT_SHA}|g" "$f" - sed -i "s|gcr.io/PROJECT_ID|docker.io/${_DOCKER_USER}/${_REPO}|g" "$f" - done - kubectl apply -n ${_NAMESPACE} -f k8s/staging/ + kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/zipkin --timeout=150s || true + kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/service-discovery --timeout=180s || true + kubectl -n ${_NAMESPACE} wait --for=condition=available deployment/cloud-config --timeout=180s || true - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' args: - '-c' - - 'kubectl -n ${_NAMESPACE} wait --for=condition=available --all deployments --timeout=900s' + - 'kubectl apply -n ${_NAMESPACE} -f k8s/staging/compose.yml' + + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + entrypoint: 'bash' + args: + - '-c' + - 'kubectl -n ${_NAMESPACE} wait --for=condition=available --all deployments --timeout=1800s' + + + - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + entrypoint: 'bash' + args: ['-c', 'kubectl -n ${_NAMESPACE} delete pod stage-tester --ignore-not-found'] images: - - 'docker.io/${_DOCKER_USER}/${_REPO}-api-gateway:$SHORT_SHA' - - 'docker.io/${_DOCKER_USER}/${_REPO}-cloud-config:$SHORT_SHA' - - 'docker.io/${_DOCKER_USER}/${_REPO}-service-discovery:$SHORT_SHA' - - 'docker.io/${_DOCKER_USER}/${_REPO}-proxy-client:$SHORT_SHA' - - 'docker.io/${_DOCKER_USER}/${_REPO}-user-service:$SHORT_SHA' - - 'docker.io/${_DOCKER_USER}/${_REPO}-product-service:$SHORT_SHA' - - 'docker.io/${_DOCKER_USER}/${_REPO}-order-service:$SHORT_SHA' - - 'docker.io/${_DOCKER_USER}/${_REPO}-payment-service:$SHORT_SHA' - - 'docker.io/${_DOCKER_USER}/${_REPO}-favourite-service:$SHORT_SHA' - - 'docker.io/${_DOCKER_USER}/${_REPO}-shipping-service:$SHORT_SHA' + - 'docker.io/juancato/ecomerce-taller-api-gateway:$SHORT_SHA' + - 'docker.io/juancato/ecomerce-taller-cloud-config:$SHORT_SHA' + - 'docker.io/juancato/ecomerce-taller-service-discovery:$SHORT_SHA' + - 'docker.io/juancato/ecomerce-taller-proxy-client:$SHORT_SHA' + - 'docker.io/juancato/ecomerce-taller-user-service:$SHORT_SHA' + - 'docker.io/juancato/ecomerce-taller-product-service:$SHORT_SHA' + - 'docker.io/juancato/ecomerce-taller-order-service:$SHORT_SHA' + - 'docker.io/juancato/ecomerce-taller-payment-service:$SHORT_SHA' + - 'docker.io/juancato/ecomerce-taller-favourite-service:$SHORT_SHA' + - 'docker.io/juancato/ecomerce-taller-shipping-service:$SHORT_SHA' availableSecrets: secretManager: