in online_archive/src/main/scala/FileUploader.scala [186:236]
private def uploadFile(file: File, keyName: String, contentType: Option[String] = None): Future[HeadObjectResponse] = {
import scala.jdk.FutureConverters._
val loggerContext = Option(MDC.getCopyOfContextMap)
val md5Result = calculateMD5(file)
md5Result match {
case Success(md5) =>
logger.info(s"Calculated MD5 for $file: $md5")
val basePutReq = PutObjectRequest.builder()
.bucket(bucketName)
.key(keyName)
.contentMD5(md5)
val putReq = contentType match {
case Some(contentType) => basePutReq.contentType(contentType)
case None => basePutReq
}
logger.info(s"Put request for $file: ${putReq.build().toString}")
val response = for {
job <- Future.fromTry(Try {
val md5 = calculateMD5(file).get
val req = UploadRequest.builder().putObjectRequest(putReq.contentMD5(md5).build()).requestBody(AwsRequestBodyFromFile(file))
.build()
logger.info(s"Request used by S3TransferManager: $req")
transferManager.upload(req)
})
_ <- job.completionFuture().asScala
result <- Future.fromTry(getObjectMetadata(bucketName, keyName))
} yield result
response.recover {
case e: S3Exception =>
logger.error(s"S3Exception when uploading $file: ${e.getMessage}", e)
throw e
case e =>
logger.error(s"Other exception when uploading $file: ${e.getMessage}", e)
throw e
}.map(result => {
loggerContext.map(MDC.setContextMap) //restore the logger context if it was set
result
})
case Failure(e) =>
logger.error(s"Failed to calculate MD5 for $file: ${e.getMessage}", e)
Future.failed(e)
}
}