{"id":16998554,"url":"https://github.com/sivaprasadreddy/spring-modular-monolith","last_synced_at":"2025-10-05T12:15:56.163Z","repository":{"id":254799744,"uuid":"847515370","full_name":"sivaprasadreddy/spring-modular-monolith","owner":"sivaprasadreddy","description":"A modular monolith application built with Spring Modulith","archived":false,"fork":false,"pushed_at":"2025-06-06T20:00:54.000Z","size":550,"stargazers_count":70,"open_issues_count":10,"forks_count":16,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-06T21:18:40.365Z","etag":null,"topics":["java","spring-boot","spring-modulith"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sivaprasadreddy.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,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-08-26T02:27:43.000Z","updated_at":"2025-05-25T12:42:39.000Z","dependencies_parsed_at":"2024-10-14T04:05:42.931Z","dependency_job_id":"6a3a007d-d703-4f6b-8303-3f732a462b19","html_url":"https://github.com/sivaprasadreddy/spring-modular-monolith","commit_stats":{"total_commits":53,"total_committers":3,"mean_commits":"17.666666666666668","dds":0.05660377358490565,"last_synced_commit":"08356caa9a2b153b83e93b5baf907c65f3f7fc9b"},"previous_names":["sivaprasadreddy/spring-modular-monolith-ddd","sivaprasadreddy/spring-modular-monolith"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sivaprasadreddy/spring-modular-monolith","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sivaprasadreddy%2Fspring-modular-monolith","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sivaprasadreddy%2Fspring-modular-monolith/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sivaprasadreddy%2Fspring-modular-monolith/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sivaprasadreddy%2Fspring-modular-monolith/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sivaprasadreddy","download_url":"https://codeload.github.com/sivaprasadreddy/spring-modular-monolith/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sivaprasadreddy%2Fspring-modular-monolith/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262103306,"owners_count":23259429,"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":["java","spring-boot","spring-modulith"],"created_at":"2024-10-14T04:05:35.041Z","updated_at":"2025-10-05T12:15:56.154Z","avatar_url":"https://github.com/sivaprasadreddy.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# spring-modular-monolith\nAn e-commerce application following Modular Monolith architecture using [Spring Modulith](https://spring.io/projects/spring-modulith).\nThe goal of this application is to demonstrate various features of Spring Modulith with a practical application.\n\n![bookstore-modulith.png](docs/bookstore-modulith.png)\n\nThis application follows modular monolith architecture with the following modules:\n\n* **Common:** This module contains the code that is shared by all modules.\n* **Catalog:** This module manages the catalog of products and store data in `catalog` schema.\n* **Orders:** This module implements the order management and store the data in `orders` schema.\n* **Inventory:** This module implements the inventory management and store the data in `inventory` schema.\n* **Notifications:** This module handles the events published by other modules and sends notifications to the interested parties.\n\n**Goals:**\n* Implement each module as independently as possible.\n* Prefer event-driven communication instead of direct module dependency wherever applicable.\n* Store data managed by each module in an isolated manner by using different schema or database.\n* Each module should be testable by loading only module-specific components.\n\n**Module communication:**\n\n* **Common** module is an OPEN module that can be used by other modules.\n* **Orders** module invokes the **Catalog** module public API to validate the order details\n* When an Order is successfully created, **Orders** module publishes **\"OrderCreatedEvent\"**\n* The **\"OrderCreatedEvent\"** will also be published to external broker like RabbitMQ. Other applications may consume and process those events.\n* **Inventory** module consumes \"OrderCreatedEvent\" and updates the stock level for the products.\n* **Notifications** module consumes \"OrderCreatedEvent\" and sends an order confirmation email to the customer.\n\n## Prerequisites\n* JDK 24\n* Docker and Docker Compose\n* Your favourite IDE (Recommended: [IntelliJ IDEA](https://www.jetbrains.com/idea/))\n\nInstall JDK, Maven, Gradle, etc using [SDKMAN](https://sdkman.io/)\n\n```shell\n$ curl -s \"https://get.sdkman.io\" | bash\n$ source \"$HOME/.sdkman/bin/sdkman-init.sh\"\n$ sdk install java 24.0.1-tem\n$ sdk install maven\n```\n\nTask is a task runner that we can use to run any arbitrary commands in easier way.\n\n```shell\n$ brew install go-task\n(or)\n$ go install github.com/go-task/task/v3/cmd/task@latest\n```\n\nOn Linux you can install `task` using your package manager or via `go install`:\n\n```shell\n# Debian/Ubuntu (using apt via the official binary repo):\nsudo sh -c \"wget -qO - https://taskfile.dev/install.sh | bash\"\n\n# or using snap (if available):\nsudo snap install task --classic\n\n# or build from source with Go:\ngo install github.com/go-task/task/v3/cmd/task@latest\n```\n\nOn Windows you can use Chocolatey, Scoop, or `go install`:\n\n```powershell\n# Chocolatey\nchoco install gotask -y\n\n# Scoop\nscoop install task\n\n# or build from source with Go (requires Go installed and in PATH):\ngo install github.com/go-task/task/v3/cmd/task@latest\n```\n\nVerify the prerequisites\n\n```shell\n$ java -version\n$ docker info\n$ docker compose version\n$ task --version\n```\n\n## Using `task` to perform various tasks:\n\n```shell\n# Run tests\n$ task test\n\n# Automatically format code using spotless-maven-plugin\n$ task format\n\n# Build docker image\n$ task build_image\n\n# Run application in docker container\n$ task start\n$ task stop\n$ task restart\n```\n\n* Application URL: http://localhost:8080\n* Actuator URL: http://localhost:8080/actuator\n* Actuator URL for modulith: http://localhost:8080/actuator/modulith\n* RabbitMQ Admin URL: http://localhost:15672 (Credentials: guest/guest)\n* Zipkin URL: http://localhost:9411\n\n## Deploying on k8s cluster\n* [Install kubectl](https://kubernetes.io/docs/tasks/tools/)\n* [Install kind](https://kind.sigs.k8s.io/docs/user/quick-start/)\n\n```shell\n$ brew install kubectl\n$ brew install kind\n```\n\nCreate a KinD cluster and deploy an app.\n\n```shell\n# Create KinD cluster\n$ task kind_create\n\n# deploy app to kind cluster \n$ task k8s_deploy\n\n# undeploy app\n$ task k8s_undeploy\n\n# Destroy KinD cluster\n$ task kind_destroy\n```\n\n* Application URL: http://localhost:30090\n* RabbitMQ Admin URL: http://localhost:30091 (Credentials: guest/guest)\n* Zipkin URL: http://localhost:30092\n\n### Kubernetes Deployment Notes and Troubleshooting\n\nThese notes explain how `task kind_create` / `task k8s_deploy` behave and common troubleshooting steps you can use when deploying the app to a local KinD cluster.\n\n- Host-port mappings and fallback:\n    - The Kind configuration (`k8s/kind/kind-config.yml`) maps host ports (80, 443, 30090-30092) into the control-plane node so services are accessible from the host.\n    - If any of those host ports are already in use on your machine (for example a local web server or another Kubernetes runtime), the PowerShell and shell helpers will detect the conflict and create the Kind cluster without hostPort mappings.\n    - When host-port mappings are skipped, the app is still deployed inside the cluster — you'll need to port-forward or use `kubectl port-forward` (or access services via the cluster network) to reach them from your host.\n\n- Postgres readiness and app startup:\n    - The application depends on the Postgres pod becoming Ready before it can run Flyway migrations and bring up the Spring Boot application.\n    - Sometimes the app starts before Postgres finishes initialization, which causes connection errors and a crash loop. In this setup the app will typically retry on pod restart (and succeed) once Postgres is Ready.\n    - If the app repeatedly fails with messages like `Connection to spring-modular-monolith-postgres-svc:5432 refused`, check the Postgres pod logs (see commands below) and ensure it reaches `database system is ready to accept connections`.\n\n- Quick troubleshooting commands\n    - Show pods and their status:\n        - `kubectl get pods -A -o wide`\n    - Show the nodes\n        - `kubectl get nodes`\n    - Describe a failing pod to see events:\n        - `kubectl describe pod \u003cpod-name\u003e -n \u003cnamespace\u003e`\n    - Show logs for a container (current + previous):\n        - `kubectl logs \u003cpod-name\u003e -c \u003ccontainer-name\u003e`\n        - `kubectl logs \u003cpod-name\u003e -c \u003ccontainer-name\u003e --previous`\n    - If Postgres is not Ready, inspect its logs:\n        - `kubectl logs \u003cpostgres-pod-name\u003e -c postgres`\n    - If hostPort mappings were skipped and you want to access the app locally:\n        - Port-forward the service to localhost: `kubectl port-forward svc/spring-modular-monolith-svc 8080:8080`\n        - Then visit: `http://localhost:8080`\n\n- If you want hostPort mappings enforced\n    - Free the host ports (80, 443, 30090-30092) on your machine, or edit `k8s/kind/kind-config.yml` to remove the hostPort entries.\n    - Then recreate the cluster with `task kind_destroy` followed by `task kind_create`.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsivaprasadreddy%2Fspring-modular-monolith","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsivaprasadreddy%2Fspring-modular-monolith","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsivaprasadreddy%2Fspring-modular-monolith/lists"}