Skip to content

Commit

Permalink
Temporary changes to test judgment flow
Browse files Browse the repository at this point in the history
  • Loading branch information
vimleshtna committed Jul 29, 2024
1 parent f2a762f commit 713a55d
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 586 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ on:
push:
branches:
- master
- test-load-testing-for-judgment
jobs:
pre-deploy:
uses: nationalarchives/tdr-github-actions/.github/workflows/ecs_build.yml@main
Expand Down
93 changes: 88 additions & 5 deletions app/controllers/FileChecksController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import graphql.codegen.types.ConsignmentStatusInput
import io.circe.syntax._
import org.pac4j.play.scala.SecurityComponents
import play.api.i18n.I18nSupport
import play.api.mvc.{Action, AnyContent, Request, RequestHeader}
import services.Statuses.{CompletedValue, CompletedWithIssuesValue, UploadType}
import services.{BackendChecksService, ConsignmentService, ConsignmentStatusService}
import play.api.mvc._
import services.Statuses._
import services._
import viewsapi.Caching.preventCaching

import java.util.UUID
import javax.inject.{Inject, Singleton}
import scala.concurrent.{ExecutionContext, Future}
import scala.concurrent.{ExecutionContext, Future, blocking}

@Singleton
class FileChecksController @Inject() (
Expand All @@ -24,7 +24,9 @@ class FileChecksController @Inject() (
val consignmentService: ConsignmentService,
val applicationConfig: ApplicationConfig,
val backendChecksService: BackendChecksService,
val consignmentStatusService: ConsignmentStatusService
val consignmentStatusService: ConsignmentStatusService,
val confirmTransferService: ConfirmTransferService,
val consignmentExportService: ConsignmentExportService
)(implicit val ec: ExecutionContext)
extends TokenSecurity
with I18nSupport {
Expand Down Expand Up @@ -71,6 +73,13 @@ class FileChecksController @Inject() (
.map(Ok(_))
}

def exportProgress(consignmentId: UUID): Action[AnyContent] = secureAction.async { implicit request => {
consignmentStatusService.getConsignmentStatuses(consignmentId, request.token.bearerAccessToken)
.map(consignmentStatuses => consignmentStatusService.getStatusValues(consignmentStatuses, ExportType).values.headOption.flatten)
.map(status => Ok(status.getOrElse("")))
}
}

def fileChecksPage(consignmentId: UUID, uploadFailed: Option[String]): Action[AnyContent] = standardTypeAction(consignmentId) { implicit request: Request[AnyContent] =>
val token = request.token.bearerAccessToken
for {
Expand All @@ -93,6 +102,24 @@ class FileChecksController @Inject() (
} yield result
}

def judgmentCompleteTransfer(consignmentId: UUID): Action[AnyContent] = judgmentTypeAction(consignmentId) { implicit request: Request[AnyContent] =>
val token = request.token.bearerAccessToken
for {
reference <- consignmentService.getConsignmentRef(consignmentId, token)
result <-
(
for {
_ <- waitForFileChecksToBeCompleted(consignmentId)
result <- JudgmentCompleteTransfer(consignmentId)
} yield result
).recover { case _: Exception =>
Ok(views.html.uploadInProgress(consignmentId, reference, "Uploading your records", request.token.name, isJudgmentUser = true)).uncache()
}
} yield {
result
}
}

private def handleSuccessfulUpload(consignmentId: UUID, reference: String, isJudgmentUser: Boolean)(implicit request: Request[AnyContent]) = {
val token = request.token.bearerAccessToken
(for {
Expand Down Expand Up @@ -129,6 +156,62 @@ class FileChecksController @Inject() (
Ok(views.html.uploadInProgress(consignmentId, reference, "Uploading your records", request.token.name, isJudgmentUser)).uncache()
}
}

private def JudgmentCompleteTransfer(consignmentId: UUID)(implicit request: Request[AnyContent]): Future[Result] = {
val pageTitle = "Results of checks"
for {
consignmentStatuses <- consignmentStatusService.getConsignmentStatuses(consignmentId, request.token.bearerAccessToken)
reference <- consignmentService.getConsignmentRef(consignmentId, request.token.bearerAccessToken)
exportStatus = consignmentStatusService.getStatusValues(consignmentStatuses, ExportType).values.headOption.flatten
result <- exportStatus match {
case Some(InProgressValue.value) | Some(CompletedValue.value) | Some(FailedValue.value) =>
Future(Ok(views.html.transferAlreadyCompleted(consignmentId, reference, request.token.name, isJudgmentUser = true)).uncache())
case None =>
for {
fileCheck <- consignmentService.fileCheckProgress(consignmentId, request.token.bearerAccessToken)
result <-
if (fileCheck.allChecksSucceeded) {
val token: BearerAccessToken = request.token.bearerAccessToken
val legalCustodyTransferConfirmation = FinalTransferConfirmationData(transferLegalCustody = true)
for {
_ <- confirmTransferService.addFinalTransferConfirmation(consignmentId, token, legalCustodyTransferConfirmation)
_ <- consignmentExportService.updateTransferInitiated(consignmentId, request.token.bearerAccessToken)
_ <- consignmentExportService.triggerExport(consignmentId, request.token.bearerAccessToken.toString)
res <- Future(Ok("{}").uncache())
} yield res
} else {
Future(Ok(views.html.fileChecksResultsFailed(request.token.name, pageTitle, reference, isJudgmentUser = true)).uncache())
}
} yield result
case _ =>
throw new IllegalStateException(s"Unexpected Export status: $exportStatus for consignment $consignmentId")
}
} yield result
}

private def waitForFileChecksToBeCompleted(consignmentId: UUID)(implicit request: Request[AnyContent]): Future[Unit] = {
val totalSleepTime = 480 * 1000 // Total sleep time in milliseconds
val interval = 5 * 1000 // Interval time in milliseconds (5 seconds)
val intervals = totalSleepTime / interval

def checkStatus(remainingIntervals: Int): Future[Unit] = {
if (remainingIntervals <= 0) {
Future.unit
} else {
getFileChecksProgress(request, consignmentId).flatMap { progress =>
if (progress.isComplete) {
Future.unit
} else {
Future {
blocking(Thread.sleep(interval))
}.flatMap(_ => checkStatus(remainingIntervals - 1))
}
}
}
}

checkStatus(intervals)
}
}

case class FileChecksProgress(totalFiles: Int, avMetadataProgressPercentage: Int, checksumProgressPercentage: Int, ffidMetadataProgressPercentage: Int) {
Expand Down
2 changes: 1 addition & 1 deletion app/views/judgment/judgmentFileChecksProgress.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ <h1 class="govuk-heading-l">Checking your upload</h1>
</p>

<!-- Form to redirect user once file checks have completed. It sends consignmentId to record results' placeholder page -->
@form(routes.FileChecksResultsController.judgmentFileCheckResultsPage(consignmentId), Symbol("id") -> "file-checks-form") { }
@form(routes.TransferCompleteController.judgmentTransferComplete(consignmentId), Symbol("id") -> "file-checks-form") { }
</div>
@transferReference(consignmentRef, isJudgmentUser = true)
</div>
Expand Down
2 changes: 2 additions & 0 deletions conf/routes
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ GET /judgment/:consignmentId/before-uploading
GET /judgment/:consignmentId/upload controllers.UploadController.judgmentUploadPage(consignmentId: java.util.UUID)
GET /judgment/:consignmentId/file-checks controllers.FileChecksController.judgmentFileChecksPage(consignmentId: java.util.UUID, uploadFailed: Option[String])
POST /judgment/:consignmentId/file-check-progress controllers.FileChecksController.fileCheckProgress(consignmentId: java.util.UUID)
POST /judgment/:consignmentId/export-progress controllers.FileChecksController.exportProgress(consignmentId: java.util.UUID)
POST /judgment/:consignmentId/continue-transfer controllers.FileChecksController.judgmentCompleteTransfer(consignmentId: java.util.UUID)
GET /judgment/:consignmentId/file-checks-results controllers.FileChecksResultsController.judgmentFileCheckResultsPage(consignmentId: java.util.UUID)
GET /judgment/:consignmentId/transfer-complete controllers.TransferCompleteController.judgmentTransferComplete(consignmentId: java.util.UUID)

Expand Down
34 changes: 32 additions & 2 deletions npm/src/checks/get-checks-progress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,35 @@ export const getFileChecksProgress: () => Promise<
)
}

export const getExportProgress: () => Promise<
Boolean | Error
> = async () => {
const progress = await getProgress("export-progress")
if (!isError(progress)) {
console.log("progress >>>>>>>" + progress)
const response = progress as String
console.log("Resposnse >>>>>>>" + response)
return response === "InProgress" || response === "Failed" || response === "Completed"
} else
return Error(
`Failed to retrieve progress for file checks: ${progress.message}`
)
}

export const continueTransfer: () => Promise<
String | Error
> = async () => {
const progress = await getProgress("continue-transfer")
if (isError(progress)) {
return Error(
`Failed to retrieve progress for file checks: ${progress.message}`
)
}
}

const getProgress: (
progressEndpoint: string
) => Promise<IProgress | Error> = async (progressEndpoint) => {
) => Promise<String | IProgress | Error> = async (progressEndpoint) => {
const consignmentId = getConsignmentId()
if (!isError(consignmentId)) {
const csrfInput: HTMLInputElement = document.querySelector(
Expand All @@ -109,7 +135,11 @@ const getProgress: (
} else if (result.status != 200) {
return Error(`Retrieving progress failed: ${result.statusText}`)
} else {
return await result.json()
if (progressEndpoint === "export-progress") {
return await result.text()
} else {
return await result.json()
}
}
} else {
return Error(`Failed to retrieve consignment id: ${consignmentId.message}`)
Expand Down
34 changes: 15 additions & 19 deletions npm/src/checks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,31 @@ import {
} from "./verify-checks-have-completed"
import { displayChecksCompletedBanner } from "./display-checks-completed-banner"
import {
getDraftMetadataValidationProgress,
continueTransfer,
getDraftMetadataValidationProgress, getExportProgress,
getFileChecksProgress,
IDraftMetadataValidationProgress,
IFileCheckProgress
} from "./get-checks-progress"
import { isError } from "../errorhandling"

export class Checks {
updateFileCheckProgress: (
isJudgmentUser: boolean,
goToNextPage: (formId: string) => void
) => void | Error = (
isJudgmentUser: boolean,
goToNextPage: (formId: string) => void
updateFileCheckProgress: (isJudgmentUser: boolean, goToNextPage: (formId: string) => void) => Promise<void> = async (
isJudgmentUser: boolean,
goToNextPage: (formId: string) => void
) => {
continueTransfer()
const intervalId: ReturnType<typeof setInterval> = setInterval(async () => {
const fileChecksProgress: IFileCheckProgress | Error =
await getFileChecksProgress()
if (!isError(fileChecksProgress)) {
const checksCompleted = haveFileChecksCompleted(fileChecksProgress)
if (checksCompleted) {
clearInterval(intervalId)
isJudgmentUser
? goToNextPage("#file-checks-form")
: displayChecksCompletedBanner("file-checks")
const isCompleted: Boolean | Error = await getExportProgress()
if (!isError(isCompleted)) {
const v = isCompleted as boolean
if (v) {
clearInterval(intervalId)
goToNextPage("#file-checks-form")
}
} else {
return isCompleted
}
} else {
return fileChecksProgress
}
}, 5000)
}

Expand Down
Loading

0 comments on commit 713a55d

Please sign in to comment.