in online_archive/src/main/scala/archivehunter/ArchiveHunterCommunicator.scala [64:106]
protected def callToArchiveHunter[T:io.circe.Decoder](req: HttpRequest, maybeChecksum:Option[String], attempt: Int = 1, retryLimit:Int=10, overrideTime:Option[ZonedDateTime]=None): Future[Option[T]] = if (retryLimit > 10) {
Future.failed(new RuntimeException("Too many retries, see logs for details"))
} else {
logger.debug(s"Request URL is ${req.uri.toString()}")
val contentChecksum = maybeChecksum match {
case Some(content)=>content
case None=> //if we are not sending any content, use the checksum of an empty string
val checksumBytes = MessageDigest.getInstance("SHA-384").digest("".getBytes)
Base64.getEncoder.encodeToString(checksumBytes)
}
val signatureTime = overrideTime.getOrElse(ZonedDateTime.now()).withZoneSameInstant(ZoneId.of("UTC"))
val httpDate = httpDateFormatter.format(signatureTime)
val token = getToken(req.uri, httpDate, req.entity.contentLengthOption.getOrElse(0L).toInt, req.method.value, contentChecksum)
val updatedRequest = req.withHeaders(req.headers ++ Seq(
akka.http.scaladsl.model.headers.RawHeader("Date", httpDate),
akka.http.scaladsl.model.headers.RawHeader("X-Sha384-Checksum", contentChecksum),
akka.http.scaladsl.model.headers.Authorization(GenericHttpCredentials("HMAC", token))
))
val loggerContext = Option(MDC.getCopyOfContextMap)
callHttp
.singleRequest(updatedRequest)
.flatMap(response=>{
//restore the logger context, in case it got lost on the journey through Akka
if(loggerContext.isDefined) MDC.setContextMap(loggerContext.get)
AkkaHttpHelpers.handleResponse(response, "Archive Hunter").flatMap({
case Right(Some(stream))=>
contentBodyToJson(consumeStream(stream.dataBytes))
case Right(None)=>
Future(None)
case Left(RedirectRequired(newUri))=>
logger.info(s"Redirecting to $newUri")
callToArchiveHunter(req.withUri(newUri), maybeChecksum, attempt + 1)
case Left(RetryRequired)=>
Thread.sleep(500 * attempt)
callToArchiveHunter(req, maybeChecksum, attempt + 1)
})
})
}