Skip to content

octodemo/java-springboot-demo

Repository files navigation

Java Demo App

Overview

This is a simple Sales Manager Java App that stores sales items in a table presented in a web app. This demo repo is designed to help understand some of CI/CD (Continuous Integration/Continuous Delivery) principles and best practices.

Technology Stack

  • Language: Java (Spring Boot framework)
  • Design Patterns: MVC (Model View Controller) and OOP (Object Oriented Programming)
  • Database: PostreSQL 10.4 (compatible with other versions)
  • CI/CD Pipeline: GitHub Actions

CI/CD Pipeline

The pipeline is optimized using various tools. See the .github/workflows/ci.yml and .github/workflows/cd.yml for more detailed configuration.

Continuous Integration

Continuous Delivery/Deployment

CI/CD Diagram

stateDiagram
    state Developer-Workflow {
    Commits --> PR: Developers Commit new changes in a Pull Request
    PR --> Build: Build & Unit Test Suite
    }
    
    state Continuous-Integration {
        state Security-Scans {
        Build --> App: CodeQL Analysis
        Build --> Database: Liquibase Quality Checks
        Build --> Package: Compile
        }
        Build --> JunitTests: Storing Artifacts
        state Parallel-Testing {
        JunitTests --> JunitTest1: Each test runs in \na containerized environment
        JunitTests --> JunitTest2
        JunitTests --> JunitTest3
        JunitTests --> JunitTest4
        JunitTests --> JunitTest..N
        }
        JunitTests --> Publish: If CI passes, \nmerging to main branch \nand publishing Containerised\n App to GitHub\n Container Registry
    }

    state Continuous-Delivery {
    Publish --> SystemTesting: Pulling Image from GHCR
    SystemTesting --> IntegrationTesting: [staging]
    IntegrationTesting --> AccepetanceTesting: [staging]
    }
    AccepetanceTesting --> Deploy: Login with OpenID Connect and \nDeploy the app to K8s
    Deploy --> [ProdInstance1]: Blue
    Deploy --> [ProdInstance2]: Green
Loading

Blue-Green Deployment Strategy Diagram

sequenceDiagram
    participant C as Commit
    participant G as GitHub Actions
    participant H as Helm
    participant K as Kubernetes
    C->>G: Developer pushes a commit
    G->>G: GitHub Actions extracts the commit message
    Note over G: GitHub Actions checks if the commit message starts with [v1]
    alt Commit message starts with [v1]
        G->>H: GitHub Actions tells Helm to update the app without changing the v2 image
        Note over G: The v2 image remains the same
    else Commit message does not start with [v1]
        G->>H: GitHub Actions tells Helm to update the app and change the v2 image
        Note over G: The v2 image is updated to the new version
    end
    H->>K: Helm deploys or updates the Kubernetes resources
    G->>K: GitHub Actions checks the status of the deployments
Loading

App deployment flow - in this diagram

User Request Flow

  1. User sends a request to the Load Balancer.
  2. Load Balancer routes the request to the Kubernetes Service.
  3. Kubernetes Service routes the request to the Spring Boot App.
  4. Spring Boot App queries the Database.
  5. Database returns data to the Spring Boot App.
  6. Spring Boot App checks the Feature Flag.
  7. Feature Flag returns the flag status to the Spring Boot App.
  8. Spring Boot App checks the Redis Cache.
  9. Redis Cache returns the session data to the Spring Boot App.
  10. Spring Boot App returns the response to the User.

Deployment Process

  1. App Startup deploys the Database.
  2. Canary Deployment spins up new pods.
  3. Rollback triggers a Canary Deployment.
  4. Canary Deployment deploys the previous stable Docker image.
  5. Canary Deployment reverts database changes.
  6. Promote deploys to all pods.

Monitoring and Issue Resolution

  1. Monitoring alerts the Ops Team.
  2. Ops Team fixes issues.
  3. Rollback/Canary Deployment deploys the fix.
  4. New Pods verifies the fix.
  5. Monitoring verifies the fix.
graph LR
    A[User] -->|Sends Request| B[Load Balancer]
    B -->|Routes Request| C[Kubernetes Service]
    C -->|Routes to Pod| D[Spring Boot App]
    D -->|Queries| E[Database]
    E -->|Returns Data| D
    D -->|Checks| F[Feature Flag]
    F -->|Returns Flag Status| D
    D -->|Checks| G[Redis Cache]
    G -->|Returns Session Data| D
    D -->|Returns Response| A
    H[App Startup] -->|Deploys Database| E
    I[Canary Deployment] -->|Spins Up New Pods| C
    J[Rollback] -->|Triggers Canary Deployment| K[Canary Deployment]
    K -->|Deploys Previous Stable Docker Image| L[New Pods]
    K -->|Reverts Database Changes| M[Database Deployment]
    N[Promote] -->|Deploys to All Pods| C
    O[Monitoring] -->|Alerts| P[Ops Team]
    P -->|Fixes Issues| Q[Rollback/Canary Deployment]
    Q -->|Deploys Fix| R[New Pods]
    R -->|Verifies Fix| S[Monitoring]
    style A fill:#f9d,stroke:#333,stroke-width:4px
    style B fill:#ccf,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5
    style C fill:#ff9,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5
    style D fill:#9f6,stroke:#333,stroke-width:2px,stroke-dasharray: 5, 5
    style E fill:#9f6,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5
    style F fill:#cfc,stroke:#333,stroke-width:2px
    style G fill:#6cf,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5
    style H fill:#f6c,stroke:#333,stroke-width:2px
    style I fill:#6fc,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5
    style J fill:#cf6,stroke:#333,stroke-width:2px
    style K fill:#6cf,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5
    style L fill:#f6c,stroke:#333,stroke-width:2px
    style M fill:#6fc,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5
    style N fill:#cf6,stroke:#333,stroke-width:2px
    style O fill:#6cf,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5
    style P fill:#f6c,stroke:#333,stroke-width:2px
    style Q fill:#6fc,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5
    style R fill:#cf6,stroke:#333,stroke-width:2px
    style S fill:#6cf,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5
Loading

GitFlow Diagram

graph TB
  A[Local Branch] -->|pull request| B((Main Branch))
  B --> C{GitHub Actions Workflow}
  C -->|Build| D[GitHub Artifacts/Container Registry]
  C -->|Infrastructure Build| E[K8s Configuration]
  D --> F{GitHub Actions Test Job}
  E --> F
  F -->|tests pass| G[Unit Tests]
  G -->|tests pass| H[Merge to Main Branch]
  H --> I[Deployment Approval]
  I --> J[Canary Deployment]
  J -->|monitoring| K{Decision Point}
  K -->|rollback| L[Revert Commit]
  K -->|promote| M[Full Deployment]
  style A fill:#f9d,stroke:#333,stroke-width:4px
  style B fill:#ccf,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5
  style C fill:#ff9,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5
  style D fill:#9f6,stroke:#333,stroke-width:2px,stroke-dasharray: 5, 5
  style E fill:#9f6,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5
  style F fill:#cfc,stroke:#333,stroke-width:2px
  style G fill:#6cf,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5
  style H fill:#f6c,stroke:#333,stroke-width:2px
  style I fill:#6fc,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5
  style J fill:#cf6,stroke:#333,stroke-width:2px
  style K fill:#6cf,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5
  style L fill:#f6c,stroke:#333,stroke-width:2px
  style M fill:#6fc,stroke:#f66,stroke-width:2px,stroke-dasharray: 5, 5
Loading