Spring Boot REST API for managing hotels, rooms, bookings, and cached room availability with MySQL persistence, Redis caching, JWT authentication, and OAuth2 login support via Keycloak and Google.
This release keeps the hotel-management workflow intact while refreshing the security layer, extending the domain model, and adding a persistent audit trail. The application supports Keycloak-backed JWT/resource-server access, Google OAuth2 login, Redis-backed room availability, and role-based endpoint protection through Spring Security annotations.
| Layer | Responsibility |
|---|---|
| API layer | Exposes hotel, room, user, and booking endpoints |
| Domain layer | Models hotels, rooms, users, and booking lifecycle states |
| Security layer | Uses JWT, OAuth2 login, and method-level authorization |
| Cache layer | Caches room-availability lookups in Redis and invalidates them on booking changes |
| Audit layer | Persists booking and security-sensitive actions in an audit log |
| Persistence layer | Stores hotel, room, user, and booking data in MySQL |
| View layer | Provides a Thymeleaf login page for browser sign-in |
- Spring Boot REST API setup
- Spring Data JPA repository pattern
- MySQL-backed persistence
- Spring Security with JWT resource-server support
- OAuth2 login with Keycloak
- OAuth2 login support for Google
- Method-level authorization with
@PreAuthorize - Public user registration and user listing
- Hotel creation, retrieval, listing, and deletion endpoints
- Room management for hotel inventory
- Booking creation with request/confirm/reject statuses
- Date-range validation for room availability
- Concurrency-safe booking writes using a locked room lookup
- Redis-backed caching for room availability searches
- Cache invalidation when rooms or bookings change
- Persistent audit logging for login, profile access, CRUD, and booking actions
/logincustom page backed by Thymeleaf- Google user authority mapping from the local user table
- Java 17
- Spring Boot 3.3
- Spring Web
- Spring Data JPA
- Spring Security
- Spring Validation
- Spring OAuth2 Client
- Spring OAuth2 Resource Server
- Spring Cache
- Thymeleaf
- Redis
- MySQL
- Hibernate/JPA auditing patterns
- Maven
- Lombok
- JJWT
hotel/
├── CHANGELOG.md
├── README.md
├── pom.xml
├── mvnw
├── mvnw.cmd
└── src/
└── main/
├── java/com/cn/hotelDemo/
│ ├── config/
│ ├── controller/
│ ├── dto/
│ ├── model/
│ ├── repository/
│ ├── service/
│ └── HotelDemoApplication.java
└── resources/
├── application.yml
└── templates/
└── login.html
- Open a terminal in the project root.
- Update MySQL, Redis, Keycloak, and Google client settings in
src/main/resources/application.ymlif needed. The Google entries are placeholders in the published template, and Redis defaults tolocalhost:6379. - Run
mvn test. - Run
mvn spring-boot:run. - Open
http://localhost:8082/loginfor the custom login page. - Use the API under
http://localhost:8082.
Available endpoints:
GET /loginGET /hotel/userDetailPOST /hotel/createGET /hotel/id/{id}GET /hotel/getAllDELETE /hotel/remove/id/{id}POST /hotel/rooms/createGET /hotel/rooms/id/{id}GET /hotel/rooms/hotel/{hotelId}GET /hotel/rooms/hotel/{hotelId}/available?checkInDate=YYYY-MM-DD&checkOutDate=YYYY-MM-DDGET /hotel/rooms/getAllPOST /hotel/bookings/createGET /hotel/bookings/id/{id}GET /hotel/bookings/getAllGET /hotel/bookings/user/{userId}GET /hotel/bookings/hotel/{hotelId}GET /audit/getAllGET /user/getUsersGET /user/getUsers/{id}POST /user/createUserDELETE /user/remove/id/{id}
Access notes:
/loginis public.GET /hotel/id/{id}is forNORMALusers.POST /hotel/create,GET /hotel/getAll, andDELETE /hotel/remove/id/{id}are restricted to admin-style access.POST /hotel/rooms/createandGET /hotel/rooms/getAllare admin-only operations.GET /audit/getAllis admin-only.GET /hotel/bookings/getAllandGET /hotel/bookings/hotel/{hotelId}are admin-only operations.POST /hotel/bookings/createis available to authenticated hotel users.GET /hotel/userDetailuses the authenticated OIDC principal.- Google login uses local user-role mapping from the MySQL user table.
Example user registration body:
{
"username": "john",
"password": "john123",
"email": "john@example.com",
"role": "NORMAL"
}Example hotel creation body:
{
"name": "Sea View Inn",
"rating": 8,
"city": "Goa"
}Example room creation body:
{
"hotelId": 1,
"roomNumber": "101",
"roomType": "Deluxe",
"capacity": 2,
"nightlyRate": 4500.00,
"status": "AVAILABLE"
}Example room availability check:
GET /hotel/rooms/hotel/1/available?checkInDate=2026-06-05&checkOutDate=2026-06-08
Example booking creation body:
{
"hotelId": 1,
"roomId": 1,
"userId": 2,
"checkInDate": "2026-06-05",
"checkOutDate": "2026-06-08",
"guestCount": 2,
"specialRequests": "Late check-in"
}Example booking response:
{
"bookingReference": "BOOK-1A2B3C4D",
"status": "CONFIRMED",
"message": "Booking confirmed successfully",
"bookingId": 10
}flowchart LR
Browser[Browser/User] --> Login["GET /login"]
Login --> Keycloak["Keycloak OIDC"]
Login --> Google["Google OIDC"]
Keycloak --> Token["JWT / OIDC claims"]
Google --> Token
Token --> Security["HotelSecurityConfig"]
Security --> RoleMap["Role mapping from token + local user table"]
RoleMap --> Secured["@PreAuthorize protected endpoints"]
Secured --> Audit["Audit log entry"]
flowchart LR
Guest[Authenticated Guest] --> BookingRequest["POST /hotel/bookings/create"]
BookingRequest --> RoomLock["Pessimistic room lock"]
RoomLock --> Availability["Date-range overlap check"]
Availability -->|available| Confirmed["CONFIRMED booking"]
Availability -->|conflict| Rejected["REJECTED booking"]
Confirmed --> CacheEvict["Evict room-availability cache"]
Rejected --> CacheEvict
Confirmed --> Audit["Audit log entry"]
Rejected --> Audit
Confirmed --> Persist["Persist booking + booking reference"]
Rejected --> Persist
flowchart LR
Guest[Authenticated Guest] --> UserAPI["/user/*"]
Guest --> HotelAPI["/hotel/*"]
Guest --> AuditAPI["/audit/*"]
HotelAPI --> Hotels["Hotel"]
HotelAPI --> Rooms["Room inventory"]
HotelAPI --> Bookings["Booking lifecycle"]
HotelAPI --> Cache["Redis cache"]
HotelAPI --> Audit["Audit trail"]
Hotels --> Rooms
Rooms --> LockedRoom["Pessimistic room lock"]
LockedRoom --> Availability["Date-range availability check"]
Availability --> Cache
Bookings --> Audit
- Suggested repository description:
Spring Boot REST API for hotel, room, booking, cached room-availability, and audit-log management with MySQL persistence, Redis caching, JWT authentication, and OAuth2 login support via Keycloak and Google. - Suggested topics:
java,java-17,spring-boot,spring-security,spring-data-jpa,spring-validation,spring-cache,redis,mysql,rest-api,hotel-management,room-booking,room-availability,cache-invalidation,audit-log,observability,concurrency,pessimistic-locking,jwt,oauth2,keycloak,google-login,thymeleaf,maven,learning-project,portfolio-project