Lorem ipsum text processor based on the loripsum.net API.
A Spring Boot microservices example showing how to fetch and process dummy text, publish results to Kafka, and expose a pageable reports history via REST. Includes Swagger UI, health checks, metrics, and a ready-to-run demo stack.
- Runtime: Java 21 (with Java 25 features), Spring Boot 3.5.6, Spring Framework 6.x
- Web Server: Undertow (replacing Tomcat for better performance)
- Messaging: Apache Kafka (Confluent 7.8.3) with Spring Kafka
- Database: PostgreSQL 16.6 with Liquibase migrations
- Caching: EhCache with Spring Cache abstraction
- Build Tool: Maven 3.x with multi-module structure
- Code Quality: Checkstyle, PMD, SpotBugs, Qulice
- Testing: JUnit 5, Testcontainers, WireMock, Spring Boot Test
- Code Coverage: JaCoCo (minimum 80% coverage)
- Monitoring: Micrometer with Prometheus metrics
- Logging: Logback with structured JSON logging (Logstash encoder)
- Tracing: Micrometer Tracing with Brave
- Dashboards: Grafana with pre-configured dashboards
- Code Analysis: SonarQube integration
- Containerization: Docker & Docker Compose
Module | Description | Default port | Main endpoint |
---|---|---|---|
words-processing |
Calls loripsum.net, analyzes text, publishes a report to Kafka and returns it | 8085 | GET /api/v1/text?p={1..10}&l={short,medium,long,verylong} |
reports-history |
Consumes reports from Kafka and stores in Postgres; exposes pageable history | 8086 | GET /api/v1/history?page=0&size=20&sort=id,desc |
- Words Processing API: http://localhost:8085/swagger-ui.html
- Reports History API: http://localhost:8086/swagger-ui.html
- Words Processing: http://localhost:8085/v3/api-docs
- Reports History: http://localhost:8086/v3/api-docs
- Development Guide: development.md - Detailed development setup and guidelines
- API Reference: api-reference.md - Complete API reference documentation
Run the pre-built images with all dependencies (Kafka, Postgres) in one go:
docker compose -f docker-compose.yml up
Once started:
- Words Processing API:
http://localhost:8085/api/v1/text
- Reports History API:
http://localhost:8086/api/v1/history
Example calls:
curl "http://localhost:8085/api/v1/text?p=2&l=short"
curl "http://localhost:8086/api/v1/history?page=0&size=10&sort=id,desc"
Stop the demo stack:
docker compose -f docker-compose.yml down
- Git: Version control
- JDK 21+: OpenJDK or Oracle JDK (Java 25 features supported)
- Docker & Docker Compose: For infrastructure services
- Maven 3.8+: Build tool (wrapper included)
- IDE: IntelliJ IDEA, VS Code, or Eclipse with Spring Boot support
- Records: Immutable DTOs and value objects
- Pattern Matching: Enhanced switch expressions
- Text Blocks: Improved string handling
- Sealed Classes: Restricted inheritance hierarchies
- Virtual Threads: Project Loom integration (when available)
Clone the repo:
git clone https://github.com/IQKV/sample-lorem.git
cd sample-lorem
docker compose -f compose.yaml up -d
This exposes Postgres on localhost:5432
and Kafka on localhost:9092
. Optional services: Prometheus, Grafana, SonarQube (see compose.yaml
).
./mvnw -q -DskipTests package
- Words Processing:
java -jar words-processing/target/*.jar
Open Swagger UI: http://localhost:8085/swagger-ui.html
- Reports History:
java -jar reports-history/target/*.jar
Open Swagger UI: http://localhost:8086/swagger-ui.html
curl "http://localhost:8085/api/v1/text?p=3&l=medium"
curl "http://localhost:8086/api/v1/history?page=0&size=5&sort=id,desc"
This repository follows a Maven aggregator pattern (packaging=pom
) with a clean separation of concerns:
sample-lorem (com.iqkv:sample-lorem:0.25.0-SNAPSHOT)
ββ shared/ # Common utilities, DTOs, Kafka configuration
β ββ sample-lorem-shared # Shared across all modules
ββ words-processing/ # Text processing microservice
β ββ sample-lorem-words-processing # Port 8085
ββ reports-history/ # Report storage microservice
ββ sample-lorem-reports-history # Port 8086
βββββββββββββββββββ ββββββββββββββββββββ
β words-processingβ β reports-history β
β β β β
β β’ REST API β β β’ REST API β
β β’ Text analysis β β β’ Kafka consumer β
β β’ Kafka producerβ β β’ PostgreSQL β
β β’ External API β β β’ JPA/Hibernate β
βββββββββββ¬ββββββββ βββββββββββ¬βββββββββ
β β
ββββββββ¬ββββββββββββββ¬βββ
β β
βββββββββΌββββββββββββββΌββββ
β shared β
β β
β β’ Common DTOs β
β β’ Kafka configuration β
β β’ Validation utilities β
β β’ OpenAPI documentation β
β β’ Actuator endpoints β
βββββββββββββββββββββββββββ
- Shared Module: Contains common utilities, DTOs, and configurations to avoid duplication
- Service Independence: Each service can be built, tested, and deployed independently
- Event-Driven Communication: Services communicate via Kafka for loose coupling
- Database per Service: Each service owns its data (reports-history uses PostgreSQL)
- Observability: All modules include Micrometer metrics and structured logging
- Build everything:
./mvnw -q clean install
- Build and run only
words-processing
, building its deps (-am
):
./mvnw -q -pl words-processing -am clean package
java -jar words-processing/target/*.jar
- Build and run only
reports-history
:
./mvnw -q -pl reports-history -am clean package
java -jar reports-history/target/*.jar
- Run tests with Testcontainers profile for all modules:
./mvnw verify -P use-testcontainers
- Limit actions to a module (e.g., unit tests only for
shared
):
./mvnw -q -pl shared test
- Start
words-processing
(build dependencies and run):
./mvnw -q -pl words-processing -am spring-boot:run
- Start
reports-history
:
./mvnw -q -pl reports-history -am spring-boot:run
- Optionally enable the
dev
profile while running:
./mvnw -q -pl words-processing -am spring-boot:run -Dspring-boot.run.profiles=dev
./mvnw -q -pl reports-history -am spring-boot:run -Dspring-boot.run.profiles=dev
dev
: adds Spring Boot DevTools to the service modulesuse-testcontainers
: enables embedded Kafka/Postgres testinguse-qulice
: enables additional static analysis checks
Applications support environment variables (see words-processing/src/main/resources/application.yml
and reports-history/src/main/resources/application.yml
). Common ones:
Variable | Description | Default |
---|---|---|
SERVER_PORT |
HTTP port | 8085 (words), 8086 (history) |
KAFKA_BOOTSTRAP_SERVERS |
Kafka broker list | localhost:9092 |
KAFKA_SECURITY_PROTOCOL |
Security protocol | PLAINTEXT |
KAFKA_TOPIC_WORDS_PROCESSED |
Topic for processed reports | words.processed |
KAFKA_TOPIC_PARTITIONS_WORDS_PROCESSED |
Topic partitions | 4 |
KAFKA_CONSUMER_THREADS |
Consumer threads (history) | 4 |
KAFKA_CONSUMERS_GROUP |
Consumer group (history) | reports-history |
KAFKA_ADMIN_CREATES_TOPICS |
Auto-create topics on startup | true |
DATASOURCE_URL |
JDBC URL (history) | jdbc:postgresql://localhost:5432/lorem_db |
DATASOURCE_USERNAME |
DB username (history) | postgres |
DATASOURCE_PASSWORD |
DB password (history) | postgres |
- Input Validation: Bean Validation (JSR-303) with custom validators
- CORS Configuration: Configurable cross-origin resource sharing
- Actuator Security: Production-ready endpoint security
- Dependency Scanning: OWASP dependency check integration
# Check for security vulnerabilities
./mvnw org.owasp:dependency-check-maven:check
# Security headers validation
curl -I http://localhost:8085/api/v1/text
- Development: Relaxed CORS, debug endpoints enabled
- Production: Strict CORS, minimal actuator endpoints, HTTPS only
- Application Metrics: Custom business metrics via Micrometer
- JVM Metrics: Memory, GC, thread pools automatically exposed
- Database Metrics: Connection pool, query performance via Hibernate
- Kafka Metrics: Producer/consumer lag, throughput metrics
# Start monitoring infrastructure
docker compose -f compose.yaml up -d prometheus grafana
# Access dashboards
open http://localhost:3000 # Grafana (admin/changeme)
open http://localhost:9090 # Prometheus
- Application Overview: Request rates, response times, error rates
- JVM Monitoring: Memory usage, GC performance, thread metrics
- Database Performance: Connection pools, query execution times
- Kafka Monitoring: Topic throughput, consumer lag, partition metrics
- Structured Logging: JSON format with correlation IDs
- Log Levels: Environment-specific configuration
- Centralized Logging: Loki integration available
# Run all tests with Testcontainers
./mvnw verify -P use-testcontainers
# Run only unit tests
./mvnw test
# Run integration tests
./mvnw integration-test
# Generate coverage report
./mvnw jacoco:report
- Unit Tests: JUnit 5, Mockito, Hamcrest
- Integration Tests: Spring Boot Test, Testcontainers (PostgreSQL, Kafka)
- API Testing: MockMvc, WireMock for external service mocking
- Architecture Tests: ArchUnit for enforcing architectural constraints
- Minimum Code Coverage: 80% (enforced by JaCoCo)
- Branch Coverage: 85% minimum
- Mutation Testing: Available via PIT testing
- Static Analysis: Checkstyle, PMD, SpotBugs
- Undertow Server: Non-blocking I/O for better throughput
- Connection Pooling: HikariCP for optimal database connections
- Caching Strategy: EhCache for frequently accessed data
- Kafka Partitioning: 4 partitions for parallel processing
# Application metrics
curl http://localhost:8085/actuator/metrics
curl http://localhost:8086/actuator/metrics
# Health checks
curl http://localhost:8085/actuator/health
curl http://localhost:8086/actuator/health
# Prometheus metrics
curl http://localhost:8085/actuator/prometheus
- Horizontal Scaling: Stateless services support multiple instances
- Database Scaling: Read replicas supported via Spring profiles
- Kafka Consumer Groups: Multiple consumer instances for load distribution
- Caching: Distributed caching ready (Redis integration available)
The code follows the Google Java Style and is checked by Checkstyle, PMD, and SpotBugs. Optional SonarQube is available in compose.yaml
.
The project includes Cursor Editor rules for consistent development practices:
- Java Language Best Practices: Rules for code style, performance, security, and testing to ensure clean, maintainable, and efficient Java code.
- Spring Boot Best Practices: Guidelines for proper implementation of Spring Boot patterns, dependency injection, configuration, and RESTful API design.
These rules are available in the .cursor/rules
directory and are automatically applied when using the Cursor Editor.
# Clear Maven cache
./mvnw dependency:purge-local-repository
# Skip tests if needed
./mvnw clean install -DskipTests
# Check for dependency conflicts
./mvnw dependency:tree
# Check application health
curl http://localhost:8085/actuator/health
curl http://localhost:8086/actuator/health
# View application logs
docker logs lorem-demo-words-processing
docker logs lorem-demo-reports-history
# Check Kafka connectivity
docker exec -it lorem-demo-kafka kafka-topics --bootstrap-server localhost:9092 --list
# Connect to PostgreSQL
docker exec -it lorem-demo-postgres psql -U postgres -d lorem_db
# Check database migrations
./mvnw liquibase:status -pl reports-history
# Reset database (development only)
docker compose -f compose.yaml down -v
docker compose -f compose.yaml up -d postgres
# JVM tuning for containers
export JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0"
# Enable virtual threads (Java 21+)
export JAVA_OPTS="$JAVA_OPTS --enable-preview"
# Database connection tuning
export DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE=20
export DATASOURCE_HIKARI_MINIMUM_IDLE=5
# Clean build artifacts
./mvnw clean
# Stop and remove containers
docker compose -f compose.yaml down
# Remove volumes (data loss!)
docker compose -f compose.yaml down -v
# Clean Docker system
docker system prune -f
# Health check endpoints
curl http://localhost:8085/actuator/health/liveness
curl http://localhost:8086/actuator/health/readiness
# Graceful shutdown
curl -X POST http://localhost:8085/actuator/shutdown
curl -X POST http://localhost:8086/actuator/shutdown
# Log rotation and cleanup
find logs/ -name "*.log" -mtime +7 -delete
Licensed under the Apache License, Version 2.0. See LICENSE.