Skip to content

Commit

Permalink
PIN-4923: generate presigned url (#291)
Browse files Browse the repository at this point in the history
  • Loading branch information
AsterITA authored Jun 10, 2024
1 parent ef4eb0b commit 0907822
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 3 deletions.
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import akka.http.scaladsl.server.directives.FileInfo
import it.pagopa.interop.commons.files.service.impl.{FileManagerImpl, S3ManagerImpl}

import java.io.{ByteArrayOutputStream, File}
import scala.concurrent.duration.FiniteDuration
import scala.concurrent.{ExecutionContextExecutor, Future}
import scala.util.Try

trait FileManager {

Expand Down Expand Up @@ -40,6 +42,10 @@ trait FileManager {
def delete(containerPath: String)(filePath: StorageFilePath): Future[Boolean]

def close(): Unit

def generateGetPresignedUrl(bucketName: String, path: String, fileName: String, durationInMinutes: FiniteDuration): Try[String]

def generatePutPresignedUrl(bucketName: String, path: String, fileName: String, durationInMinutes: FiniteDuration): Try[String]
}

object FileManager {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import java.nio.file.{Files, Path, Paths, StandardCopyOption}
import scala.concurrent.{ExecutionContextExecutor, Future}
import java.nio.file.FileVisitOption
import java.util.stream.Collectors
import scala.concurrent.duration.FiniteDuration
import scala.jdk.CollectionConverters._
import scala.util.Try

final class FileManagerImpl(blockingExecutionContext: ExecutionContextExecutor) extends FileManager {

Expand Down Expand Up @@ -85,4 +87,23 @@ final class FileManagerImpl(blockingExecutionContext: ExecutionContextExecutor)
pathCreated.resolve(fileName.stripMargin('/'))
}

override def generateGetPresignedUrl(
bucketName: String,
path: String,
fileName: String,
duration: FiniteDuration
): Try[String] = {
val destPath: String = createPath(path, "", fileName).toAbsolutePath.toString
Try(destPath)
}

override def generatePutPresignedUrl(
bucketName: String,
path: String,
fileName: String,
durationInMinutes: FiniteDuration
): Try[String] = {
val destPath: String = createPath(path, "", fileName).toAbsolutePath.toString
Try(destPath)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,19 @@ import software.amazon.awssdk.core.client.config.{ClientAsyncConfiguration, SdkA
import software.amazon.awssdk.http.async.SdkAsyncHttpClient
import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient
import software.amazon.awssdk.services.s3.model._
import software.amazon.awssdk.services.s3.presigner.S3Presigner
import software.amazon.awssdk.services.s3.presigner.model.{GetObjectPresignRequest, PutObjectPresignRequest}
import software.amazon.awssdk.services.s3.{S3AsyncClient, S3AsyncClientBuilder, S3Configuration}

import java.io.{ByteArrayOutputStream, File}
import java.nio.file.Files
import java.time.Duration
import java.util.concurrent.Executor
import scala.concurrent.duration.FiniteDuration
import scala.concurrent.{ExecutionContext, ExecutionContextExecutor, Future}
import scala.jdk.CollectionConverters._
import scala.jdk.FutureConverters._
import scala.util.{Try, Using}

final class S3ManagerImpl(blockingExecutionContext: ExecutionContextExecutor)(
confOverride: S3AsyncClientBuilder => S3AsyncClientBuilder = identity
Expand Down Expand Up @@ -162,4 +167,56 @@ final class S3ManagerImpl(blockingExecutionContext: ExecutionContextExecutor)(
def calcContentMd5(file: File): String = calcContentMd5(Files.readAllBytes(file.toPath))

def calcContentMd5(byteArray: Array[Byte]): String = new String(Base64.encodeBase64(DigestUtils.md5(byteArray)))

override def generateGetPresignedUrl(
bucketName: String,
path: String,
fileName: String,
durationInMinutes: FiniteDuration
): Try[String] = {
val key: String = s3Key(path, "", fileName)

Using(S3Presigner.create()) { s3Presigner =>
val objectRequest: GetObjectRequest = GetObjectRequest
.builder()
.bucket(bucketName)
.key(key)
.build()

val presignRequest: GetObjectPresignRequest = GetObjectPresignRequest
.builder()
.signatureDuration(Duration.ofMinutes(durationInMinutes.toMinutes))
.getObjectRequest(objectRequest)
.build()

val presignedGetObjectRequest = s3Presigner.presignGetObject(presignRequest)
presignedGetObjectRequest.url().toString
}
}

override def generatePutPresignedUrl(
bucketName: String,
path: String,
fileName: String,
durationInMinutes: FiniteDuration
): Try[String] = {
val key: String = s3Key(path, "", fileName)

Using(S3Presigner.create()) { s3Presigner =>
val objectRequest: PutObjectRequest = PutObjectRequest
.builder()
.bucket(bucketName)
.key(key)
.build()

val presignRequest: PutObjectPresignRequest = PutObjectPresignRequest
.builder()
.signatureDuration(Duration.ofMinutes(durationInMinutes.toMinutes))
.putObjectRequest(objectRequest)
.build()

val presignedGetObjectRequest = s3Presigner.presignPutObject(presignRequest)
presignedGetObjectRequest.url().toString
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ import org.scalatest.concurrent.ScalaFutures

import java.util.concurrent.Executors
import it.pagopa.interop.commons.files.service.FileManager

import scala.concurrent.ExecutionContext
import org.scalatest.time._
import org.scalatest.BeforeAndAfterAll

import java.util.concurrent.ExecutorService
import java.net.URI
import it.pagopa.interop.commons.files.service.impl.S3ManagerImpl
import software.amazon.awssdk.auth.credentials.{AwsBasicCredentials, StaticCredentialsProvider}

import scala.concurrent.Future
import scala.concurrent.ExecutionContextExecutor
import org.scalatest.BeforeAndAfterEach
Expand Down Expand Up @@ -94,15 +97,22 @@ class S3FileManagerTest
files <- fileManager.getAllFiles("testBucket")("")
} yield files

val files = filesF.futureValue
val files = filesF.futureValue
val contentMap = files.map { case (k, v) => (k, new String(v)) }
val expected = Map(
val expected = Map(
"rootFile" -> "rootFile",
"testFolder/testFile" -> "testFile",
"testFolder/nestedFolder/nestedFile" -> "nestedFile"
)
assert(contentMap == expected)
}
"Get presigned url" in {
val url = fileManager.generateGetPresignedUrl("testBucket", "testFolder", "testFile", FiniteDuration(5, MINUTES)).get
assert(url.nonEmpty)
}
"Put presigned url" in {
val url = fileManager.generatePutPresignedUrl("testBucket", "testFolder", "testFile", FiniteDuration(1, MINUTES)).get
assert(url.nonEmpty)
}
}

}

0 comments on commit 0907822

Please sign in to comment.