Skip to content
Snippets Groups Projects
Commit 918f9b4e authored by Abdelsamad, Mouaz R (UG - SISC)'s avatar Abdelsamad, Mouaz R (UG - SISC)
Browse files

Merge branch 'MA/GetUpcomingFlights' into 'main'

Add Endpoints for flight history and upcoming flights.

See merge request ma03081/COM3014!31
parents e2976612 7584eab9
No related branches found
No related tags found
No related merge requests found
Showing
with 209 additions and 10 deletions
namespace BookingMicroservice.Clients
using BookingMicroservice.Models;
namespace BookingMicroservice.Clients
{
public class FlightServiceClient : IFlightServiceClient
{
......@@ -27,5 +29,10 @@
return await httpClient.PutAsync($"{SEAT_API_PATH}/{seatId}", null);
}
public async Task<HttpResponseMessage> GetFlightsByIdAsync(FlightIdCollection flightIdCollection)
{
return await httpClient.PostAsJsonAsync($"{FLIGHT_API_PATH}/byIds", flightIdCollection);
}
}
}
namespace BookingMicroservice.Clients
using BookingMicroservice.Models;
namespace BookingMicroservice.Clients
{
public interface IFlightServiceClient
{
Task<HttpResponseMessage> GetFlightCapacityAsync(int flightId, int classType);
Task<HttpResponseMessage> IsSeatAvailableAsync(int seatId);
Task<HttpResponseMessage> BookSeatAsync(int seatId);
Task<HttpResponseMessage> GetFlightsByIdAsync(FlightIdCollection flightIdCollection);
}
}
......@@ -87,5 +87,44 @@ namespace BookingMicroservice.Controllers
return Ok(new { BookedSeat = false, Message = exception.Message });
}
}
[Authorize]
[HttpGet("upcoming")]
public async Task<IActionResult> GetUpcomingFlightBookings()
{
string? userIdValue = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
if (!int.TryParse(userIdValue, out int userId))
return BadRequest("Unable to get User Id from Token");
try
{
IEnumerable<FlightBookingInfo> flights = await reservationComplianceService.TryGetUpcomingFlightsAsync(userId);
return Ok(flights);
}
catch(InvalidOperationException exception)
{
return BadRequest(exception.Message);
}
}
[Authorize]
[HttpGet("history")]
public async Task<IActionResult> GetPreviousFlightBookings()
{
string? userIdValue = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
if (!int.TryParse(userIdValue, out int userId))
return BadRequest("Unable to get User Id from Token");
try
{
IEnumerable<FlightBookingInfo> flights = await reservationComplianceService.TryGetPreviousFlightsAsync(userId);
return Ok(flights);
}
catch (InvalidOperationException exception)
{
return BadRequest(exception.Message);
}
}
}
}
......@@ -23,10 +23,4 @@
SeatId = seatId;
}
}
public enum BookingClass
{
BUSINESS = 0,
ECONOMY = 1
}
}
namespace BookingMicroservice.Models
{
public enum BookingClass
{
BUSINESS = 0,
ECONOMY = 1
}
}
namespace BookingMicroservice.Models
{
public class Flight
{
public int Id { get; set; }
public int AirlineId { get; set; }
public string Origin { get; set; }
public string Destination { get; set; }
public DateTime DepartureTime { get; set; }
public DateTime ArrivalTime { get; set; }
}
}
namespace BookingMicroservice.Models
{
public class FlightBookingInfo
{
public Flight Flight { get; set; }
public Booking Booking { get; set; }
public FlightBookingInfo(Flight flight, Booking booking)
{
Flight = flight;
Booking = booking;
}
}
}
namespace BookingMicroservice.Models
{
public class FlightIdCollection
{
public required List<int> FlightIds { get; set; }
}
}
using System.Text.Json.Serialization;
namespace BookingMicroservice.Models
{
public class FlightResponseWrapper
{
[JsonPropertyName("$values")]
public List<Flight> Values { get; set; }
}
}
......@@ -6,6 +6,7 @@ namespace BookingMicroservice.Services
{
Task<Booking?> TryCreateBookingAsync(int flightId, int userId, BookingClass bookingClass, int? seatId);
Task TryBookSeatAsync(int bookingId, int seatId);
Task<IEnumerable<FlightBookingInfo>> TryGetUpcomingFlightsAsync(int userId);
Task<IEnumerable<FlightBookingInfo>> TryGetPreviousFlightsAsync(int userId);
}
}
using BookingMicroservice.Clients;
using BookingMicroservice.Exceptions;
using BookingMicroservice.Models;
using System.Linq;
using System.Text.Json;
namespace BookingMicroservice.Services
{
......@@ -76,5 +78,52 @@ namespace BookingMicroservice.Services
bookingService.UpdateBooking(bookingId, seatId);
}
public async Task<IEnumerable<FlightBookingInfo>> TryGetUpcomingFlightsAsync(int userId)
{
return await GetFlightsAsync(userId, true);
}
public async Task<IEnumerable<FlightBookingInfo>> TryGetPreviousFlightsAsync(int userId)
{
return await GetFlightsAsync(userId, false);
}
private async Task<IEnumerable<FlightBookingInfo>> GetFlightsAsync(int userId, bool isUpcoming)
{
List<Booking> bookings = bookingService.GetBookings(userId: userId);
List<int> flightIds = bookings.Select(booking => booking.FlightId).ToList();
FlightIdCollection flightIdCollection = new FlightIdCollection { FlightIds = flightIds };
HttpResponseMessage flightsResponse = await flightServiceClient.GetFlightsByIdAsync(flightIdCollection);
if (!flightsResponse.IsSuccessStatusCode)
throw new InvalidOperationException("Could not retrieve flights.");
string flightsString = await flightsResponse.Content.ReadAsStringAsync();
FlightResponseWrapper? flightResponse = JsonSerializer.Deserialize<FlightResponseWrapper>(flightsString, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
if (flightResponse?.Values == null)
throw new InvalidOperationException("Deserialization of flights failed.");
List<Flight> flights = flightResponse.Values;
DateTime comparisonTime = DateTime.UtcNow;
IEnumerable<Flight> filteredFlights = isUpcoming
? flights.Where(flight => flight.DepartureTime > comparisonTime)
: flights.Where(flight => flight.DepartureTime <= comparisonTime);
List<FlightBookingInfo> result = filteredFlights.Select(flight =>
{
Booking? matchingBooking = bookings.FirstOrDefault(booking => booking.FlightId == flight.Id);
if (matchingBooking == null)
throw new InvalidOperationException($"No booking found for flight ID {flight.Id}.");
return new FlightBookingInfo(flight, matchingBooking);
}).ToList();
return result;
}
}
}
......@@ -78,6 +78,16 @@ namespace FlightMicroservice.Controllers
return Ok(seats);
}
[HttpPost("byIds")]
public IActionResult GetFlightsByIds([FromBody] FlightIdCollection flightIdCollection)
{
List<Flight> flights = flightService.GetFlightsByIds(flightIdCollection.FlightIds);
if (flights == null)
return NotFound();
return Ok(flights);
}
}
}
namespace FlightMicroservice.Models
{
public class FlightIdCollection
{
public required List<int> FlightIds { get; set; }
}
}
......@@ -80,6 +80,14 @@ namespace FlightMicroservice.Services
.ToList();
}
public List<Flight> GetFlightsByIds(List<int> ids)
{
return dbContext.Flights
.Where(flight => ids.Contains(flight.Id))
.ToList();
}
private void InitializeSeatsForFlight(Flight flight)
{
int businessRows = flight.BusinessCapacity / Flight.BUSINESS_SEATS_PER_ROW;
......
......@@ -9,5 +9,6 @@ namespace FlightMicroservice.Services
Flight CreateFlight(int airlineId, string origin, string destination, DateTime departureTime, DateTime arrivalTime, int economyCapacity, int businessCapacity, decimal economyPrice, decimal businessPrice);
bool RemoveFlight(int flightId);
List<Seat> GetSeatsByFlightId(int flightId);
List<Flight> GetFlightsByIds(List<int> ids);
}
}
......@@ -47,5 +47,16 @@ namespace GatewayAPI.Clients.BookingService
}
public Task<HttpResponseMessage> GetUpcomingFlightBookingsAsync()
{
return httpClient.GetAsync($"{API_PATH}/upcoming");
}
public Task<HttpResponseMessage> GetPreviousFlightBookingsAsync()
{
return httpClient.GetAsync($"{API_PATH}/history");
}
}
}
......@@ -7,5 +7,8 @@ namespace GatewayAPI.Clients.BookingService
Task<HttpResponseMessage> GetBookingAsync(int id);
Task<HttpResponseMessage> GetBookingsAsync(int? flightId = null, int? userId = null, int? bookingClass = null);
Task<HttpResponseMessage> MakeBookingAsync(BookingCreation bookingModel);
Task<HttpResponseMessage> UpdateBookingAsync(int bookindId, BookingUpdate bookingModel); }
Task<HttpResponseMessage> UpdateBookingAsync(int bookindId, BookingUpdate bookingModel);
Task<HttpResponseMessage> GetUpcomingFlightBookingsAsync();
Task<HttpResponseMessage> GetPreviousFlightBookingsAsync();
}
}
......@@ -43,5 +43,19 @@ namespace GatewayAPI.Controllers
HttpResponseMessage response = await bookingServiceClient.UpdateBookingAsync(id, bookingUpdateModel);
return new HttpResponseMessageResult(response);
}
[HttpGet("upcoming")]
public async Task<IActionResult> GetUpcomingFlightBookings()
{
HttpResponseMessage response = await bookingServiceClient.GetUpcomingFlightBookingsAsync();
return new HttpResponseMessageResult(response);
}
[HttpGet("history")]
public async Task<IActionResult> GetPreviousFlightBookings()
{
HttpResponseMessage response = await bookingServiceClient.GetPreviousFlightBookingsAsync();
return new HttpResponseMessageResult(response);
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment