вернуть содержимое из S3 в Playframework 2.5 (scala)

В Playframework 2.4.X я восстанавливаю контент из S3 следующим образом:

  val s3Client = new AmazonS3Client()
  val s3doc = s3Client.getObject(new GetObjectRequest(bucketName, key))
  val stream = s3doc.getObjectContent

  Ok.feed(Enumerator.fromStream(stream)).as(contentType)

Но теперь в игре 2.5 .feed @deprecated("Используйте вместо этого sendEntity с Streamed сущностью"

Я предполагаю, что это что-то вроде этого:

Ok.sendEntity(HttpEntity.Streamed(stream, None, None))

Но мне нужно преобразовать поток в Source[ByteString, _]

Как мне это сделать?


person aloon    schedule 08.03.2016    source источник
comment
Смотрите мое последнее редактирование ответа ниже.   -  person marcospereira    schedule 08.03.2016


Ответы (1)


У контроллера активов есть "пример" того, как это сделать. В принципе, вам нужно сделать что-то вроде этого:

import akka.stream.scaladsl.Source
import play.api.libs.streams.Streams

val stream = s3doc.getObjectContent
val data = Enumerator.fromStream(stream)

val source = Source.fromPublisher(Streams.enumeratorToPublisher(data)).map(ByteString.apply)
Ok.sendEntity(HttpEntity.Streamed(source, None, Some(contentType)))

Изменить:

У меня не было времени протестировать его, но после более внимательного изучения исходный код Akka Stream, возможно, это тоже возможное (и более простое) решение:

val stream = s3doc.getObjectContent
val source: Source[ByteString, _] = StreamConverters.fromInputStream(() => stream)
Ok.sendEntity(HttpEntity.Streamed(source, None, Some("")))
person marcospereira    schedule 08.03.2016
comment
Не удается записать экземпляр play.api.http.HttpEntity.Streamed в ответ HTTP. Попробуйте определить Writeable[play.api.http.HttpEntity.Streamed] [ошибка] Ok(HttpEntity.Streamed(источник, Some(metadata.getContentLength), Some(metadata.getContentType))) [ошибка] ^ [ошибка] один обнаружена ошибка [ошибка] (compile:compileIncremental) Ошибка компиляции - person aloon; 08.03.2016
comment
Хорошо, у обоих отсутствовал sendEntity. - person marcospereira; 08.03.2016
comment
Имейте в виду, что если вы не укажете content-length, содержимое будет загружено в память для расчета content-length, как указано в документации по игре: playframework.com/documentation/2.5.x/ В контексте вопроса вы можете получить размер объекта с помощью S3 API, как это s3Object.getObjectMetadata().getContentLength() - person endertunc; 26.06.2017