org.http4s.EntityDecoder Scala Examples
The following examples show how to use org.http4s.EntityDecoder.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
Example 1
Source File: PriceRoutes.scala From http4s-poc-api with MIT License | 5 votes |
package server import cats.effect.Sync import cats.syntax.applicativeError._ import cats.syntax.flatMap._ import cats.syntax.functor._ import cats.syntax.show._ import errors.PriceServiceError import errors.PriceServiceError._ import external.library.syntax.response._ import model.DomainModel._ import org.http4s.dsl.Http4sDsl import org.http4s.{EntityDecoder, EntityEncoder, HttpRoutes, Method, Request, Response} import service.PriceService sealed abstract class PriceRoutes[F[_]: Sync]( implicit requestDecoder: EntityDecoder[F, PricesRequestPayload], responseEncoder: EntityEncoder[F, List[Price]] ) extends Http4sDsl[F] { def make(priceService: PriceService[F]): HttpRoutes[F] = HttpRoutes.of[F] { case req @ Method.POST -> Root => postResponse(req, priceService) handlingFailures priceServiceErrors handleErrorWith unhandledThrowable } private[this] def postResponse(request: Request[F], priceService: PriceService[F]): F[Response[F]] = for { payload <- request.as[PricesRequestPayload] prices <- priceService.prices(payload.userId, payload.productIds) resp <- Ok(prices) } yield resp private[this] def priceServiceErrors: PriceServiceError => F[Response[F]] = { case UserErr(r) => FailedDependency(r) case PreferenceErr(r) => FailedDependency(r) case ProductErr(r) => FailedDependency(r) case ProductPriceErr(r) => FailedDependency(r) case CacheLookupError(r) => FailedDependency(r) case CacheStoreError(r) => FailedDependency(r) case InvalidShippingCountry(r) => BadRequest(r) } private[this] def unhandledThrowable: Throwable => F[Response[F]] = { th => import external.library.instances.throwable._ InternalServerError(th.show) } } object PriceRoutes { def apply[ F[_]: Sync: EntityDecoder[*[_], PricesRequestPayload]: EntityEncoder[*[_], List[Price]] ]: PriceRoutes[F] = new PriceRoutes[F] {} }
Example 2
Source File: ResponseContent.scala From aws4s with MIT License | 5 votes |
package org.aws4s.core import cats.data.NonEmptyList import cats.effect.{Effect, Sync} import io.circe.Json import org.http4s.{EntityDecoder, MediaRange, Message} import org.http4s.scalaxml._ import org.http4s.circe._ private[aws4s] sealed trait ResponseContent { final def tryParse[A](pf: PartialFunction[ResponseContent, Option[A]]): Option[A] = pf.orElse[ResponseContent, Option[A]]({ case _ => None })(this) } private[aws4s] case class XmlContent(elem: scala.xml.Elem) extends ResponseContent private[aws4s] case class JsonContent(json: Json) extends ResponseContent private[aws4s] case class StringContent(text: String) extends ResponseContent private[aws4s] case object NoContent extends ResponseContent private[aws4s] object ResponseContent { implicit def entityDecoder[F[_]: Effect]: EntityDecoder[F, ResponseContent] = EntityDecoder[F, scala.xml.Elem].map(elem => XmlContent(elem)).widen[ResponseContent] orElse EntityDecoder[F, Json].map(json => JsonContent(json)).widen[ResponseContent] orElse inclusiveJsonEntityDecoder.map(json => JsonContent(json)).widen[ResponseContent] orElse EntityDecoder[F, String].map(text => StringContent(text)).widen[ResponseContent] orElse EntityDecoder[F, Unit].map(_ => NoContent).widen[ResponseContent] private def inclusiveJsonEntityDecoder[F[_]: Sync]: EntityDecoder[F, Json] = { val json = jsonDecoder[F] val extraMediaRanges = NonEmptyList.of( "application/x-amz-json-1.0" ) map (mr => MediaRange.parse(mr).getOrElse(throw new RuntimeException(s"Invalid Media Range: $mr"))) val allMediaRanges = extraMediaRanges concat json.consumes.toList EntityDecoder.decodeBy[F, Json](allMediaRanges.head, allMediaRanges.tail: _*)((msg: Message[F]) => json.decode(msg, strict = false)) } }
Example 3
Source File: ExtraEntityDecoderInstances.scala From aws4s with MIT License | 5 votes |
package org.aws4s.core import cats.Applicative import cats.data.EitherT import cats.effect.Effect import cats.implicits._ import fs2.Stream import io.circe.Decoder import org.http4s.scalaxml._ import org.http4s.{DecodeFailure, EntityDecoder, InvalidMessageBodyFailure, MediaRange} private[aws4s] object ExtraEntityDecoderInstances { implicit def streamEntityDecoder[F[_]: Applicative]: EntityDecoder[F, Stream[F, Byte]] = EntityDecoder.decodeBy(MediaRange.`*/*`) { msg => EitherT.fromEither(msg.body.asRight[DecodeFailure]) } def fromXml[F[_]: Effect, A](f: scala.xml.Elem => Option[A]): EntityDecoder[F, A] = EntityDecoder[F, scala.xml.Elem] flatMapR { elem => val result = f(elem) EitherT.fromEither(result.toRight(InvalidMessageBodyFailure("Response was not as expected"))) } implicit def circeEntityDecoder[F[_]: Effect, A: Decoder]: EntityDecoder[F, A] = org.http4s.circe.jsonOf[F, A] }
Example 4
Source File: ListBuckets.scala From aws4s with MIT License | 5 votes |
package org.aws4s.s3 import cats.effect.Effect import org.aws4s._ import org.http4s.{EntityDecoder, Method} import cats.implicits._ import fs2.Stream import org.aws4s.core.ExtraEntityDecoderInstances private[s3] case class ListBuckets[F[_]: Effect]( region: Region ) extends S3ServiceCommand[F, ListBucketsSuccess] { override val action: Method = Method.GET override val payload: F[Stream[F, Byte]] = (Stream.empty: Stream[F, Byte]).pure[F] } case class ListBucketsSuccess( buckets: List[BucketName] ) object ListBucketsSuccess { implicit def entityDecoder[F[_]: Effect]: EntityDecoder[F, ListBucketsSuccess] = ExtraEntityDecoderInstances.fromXml { elem => if (elem.label == "ListAllMyBucketsResult") (elem \ "Buckets" \ "Bucket").toList.traverse(BucketName.parse) map { buckets => ListBucketsSuccess(buckets) } else None } }
Example 5
Source File: S3ServiceCommand.scala From aws4s with MIT License | 5 votes |
package org.aws4s.s3 import cats.effect.Effect import cats.implicits._ import fs2._ import org.aws4s.PayloadSigning import org.aws4s.core.{Command, Param, RenderedParam, ServiceName} import org.http4s.headers.Host import org.http4s.{EntityDecoder, Headers, Method, Request, Uri} private[aws4s] abstract class S3ServiceCommand[F[_]: Effect, R: EntityDecoder[F, ?]] extends Command[F, Nothing, R] { override final val serviceName: ServiceName = ServiceName.S3 val action: Method val payload: F[Stream[F, Byte]] override final val payloadSigning: PayloadSigning = PayloadSigning.Signed override final val params: List[Param[Nothing]] = List.empty override final val validator: Command.Validator[Nothing] = _ => None override final val requestGenerator: List[RenderedParam[Nothing]] => F[Request[F]] = { _ => val host = s"s3.${region.name}.amazonaws.com" val uri = Uri.unsafeFromString(s"https://$host/").withPath("/") payload map { p => Request[F](action, uri, headers = Headers(Host(host))).withBodyStream(p) } } }
Example 6
Source File: S3ObjectCommand.scala From aws4s with MIT License | 5 votes |
package org.aws4s.s3 import cats.effect.Effect import org.aws4s.core.{Command, Param, RenderedParam, ServiceName} import org.http4s.{EntityDecoder, Headers, Method, Request, Uri} import fs2._ import org.http4s.headers.Host import cats.implicits._ private[aws4s] abstract class S3ObjectCommand[F[_]: Effect, R: EntityDecoder[F, ?]] extends Command[F, Nothing, R] { override final val serviceName: ServiceName = ServiceName.S3 val action: Method val bucketName: BucketName val objectPath: ObjectPath val payload: F[Stream[F, Byte]] override final val params: List[Param[Nothing]] = List.empty override final val validator: Command.Validator[Nothing] = _ => None override final val requestGenerator: List[RenderedParam[Nothing]] => F[Request[F]] = { _ => val host = s"${bucketName.value}.s3.${region.name}.amazonaws.com" val uri = Uri.unsafeFromString(s"https://$host/").withPath(objectPath.value) for { pStream <- payload pBytes <- pStream.compile.toVector r <- Request[F](action, uri, headers = Headers(Host(host))).withBody(pBytes.toArray) } yield r } }
Example 7
Source File: SendMessage.scala From aws4s with MIT License | 5 votes |
package org.aws4s.sqs import cats.effect.Effect import org.http4s.EntityDecoder import org.aws4s.core.XmlParsing._ import org.aws4s.core.{CommandPayload, ExtraEntityDecoderInstances, Param} private[sqs] case class SendMessage[F[_]: Effect]( q: Queue, messageBody: MessageBody, delaySeconds: Option[DelaySeconds] = None, messageDeduplicationId: Option[MessageDeduplicationId] = None, ) extends SqsCommand[F, SendMessageSuccess] { override val action: String = "SendMessage" override def params: List[Param[String]] = CommandPayload.params( messageBody )( delaySeconds, messageDeduplicationId ) } case class SendMessageSuccess( messageId: MessageId, md5OfMessageBody: String, sequenceNumber: Option[SequenceNumber] ) object SendMessageSuccess { implicit def entityDecoder[F[_]: Effect]: EntityDecoder[F, SendMessageSuccess] = ExtraEntityDecoderInstances.fromXml { elem => if (elem.label == "SendMessageResponse") Some( SendMessageSuccess( MessageId(text(elem)("SendMessageResult", "MessageId")), text(elem)("SendMessageResult", "MD5OfMessageBody"), integer(elem)("SendMessageResult", "SequenceNumber") map SequenceNumber ) ) else None } }
Example 8
Source File: SqsCommand.scala From aws4s with MIT License | 5 votes |
package org.aws4s.sqs import cats.effect.Effect import org.http4s.headers.Host import org.http4s.{EntityDecoder, Headers, Method, Request, UrlForm} import org.aws4s._ import org.aws4s.core.Command.Validator import org.aws4s.core.{Command, RenderedParam, ServiceName} private[sqs] abstract class SqsCommand[F[_]: Effect, R: EntityDecoder[F, ?]] extends Command[F, String, R] { val q: Queue val action: String override final val serviceName: ServiceName = ServiceName.Sqs override final val payloadSigning: PayloadSigning = PayloadSigning.Signed override final val region: Region = q.region override final val validator: Validator[String] = _ => None override final val requestGenerator: List[RenderedParam[String]] => F[Request[F]] = { params => val body = params.map(p => (p.name, p.value)).foldLeft(UrlForm())((form, newPair) => form + newPair) + ("Action" -> action) Request[F](Method.POST, q.uri, headers = Headers(Host(q.host))).withBody[UrlForm](body) } }
Example 9
Source File: ReceiveMessage.scala From aws4s with MIT License | 5 votes |
package org.aws4s.sqs import cats.effect.Effect import org.http4s.EntityDecoder import cats.implicits._ import org.aws4s.core.{CommandPayload, ExtraEntityDecoderInstances, Param} private[sqs] case class ReceiveMessage[F[_]: Effect]( q: Queue, maxNumberOfMessages: Option[MaxNumberOfMessages], visibilityTimeout: Option[VisibilityTimeout], waitTimeSeconds: Option[WaitTimeSeconds], receiveRequestAttemptId: Option[ReceiveRequestAttemptId], ) extends SqsCommand[F, ReceiveMessageSuccess] { override val action: String = "ReceiveMessage" override final val params: List[Param[String]] = CommandPayload.params()( maxNumberOfMessages, visibilityTimeout, waitTimeSeconds, receiveRequestAttemptId ) } case class ReceiveMessageSuccess( messages: List[Message] ) object ReceiveMessageSuccess { implicit def entityDecoder[F[_]: Effect]: EntityDecoder[F, ReceiveMessageSuccess] = ExtraEntityDecoderInstances.fromXml { elem => if (elem.label == "ReceiveMessageResponse") (elem \ "ReceiveMessageResult" \ "Message").toList.traverse(Message.parse) map { messages => ReceiveMessageSuccess(messages) } else None } }
Example 10
Source File: InvoicesApi.scala From event-sourcing-kafka-streams with MIT License | 5 votes |
package org.amitayh.invoices.web import java.util.UUID import cats.effect.{Concurrent, Timer} import cats.implicits._ import fs2.Stream import fs2.concurrent.Topic import io.circe._ import io.circe.generic.auto._ import io.circe.syntax._ import org.amitayh.invoices.common.domain.CommandResult.{Failure, Success} import org.amitayh.invoices.common.domain.{Command, CommandResult} import org.amitayh.invoices.dao.InvoiceList import org.amitayh.invoices.web.CommandDto._ import org.amitayh.invoices.web.PushEvents.CommandResultRecord import org.http4s.circe._ import org.http4s.dsl.Http4sDsl import org.http4s.{EntityDecoder, HttpRoutes, Response} import scala.concurrent.duration._ class InvoicesApi[F[_]: Concurrent: Timer] extends Http4sDsl[F] { private val maxQueued = 16 implicit val commandEntityDecoder: EntityDecoder[F, Command] = jsonOf[F, Command] def service(invoiceList: InvoiceList[F], producer: Kafka.Producer[F, UUID, Command], commandResultsTopic: Topic[F, CommandResultRecord]): HttpRoutes[F] = HttpRoutes.of[F] { case GET -> Root / "invoices" => invoiceList.get.flatMap(invoices => Ok(invoices.asJson)) case request @ POST -> Root / "execute" / "async" / UuidVar(invoiceId) => request .as[Command] .flatMap(producer.send(invoiceId, _)) .flatMap(metaData => Accepted(Json.fromLong(metaData.timestamp))) case request @ POST -> Root / "execute" / UuidVar(invoiceId) => request.as[Command].flatMap { command => val response = resultStream(commandResultsTopic, command.commandId) merge timeoutStream producer.send(invoiceId, command) *> response.head.compile.toList.map(_.head) } } private def resultStream(commandResultsTopic: Topic[F, CommandResultRecord], commandId: UUID): Stream[F, Response[F]] = commandResultsTopic.subscribe(maxQueued).collectFirst { case Some((_, CommandResult(_, `commandId`, outcome))) => outcome }.flatMap { case Success(_, _, snapshot) => Stream.eval(Ok(snapshot.asJson)) case Failure(cause) => Stream.eval(UnprocessableEntity(cause.message)) } private def timeoutStream: Stream[F, Response[F]] = Stream.eval(Timer[F].sleep(5.seconds) *> RequestTimeout("timeout")) } object InvoicesApi { def apply[F[_]: Concurrent: Timer]: InvoicesApi[F] = new InvoicesApi[F] }
Example 11
Source File: Http4sRequestToRawBody.scala From tapir with Apache License 2.0 | 5 votes |
package sttp.tapir.server.http4s import java.io.ByteArrayInputStream import cats.effect.{Blocker, ContextShift, Sync} import cats.implicits._ import fs2.Chunk import org.http4s.headers.{`Content-Disposition`, `Content-Type`} import org.http4s.{Charset, EntityDecoder, Request, multipart} import sttp.model.{Header, Part} import sttp.tapir.{RawPart, RawBodyType} class Http4sRequestToRawBody[F[_]: Sync: ContextShift](serverOptions: Http4sServerOptions[F]) { def apply[R](body: fs2.Stream[F, Byte], bodyType: RawBodyType[R], charset: Option[Charset], req: Request[F]): F[R] = { def asChunk: F[Chunk[Byte]] = body.compile.to(Chunk) def asByteArray: F[Array[Byte]] = body.compile.to(Chunk).map(_.toByteBuffer.array()) bodyType match { case RawBodyType.StringBody(defaultCharset) => asByteArray.map(new String(_, charset.map(_.nioCharset).getOrElse(defaultCharset))) case RawBodyType.ByteArrayBody => asByteArray case RawBodyType.ByteBufferBody => asChunk.map(_.toByteBuffer) case RawBodyType.InputStreamBody => asByteArray.map(new ByteArrayInputStream(_)) case RawBodyType.FileBody => serverOptions.createFile(serverOptions.blockingExecutionContext, req).flatMap { file => val fileSink = fs2.io.file.writeAll(file.toPath, Blocker.liftExecutionContext(serverOptions.blockingExecutionContext)) body.through(fileSink).compile.drain.map(_ => file) } case m: RawBodyType.MultipartBody => // TODO: use MultipartDecoder.mixedMultipart once available? implicitly[EntityDecoder[F, multipart.Multipart[F]]].decode(req, strict = false).value.flatMap { case Left(failure) => throw new IllegalArgumentException("Cannot decode multipart body: " + failure) // TODO case Right(mp) => val rawPartsF: Vector[F[RawPart]] = mp.parts .flatMap(part => part.name.flatMap(name => m.partType(name)).map((part, _)).toList) .map { case (part, codecMeta) => toRawPart(part, codecMeta, req).asInstanceOf[F[RawPart]] } val rawParts: F[Vector[RawPart]] = rawPartsF.sequence rawParts.asInstanceOf[F[R]] // R is Seq[RawPart] } } } private def toRawPart[R](part: multipart.Part[F], partType: RawBodyType[R], req: Request[F]): F[Part[R]] = { val dispositionParams = part.headers.get(`Content-Disposition`).map(_.parameters).getOrElse(Map.empty) val charset = part.headers.get(`Content-Type`).flatMap(_.charset) apply(part.body, partType, charset, req) .map(r => Part( part.name.getOrElse(""), r, otherDispositionParams = dispositionParams - Part.NameDispositionParam, headers = part.headers.toList.map(h => Header(h.name.value, h.value)) ) ) } }
Example 12
Source File: ResponseVerificationSyntax.scala From http4s-poc-api with MIT License | 5 votes |
package syntax import java.nio.charset.StandardCharsets import cats.data.Validated import cats.instances.string._ import cats.syntax.eq._ import cats.syntax.show._ import cats.syntax.validated._ import cats.{Eq, Show} import org.http4s.{EntityDecoder, Response, Status} import typeclasses.RunSync import zio.Task import zio.interop.catz._ import scala.language.implicitConversions private[syntax] trait ResponseVerificationSyntax { implicit def verifiedSyntax[A](a: A): VerifiedOps[A] = new VerifiedOps(a) implicit def verifiedOptionSyntax[A](a: Option[A]): VerifiedOptionOps[A] = new VerifiedOptionOps(a) implicit def responseVerificationSyntax(response: Task[Response[Task]]) = new IoResponseResultOps(response) } private[syntax] class IoResponseResultOps(private val response: Task[Response[Task]]) extends AnyVal { import syntax.responseVerification._ def verify[A: EntityDecoder[Task, *]](status: Status, check: A => Verified[A])( implicit ev1: Eq[Status], ev2: Show[Status], run: RunSync[Task] ): Verified[A] = run .syncUnsafe(response) .fold( err => s"Should succeed but returned the error $err".invalidNel, res => res.status isSameAs status andThen { _ => verifiedResponse[A](res, check) } ) def verifyResponseText(status: Status, expected: String)( implicit ev1: Eq[Status], ev2: Show[Status], run: RunSync[Task] ): Verified[String] = run .syncUnsafe(response) .fold( err => s"Should succeed but returned the error $err".invalidNel, res => res.status isSameAs status andThen { _ => verifiedResponseText(res, expected) } ) private def verifiedResponse[A: EntityDecoder[Task, *]](res: Response[Task], check: A => Verified[A])( implicit run: RunSync[Task] ): Verified[A] = run .syncUnsafe(res.as[A]) .fold( respErr => s"Response should succeed but returned the error $respErr".invalidNel, respRes => check(respRes) ) private def verifiedResponseText[A](res: Response[Task], expected: String)( implicit run: RunSync[Task] ): Verified[String] = run .syncUnsafe(res.body.compile.toVector) .map(_.toArray) .fold( respErr => s"Response should succeed but returned the error $respErr".invalidNel, respMsg => new String(respMsg, StandardCharsets.UTF_8) isSameAs expected ) } private[syntax] class VerifiedOps[A](private val a: A) extends AnyVal { def isNotSameAs(expected: =>A)(implicit ev1: Eq[A], ev2: Show[A]): Verified[A] = Validated.condNel( a =!= expected, a, s"Unexpected value. Expected different from ${expected.show} but was ${a.show}" ) def isSameAs(expected: =>A)(implicit ev1: Eq[A], ev2: Show[A]): Verified[A] = Validated.condNel(a === expected, a, s"Unexpected value. Expected ${expected.show} but was ${a.show}") def is(p: A => Boolean, reason: =>String = "")(implicit ev: Show[A]): Verified[A] = Validated.condNel(p(a), a, s"Unexpected value ${a.show}: Reason $reason") } private[syntax] class VerifiedOptionOps[A](private val a: Option[A]) extends AnyVal { def isNotEmpty: Verified[Option[A]] = Validated.condNel(a.isDefined, a, s"Unexpected empty option value") }
Example 13
Source File: Http4sRpcTransport.scala From iotchain with MIT License | 5 votes |
package jbok.network.rpc.http import cats.effect.ConcurrentEffect import jbok.network.rpc.{RpcRequest, RpcResponse, RpcTransport} import org.http4s.client.blaze.BlazeClientBuilder import org.http4s.{EntityDecoder, EntityEncoder, Method, Request, Uri} import scala.concurrent.ExecutionContext final class Http4sRpcTransport[F[_], P]( baseUri: Uri )(implicit F: ConcurrentEffect[F], entityEncoder: EntityEncoder[F, P], entityDecoder: EntityDecoder[F, RpcResponse[P]]) extends RpcTransport[F, P] { override def fetch(request: RpcRequest[P]): F[RpcResponse[P]] = { val uri = request.path.foldLeft(baseUri)(_ / _) val req = Request[F](Method.POST, uri = uri).withEntity(request.payload) BlazeClientBuilder[F](ExecutionContext.global).resource.use { client => client.fetchAs[RpcResponse[P]](req) } } }
Example 14
Source File: Main.scala From http4s-poc-api with MIT License | 5 votes |
package server import java.util.concurrent.Executors import com.github.ghik.silencer.silent import external.{TeamOneHttpApi, TeamThreeCacheApi, TeamTwoHttpApi} import io.circe.generic.auto._ import log.effect.zio.ZioLogWriter._ import model.DomainModel._ import org.http4s.circe._ import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.syntax.kleisli._ import org.http4s.{EntityDecoder, EntityEncoder, HttpApp} import service.PriceService import zio.interop.catz._ import zio.interop.catz.implicits._ import zio.{ExitCode, RIO, Task, ZEnv, ZIO} import scala.concurrent.ExecutionContext import model.DomainModelCodecs._ @silent object Main extends zio.interop.catz.CatsApp with Pools with Codecs { private[this] val priceService: RIO[String, PriceService[Task]] = log4sFromName map { log => PriceService[Task]( TeamThreeCacheApi.productCache, TeamOneHttpApi(), TeamTwoHttpApi(), log ) } private[this] val httpApp: RIO[PriceService[Task], HttpApp[Task]] = ZIO.access { ps => Router( "/pricing-api/prices" -> PriceRoutes[Task].make(ps), "/pricing-api/health-check" -> HealthCheckRoutes[Task].make(ps.logger) ).orNotFound } private[this] val runningServer: RIO[HttpApp[Task], Unit] = ZIO.accessM { app => BlazeServerBuilder[Task](serverPool) .bindHttp(17171, "0.0.0.0") .withConnectorPoolSize(connectorPoolSize) .enableHttp2(true) .withHttpApp(app) .serve .compile .drain } private[this] val serviceRuntime: RIO[String, Unit] = priceService >>> httpApp >>> runningServer def run(args: List[String]): ZIO[ZEnv, Nothing, ExitCode] = serviceRuntime.fold(_ => ExitCode.failure, _ => ExitCode.success) provide "App log" } sealed trait Pools { protected val connectorPoolSize = Runtime.getRuntime.availableProcessors() * 2 protected val mainThreadNumber = Runtime.getRuntime.availableProcessors() + 1 protected val serverPool = ExecutionContext.fromExecutor( Executors.newWorkStealingPool(mainThreadNumber) ) } sealed trait Codecs { implicit val priceRequestPayloadDecoder: EntityDecoder[Task, PricesRequestPayload] = jsonOf[Task, PricesRequestPayload] implicit val priceResponsePayloadEncoder: EntityEncoder[Task, List[Price]] = jsonEncoderOf[Task, List[Price]] implicit val healthCheckResponsePayloadEncoder: EntityEncoder[Task, ServiceSignature] = jsonEncoderOf[Task, ServiceSignature] }
Example 15
Source File: BidderHttpAppBuilder.scala From scala-openrtb with Apache License 2.0 | 5 votes |
package com.powerspace.openrtb.examples.rtb.http4s.bidder import com.google.openrtb.BidRequest import com.powerspace.openrtb.examples.rtb.http4s.common.ExampleSerdeModule import io.circe.Decoder import monix.eval.Task import org.http4s.dsl.Http4sDsl import org.http4s.{EntityDecoder, HttpApp} object BidderHttpAppBuilder { private val bidder = new Bidder[Task] private val dsl = Http4sDsl[Task] private val serdeModule = ExampleSerdeModule private def handleBid(bidRequest: BidRequest) = { import dsl._ import org.http4s.circe._ bidder .bidOn(bidRequest) .flatMap { case Some(bidResponse) => // encode the bidResponse to a json object as part of the http response body Ok(serdeModule.bidResponseEncoder(bidResponse)) case None => Ok() } } }
Example 16
Source File: AdserverHttpClientBuilder.scala From scala-openrtb with Apache License 2.0 | 5 votes |
package com.powerspace.openrtb.examples.rtb.http4s.adserver import com.google.openrtb.{BidRequest, BidResponse} import com.powerspace.openrtb.examples.rtb.http4s.common.ExampleSerdeModule import com.powerspace.openrtb.json.SerdeModule import io.circe.{Decoder, Encoder} import monix.eval.Task import org.http4s.Uri.{Authority, RegName, Scheme} import org.http4s.client.Client import org.http4s.{EntityDecoder, EntityEncoder, Method, Request, Uri} object AdserverHttpClientBuilder { import org.http4s.circe._ val serdeModule: SerdeModule = ExampleSerdeModule implicit val bidRequestEncoder: Encoder[BidRequest] = serdeModule.bidRequestEncoder implicit val bidRequestEntityEncoder: EntityEncoder[Task, BidRequest] = jsonEncoderOf[Task, BidRequest] implicit val bidResponseDecoder: Decoder[BidResponse] = serdeModule.bidResponseDecoder implicit val bidResponseEntityDecoder: EntityDecoder[Task, BidResponse] = jsonOf[Task, BidResponse] def bid(client: Client[Task], bidRequest: BidRequest): Task[Option[BidResponse]] = { val url = Uri( scheme = Some(Scheme.http), authority = Some(Authority(host = RegName("localhost"), port = Some(9000))), path = "/bid" ) val httpRequest = Request[Task]( method = Method.POST, uri = url ).withEntity[BidRequest](bidRequest) client.expectOption[BidResponse](httpRequest) } }
Example 17
Source File: LoginTest.scala From scala-pet-store with Apache License 2.0 | 5 votes |
package io.github.pauljamescleary.petstore package infrastructure.endpoint import cats.data.Kleisli import cats.effect.IO import domain.authentication.{LoginRequest, SignupRequest} import domain.users.{Role, User} import org.http4s.circe.{jsonEncoderOf, jsonOf} import org.http4s.client.dsl.Http4sClientDsl import org.http4s.{EntityDecoder, EntityEncoder, HttpApp, Request, Response} import org.http4s.implicits._ import org.http4s.headers.Authorization import io.circe.generic.auto._ import org.http4s.dsl.Http4sDsl trait LoginTest extends Http4sClientDsl[IO] with Http4sDsl[IO] { implicit val userEnc: EntityEncoder[IO, User] = jsonEncoderOf implicit val userDec: EntityDecoder[IO, User] = jsonOf implicit val signUpRequestEnc: EntityEncoder[IO, SignupRequest] = jsonEncoderOf implicit val signUpRequestDec: EntityDecoder[IO, SignupRequest] = jsonOf implicit val loginRequestEnc: EntityEncoder[IO, LoginRequest] = jsonEncoderOf implicit val loginRequestDec: EntityDecoder[IO, LoginRequest] = jsonOf def signUpAndLogIn( userSignUp: SignupRequest, userEndpoint: HttpApp[IO], ): IO[(User, Option[Authorization])] = for { signUpRq <- POST(userSignUp, uri"/users") signUpResp <- userEndpoint.run(signUpRq) user <- signUpResp.as[User] loginBody = LoginRequest(userSignUp.userName, userSignUp.password) loginRq <- POST(loginBody, uri"/users/login") loginResp <- userEndpoint.run(loginRq) } yield { user -> loginResp.headers.get(Authorization) } def signUpAndLogInAsAdmin( userSignUp: SignupRequest, userEndpoint: Kleisli[IO, Request[IO], Response[IO]], ): IO[(User, Option[Authorization])] = signUpAndLogIn(userSignUp.copy(role = Role.Admin), userEndpoint) def signUpAndLogInAsCustomer( userSignUp: SignupRequest, userEndpoint: Kleisli[IO, Request[IO], Response[IO]], ): IO[(User, Option[Authorization])] = signUpAndLogIn(userSignUp.copy(role = Role.Customer), userEndpoint) }
Example 18
Source File: Proxy.scala From kubernetes-client with Apache License 2.0 | 5 votes |
package com.goyeau.kubernetes.client.operation import cats.effect.Sync import com.goyeau.kubernetes.client.KubeConfig import org.http4s._ import org.http4s.dsl.impl.Path import org.http4s.client.Client import org.http4s.EntityDecoder import org.http4s.headers.`Content-Type` private[client] trait Proxy[F[_]] { protected def httpClient: Client[F] implicit protected val F: Sync[F] protected def config: KubeConfig protected def resourceUri: Uri def proxy( name: String, method: Method, path: Path, contentType: `Content-Type` = `Content-Type`(MediaType.text.plain), data: Option[String] = None ): F[String] = httpClient.expect[String]( Request( method, config.server.resolve(resourceUri) / name / s"proxy$path", headers = Headers(config.authorization.toList), body = data.fold[EntityBody[F]](EmptyBody)( implicitly[EntityEncoder[F, String]].withContentType(contentType).toEntity(_).body ) ) )(EntityDecoder.text) }
Example 19
Source File: TestRoutes.scala From scala-server-lambda with MIT License | 5 votes |
package io.github.howardjohn.lambda.http4s import cats.{Applicative, MonadError} import cats.effect.Sync import cats.implicits._ import io.github.howardjohn.lambda.LambdaHandlerBehavior import io.github.howardjohn.lambda.LambdaHandlerBehavior._ import org.http4s.dsl.Http4sDsl import org.http4s.{EntityDecoder, Header, HttpRoutes} import org.http4s.circe._ import io.circe.generic.auto._ import io.circe.syntax._ import org.http4s.dsl.impl.OptionalQueryParamDecoderMatcher class TestRoutes[F[_]] { object TimesQueryMatcher extends OptionalQueryParamDecoderMatcher[Int]("times") val dsl = Http4sDsl[F] import dsl._ def routes(implicit sync: Sync[F], jsonDecoder: EntityDecoder[F, JsonBody], me: MonadError[F, Throwable], stringDecoder: EntityDecoder[F, String], ap: Applicative[F]): HttpRoutes[F] = HttpRoutes.of[F] { case GET -> Root / "hello" :? TimesQueryMatcher(times) => Ok { Seq .fill(times.getOrElse(1))("Hello World!") .mkString(" ") } case GET -> Root / "long" => Applicative[F].pure(Thread.sleep(1000)).flatMap(_ => Ok("Hello World!")) case GET -> Root / "exception" => throw RouteException() case GET -> Root / "error" => InternalServerError() case req@GET -> Root / "header" => val header = req.headers.find(h => h.name.value == inputHeader).map(_.value).getOrElse("Header Not Found") Ok(header, Header(outputHeader, outputHeaderValue)) case req@POST -> Root / "post" => req.as[String].flatMap(s => Ok(s)) case req@POST -> Root / "json" => req.as[JsonBody].flatMap(s => Ok(LambdaHandlerBehavior.jsonReturn.asJson)) } }
Example 20
Source File: Http4sSpec.scala From codepropertygraph with Apache License 2.0 | 5 votes |
package io.shiftleft.cpgserver.route import cats.effect.IO import org.http4s.{EntityDecoder, Response, Status} import io.shiftleft.cpgserver.BaseSpec trait Http4sSpec extends BaseSpec { // Helpfully lifted from https://http4s.org/v0.20/testing/ def check[A](actual: IO[Response[IO]], expectedStatus: Status, expectedBody: Option[A] = None)( implicit ev: EntityDecoder[IO, A] ): Boolean = { val actualResp = actual.unsafeRunSync val statusCheck = actualResp.status == expectedStatus val bodyCheck = expectedBody.fold[Boolean](actualResp.body.compile.toVector.unsafeRunSync.isEmpty)( // Verify Response's body is empty. expected => actualResp.as[A].unsafeRunSync == expected) statusCheck && bodyCheck } }
Example 21
Source File: HttpUploadTest.scala From temperature-machine with Apache License 2.0 | 5 votes |
package bad.robot.temperature.client import java.net.InetAddress import bad.robot.temperature.rrd.{Host, Seconds} import bad.robot.temperature.{IpAddress, Measurement, SensorReading, Temperature, UnexpectedError, jsonEncoder} import cats.data.Kleisli import cats.effect.IO import org.http4s.Method.PUT import org.http4s.client.{DisposableResponse, Client => Http4sClient} import org.http4s.dsl.io._ import org.http4s.{EntityDecoder, Request} import org.specs2.matcher.DisjunctionMatchers._ import org.specs2.mutable.Specification class HttpUploadTest extends Specification { "Ip address pre-check" >> { IpAddress.currentIpAddress.size must be_>(0) } "Encode a measurement for the wire" >> { def encodeMessageViaEntityEncoder(measurement: Measurement): String = { implicit val encoder = jsonEncoder[Measurement] val request: IO[Request[IO]] = Request(PUT).withBody(measurement) EntityDecoder.decodeString(request.unsafeRunSync()).unsafeRunSync() } val measurement = Measurement(Host("example"), Seconds(1509221361), List(SensorReading("28-0115910f5eff", Temperature(19.75)))) encodeMessageViaEntityEncoder(measurement) must_== """|{ | "host" : { | "name" : "example", | "utcOffset" : null, | "timezone" : null | }, | "seconds" : 1509221361, | "sensors" : [ | { | "name" : "28-0115910f5eff", | "temperature" : { | "celsius" : 19.75 | } | } | ] |}""".stripMargin } "Error response from server" >> { val measurement = Measurement(Host("example"), Seconds(1509221361), List(SensorReading("28-0115910f5eff", Temperature(19.75)))) val error = InternalServerError("I'm an error").map(DisposableResponse(_, IO.pure(()))) val willError: Kleisli[IO, Request[IO], DisposableResponse[IO]] = new Kleisli[IO, Request[IO], DisposableResponse[IO]](_ => error) val client = Http4sClient[IO](willError, IO.pure(())) val upload = HttpUpload(InetAddress.getLoopbackAddress, client) val value = upload.write(measurement) value must be_-\/.like { case UnexpectedError("""Failed to PUT temperature data to http://127.0.0.1:11900/temperature, response was 500 Internal Server Error: Right(I'm an error)""") => ok } } "Request has headers" >> { val measurement = Measurement(Host("example"), Seconds(1509221361), List(SensorReading("28-0115910f5eff", Temperature(19.75)))) var headers = List[String]() val client = Http4sClient[IO](new Kleisli[IO, Request[IO], DisposableResponse[IO]](request => { headers = request.headers.map(_.name.toString()).toList Ok().map(DisposableResponse(_, IO.pure(()))) }), IO.pure(())) val upload = HttpUpload(InetAddress.getLoopbackAddress, client) upload.write(measurement) headers must_== List( "Content-Type", "X-Forwarded-For", "Content-Length" ) } }
Example 22
Source File: package.scala From temperature-machine with Apache License 2.0 | 5 votes |
package bad.robot import java.io.{File, PrintWriter, StringWriter} import cats.effect.IO import cats.syntax.either._ import io.circe._ import org.http4s.circe.{jsonEncoderWithPrinterOf, jsonOf} import io.circe.parser._ import org.http4s.{EntityDecoder, EntityEncoder} import scalaz.\/ import scalaz.syntax.std.either._ package object temperature { type Degrees = Int // NB not implicit as this seems to clash with http4s implicits that are kicking around def jsonDecoder[A: Decoder]: EntityDecoder[IO, A] = jsonOf[IO, A] def jsonEncoder[A: Encoder]: EntityEncoder[IO, A] = jsonEncoderWithPrinterOf(spaces2PlatformSpecific) def encode[A: Encoder](a: A): Json = Encoder[A].apply(a) // deprecated def decodeAsDisjunction[A: Decoder](value: String): temperature.Error \/ A = { decode(value) .leftMap(error => ParseError(error.getMessage)) .disjunction } def stackTraceOf(error: Throwable): String = { val writer = new StringWriter() error.printStackTrace(new PrintWriter(writer)) writer.toString } private val eol = sys.props("line.separator") val spaces2PlatformSpecific = Printer( preserveOrder = true , dropNullValues = false , indent = " " , lbraceLeft = "" , lbraceRight = eol , rbraceLeft = eol , rbraceRight = "" , lbracketLeft = "" , lbracketRight = eol , rbracketLeft = eol , rbracketRight = "" , lrbracketsEmpty = "" , arrayCommaLeft = "" , arrayCommaRight = eol , objectCommaLeft = "" , objectCommaRight = eol , colonLeft = " " , colonRight = " " ) implicit class JsonOps(json: Json) { def spaces2ps: String = spaces2PlatformSpecific.pretty(json) } implicit class FileOps(file: File) { def /(child: String): File = new File(file, child) } }
Example 23
Source File: Http4sCirceInstances.scala From pure-movie-server with Apache License 2.0 | 5 votes |
package pms.http import fs2.Chunk import io.circe.Printer import pms.effects._ import pms.json._ import org.http4s._ import org.http4s.headers.`Content-Type` import org.http4s.{EntityDecoder, EntityEncoder} import org.http4s.circe.CirceInstances implicit def syncEntityJsonEncoder[F[_]: Applicative, T: Encoder]: EntityEncoder[F, T] = EntityEncoder[F, Chunk[Byte]] .contramap[Json] { json => val bytes = printer.printToByteBuffer(json) Chunk.byteBuffer(bytes) } .withContentType(`Content-Type`(MediaType.application.json)) .contramap(t => Encoder.apply[T].apply(t)) implicit def syncEntityJsonDecoder[F[_]: Sync, T: Decoder]: EntityDecoder[F, T] = circeInstances.jsonOf[F, T] } object Http4sCirceInstances { private val printer: Printer = Printer.noSpaces.copy(dropNullValues = true) private val circeInstances: CirceInstances = CirceInstances.withPrinter(printer).build }
Example 24
Source File: MavenCentralClient.scala From zorechka-bot with MIT License | 5 votes |
package com.wix.zorechka.clients import com.wix.zorechka.Dep import org.http4s.{EntityDecoder, Header, Headers, Method, Request, Uri} import zio.{Task, ZIO} import zio.interop.catz._ import io.circe.generic.auto._ import org.http4s.circe.jsonOf import org.http4s.client.Client trait MavenCentralClient { val client: MavenCentralClient.Service } object MavenCentralClient { trait Service { def allVersions(dep: Dep): Task[List[Dep]] } trait Live extends MavenCentralClient { protected val httpClient: Client[Task] val client = new MavenCentralClient.Service { case class Response(response: InnerResponse) case class InnerResponse(docs: Seq[Document]) case class Document(v: String) implicit val decoder: EntityDecoder[Task, Response] = jsonOf[Task, Response] override def allVersions(dep: Dep): Task[List[Dep]] = { ZIO.accessM { client => val uri = Uri .unsafeFromString("http://search.maven.org/solrsearch/select") .withQueryParam("rows", "10") .withQueryParam("core", "gav") .withQueryParam("q", s""" g:"${dep.groupId}" AND a:"${dep.artifactId}" """) println(s"Maven search: ${uri.renderString}") val request = Request[Task](Method.GET, uri, headers = Headers.of(Header("Accept", "application/json"))) httpClient.fetch(request)(response => response.as[Response]).map { _.response.docs.map(_.v).map(v => Dep(dep.groupId, dep.artifactId, v)).toList } } } } } }