{"id":18646481,"url":"https://github.com/yashwalke999/clickncart-microservices-app","last_synced_at":"2026-04-09T07:05:27.643Z","repository":{"id":218208345,"uuid":"745872088","full_name":"yashwalke999/ClicknCart-Microservices-App","owner":"yashwalke999","description":"🚀 Build a Resilient e-Commerce Backend with Microservices 🌐  Explore a cutting-edge e-Commerce backend powered by microservices architecture. Enhance robustness and scalability without the clutter. Dive into modern principles of distributed systems, seamless communication, and secure API handling. ","archived":false,"fork":false,"pushed_at":"2024-01-20T12:10:23.000Z","size":1981,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-12-27T11:47:46.909Z","etag":null,"topics":["discovery-service","docker","elk-stack","java","jhipster","jwt","kafka","kubernetes","mysql","res","resilience4j","spring-boot","spring-clou","spring-data-jpa","spring-security","zipkin"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yashwalke999.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2024-01-20T12:01:59.000Z","updated_at":"2024-08-14T11:11:27.000Z","dependencies_parsed_at":"2024-01-20T13:26:12.313Z","dependency_job_id":"ceacb685-c27c-49b2-87b0-7422053a795a","html_url":"https://github.com/yashwalke999/ClicknCart-Microservices-App","commit_stats":null,"previous_names":["yashwalke999/clickncart-microservices-app"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yashwalke999%2FClicknCart-Microservices-App","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yashwalke999%2FClicknCart-Microservices-App/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yashwalke999%2FClicknCart-Microservices-App/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yashwalke999%2FClicknCart-Microservices-App/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yashwalke999","download_url":"https://codeload.github.com/yashwalke999/ClicknCart-Microservices-App/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239449594,"owners_count":19640535,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["discovery-service","docker","elk-stack","java","jhipster","jwt","kafka","kubernetes","mysql","res","resilience4j","spring-boot","spring-clou","spring-data-jpa","spring-security","zipkin"],"created_at":"2024-11-07T06:20:10.602Z","updated_at":"2025-11-05T05:30:23.391Z","avatar_url":"https://github.com/yashwalke999.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ClicknCart  E-Commerce Web-Application  💰🛒\n\n## Introduction\n- ClicknCart is a development project comprising a set of **Spring Boot** and **Cloud**-based Microservices. These microservices implement cloud-native, intuitive, Reactive Programming, Event-driven, and Microservices design patterns, following coding best practices.\n- The project adheres to **CloudNative** recommendations and The [**twelve-factor app**](https://12factor.net/) methodology for building *software-as-a-service apps*, showcasing how e-Commerces should be developed and deployed.\n- ClicknCart utilizes cutting-edge technologies such as Docker, Kubernetes, Elasticsearch Stack for logging and monitoring, Java SE 11, H2, and MySQL databases. All components are developed with TDD in mind, covering integration \u0026 performance testing, and more.\n- The development of ClicknCart is organized into stages, with each stage's steps documented in the project's **README** file.\n\n## System Structure\n### Overview of Components\n```\nClicknCart-backend-app [e-Commerce] --\u003e Parent folder.\n|- docs --\u003e All docs and diagrams.\n|- k8s --\u003e All **Kubernetes** config files.\n    |- proxy-client --\u003e Authentication \u0026 Authorization e-Commerce, exposing all \n    |- api-gateway --\u003e API Gateway server\n    |- service-discovery --\u003e Service Registery server\n    |- cloud-config --\u003e Centralized Configuration server\n    |- user-service --\u003e Manage app users (customers \u0026 admins) as well as their credentials\n    |- product-service --\u003e Manage app products and their respective categories\n    |- favourite-service --\u003e Manage app users' favourite products added to their own favourite list\n    |- order-service --\u003e Manage app orders based on carts\n    |- shipping-service --\u003e Manage app order-shipping products\n    |- payment-service --\u003e Manage app order payments\n|- compose.yml --\u003e contains all services landscape with Kafka  \n|- run-em-all.sh --\u003e Run all microservices in separate mode. \n|- setup.sh --\u003e Install all shared POMs and shared libraries. \n|- stop-em-all.sh --\u003e Stop all services runs in standalone mode. \n|- test-em-all.sh --\u003e This will start all docker compose landscape and test them, then shutdown docker compose containers with test finishes (use switch start stop)\n```\n \nNow, as we have learned about the different system components, let's get started.\n\n## System Boundary Architecture - e-Commerces Landscape\n\n![System Boundary](app-architecture.drawio.png)\n\n## Getting Started\n\n### Prerequisites\nEnsure you have the following software installed:\n\n1. **Java 11**: JDK 11 LTS can be downloaded and installed from [Oracle](https://www.oracle.com/java/technologies/javase/jdk11-archive-downloads.html).\n\n2. **Git**: Download and install from [Git](https://git-scm.com/downloads).\n\n3. **Maven**: Download from [Maven](https://maven.apache.org/download.cgi) and install.\n\n4. **curl**: Download and install from [curl](https://curl.haxx.se/download.html).\n\n5. **jq**: Download and install from [jq](https://stedolan.github.io/jq/download/).\n\n6. **Spring Boot Initializer**: Generate spring boot projects at [Spring Initializer](https://start.spring.io/).\n\n7. **Docker**: Download from [Docker](https://www.docker.com/products/docker-desktop).\n\n8. **Kubernetes**: Install **minikube** for testing purposes from [Minikube](https://minikube.sigs.k8s.io/docs/start/).\n\nFollow the installation guide for each software and verify that they are installed correctly.\n\n### Using an IDE\n\nI recommend using an IDE that supports the development of Spring Boot applications such as Spring Tool Suite or IntelliJ IDEA Ultimate Edition. Open or import the parent folder `clickncart-microservice-backend-app` in your IDE, and you're ready to go.\n\n## Data Model\n### Entity-Relationship-Diagram\n![Entity Relationship Diagram](ecommerce-ERD.drawio.png)\n\n## Playing With ClicknCart Project\n\n### Cloning It\n\nOpen **git bash** and clone the project under your desired location:\n\n```bash\n\u003e git clone https://github.com/yashwalke/clickncart-microservice-backend-app.git\n\n### Build \u0026 Test Them In Isolation\n\nTo build and run the test cases for each service \u0026 shared modules in the project, we need to do the following:\n\n#### Build \u0026 Test e-Commerces\nNow it is the time to build our **10 microservices** and run each service integration test in\n isolation by running the following commands:\n\n```bash\nyashw@:~/ClicknCart-backend-app$ ./mvnw clean package \n```\n\nAll build commands and test suite for each microservice should run successfully, and the final output should be like this:\n\n```bash\n---------------\u003c com.yashw.app:ecommerce-microservice-backend \u003e-----------\n[INFO] ------------------------------------------------------------------------\n[INFO] Reactor Summary for ecommerce-microservice-backend 0.1.0:\n[INFO] \n[INFO] ecommerce-microservice-backend ..................... SUCCESS [  0.548 s]\n[INFO] service-discovery .................................. SUCCESS [  3.126 s]\n[INFO] cloud-config ....................................... SUCCESS [  1.595 s]\n[INFO] api-gateway ........................................ SUCCESS [  1.697 s]\n[INFO] proxy-client ....................................... SUCCESS [  3.632 s]\n[INFO] user-service ....................................... SUCCESS [  2.546 s]\n[INFO] product-service .................................... SUCCESS [  2.214 s]\n[INFO] favourite-service .................................. SUCCESS [  2.072 s]\n[INFO] order-service ...................................... SUCCESS [  2.241 s]\n[INFO] shipping-service ................................... SUCCESS [  2.197 s]\n[INFO] payment-service .................................... SUCCESS [  2.006 s]\n[INFO] ------------------------------------------------------------------------\n[INFO] BUILD SUCCESS\n[INFO] ------------------------------------------------------------------------\n[INFO] Total time:  24.156 s\n[INFO] Finished at: 2021-12-29T19:52:57+01:00\n[INFO] ------------------------------------------------------------------------\n```\n\n### Running Them All\nNow it's the time to run all of our Microservices, and it's straightforward just run the following `docker-compose` commands:\n\n```bash\nyashw@:~/ClicknCart-backend-app$ docker-compose -f compose.yml up\n```\n\nAll the **services**, **databases**, and **messaging service** will run in parallel in detach mode (option `-d`), and command output will print to the console the following:\n\n```bash\nCreating network \"ClicknCart-backend-app_default\" with the default driver\nCreating ClicknCart-backend-app_api-gateway-container_1       ... done\nCreating ClicknCart-backend-app_favourite-service-container_1 ... done\nCreating ClicknCart-backend-app_service-discovery-container_1 ... done\nCreating ClicknCart-backend-app_shipping-service-container_1  ... done\nCreating ClicknCart-backend-app_order-service-container_1     ... done\nCreating ClicknCart-backend-app_user-service-container_1      ... done\nCreating ClicknCart-backend-app_payment-service-container_1   ... done\nCreating ClicknCart-backend-app_product-service-container_1   ... done\nCreating ClicknCart-backend-app_proxy-client-container_1      ... done\nCreating ClicknCart-backend-app_zipkin-container_1            ... done\nCreating ClicknCart-backend-app_cloud-config-container_1      ... done\n```\n### Access proxy-client APIs\nYou can manually test `proxy-client` APIs throughout its **Swagger** interface at the following\n URL [https://localhost:8900/swagger-ui.html](https://localhost:8900/swagger-ui.html).\n### Access Service Discovery Server (Eureka)\nIf you would like to access the Eureka service discovery point to this URL [http://localhosts:8761/eureka](https://localhost:8761/eureka) to see all the services registered inside it. \n\n### Access user-service APIs\n URL [https://localhost:8700/swagger-ui.html](https://localhost:8700/swagger-ui.html).\n\n\u003c!--\nNote that it is accessed through API Gateway and is secured. Therefore the browser will ask you for `username:mt` and `password:p,` write them to the dialog, and you will access it. This type of security is a **basic form security**.\n--\u003e\nThe **API Gateway** and **Store Service** both act as a *resource server*. \u003c!--To know more about calling Store API in a secure way you can check the `test-em-all.sh` script on how I have changed the calling of the services using **OAuth2** security.--\u003e\n\n#### Check all **Spring Boot Actuator** exposed metrics http://localhost:8080/app/actuator/metrics:\n\n```bash\n{\n    \"names\": [\n        \"http.server.requests\",\n        \"jvm.buffer.count\",\n        \"jvm.buffer.memory.used\",\n        \"jvm.buffer.total.capacity\",\n        \"jvm.classes.loaded\",\n        \"jvm.classes.unloaded\",\n        \"jvm.gc.live.data.size\",\n        \"jvm.gc.max.data.size\",\n        \"jvm.gc.memory.allocated\",\n        \"jvm.gc.memory.promoted\",\n        \"jvm.gc.pause\",\n        \"jvm.memory.committed\",\n        \"jvm.memory.max\",\n        \"jvm.memory.used\",\n        \"jvm.threads.daemon\",\n        \"jvm.threads.live\",\n        \"jvm.threads.peak\",\n        \"jvm.threads.states\",\n        \"logback.events\",\n        \"process.cpu.usage\",\n        \"process.files.max\",\n        \"process.files.open\",\n        \"process.start.time\",\n        \"process.uptime\",\n        \"resilience4j.circuitbreaker.buffered.calls\",\n        \"resilience4j.circuitbreaker.calls\",\n        \"resilience4j.circuitbreaker.failure.rate\",\n        \"resilience4j.circuitbreaker.not.permitted.calls\",\n        \"resilience4j.circuitbreaker.slow.call.rate\",\n        \"resilience4j.circuitbreaker.slow.calls\",\n        \"resilience4j.circuitbreaker.state\",\n        \"system.cpu.count\",\n        \"system.cpu.usage\",\n        \"system.load.average.1m\",\n        \"tomcat.sessions.active.current\",\n        \"tomcat.sessions.active.max\",\n        \"tomcat.sessions.alive.max\",\n        \"tomcat.sessions.created\",\n        \"tomcat.sessions.expired\",\n        \"tomcat.sessions.rejected\",\n        \"zipkin.reporter.messages\",\n        \"zipkin.reporter.messages.dropped\",\n        \"zipkin.reporter.messages.total\",\n        \"zipkin.reporter.queue.bytes\",\n        \"zipkin.reporter.queue.spans\",\n        \"zipkin.reporter.spans\",\n        \"zipkin.reporter.spans.dropped\",\n        \"zipkin.reporter.spans.total\"\n    ]\n}\n```\n\n#### Prometheus exposed metrics at http://localhost:8080/app/actuator/prometheus\n\n```bash\n# HELP resilience4j_circuitbreaker_not_permitted_calls_total Total number of not permitted calls\n# TYPE resilience4j_circuitbreaker_not_permitted_calls_total counter\nresilience4j_circuitbreaker_not_permitted_calls_total{kind=\"not_permitted\",name=\"proxyService\",} 0.0\n# HELP jvm_gc_live_data_size_bytes Size of long-lived heap memory pool after reclamation\n# TYPE jvm_gc_live_data_size_bytes gauge\njvm_gc_live_data_size_bytes 3721880.0\n# HELP jvm_gc_pause_seconds Time spent in GC pause\n# TYPE jvm_gc_pause_seconds summary\njvm_gc_pause_seconds_count{action=\"end of minor GC\",cause=\"Metadata GC Threshold\",} 1.0\njvm_gc_pause_seconds_sum{action=\"end of minor GC\",cause=\"Metadata GC Threshold\",} 0.071\njvm_gc_pause_seconds_count{action=\"end of minor GC\",cause=\"G1 Evacuation Pause\",} 6.0\njvm_gc_pause_seconds_sum{action=\"end of minor GC\",cause=\"G1 Evacuation Pause\",} 0.551\n# HELP jvm_gc_pause_seconds_max Time spent in GC pause\n# TYPE jvm_gc_pause_seconds_max gauge\njvm_gc_pause_seconds_max{action=\"end of minor GC\",cause=\"Metadata GC Threshold\",} 0.071\njvm_gc_pause_seconds_max{action=\"end of minor GC\",cause=\"G1 Evacuation Pause\",} 0.136\n# HELP system_cpu_usage The \"recent cpu usage\" for the whole system\n# TYPE system_cpu_usage gauge\nsystem_cpu_usage 0.4069206655413552\n# HELP jvm_buffer_total_capacity_bytes An estimate of the total capacity of the buffers in this pool\n# TYPE jvm_buffer_total_capacity_bytes gauge\njvm_buffer_total_capacity_bytes{id=\"mapped\",} 0.0\njvm_buffer_total_capacity_bytes{id=\"direct\",} 24576.0\n# HELP zipkin_reporter_spans_dropped_total Spans dropped (failed to report)\n# TYPE zipkin_reporter_spans_dropped_total counter\nzipkin_reporter_spans_dropped_total 4.0\n# HELP zipkin_reporter_spans_bytes_total Total bytes of encoded spans reported\n# TYPE zipkin_reporter_spans_bytes_total counter\nzipkin_reporter_spans_bytes_total 1681.0\n# HELP tomcat_sessions_active_current_sessions  \n# TYPE tomcat_sessions_active_current_sessions gauge\ntomcat_sessions_active_current_sessions 0.0\n# HELP jvm_classes_loaded_classes The number of classes that are currently loaded in the Java virtual machine\n# TYPE jvm_classes_loaded_classes gauge\njvm_classes_loaded_classes 13714.0\n# HELP process_files_open_files The open file descriptor count\n# TYPE process_files_open_files gauge\nprocess_files_open_files 17.0\n# HELP resilience4j_circuitbreaker_slow_call_rate The slow call of the circuit breaker\n# TYPE resilience4j_circuitbreaker_slow_call_rate gauge\nresilience4j_circuitbreaker_slow_call_rate{name=\"proxyService\",} -1.0\n# HELP system_cpu_count The number of processors available to the Java virtual machine\n# TYPE system_cpu_count gauge\nsystem_cpu_count 8.0\n# HELP jvm_threads_daemon_threads The current number of live daemon threads\n# TYPE jvm_threads_daemon_threads gauge\njvm_threads_daemon_threads 21.0\n# HELP zipkin_reporter_messages_total Messages reported (or attempted to be reported)\n# TYPE zipkin_reporter_messages_total counter\nzipkin_reporter_messages_total 2.0\n# HELP zipkin_reporter_messages_dropped_total  \n# TYPE zipkin_reporter_messages_dropped_total counter\nzipkin_reporter_messages_dropped_total{cause=\"ResourceAccessException\",} 2.0\n# HELP zipkin_reporter_messages_bytes_total Total bytes of messages reported\n# TYPE zipkin_reporter_messages_bytes_total counter\nzipkin_reporter_messages_bytes_total 1368.0\n# HELP http_server_requests_seconds  \n# TYPE http_server_requests_seconds summary\nhttp_server_requests_seconds_count{exception=\"None\",method=\"GET\",outcome=\"SUCCESS\",status=\"200\",uri=\"/actuator/metrics\",} 1.0\nhttp_server_requests_seconds_sum{exception=\"None\",method=\"GET\",outcome=\"SUCCESS\",status=\"200\",uri=\"/actuator/metrics\",} 1.339804427\nhttp_server_requests_seconds_count{exception=\"None\",method=\"GET\",outcome=\"SUCCESS\",status=\"200\",uri=\"/actuator/prometheus\",} 1.0\nhttp_server_requests_seconds_sum{exception=\"None\",method=\"GET\",outcome=\"SUCCESS\",status=\"200\",uri=\"/actuator/prometheus\",} 0.053689381\n# HELP http_server_requests_seconds_max  \n# TYPE http_server_requests_seconds_max gauge\nhttp_server_requests_seconds_max{exception=\"None\",method=\"GET\",outcome=\"SUCCESS\",status=\"200\",uri=\"/actuator/metrics\",} 1.339804427\nhttp_server_requests_seconds_max{exception=\"None\",method=\"GET\",outcome=\"SUCCESS\",status=\"200\",uri=\"/actuator/prometheus\",} 0.053689381\n# HELP resilience4j_circuitbreaker_slow_calls The number of slow successful which were slower than a certain threshold\n# TYPE resilience4j_circuitbreaker_slow_calls gauge\nresilience4j_circuitbreaker_slow_calls{kind=\"successful\",name=\"proxyService\",} 0.0\nresilience4j_circuitbreaker_slow_calls{kind=\"failed\",name=\"proxyService\",} 0.0\n# HELP jvm_classes_unloaded_classes_total The total number of classes unloaded since the Java virtual machine has started execution\n# TYPE jvm_classes_unloaded_classes_total counter\njvm_classes_unloaded_classes_total 0.0\n# HELP process_files_max_files The maximum file descriptor count\n# TYPE process_files_max_files gauge\nprocess_files_max_files 1048576.0\n# HELP resilience4j_circuitbreaker_calls_seconds Total number of successful calls\n# TYPE resilience4j_circuitbreaker_calls_seconds summary\nresilience4j_circuitbreaker_calls_seconds_count{kind=\"successful\",name=\"proxyService\",} 0.0\nresilience4j_circuitbreaker_calls_seconds_sum{kind=\"successful\",name=\"proxyService\",} 0.0\nresilience4j_circuitbreaker_calls_seconds_count{kind=\"failed\",name=\"proxyService\",} 0.0\nresilience4j_circuitbreaker_calls_seconds_sum{kind=\"failed\",name=\"proxyService\",} 0.0\nresilience4j_circuitbreaker_calls_seconds_count{kind=\"ignored\",name=\"proxyService\",} 0.0\nresilience4j_circuitbreaker_calls_seconds_sum{kind=\"ignored\",name=\"proxyService\",} 0.0\n# HELP resilience4j_circuitbreaker_calls_seconds_max Total number of successful calls\n# TYPE resilience4j_circuitbreaker_calls_seconds_max gauge\nresilience4j_circuitbreaker_calls_seconds_max{kind=\"successful\",name=\"proxyService\",} 0.0\nresilience4j_circuitbreaker_calls_seconds_max{kind=\"failed\",name=\"proxyService\",} 0.0\nresilience4j_circuitbreaker_calls_seconds_max{kind=\"ignored\",name=\"proxyService\",} 0.0\n# HELP zipkin_reporter_spans_total Spans reported\n# TYPE zipkin_reporter_spans_total counter\nzipkin_reporter_spans_total 5.0\n# HELP zipkin_reporter_queue_bytes Total size of all encoded spans queued for reporting\n# TYPE zipkin_reporter_queue_bytes gauge\nzipkin_reporter_queue_bytes 0.0\n# HELP tomcat_sessions_expired_sessions_total  \n# TYPE tomcat_sessions_expired_sessions_total counter\ntomcat_sessions_expired_sessions_total 0.0\n# HELP tomcat_sessions_alive_max_seconds  \n# TYPE tomcat_sessions_alive_max_seconds gauge\ntomcat_sessions_alive_max_seconds 0.0\n# HELP process_uptime_seconds The uptime of the Java virtual machine\n# TYPE process_uptime_seconds gauge\nprocess_uptime_seconds 224.402\n# HELP tomcat_sessions_active_max_sessions  \n# TYPE tomcat_sessions_active_max_sessions gauge\ntomcat_sessions_active_max_sessions 0.0\n# HELP process_cpu_usage The \"recent cpu usage\" for the Java Virtual Machine process\n# TYPE process_cpu_usage gauge\nprocess_cpu_usage 5.625879043600563E-4\n# HELP jvm_gc_memory_promoted_bytes_total Count of positive increases in the size of the old generation memory pool before GC to after GC\n# TYPE jvm_gc_memory_promoted_bytes_total counter\njvm_gc_memory_promoted_bytes_total 1.7851088E7\n# HELP logback_events_total Number of error level events that made it to the logs\n# TYPE logback_events_total counter\nlogback_events_total{level=\"warn\",} 5.0\nlogback_events_total{level=\"debug\",} 79.0\nlogback_events_total{level=\"error\",} 0.0\nlogback_events_total{level=\"trace\",} 0.0\nlogback_events_total{level=\"info\",} 60.0\n# HELP tomcat_sessions_created_sessions_total  \n# TYPE tomcat_sessions_created_sessions_total counter\ntomcat_sessions_created_sessions_total 0.0\n# HELP jvm_threads_live_threads The current number of live threads including both daemon and non-daemon threads\n# TYPE jvm_threads_live_threads gauge\njvm_threads_live_threads 25.0\n# HELP jvm_threads_states_threads The current number of threads having NEW state\n# TYPE jvm_threads_states_threads gauge\njvm_threads_states_threads{state=\"runnable\",} 6.0\njvm_threads_states_threads{state=\"blocked\",} 0.0\njvm_threads_states_threads{state=\"waiting\",} 8.0\njvm_threads_states_threads{state=\"timed-waiting\",} 11.0\njvm_threads_states_threads{state=\"new\",} 0.0\njvm_threads_states_threads{state=\"terminated\",} 0.0\n# HELP tomcat_sessions_rejected_sessions_total  \n# TYPE tomcat_sessions_rejected_sessions_total counter\ntomcat_sessions_rejected_sessions_total 0.0\n# HELP process_start_time_seconds Start time of the process since unix epoch.\n# TYPE process_start_time_seconds gauge\nprocess_start_time_seconds 1.64088634006E9\n# HELP resilience4j_circuitbreaker_buffered_calls The number of buffered failed calls stored in the ring buffer\n# TYPE resilience4j_circuitbreaker_buffered_calls gauge\nresilience4j_circuitbreaker_buffered_calls{kind=\"successful\",name=\"proxyService\",} 0.0\nresilience4j_circuitbreaker_buffered_calls{kind=\"failed\",name=\"proxyService\",} 0.0\n# HELP jvm_memory_max_bytes The maximum amount of memory in bytes that can be used for memory management\n# TYPE jvm_memory_max_bytes gauge\njvm_memory_max_bytes{area=\"nonheap\",id=\"CodeHeap 'profiled nmethods'\",} 1.22908672E8\njvm_memory_max_bytes{area=\"heap\",id=\"G1 Survivor Space\",} -1.0\njvm_memory_max_bytes{area=\"heap\",id=\"G1 Old Gen\",} 5.182062592E9\njvm_memory_max_bytes{area=\"nonheap\",id=\"Metaspace\",} -1.0\njvm_memory_max_bytes{area=\"nonheap\",id=\"CodeHeap 'non-nmethods'\",} 5836800.0\njvm_memory_max_bytes{area=\"heap\",id=\"G1 Eden Space\",} -1.0\njvm_memory_max_bytes{area=\"nonheap\",id=\"Compressed Class Space\",} 1.073741824E9\njvm_memory_max_bytes{area=\"nonheap\",id=\"CodeHeap 'non-profiled nmethods'\",} 1.22912768E8\n# HELP jvm_memory_committed_bytes The amount of memory in bytes that is committed for the Java virtual machine to use\n# TYPE jvm_memory_committed_bytes gauge\njvm_memory_committed_bytes{area=\"nonheap\",id=\"CodeHeap 'profiled nmethods'\",} 1.6646144E7\njvm_memory_committed_bytes{area=\"heap\",id=\"G1 Survivor Space\",} 2.4117248E7\njvm_memory_committed_bytes{area=\"heap\",id=\"G1 Old Gen\",} 1.7301504E8\njvm_memory_committed_bytes{area=\"nonheap\",id=\"Metaspace\",} 7.6857344E7\njvm_memory_committed_bytes{area=\"nonheap\",id=\"CodeHeap 'non-nmethods'\",} 2555904.0\njvm_memory_committed_bytes{area=\"heap\",id=\"G1 Eden Space\",} 2.71581184E8\njvm_memory_committed_bytes{area=\"nonheap\",id=\"Compressed Class Space\",} 1.0354688E7\njvm_memory_committed_bytes{area=\"nonheap\",id=\"CodeHeap 'non-profiled nmethods'\",} 6619136.0\n# HELP jvm_memory_used_bytes The amount of used memory\n# TYPE jvm_memory_used_bytes gauge\njvm_memory_used_bytes{area=\"nonheap\",id=\"CodeHeap 'profiled nmethods'\",} 1.6585088E7\njvm_memory_used_bytes{area=\"heap\",id=\"G1 Survivor Space\",} 2.4117248E7\njvm_memory_used_bytes{area=\"heap\",id=\"G1 Old Gen\",} 2.0524392E7\njvm_memory_used_bytes{area=\"nonheap\",id=\"Metaspace\",} 7.4384552E7\njvm_memory_used_bytes{area=\"nonheap\",id=\"CodeHeap 'non-nmethods'\",} 1261696.0\njvm_memory_used_bytes{area=\"heap\",id=\"G1 Eden Space\",} 2.5165824E7\njvm_memory_used_bytes{area=\"nonheap\",id=\"Compressed Class Space\",} 9365664.0\njvm_memory_used_bytes{area=\"nonheap\",id=\"CodeHeap 'non-profiled nmethods'\",} 6604416.0\n# HELP system_load_average_1m The sum of the number of runnable entities queued to available processors and the number of runnable entities running on the available processors averaged over a period of time\n# TYPE system_load_average_1m gauge\nsystem_load_average_1m 8.68\n# HELP resilience4j_circuitbreaker_state The states of the circuit breaker\n# TYPE resilience4j_circuitbreaker_state gauge\nresilience4j_circuitbreaker_state{name=\"proxyService\",state=\"forced_open\",} 0.0\nresilience4j_circuitbreaker_state{name=\"proxyService\",state=\"closed\",} 1.0\nresilience4j_circuitbreaker_state{name=\"proxyService\",state=\"disabled\",} 0.0\nresilience4j_circuitbreaker_state{name=\"proxyService\",state=\"open\",} 0.0\nresilience4j_circuitbreaker_state{name=\"proxyService\",state=\"half_open\",} 0.0\nresilience4j_circuitbreaker_state{name=\"proxyService\",state=\"metrics_only\",} 0.0\n# HELP jvm_buffer_memory_used_bytes An estimate of the memory that the Java virtual machine is using for this buffer pool\n# TYPE jvm_buffer_memory_used_bytes gauge\njvm_buffer_memory_used_bytes{id=\"mapped\",} 0.0\njvm_buffer_memory_used_bytes{id=\"direct\",} 24576.0\n# HELP resilience4j_circuitbreaker_failure_rate The failure rate of the circuit breaker\n# TYPE resilience4j_circuitbreaker_failure_rate gauge\nresilience4j_circuitbreaker_failure_rate{name=\"proxyService\",} -1.0\n# HELP zipkin_reporter_queue_spans Spans queued for reporting\n# TYPE zipkin_reporter_queue_spans gauge\nzipkin_reporter_queue_spans 0.0\n# HELP jvm_gc_memory_allocated_bytes_total Incremented for an increase in the size of the (young) heap memory pool after one GC to before the next\n# TYPE jvm_gc_memory_allocated_bytes_total counter\njvm_gc_memory_allocated_bytes_total 1.402994688E9\n# HELP jvm_buffer_count_buffers An estimate of the number of buffers in the pool\n# TYPE jvm_buffer_count_buffers gauge\njvm_buffer_count_buffers{id=\"mapped\",} 0.0\njvm_buffer_count_buffers{id=\"direct\",} 3.0\n# HELP jvm_threads_peak_threads The peak live thread count since the Java virtual machine started or peak was reset\n# TYPE jvm_threads_peak_threads gauge\njvm_threads_peak_threads 25.0\n# HELP jvm_gc_max_data_size_bytes Max size of long-lived heap memory pool\n# TYPE jvm_gc_max_data_size_bytes gauge\njvm_gc_max_data_size_bytes 5.182062592E9\n```\n\n#### Check All Services Health\nFrom ecommerce front Service proxy we can check all the core services health when you have all the\n microservices up and running using Docker Compose,\n```bash\nyashw@:~/ClicknCart-backend-app$ curl -k https://localhost:8443/actuator/health -s | jq .components.\"\\\"Core Microservices\\\"\"\n```\nThis will result in the following response:\n```json\n{\n    \"status\": \"UP\",\n    \"components\": {\n        \"circuitBreakers\": {\n            \"status\": \"UP\",\n            \"details\": {\n                \"proxyService\": {\n                    \"status\": \"UP\",\n                    \"details\": {\n                        \"failureRate\": \"-1.0%\",\n                        \"failureRateThreshold\": \"50.0%\",\n                        \"slowCallRate\": \"-1.0%\",\n                        \"slowCallRateThreshold\": \"100.0%\",\n                        \"bufferedCalls\": 0,\n                        \"slowCalls\": 0,\n                        \"slowFailedCalls\": 0,\n                        \"failedCalls\": 0,\n                        \"notPermittedCalls\": 0,\n                        \"state\": \"CLOSED\"\n                    }\n                }\n            }\n        },\n        \"clientConfigServer\": {\n            \"status\": \"UNKNOWN\",\n            \"details\": {\n                \"error\": \"no property sources located\"\n            }\n        },\n        \"discoveryComposite\": {\n            \"status\": \"UP\",\n            \"components\": {\n                \"discoveryClient\": {\n                    \"status\": \"UP\",\n                    \"details\": {\n                        \"services\": [\n                            \"proxy-client\",\n                            \"api-gateway\",\n                            \"cloud-config\",\n                            \"product-service\",\n                            \"user-service\",\n                            \"favourite-service\",\n                            \"order-service\",\n                            \"payment-service\",\n                            \"shipping-service\"\n                        ]\n                    }\n                },\n                \"eureka\": {\n                    \"description\": \"Remote status from Eureka server\",\n                    \"status\": \"UP\",\n                    \"details\": {\n                        \"applications\": {\n                            \"FAVOURITE-SERVICE\": 1,\n                            \"PROXY-CLIENT\": 1,\n                            \"API-GATEWAY\": 1,\n                            \"PAYMENT-SERVICE\": 1,\n                            \"ORDER-SERVICE\": 1,\n                            \"CLOUD-CONFIG\": 1,\n                            \"PRODUCT-SERVICE\": 1,\n                            \"SHIPPING-SERVICE\": 1,\n                            \"USER-SERVICE\": 1\n                        }\n                    }\n                }\n            }\n        },\n        \"diskSpace\": {\n            \"status\": \"UP\",\n            \"details\": {\n                \"total\": 981889826816,\n                \"free\": 325116776448,\n                \"threshold\": 10485760,\n                \"exists\": true\n            }\n        },\n        \"ping\": {\n            \"status\": \"UP\"\n        },\n        \"refreshScope\": {\n            \"status\": \"UP\"\n        }\n    }\n}\n```\n### Testing Them All\nNow it's time to test all the application functionality as one part. To do so just run\n the following automation test script:\n\n```bash\nyashw@:~/ClicknCart-backend-app$ ./test-em-all.sh start\n```\n\u003e You can use `stop` switch with `start`, that will \n\u003e1. start docker, \n\u003e2. run the tests, \n\u003e3. stop the docker instances.\n\nThe result will look like this:\n\n```bash\nStarting 'ClicknCart-backend-app' for [Blackbox] testing...\n\nStart Tests: Tue, May 31, 2020 2:09:36 AM\nHOST=localhost\nPORT=8080\nRestarting the test environment...\n$ docker-compose -p -f compose.yml down --remove-orphans\n$ docker-compose -p -f compose.yml up -d\nWait for: curl -k https://localhost:8080/actuator/health... , retry #1 , retry #2, {\"status\":\"UP\"} DONE, continues...\nTest OK (HTTP Code: 200)\n...\nTest OK (actual value: 1)\nTest OK (actual value: 3)\nTest OK (actual value: 3)\nTest OK (HTTP Code: 404, {\"httpStatus\":\"NOT_FOUND\",\"message\":\"No product found for productId: 13\",\"path\":\"/app/api/products/20\",\"time\":\"2020-04-12@12:34:25.144+0000\"})\n...\nTest OK (actual value: 3)\nTest OK (actual value: 0)\nTest OK (HTTP Code: 422, {\"httpStatus\":\"UNPROCESSABLE_ENTITY\",\"message\":\"Invalid productId: -1\",\"path\":\"/app/api/products/-1\",\"time\":\"2020-04-12@12:34:26.243+0000\"})\nTest OK (actual value: \"Invalid productId: -1\")\nTest OK (HTTP Code: 400, {\"timestamp\":\"2020-04-12T12:34:26.471+00:00\",\"path\":\"/app/api/products/invalidProductId\",\"status\":400,\"error\":\"Bad Request\",\"message\":\"Type mismatch.\",\"requestId\":\"044dcdf2-13\"})\nTest OK (actual value: \"Type mismatch.\")\nTest OK (HTTP Code: 401, )\nTest OK (HTTP Code: 200)\nTest OK (HTTP Code: 403, )\nStart Circuit Breaker tests!\nTest OK (actual value: CLOSED)\nTest OK (HTTP Code: 500, {\"timestamp\":\"2020-05-26T00:09:48.784+00:00\",\"path\":\"/app/api/products/2\",\"status\":500,\"error\":\"Internal Server Error\",\"message\":\"Did not observe any item or terminal signal within 2000ms in 'onErrorResume' (and no fallback has been configured)\",\"requestId\":\"4aa9f5e8-119\"})\n...\nTest OK (actual value: Did not observe any item or terminal signal within 2000ms)\nTest OK (HTTP Code: 200)\nTest OK (actual value: Fallback product2)\nTest OK (HTTP Code: 200)\nTest OK (actual value: Fallback product2)\nTest OK (HTTP Code: 404, {\"httpStatus\":\"NOT_FOUND\",\"message\":\"Product Id: 14 not found in fallback cache!\",\"path\":\"/app/api/products/14\",\"timestamp\":\"2020-05-26@00:09:53.998+0000\"})\n...\nTest OK (actual value: product name C)\nTest OK (actual value: CLOSED)\nTest OK (actual value: CLOSED_TO_OPEN)\nTest OK (actual value: OPEN_TO_HALF_OPEN)\nTest OK (actual value: HALF_OPEN_TO_CLOSED)\nEnd, all tests OK: Tue, May 31, 2020 2:10:09 AM\n```\n### Tracking the services with Zipkin\nNow, you can now track Microservices interactions throughout Zipkin UI from the following link:\n[http://localhost:9411/zipkin/](http://localhost:9411/zipkin/)\n![Zipkin UI](zipkin-dash.png)\n\n### Closing The Story\n\nFinally, to close the story, we need to shut down Microservices manually service by service, hahaha just kidding, run the following command to shut them all:\n\n```bash\nyashw@:~/ClicknCart-backend-app$ docker-compose -f compose.yml down --remove-orphans\n```\n And you should see output like the following:\n\n```bash\nRemoving ClicknCart-backend-app_payment-service-container_1   ... done\nRemoving ClicknCart-backend-app_zipkin-container_1            ... done\nRemoving ClicknCart-backend-app_service-discovery-container_1 ... done\nRemoving ClicknCart-backend-app_product-service-container_1   ... done\nRemoving ClicknCart-backend-app_cloud-config-container_1      ... done\nRemoving ClicknCart-backend-app_proxy-client-container_1      ... done\nRemoving ClicknCart-backend-app_order-service-container_1     ... done\nRemoving ClicknCart-backend-app_user-service-container_1      ... done\nRemoving ClicknCart-backend-app_shipping-service-container_1  ... done\nRemoving ClicknCart-backend-app_api-gateway-container_1       ... done\nRemoving ClicknCart-backend-app_favourite-service-container_1 ... done\nRemoving network ClicknCart-backend-app_default\n```\n# The End\n\nIn conclusion, I hope you enjoyed exploring the ClicknCart application and found it useful, much like I did during its development. If you wish to contribute and enhance the project, please consider:\n\n- **Opening PRs**\n- Providing **Feedback**\n- Adding **New Suggestions**\n- Lastly, show your support with a ⭐️.\n\n*Happy Coding...* 🙂\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyashwalke999%2Fclickncart-microservices-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyashwalke999%2Fclickncart-microservices-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyashwalke999%2Fclickncart-microservices-app/lists"}