trying to convert java file to bytestring for using in stream

684 views Asked by At

Im creating an api to send me files and I will upload them to S3, and im using akka-stream-alpakka-s3 library to do it using streams.

my issue is that in my controller I can convert the file to Jave file:

  def uploadToS3() = Action(parse.multipartFormData) { request =>
    request.body.file("file").map { filePart =>
      val filename = Paths.get(filePart.filename).getFileName
      val file = Paths.get(s"/tmp/$filename").toFile // this is java file
      saveToS3(file, filename)
    }
    ...
  }

and in my s3 service func I counld only use scala file since it have a "toByteArray" func and I need it for the source, it looks like this:

import scala.reflect.io.File

class S3Service @Inject()(mys3Client: S3Client,
                          configuration: Configuration,
                          implicit val executionContext: ExecutionContext,
                          implicit val actorSystem: ActorSystem) {

  implicit val materializer: ActorMaterializer = ActorMaterializer()
  val bucket: String = configuration.get[String]("my.aws.s3.bucket")

// func to save to s3
  def saveToS3(file: File, fileName: String): Future[AWSLocation] = {

// here im creating uuid so i to pass as directory so it will be possible to have files with the same name
    val fileNameUUID: String = s"${UUID.randomUUID()}-$fileName"
// this will be my sinc for the stream    
    val s3Sink: Sink[ByteString, Future[MultipartUploadResult]] = mys3Client.multipartUpload(s"$bucket/$fileNameUUID", fileName)

// here is my issue: i need to transform the file to bytstring so I can creat it as the source but the file im getting from the controller is Java file and the function to create byteString is of Scala file so had to use scala file in this func.
    Future.fromTry( Try{
      ByteString(file.toByteArray())
    }).flatMap { byteString =>
      Source.single(byteString).runWith(s3Sink) map { res =>
        AWSLocation(s"$bucket/$fileNameUUID", res.key)
      }
    }.recover {
      case ex: S3Exception =>
        logger.error("some message", ex)
        throw ex
      case ex: Throwable =>
        logger.error("some message", ex)
        throw ex
    }
  }
}

what would be the best way to align the file types so I will be able to pass bytestring file to my Source?

1

There are 1 answers

0
dvim On BEST ANSWER

Take a look at FileIO.fromPath which will give you Source[ByteString, ...] from java.nio.file.Path.