All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sttp.tapir.server.pekkogrpc.PekkoGrpcRequestBody.scala Maven / Gradle / Ivy

There is a newer version: 1.11.4
Show newest version
package sttp.tapir.server.pekkogrpc

import org.apache.pekko.grpc.internal.{GrpcProtocolNative, Identity, SingleParameterSink}
import org.apache.pekko.http.scaladsl.model.HttpEntity
import org.apache.pekko.http.scaladsl.server.RequestContext
import org.apache.pekko.stream.Materializer
import org.apache.pekko.util.ByteString
import sttp.capabilities.pekko.PekkoStreams
import sttp.tapir.{InputStreamRange, RawBodyType}
import sttp.tapir.model.ServerRequest
import sttp.tapir.server.pekkohttp.PekkoHttpServerOptions
import sttp.tapir.server.interpreter.{RawValue, RequestBody}

import scala.concurrent.{ExecutionContext, Future}
import scala.util.Try

private[pekkogrpc] class PekkoGrpcRequestBody(serverOptions: PekkoHttpServerOptions)(implicit
    mat: Materializer,
    ec: ExecutionContext
) extends RequestBody[Future, PekkoStreams] {
  private val grpcProtocol = GrpcProtocolNative.newReader(Identity)

  override val streams: PekkoStreams = PekkoStreams
  override def toRaw[R](request: ServerRequest, bodyType: RawBodyType[R], maxBytes: Option[Long]): Future[RawValue[R]] =
    toRawFromEntity(request, akkaRequestEntity(request), bodyType)

  override def toStream(request: ServerRequest, maxBytes: Option[Long]): streams.BinaryStream = ???

  private def akkaRequestEntity(request: ServerRequest) = request.underlying.asInstanceOf[RequestContext].request.entity

  private def toRawFromEntity[R](request: ServerRequest, body: HttpEntity, bodyType: RawBodyType[R]): Future[RawValue[R]] = {
    // Copy-paste from akka.grpc.scaladsl.GrpcMarshalling#unmarshal
    body match {
      case HttpEntity.Strict(_, data) => Future.fromTry(Try(toExpectedBodyType(data, bodyType)))
      case _ => body.dataBytes.via(grpcProtocol.dataFrameDecoder).map(toExpectedBodyType(_, bodyType)).runWith(SingleParameterSink())
    }
  }

  private def toExpectedBodyType[R](byteString: ByteString, bodyType: RawBodyType[R]): RawValue[R] = {
    bodyType match {
      case RawBodyType.ByteArrayBody        => RawValue(byteString.toArrayUnsafe())
      case RawBodyType.ByteBufferBody       => RawValue(byteString.asByteBuffer)
      case RawBodyType.InputStreamBody      => RawValue(byteString.asInputStream)
      case RawBodyType.InputStreamRangeBody => RawValue(InputStreamRange(() => byteString.asInputStream))
      case RawBodyType.FileBody             => ???
      case m: RawBodyType.MultipartBody     => ???
      case _                                => ???
    }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy