Skip to content

sero583/java_survey_app-cloud_computing_2025

Repository files navigation

Java Survey App

A QR code-based survey application with anonymous access, built with Java, Docker, and PostgreSQL.

Java Spring Boot PostgreSQL Docker License: MIT

CI Status Tests Coverage Release

Table of Contents

Introduction

Create and share surveys instantly—no registration required. This application allows anyone to create yes/no question surveys, share them via QR code or link, and view real-time results in an admin dashboard.

Key highlights:

  • Anonymous survey creation and participation
  • Instant QR code and shareable link generation
  • Real-time results with interactive charts
  • Containerized deployment with load balancing

Features

  • No registration required: Anyone can create and share surveys.
  • Custom Yes/No questions: Add as many questions as you like.
  • QR Code & Link Sharing: Instantly share your survey via QR code or URL.
  • Admin Dashboard: View real-time results and close surveys.
  • Graphical Results: Visualize responses with charts.
  • Secure Admin Access: Each survey has a unique admin link for management.
  • Responsive UI: Built with Materialize CSS and Thymeleaf.

Screenshots

Survey Creation

Create surveys with custom yes/no questions without registration.

Survey Creation

QR Code & Link Generation

Each survey generates a unique QR code and shareable link instantly.

QR Code Generation

Participant View

Survey participants can easily answer questions through a clean, responsive interface.

Participant View

Submission Confirmation

Users receive immediate confirmation after submitting their responses.

Submission Confirmation

Admin Dashboard & Results

View real-time results with interactive charts and close surveys when complete.

Admin Dashboard

Architecture

The application uses a containerized, load-balanced architecture with network isolation.

System Components

  • Backend: Java 21, Spring Boot 3.5, Spring Data JPA, PostgreSQL.
  • Frontend: Thymeleaf templates, Materialize CSS, Chart.js for results.
  • QR Code Generation: ZXing library.
  • Load Balancing: HAProxy 2.7 with round-robin distribution and health checks.
  • Monitoring: Spring Boot Actuator for health checks and observability.
  • Containerization: Docker & Docker Compose with multi-stage builds for optimized images.
  • Persistence: PostgreSQL (configurable via environment variables).
  • Build Tool: Maven.
  • Security: Non-root container users, resource limits, health monitoring.

Tech Stack

Category Technologies
Backend Java 21, Spring Boot 3.5, Spring Data JPA, Spring Boot Actuator
Database PostgreSQL
Frontend Thymeleaf, Materialize CSS, Chart.js
QR Codes ZXing (Zebra Crossing)
Load Balancer HAProxy 2.7 (with health checks)
Containerization Docker, Docker Compose (multi-stage builds)
Build Tool Maven
Monitoring Spring Boot Actuator (health, info endpoints)

Configuration

The application uses src/main/resources/application.properties for configuration. You can override settings using environment variables:

  • APP_BASE_URL – The base URL for generating links (default: http://localhost)
  • DB_URL, DB_USERNAME, DB_PASSWORD – PostgreSQL connection details

Example .env file:

APP_BASE_URL=http://localhost
DB_URL=jdbc:postgresql://database:5432/surveydb
DB_USERNAME=postgres
DB_PASSWORD=test123

Deployment Architecture

The application uses a containerized, load-balanced architecture with the following components:

  • Load Balancer (HAProxy): Routes traffic to webserver instances on port 80 with health checks
  • Webserver1 & Webserver2: Two Spring Boot application instances for high availability (with health monitoring via Actuator)
  • Database: PostgreSQL container with persistent storage and health checks
  • Network Isolation: Separate networks for app and database communication
  • Resource Limits: CPU and memory limits on all containers for production stability
  • Health Monitoring: Automated health checks on all services with HAProxy integration
                    ┌──────────────┐
                    │  HAProxy :80 │
                    └──────┬───────┘
                           │
              ┌────────────┴────────────┐
              │                         │
      ┌───────▼────────┐       ┌───────▼────────┐
      │ Webserver1     │       │ Webserver2     │
      │ :8080          │       │ :8081          │
      └───────┬────────┘       └───────┬────────┘
              │                         │
              └────────────┬────────────┘
                           │
                   ┌───────▼────────┐
                   │  PostgreSQL    │
                   │  :5432         │
                   └────────────────┘

Getting Started

Prerequisites

For Docker deployment:

  • Docker & Docker Compose

For local development:

  • Java 21 JDK
  • Maven
  • PostgreSQL

Docker Deployment (Recommended)

Start the complete stack with HAProxy load balancer, two Spring Boot instances, and PostgreSQL:

docker compose up

Access points:

Rebuild after code changes:

docker compose up --build

Stop all containers:

docker compose down

Local Development

For development without Docker, you need Java 21, Maven, and PostgreSQL installed locally.

# Compile
mvn compile

# Run tests
mvn verify

# Run the application (requires PostgreSQL)
mvn spring-boot:run

Application will be available at http://localhost:8080

Note: You must configure PostgreSQL connection in application.properties or via environment variables. For most use cases, Docker deployment is recommended.

Usage

Once the application is running, follow these steps:

1. Create a Survey

  1. Navigate to http://localhost
  2. Enter your yes/no questions (add as many as you like)
  3. Click "Start Survey"

2. Share the Survey

  • Copy the generated public link and share it with participants
  • Or share the QR code (can be scanned with any smartphone)

3. Collect Responses

  • Participants access the survey via the link or QR code
  • They answer the yes/no questions
  • Responses are stored in real-time

4. View Results

  • Use the admin link provided when creating the survey
  • View interactive charts showing response distribution
  • Close the survey when complete (button becomes disabled)

5. Health Monitoring

  • Check application health: http://localhost:8080/actuator/health
  • HAProxy automatically monitors backend health and removes unhealthy instances from rotation
  • Docker health checks ensure containers restart automatically if they become unhealthy

Development Notes

  • Ensure PostgreSQL is running and configured as specified in application.properties
  • You can adjust server settings (like port) in src/main/resources/application.properties
  • For development, ensure your IDE has annotation processing enabled for Lombok support
  • The application uses environment variables for configuration (see Configuration section)
  • Health endpoint is available at /actuator/health for monitoring and health checks
  • Multi-stage Docker builds optimize image size (JRE-only runtime, ~300MB vs ~800MB for full JDK)

Testing and Coverage

This project includes a comprehensive test suite (unit, controller, repository, and end-to-end tests) and enforces a minimum code coverage threshold via JaCoCo.

  • Run tests and coverage (no Docker required; tests use H2 in-memory DB):

    Windows:

     .\mvnw.cmd verify

    Linux/macOS:

     ./mvnw verify
  • View the HTML coverage report after the run:

    • Open target/site/jacoco/index.html in your browser.
  • Artifacts/locations:

    • Test reports: target/surefire-reports/
    • Coverage report (HTML/XML/CSV): target/site/jacoco/

Notes:

  • Controller tests use standalone MockMvc with Mockito (fast, no full context).
  • Integration/E2E tests run on a Spring context with H2 and MockMvc; they don’t require Docker.
  • The coverage rule is currently set to 80% line coverage at the bundle level and is passing.

Troubleshooting

Docker compose up fails on Windows with port 80 in use

  • Symptom: docker compose up exits quickly and the loadbalancer container logs show a bind error for *:80.

  • Cause: Port 80 is often reserved by IIS/HTTP.sys on Windows.

  • Fix options:

    • Run Docker Desktop with elevated privileges and stop conflicting services, or
    • Use an override to map HAProxy to a non-privileged port (e.g., 8080). Create docker-compose.override.yml with:
     services:
       loadbalancer:
         ports:
           - "8080:80"

    Then access the app at http://localhost:8080 and, if needed, set APP_BASE_URL=http://localhost:8080.

Check container logs

  • Use docker compose logs -f loadbalancer or docker compose logs -f webserver1 to see detailed errors.
  • Verify database is up: docker compose logs -f database.

CI/CD

This repository uses GitHub Actions for continuous integration and automated releases with semantic versioning.

Continuous Integration

  • Workflow: .github/workflows/ci.yml
  • Triggers: Push and pull requests to main
  • Actions:
    • Builds with Java 21
    • Runs all 87 tests
    • Executes mvn verify with JaCoCo coverage check (80% minimum)
    • Updates dynamic badges (test count, coverage, CI status)
  • Status: See CI badge at top of README

Versioning System

The project uses semantic versioning that syncs with Git tags:

  • Development: Uses docker-compose.yml for local builds
  • Releases: Version extracted from Git tag (e.g., v1.2.3)
  • Docker tags: Images tagged with version (e.g., :v1.2.3) and :latest

Release Process

Workflow: .github/workflows/release-on-tag.yml

How to create a release:

# Tag with semantic version (e.g., v1.0.0, v2.1.3, v1.0.0-beta.1)
git tag -a v1.0.0 -m "Release v1.0.0: Initial production release"
git push origin v1.0.0

What happens automatically:

  1. Tests run first - Release aborts if any tests fail
  2. Docker images built and published to GitHub Container Registry:
    • ghcr.io/sero583/java_survey_app-cloud_computing_2025-webserver:v1.0.0
    • ghcr.io/sero583/java_survey_app-cloud_computing_2025-database:v1.0.0
    • Both also tagged as :latest
  3. Production-ready docker-compose-v1.0.0.yml generated and attached
  4. GitHub Release created with:
    • Auto-generated release notes
    • Docker Compose file for one-command deployment
    • Clear instructions for users

Release Artifacts:

Artifact Purpose
docker-compose-vX.X.X.yml Ready-to-use deployment file - just download and run
ghcr.io/.../webserver:vX.X.X Spring Boot application image
ghcr.io/.../database:vX.X.X PostgreSQL database image

View releases: GitHub Releases page

Deploying a Release

New users can deploy the app with just two commands:

Linux/macOS:

# Download the Docker Compose file for your chosen version
curl -sL https://github.com/sero583/java_survey_app-cloud_computing_2025/releases/download/v1.0.0/docker-compose-v1.0.0.yml -o docker-compose.yml

# Start the application
docker compose up -d

Windows PowerShell:

# Download the Docker Compose file for your chosen version
Invoke-WebRequest -Uri "https://github.com/sero583/java_survey_app-cloud_computing_2025/releases/download/v1.0.0/docker-compose-v1.0.0.yml" -OutFile "docker-compose.yml"

# Start the application
docker compose up -d

Then open http://localhost in your browser.

Local Testing

Test CI workflow:

Windows:

# With act (requires Docker)
act -j build

# Or run Maven directly
.\mvnw.cmd -B -ntp verify

Linux/macOS:

# With act (requires Docker)
act -j build

# Or run Maven directly
./mvnw -B -ntp verify

Build Docker images locally (all platforms):

# Build images from source
docker compose build

# Or build and run
docker compose up --build

Version Tagging Best Practices

Follow Semantic Versioning:

  • Major: Breaking changes (v2.0.0)
  • Minor: New features, backwards compatible (v1.1.0)
  • Patch: Bug fixes (v1.0.1)
  • Pre-release: Beta/RC versions (v1.0.0-beta.1, v1.0.0-rc.2)

Examples:

# First production release
git tag -a v1.0.0 -m "Release v1.0.0"

# Bug fix release
git tag -a v1.0.1 -m "Fix: QR code generation issue"

# New feature release
git tag -a v1.1.0 -m "Feature: Export results to CSV"

# Breaking change
git tag -a v2.0.0 -m "Breaking: New database schema"

Note: Always push tags after commits: git push origin <tag-name>

Production Deployment Considerations

For production deployment, the following enhancements should be implemented:

Security

  • HTTPS/TLS: Use Let's Encrypt or cloud provider certificates for SSL/TLS encryption
  • Secrets Management: Store database credentials in AWS Secrets Manager, Azure Key Vault, or HashiCorp Vault
  • CORS Configuration: Restrict allowed origins for API endpoints
  • Input Validation: Add comprehensive input sanitization and validation
  • Container Security: Non-root users in all containers
  • Resource Isolation: CPU and memory limits on all services

Scalability & Performance

  • Horizontal Scaling: Use Kubernetes or Docker Swarm for auto-scaling based on load
  • Database Connection Pooling: Fine-tune HikariCP configuration for optimal performance
  • Caching: Implement Redis for session management and frequently accessed data
  • CDN Integration: Serve static assets via CloudFront or similar CDN

Observability

  • Logging: Centralized logging with ELK Stack (Elasticsearch, Logstash, Kibana) or Splunk
  • Monitoring: Application metrics with Prometheus and Grafana (extend Actuator with Micrometer)
  • Distributed Tracing: Implement OpenTelemetry or Jaeger for microservices tracing
  • Health Checks: Implemented with Spring Boot Actuator and HAProxy integration
    • Application health endpoint: /actuator/health
    • Database connectivity monitoring
    • HAProxy backend health checks with automatic failover

High Availability

  • Load Balancing: Implemented with HAProxy round-robin and health-based routing
  • Database Replication: PostgreSQL primary-replica setup with automatic failover
  • Load Balancer Redundancy: Multiple HAProxy instances or managed cloud load balancers
  • Backup & Recovery: Automated database backups with point-in-time recovery
  • Circuit Breakers: Implement Resilience4j for fault tolerance

License

This project is licensed under the MIT License - see the LICENSE file for details.

Author

Serhat Güler@sero583


Originally developed for the Cloud Computing course (SS2025), enhanced and published as a portfolio project.

About

A QR code-based survey application with anonymous access, built with Java, Docker, and PostgreSQL.

Resources

License

Stars

Watchers

Forks

Packages