A Spring Boot application for managing the reservation and booking of any type of resources within an organization. This system provides a RESTful API for managing resources, users, bookings, and notifications, with a focus on secure access through Keycloak integration.
Note: This backend is part of a larger project available at cloud-resource-reservation, which includes the frontend, Keycloak configuration, and Docker Compose setup to run the complete system.
This system enables organizations to:
- Manage any type of resources, which are configurable through resource types
- Track resource status (active, maintenance, unavailable)
- Allow users to book resources for specific time periods
- Prevent booking conflicts through time-slot validation
- Manage users and roles via Keycloak integration
- Send and manage notifications to users
- Support hierarchical resource structures with parent-child relationships
- Store and manage SSH public keys for accessing resources
- Manage resources across different physical or logical locations (Sites).
- Support for Global Administrators and Site Administrators with scoped permissions.
- Notify external systems about booking events via Webhooks.
- Track important actions through Audit Logs.
The application follows a standard Spring Boot architecture:
- Controllers: REST API endpoints
- Services: Business logic layer
- Repositories: Data access layer
- Models: Data entities
- DTOs: Data transfer objects
- Configuration: System configuration
The application uses OAuth2/OpenID Connect authentication through Keycloak:
- JWT-based authentication
- Role-based authorization (
global_admin,site_admin,USERroles) - Fine-grained method-level security
- Development mode with simplified authentication
- Java 17+
- Maven
- Database (H2 for dev, PostgreSQL for test, Oracle for production)
- Keycloak server (optional for development)
The application has different configuration profiles:
- dev: Uses H2 in-memory database and mocked Keycloak service for quick local development
- test: Uses PostgreSQL and Keycloak, designed for running in Docker Compose environment
- pro: Uses Oracle database and requires a running Keycloak server for production deployment
Maven profiles are aligned with Spring profiles to ensure proper dependency management:
- dev (default): Includes H2 dependencies
- test: Includes PostgreSQL dependencies
- pro: Includes Oracle JDBC dependencies
For quick setup and testing on your local machine, use the dev profile:
./mvnw spring-boot:run -Dspring-boot.run.profiles=dev -PdevTo run the application in a containerized environment with PostgreSQL and Keycloak, use the test profile.
The Docker Compose project for running the entire stack is available at:
https://github.com/giovannimirarchi420/cloud-resource-reservation
Run with:
./mvnw spring-boot:run -Dspring-boot.run.profiles=test -PtestFor production deployment with Oracle database and Keycloak integration:
./mvnw spring-boot:run -Dspring-boot.run.profiles=pro -PproThe application supports multiple databases based on profile:
- H2 in-memory database for development (
devprofile) - PostgreSQL for testing in Docker Compose (
testprofile) - Oracle for production (
proprofile)
Database migrations are handled automatically through Hibernate.
When using the Docker Compose setup from the parent repository, the Keycloak configuration is performed automatically with pre-configured realm, client, and roles.
If you're setting up Keycloak manually:
- Install and run Keycloak server
- Create a new realm called
resource-management - Create a client called
resource-management-app - Configure the client settings according to your environment
- Create the required roles:
ADMINandUSER
All API endpoints (except for swagger documentation) require authentication. The application uses OAuth2 with JWT tokens from Keycloak.
Most endpoints return data in a standard format:
{
"success": true|false,
"message": "Operation result message",
"data": { ... } // Optional response data
}Resources represent any physical or virtual assets that can be booked, configurable through resource types.
GET /resources
Optional query parameters:
status: Filter by resource status (ACTIVE, MAINTENANCE, UNAVAILABLE)typeId: Filter by resource type ID
GET /resources/{id}
POST /resources
{
"name": "Resource XYZ",
"specs": "Specifications for the resource",
"location": "Location identifier",
"status": "ACTIVE",
"typeId": 1
}PUT /resources/{id}
PATCH /resources/{id}/status?status=MAINTENANCE
DELETE /resources/{id}
GET /resources/search?query=term
Resource types categorize resources and are fully configurable.
GET /resource-types
GET /resource-types/{id}
POST /resource-types
{
"name": "Custom Resource Type",
"color": "#1976d2"
}PUT /resource-types/{id}
DELETE /resource-types/{id}
Events represent resource bookings for a specific time period.
GET /events
Optional query parameters:
resourceId: Filter by resource IDstartDate: Filter by start dateendDate: Filter by end date
GET /events/my-events
GET /events/{id}
POST /events
{
"title": "Resource reservation",
"description": "Purpose of booking",
"resourceId": 1,
"start": "2023-04-01T09:00:00",
"end": "2023-04-01T17:00:00"
}PUT /events/{id}
DELETE /events/{id}
GET /events/check-conflicts?resourceId=1&start=2023-04-01T09:00:00&end=2023-04-01T17:00:00
GET /events/check-resource-availability?resourceId=1
Provides user management capabilities.
GET /users
GET /users/{id}
GET /users/me
POST /users
{
"username": "johndoe",
"email": "john@example.com",
"firstName": "John",
"lastName": "Doe",
"password": "securePassword",
"roles": ["USER"]
}PUT /users/{id}
PUT /users/me
{
"firstName": "John",
"lastName": "Doe",
"email": "john@example.com",
"avatar": "JD"
}DELETE /users/{id}
GET /users/by-role/{role}
GET /users/me/ssh-key
PUT /users/me/ssh-key
{
"sshPublicKey": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQ...user@example.com"
}DELETE /users/me/ssh-key
Manage physical or logical locations for resources.
GET /sites
GET /sites/{id}
POST /sites
{
"name": "Site Name",
"location": "Site Location"
}PUT /sites/{id}
DELETE /sites/{id}
GET /sites/{siteId}/resources
POST /sites/{siteId}/admins
{
"userId": "user-keycloak-id"
}DELETE /sites/{siteId}/admins/{userId}
Configure webhooks to notify external systems about events (e.g., bookings).
GET /webhooks
GET /webhooks/{id}
POST /webhooks
{
"url": "https://external.system/webhook-endpoint",
"eventTypes": ["BOOKING_CREATED", "BOOKING_UPDATED", "BOOKING_DELETED"],
"secret": "optional-secret-for-verification",
"isActive": true
}PUT /webhooks/{id}
DELETE /webhooks/{id}
POST /webhooks/{id}/test
Track significant actions performed within the system.
GET /audit-logs
Optional query parameters:
userId: Filter by user IDaction: Filter by action type (e.g.,RESOURCE_CREATE,BOOKING_DELETE)startDate: Filter logs from this dateendDate: Filter logs up to this datepage,size: For pagination
System notifications to users.
GET /notifications
Optional query parameters:
unreadOnly: Filter to show only unread notifications (default: false)
GET /notifications/unread-count
PATCH /notifications/{id}/mark-read
PATCH /notifications/mark-all-read
DELETE /notifications/{id}
POST /notifications/send?userId=1&message=Your+message&type=INFO
API documentation is available through Swagger UI:
GET /api/swagger-ui.html
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details