Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drtii 1608 flexible pax endpoint #1939

Merged
merged 13 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
743 changes: 707 additions & 36 deletions client/package-lock.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ object DashboardTerminalSummary {
}
}

def aggSplits(paxFeedSourceOrder: List[FeedSource], flights: Seq[ApiFlightWithSplits]): Map[PaxTypeAndQueue, Int] = BigSummaryBoxes.aggregateSplits(flights, paxFeedSourceOrder)
def aggSplits(paxFeedSourceOrder: List[FeedSource], flights: Seq[ApiFlightWithSplits]): Map[PaxTypeAndQueue, Int] =
BigSummaryBoxes.aggregateSplits(flights, paxFeedSourceOrder)

case class Props(flights: List[ApiFlightWithSplits],
crunchMinutes: List[CrunchMinute],
Expand All @@ -133,8 +134,8 @@ object DashboardTerminalSummary {

val component: Component[Props, Unit, Unit, CtorType.Props] = ScalaComponent.builder[Props]("SummaryBox")
.render_P { props =>
val crunchMinuteTimeSlots = groupCrunchMinutesByX(groupSize = 15)(
CrunchApi.terminalMinutesByMinute[CrunchMinute, CrunchMinute, TQM](props.crunchMinutes, props.terminal),
val crunchMinuteTimeSlots = groupCrunchMinutesBy(groupSize = 15)(
CrunchApi.terminalMinutesByMinute(props.crunchMinutes, props.terminal),
props.terminal,
Queues.queueOrder).flatMap(_._2)

Expand Down
2 changes: 1 addition & 1 deletion e2e/cypress/e2e/multi-day-export.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ describe('Multi day export', () => {
cy
.addFlight({
"SchDT": todayAtUtcString(0, 55),
"ActChoxDT": todayAtUtcString(3, 2),
"ActChoxDT": todayAtUtcString(4, 2),
"ActPax": 51
})
.asABorderForceOfficer()
Expand Down
2 changes: 1 addition & 1 deletion project/Settings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ object Settings {
/** Declare global dependency versions here to avoid mismatches in multi part dependencies */
//noinspection ScalaStyle
object versions {
val drtLib = "v898"
val drtLib = "v914"

val scala = "2.13.12"
val scalaDom = "2.8.0"
Expand Down
3 changes: 3 additions & 0 deletions server/src/main/resources/routes
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ GET /api/passengers/:startLocalDate/:endLocalDate
GET /api/passengers/:startLocalDate/:endLocalDate/:terminalName controllers.application.SummariesController.exportPassengersByTerminalForDateRangeApi(startLocalDate: String, endLocalDate: String, terminalName: String)
PUT /api/passengers/:localDate controllers.application.SummariesController.populatePassengersForDate(localDate: String)

GET /api/v1/queues controllers.application.api.v1.QueuesApiController.queues()
GET /api/v1/flights controllers.application.api.v1.FlightsApiController.flights()

GET /debug/flights/:persistenceId/:dateString/:messages controllers.application.DebugController.getMessagesForFlightPersistenceIdAtTime(persistenceId: String, dateString: String, messages: Int)
POST /email/feedback/:feedback controllers.application.EmailNotificationController.feedBack(feedback: String)
# Logging
Expand Down
9 changes: 0 additions & 9 deletions server/src/main/scala/api/ApiResponseBody.scala

This file was deleted.

132 changes: 0 additions & 132 deletions server/src/main/scala/api/KeyCloakAuth.scala

This file was deleted.

15 changes: 8 additions & 7 deletions server/src/main/scala/controllers/Application.scala
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
package controllers

import akka.event.Logging
import api._
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import buildinfo.BuildInfo
import com.google.inject.Inject
import com.typesafe.config.ConfigFactory
import controllers.application._
import drt.http.ProdSendAndReceive
import spray.json.enrichAny
import drt.shared.DrtPortConfigs
import org.joda.time.chrono.ISOChronology
import play.api.mvc._
import play.api.{Configuration, Environment}
import services.{ActorResponseTimeHealthCheck, FeedsHealthCheck, HealthChecker}
import slickdb._
import spray.json.enrichAny
import uk.gov.homeoffice.drt.auth.Roles.BorderForceStaff
import uk.gov.homeoffice.drt.crunchsystem.DrtSystemInterface
import uk.gov.homeoffice.drt.db.dao.{IABFeatureDao, IUserFeedbackDao}
import uk.gov.homeoffice.drt.keycloak.{KeyCloakAuth, KeyCloakAuthError, KeyCloakAuthResponse, KeyCloakAuthToken, KeyCloakAuthTokenParserProtocol}
import uk.gov.homeoffice.drt.ports._
import uk.gov.homeoffice.drt.time.TimeZoneHelper.europeLondonTimeZone
import uk.gov.homeoffice.drt.time.{MilliTimes, SDate, SDateLike}
Expand Down Expand Up @@ -73,7 +74,7 @@ trait ABFeatureProviderLike {
}

class Application @Inject()(cc: ControllerComponents, ctrl: DrtSystemInterface)(implicit environment: Environment)
extends AuthController(cc, ctrl) {
extends AuthController(cc, ctrl) with KeyCloakAuthTokenParserProtocol {

val googleTrackingCode: String = config.get[String]("googleTrackingCode")

Expand Down Expand Up @@ -193,7 +194,6 @@ class Application @Inject()(cc: ControllerComponents, ctrl: DrtSystemInterface)(

def viewedFeatureGuideIds: Action[AnyContent] = authByRole(BorderForceStaff) {
Action.async { implicit request =>
import spray.json.DefaultJsonProtocol.{StringJsonFormat, immSeqFormat}
val userEmail = request.headers.get("X-Forwarded-Email").getOrElse("Unknown")
ctrl.featureGuideViewService.featureViewed(userEmail).map(a => Ok(a.toJson.toString()))
}
Expand Down Expand Up @@ -252,7 +252,7 @@ class Application @Inject()(cc: ControllerComponents, ctrl: DrtSystemInterface)(
val clientSecretOption = config.getOptional[String]("key-cloak.client_secret")
val usernameOption = postStringValOrElse("username")
val passwordOption = postStringValOrElse("password")
import KeyCloakAuthTokenParserProtocol._

import spray.json._

def tokenToHttpResponse(username: String)(token: KeyCloakAuthResponse): Result = token match {
Expand All @@ -274,7 +274,8 @@ class Application @Inject()(cc: ControllerComponents, ctrl: DrtSystemInterface)(
clientSecret <- clientSecretOption
} yield (usernameOption, passwordOption) match {
case (Some(username), Some(password)) =>
val authClient = new KeyCloakAuth(tokenUrl, clientId, clientSecret) with ProdSendAndReceive
val requestToEventualResponse: HttpRequest => Future[HttpResponse] = request => Http().singleRequest(request)
val authClient = KeyCloakAuth(tokenUrl, clientId, clientSecret, requestToEventualResponse)
authClient.getToken(username, password).map(tokenToHttpResponse(username))
case _ =>
log.info(s"Invalid post fields for api login.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,16 @@ package controllers.application
import actors.persistent.nebo.NeboArrivalActor
import akka.actor.ActorRef
import akka.pattern.ask
import api.ApiResponseBody
import com.google.inject.Inject
import controllers.model.RedListCounts
import controllers.model.RedListCountsJsonFormats._
import drt.server.feeds.StoreFeedImportArrivals
import drt.server.feeds.lhr.forecast.LHRForecastCSVExtractor
import drt.server.feeds.stn.STNForecastXLSExtractor
import drt.shared.FlightsApi.Flights
import drt.shared.{NeboArrivals, RedListPassengers}
import play.api.libs.Files
import play.api.libs.json.Json._
import play.api.libs.json.OWrites
import play.api.mvc._
import spray.json._
import uk.gov.homeoffice.drt.auth.Roles.{NeboUpload, PortFeedUpload}
Expand All @@ -26,7 +25,13 @@ import scala.concurrent.Future
import scala.util.Try


class ImportsController@Inject()(cc: ControllerComponents, ctrl: DrtSystemInterface) extends AuthController(cc, ctrl) {
case class ApiResponseBody(message: String)

object ApiResponseBody {
implicit val w: OWrites[ApiResponseBody] = writes[ApiResponseBody]
}

class ImportsController @Inject()(cc: ControllerComponents, ctrl: DrtSystemInterface) extends AuthController(cc, ctrl) {

def feedImportRedListCounts: Action[AnyContent] = authByRole(NeboUpload) {
Action.async { request =>
Expand All @@ -42,9 +47,9 @@ class ImportsController@Inject()(cc: ControllerComponents, ctrl: DrtSystemInterf
.ask(RedListCounts(updatedRedListCounts))
Accepted(toJson(ApiResponseBody(s"${redListCounts.passengers} red list records imported")))
}.recover {
case e => log.warning(s"Error while updating redListPassenger", e)
BadRequest("Failed to update the red List Passenger")
}
case e => log.warning(s"Error while updating redListPassenger", e)
BadRequest("Failed to update the red List Passenger")
}
}.getOrElse(Future.successful(BadRequest("Failed to parse json")))
case None => Future.successful(BadRequest("No content"))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ class SimulationsController @Inject()(cc: ControllerComponents, ctrl: DrtSystemI

val fileName = CsvFileStreaming.makeFileName(s"simulation-${simulationParams.passengerWeighting}",
Option(simulationParams.terminal),
simulationParams.date,
simulationParams.date,
SDate(simulationParams.date),
SDate(simulationParams.date),
airportConfig.portCode
) + ".csv"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ class StaffingController @Inject()(cc: ControllerComponents,
CsvFileStreaming.makeFileName(
"staff-movements",
Option(terminal),
localDate,
localDate,
SDate(localDate),
SDate(localDate),
airportConfig.portCode
) + ".csv"
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import scala.concurrent.Future
import scala.util.{Failure, Success, Try}


class SummariesController @Inject()(cc: ControllerComponents, ctrl: DrtSystemInterface) extends AuthController(cc, ctrl) {
class SummariesController @Inject()(cc: ControllerComponents, ctrl: DrtSystemInterface) extends AuthController(cc, ctrl) {
def populatePassengersForDate(localDateStr: String): Action[AnyContent] = authByRole(SuperAdmin) {
LocalDate.parse(localDateStr) match {
case Some(localDate) =>
Expand All @@ -35,6 +35,7 @@ class SummariesController @Inject()(cc: ControllerComponents, ctrl: DrtSystemInt
Action(BadRequest(s"Invalid date format for $localDateStr. Expected YYYY-mm-dd"))
}
}

def exportPassengersByTerminalForDateRangeApi(startLocalDateString: String,
endLocalDateString: String,
terminalName: String): Action[AnyContent] =
Expand All @@ -57,7 +58,7 @@ class SummariesController @Inject()(cc: ControllerComponents, ctrl: DrtSystemInt
): Result =
(LocalDate.parse(startLocalDateString), LocalDate.parse(endLocalDateString)) match {
case (Some(start), Some(end)) =>
val fileName = makeFileName("passengers", maybeTerminal, start, end, airportConfig.portCode) + ".csv"
val fileName = makeFileName("passengers", maybeTerminal, SDate(start), SDate(end), airportConfig.portCode) + ".csv"
val contentStream = streamForGranularity(maybeTerminal, request.getQueryString("granularity"), acceptHeader(request))

val result = if (acceptHeader(request) == "text/csv")
Expand Down Expand Up @@ -119,10 +120,10 @@ class SummariesController @Inject()(cc: ControllerComponents, ctrl: DrtSystemInt
}

private val hourlyStream: (LocalDate => Future[Map[Long, Map[Queue, Int]]], LocalDate => Future[Map[Long, Int]]) => (LocalDate, LocalDate) => Source[(Map[Queue, Int], Int, Option[Long]), NotUsed] =
(queueTotalsForDate, capacityTotalsForDate) => (start, end) =>
(queueTotalsForDate, hourlyCapacityTotalsForDate) => (start, end) =>
Source(DateRange(start, end))
.mapAsync(1) { date =>
capacityTotalsForDate(date).map { capacityTotals =>
hourlyCapacityTotalsForDate(date).map { capacityTotals =>
(date, capacityTotals)
}
}
Expand Down
Loading
Loading