Small event-processing microservice core showing:
- EventRouter -> EventHandler
- DependencyClient calls with retry discipline
- Retry only on transient failures
- Exponential backoff + jitter (avoid retry storms)
- Idempotency cache by eventId
- Metrics: events.success, events.failure, per-action metrics
- Java 17
- Maven 3.8+
mvn test
mvn -q -DskipTests package
java -cp target/event-processing-1.0-SNAPSHOT.jar com.microservice.eventprocessing.App
## Notes
TransientDependencyException => retryable
PermanentDependencyException => NOT retryable (fail fast)
IdempotencyCache prevents duplicate processing by eventId
## Submit event (local)
curl -X POST http://localhost:8080/events \
-H "Content-Type: application/json" \
-d '{"eventId":"evt-1001","type":"PAYMENT","action":"payment.charge","payloadJson":"{\"amount\":25}"}'
## Metrics endpoints
http://localhost:8080/actuator/health
http://localhost:8080/actuator/metrics
http://localhost:8080/actuator/metrics/events.success
http://localhost:8080/actuator/metrics/events.failure
http://localhost:8080/actuator/metrics/events.action.success
http://localhost:8080/actuator/metrics/events.action.failure
What each component is doing (short and practical)
EventController: entry point for local testing (stands in for Kafka consumer).
EventRouter: core orchestration (idempotency → route → retry → metrics).
EventHandler: per-domain logic (PAYMENT/PROFILE) calling dependencies.
DependencyClient: external call boundary (where transient vs permanent errors happen).
RetryPolicy: retries only TransientDependencyException with max attempts + backoff + jitter.
IdempotencyCache: blocks duplicates by eventId (exactly-once behavior at the business level).
MetricsRecorder: records events.success, events.failure, and per-action counters.
## http://localhost:8080/events -> (same eventId) → you’ll get DUPLICATE_IGNORED