java
Java Microservices Project
This project demonstrates a simple microservices architecture implemented in Java using Spring Boot. It consists of four services:
- User Service: Manages user-related data.
- Product Service: Manages product-related data.
- Order Service: Handles order creation and management, demonstrating service-to-service communication with User and Product services.
- Notification Service: A placeholder service for sending notifications.
Architecture Overview
The architecture is based on a set of independently deployable services that communicate with each other.
+-------------------+ +-------------------+
| User Service |<----->| Order Service |
| (Port 8080) | | (Port 8082) |
+-------------------+ +-------------------+
^
|
v
+-------------------+ +-------------------+
| Product Service |<----->| Order Service |
| (Port 8081) | | (Port 8082) |
+-------------------+ +-------------------+
^
|
v
+-------------------+
| Notification Svc |
| (Port 8083) |
+-------------------+
Service-to-Service Communication
In a Kubernetes environment, service-to-service communication is facilitated by Kubernetes DNS. Each Service resource in Kubernetes gets a DNS name (e.g., user-service, product-service). Other services within the same Kubernetes cluster can resolve these DNS names to the respective service's ClusterIP, allowing them to communicate without needing to know the exact IP addresses.
For example, the Order Service communicates with the User Service and Product Service using their Kubernetes service names:
http://user-service:8080/users/{userId}http://product-service:8081/products/{productId}
The port numbers (8080, 8081) correspond to the targetPort defined in each service's Kubernetes Service manifest.
Services Details
Maven Project Structure (POMs)
Each microservice in this Java project is an independent Maven project with its own pom.xml. These pom.xml files inherit from the spring-boot-starter-parent, which provides sensible defaults for Spring Boot applications. This approach allows for independent development, building, and deployment of each service.
1. User Service
- Functionality: Provides REST endpoints for managing users.
- Technology: Spring Boot
- Endpoints:
GET /users: Get all users.GET /users/{id}: Get user by ID.
- Port: 8080
2. Product Service
- Functionality: Provides REST endpoints for managing products.
- Technology: Spring Boot
- Endpoints:
GET /products: Get all products.GET /products/{id}: Get product by ID.
- Port: 8081
3. Order Service
- Functionality: Handles order creation and retrieval. Demonstrates calling other microservices.
- Technology: Spring Boot (using WebClient for HTTP calls)
- Endpoints:
GET /orders: Get all orders.GET /orders/{id}: Get order by ID.GET /orders/create/{userId}/{productId}/{quantity}: Create a dummy order and call User/Product services.
- Port: 8082
4. Notification Service
- Functionality: A simple service to simulate sending notifications.
- Technology: Spring Boot
- Endpoints:
POST /notifications/send: Send a notification.
- Port: 8083
Setup and Local Development
-
Prerequisites:
- Java 11 or higher
- Maven
- Docker
- Kubernetes cluster (e.g., Minikube, Docker Desktop Kubernetes)
kubectlconfigured to connect to your cluster
-
Build Services: Navigate to each service directory (
user-service,product-service,order-service,notification-service) and run:bash mvn clean installThis will build the JAR files for each service and run unit tests. -
Build Docker Images: From the root of each service directory, build the Docker image. Replace
your-docker-registrywith your actual Docker registry (e.g.,myusernamefor Docker Hub).bash docker build -t your-docker-registry/user-service:0.0.1-SNAPSHOT . docker build -t your-docker-registry/product-service:0.0.1-SNAPSHOT . docker build -t your-docker-registry/order-service:0.0.1-SNAPSHOT . docker build -t your-docker-registry/notification-service:0.0.1-SNAPSHOT .Then push them to your registry:bash docker push your-docker-registry/user-service:0.0.1-SNAPSHOT docker push your-docker-registry/product-service:0.0.1-SNAPSHOT docker push your-docker-registry/order-service:0.0.1-SNAPSHOT docker push your-docker-registry/notification-service:0.0.1-SNAPSHOTNote: Update theimagefield in thekubernetes/deployment.yamlfiles for each service to point to your pushed images (e.g.,image: your-docker-registry/user-service:0.0.1-SNAPSHOT). -
Deploy to Kubernetes: Apply the Kubernetes manifests for each service. You can do this individually or create a script.
bash kubectl apply -f user-service/kubernetes/deployment.yaml kubectl apply -f user-service/kubernetes/service.yaml kubectl apply -f product-service/kubernetes/deployment.yaml kubectl apply -f product-service/kubernetes/service.yaml kubectl apply -f order-service/kubernetes/deployment.yaml kubectl apply -f order-service/kubernetes/service.yaml kubectl apply -f notification-service/kubernetes/deployment.yaml kubectl apply -f notification-service/kubernetes/service.yaml -
Access Services: Since all services are
ClusterIPtype, they are only accessible within the cluster. To access them from outside (e.g., for testing), you can usekubectl port-forwardor set up an Ingress controller.Example for
user-service:bash kubectl port-forward service/user-service 8080:8080Then accesshttp://localhost:8080/usersin your browser.
CI/CD with Jenkins
Two Jenkinsfiles are provided:
-
Jenkinsfile(Standard CI/CD Pipeline): This file defines a Jenkins Pipeline that automates the build, Docker image creation, and deployment to Kubernetes for all services. The pipeline includes the following stages:- Unit Tests: Runs
mvn testfor each service. - SonarQube Analysis: Performs static code analysis using SonarQube for each service. The pipeline is configured to continue even if the SonarQube quality gate fails, marking the build as
UNSTABLE. - Package and Docker Build: Builds the JAR files and Docker images for each service.
- Deploy to Kubernetes: Applies the Kubernetes manifests to deploy the services.
- Unit Tests: Runs
-
Jenkinsfile.devsecops(DevSecOps Pipeline): This file extends the standard CI/CD pipeline by integrating additional security checks. The pipeline includes the following stages:- Unit Tests: Runs
mvn testfor each service. - Static Application Security Testing (SAST) - SonarQube: Performs static code analysis including security vulnerability detection using SonarQube.
- Dependency Vulnerability Scanning (SCA): Scans project dependencies for known vulnerabilities using OWASP Dependency-Check. The pipeline is configured to continue even if vulnerabilities are found, marking the build as
UNSTABLE. - Package and Docker Build: Builds the JAR files and Docker images for each service.
- Container Image Scanning: Scans Docker images for vulnerabilities using Trivy. The pipeline is configured to continue even if vulnerabilities are found, marking the build as
UNSTABLE. - Deploy to Kubernetes: Applies the Kubernetes manifests to deploy the services.
- Unit Tests: Runs
Steps to use the Jenkinsfile:
- Configure a Jenkins server with Docker and Kubernetes plugins.
- Ensure
kubectlis configured on the Jenkins agent to access your Kubernetes cluster. - Configure SonarQube integration in Jenkins (e.g., install SonarQube Scanner, configure SonarQube server connection).
- For
Jenkinsfile.devsecops, ensuredependency-check-mavenplugin is configured inpom.xml(or manually run) and Trivy is installed on the Jenkins agent. - Create a new Pipeline job in Jenkins.
- Configure the job to use "Pipeline script from SCM" and point it to this repository, specifying either
JenkinsfileorJenkinsfile.devsecopsas the script path. - Run the Jenkins job. It will execute the stages defined in the selected
Jenkinsfile.
Important: Remember to replace your-docker-registry in the Jenkinsfile(s) and Kubernetes manifests with your actual Docker registry. Also, ensure your Jenkins setup has the necessary SonarQube credentials (sonarqube-token) and SONAR_SCANNER_HOME tool configured.