A Java-based REST API system that accepts and processes EMAIL, SMS, and PUSH notification events asynchronously. Events are handled in separate FIFO queues and callbacks are sent to clients on completion.
To build a simple, scalable notification system with asynchronous processing using Java and Spring Boot, complete with Docker support, callback integration, graceful shutdown, and unit testing.
- Accepts notification events via REST API (
/api/events) - Processes EMAIL, SMS, and PUSH events in separate FIFO queues
- Simulated processing delays (EMAIL: 5s, SMS: 3s, PUSH: 2s)
- Simulates random failure (10% of events)
- Sends HTTP POST callback on success/failure
- Graceful shutdown (finishes in-progress tasks before exit)
- Fully Dockerized
- JUnit-based unit testing
| Technology | Purpose |
|---|---|
| Java 17 | Programming language |
| Spring Boot 3 | REST API and background task management |
| Maven | Project and dependency management |
| WebClient | Async HTTP client for callbacks |
| Docker | Containerization |
| Docker Compose | Local multi-service environment |
| JUnit 5 | Unit testing |
- π§ Sends email
- β± 5 seconds simulated processing time
Payload Example
{
"eventType": "EMAIL",
"payload": {
"recipient": "user@example.com",
"message": "Welcome to our service!"
},
"callbackUrl": "http://client.com/callback"
}- π± Sends SMS
- β± 3 seconds simulated processing time
Payload Example
{
"eventType": "SMS",
"payload": {
"phoneNumber": "+919876543210",
"message": "Your OTP is 123456"
},
"callbackUrl": "http://client.com/callback"
}- π Sends push notification to device
- β± 2 seconds simulated processing time
Payload Example
{
"eventType": "PUSH",
"payload": {
"deviceId": "xyz-abc-123",
"message": "Your order is out for delivery"
},
"callbackUrl": "http://client.com/callback"
}Once processing completes, your system will receive an HTTP POST request to the callback URL.
{
"eventId": "e123",
"status": "COMPLETED",
"eventType": "EMAIL",
"processedAt": "2025-07-01T12:34:56Z"
}{
"eventId": "e123",
"status": "FAILED",
"eventType": "SMS",
"errorMessage": "Simulated processing failure",
"processedAt": "2025-07-01T12:34:56Z"
}Submits a new notification event for asynchronous processing and delivery.
{
"eventType": "EMAIL",
"payload": {
"recipient": "user@example.com",
"message": "Welcome to the service!"
},
"callbackUrl": "http://client.com/callback"
}π Note
- eventType:
"EMAIL","SMS","PUSH"- payload: Varies based on
eventType- callbackUrl: For receiving async delivery status updates
{
"eventId": "e123",
"message": "Event accepted for processing."
}./mvnw clean install -DskipTests
java -jar target/event-notification-system-1.0.0.jarVisit: http://localhost:8080/api/events
docker compose up --build./mvnw testTest coverage includes:
- Event creation & routing
- FIFO queueing per event type
- Callback delivery
- Graceful shutdown
- Simulated failures
Event-Notification-System/
βββ src/
β βββ main/
β β βββ java/com/sprih/eventnotificationsystem/
β β β βββ controller/ # REST endpoints
β β β βββ dto/ # Request/response data transfer objects
β β β βββ enums/ # Enum definitions
β β β βββ service/ # Service interfaces and implementations
β β β βββ util/ # Utility classes
β β β βββ config/ # Configuration
β β β βββ EventNotificationApplication.java # Main Spring Boot application
β β βββ resources/
β β βββ application.yml # Spring Boot app configuration
β β
β βββ test/java/com/sprih/eventnotificationsystem/
β βββ controller/ # Unit tests for controllers
β βββ service/ # Unit tests for services
β βββ ... # Other tests
β
βββ Dockerfile # Docker build definition
βββ docker-compose.yml # Docker multi-container setup
βββ pom.xml # Maven build and dependencies config
βββ README.md # Project documentation
- FIFO processing per event type
- Clear separation of concerns
- Fault-tolerant with retry-ready design
- Lightweight, Docker-ready deployment
- Easily testable with JUnit
| Test Case | Expected Outcome |
|---|---|
| Valid EMAIL event | Added to EMAIL queue, processed in FIFO |
| Invalid event type | Returns 400 Bad Request |
| Missing fields | Returns 400 Bad Request |
| Simulated failure | 10% events return FAILED |
| Callback triggered | POST sent to callback URL |
| Graceful shutdown | New requests rejected, queues drained |
| Thread cleanup | All threads shutdown cleanly |
We welcome contributions! To get started:
- Fork the repository
- Create a new branch:
git checkout -b feature/your-feature-name- Make your changes
- Commit your code:
git commit -m "Add new feature"- Push to your branch:
git push origin feature/your-feature-name- Submit a pull request β
This project is licensed under the MIT License.
Gajendra Ingle
Software Engineer | Pune, India
π§ Email: gajendraingle01@gmail.com
π GitHub: github.com/gajendra-ingle
πΌ LinkedIn: linkedin.com/in/gajendraingle