in app/controllers/BulkDownloadsController.scala [259:318]
def getDownloadIdWithToken(tokenValue:String, fileId:String) = Action.async {
implicit val timeout:akka.util.Timeout = 30 seconds
serverTokenDAO.get(tokenValue).flatMap({
case None=>
Future(Forbidden(GenericErrorResponse("forbidden", "invalid or expired token").asJson))
case Some(Left(err))=>
Future(Forbidden(GenericErrorResponse("forbidden", "invalid or expired token").asJson))
case Some(Right(_))=>
indexer.getById(fileId).flatMap(archiveEntry=>{
val s3Client = s3ClientManager.getS3Client(profileName,archiveEntry.region.map(software.amazon.awssdk.regions.Region.of))
val response = (glacierRestoreActor ? GlacierRestoreActor.CheckRestoreStatusBasic(archiveEntry)).mapTo[GlacierRestoreActor.GRMsg]
response.map({
case GlacierRestoreActor.NotInArchive(entry)=>
getPresignedURL(archiveEntry, defaultLinkExpiry, defaultRegion, profileName)
.map(url=>Ok(RestoreStatusResponse("ok",entry.id, RestoreStatus.RS_UNNEEDED, None, Some(url.toString)).asJson))
case GlacierRestoreActor.RestoreCompleted(entry, expiry)=>
getPresignedURL(archiveEntry, defaultLinkExpiry, defaultRegion, profileName)
.map(url=>Ok(RestoreStatusResponse("ok", entry.id, RestoreStatus.RS_SUCCESS, Some(expiry), Some(url.toString)).asJson))
case GlacierRestoreActor.RestoreInProgress(entry)=>
Success(Ok(RestoreStatusResponse("ok", entry.id, RestoreStatus.RS_UNDERWAY, None, None).asJson))
case GlacierRestoreActor.RestoreNotRequested(entry)=>
if(entry.storageClass!=StorageClass.GLACIER){ //if the file is not registered as in Glacier, then update it.
val updatedEntry = entry.copy(storageClass=StorageClass.GLACIER)
indexer.indexSingleItem(updatedEntry, Some(updatedEntry.id)).onComplete({
case Failure(err)=>
logger.error(s"Could not update storage class for incorrect item $entry: $err")
case Success(_)=>
logger.info(s"Updated $entry as it had invalid storage class. Now requesting restore")
glacierRestoreActor ! GlacierRestoreActor.InitiateRestoreBasic(updatedEntry,None)
})
}
Success(Ok(RestoreStatusResponse("not_requested", entry.id, RestoreStatus.RS_ERROR, None, None).asJson))
case GlacierRestoreActor.ItemLost(entry)=>
logger.error(s"Bulk item ${entry.bucket}:${entry.path} is lost")
val updatedEntry = entry.copy(beenDeleted = true)
indexer.indexSingleItem(updatedEntry, Some(updatedEntry.id)).onComplete({
case Success(_)=>
logger.info(s"${entry.bucket}:${entry.path} has been updated to indicate it is lost")
case Failure(err)=>
logger.error(s"Could not update ${entry.bucket}:${entry.path}")
})
Success(NotFound(GenericErrorResponse("not_found","item has been deleted!").asJson))
case GlacierRestoreActor.RestoreFailure(err)=>
logger.error(s"Could not check restore status: ", err)
Success(InternalServerError(GenericErrorResponse("error",err.toString).asJson))
}).map({
case Success(httpResponse)=>httpResponse
case Failure(err)=>
logger.error(s"Could not get download for $fileId with token $tokenValue", err)
InternalServerError(GenericErrorResponse("error",err.toString).asJson)
})
}).recover({
case err:Throwable=>
logger.error(s"Could not ascertain glacier restore status for $fileId: ", err)
InternalServerError(GenericErrorResponse("error", err.toString).asJson)
})
})
}