Skip to content

Commit

Permalink
refactor: remove imports and use correct encoder and decoder
Browse files Browse the repository at this point in the history
  • Loading branch information
MoeQuadrat committed Feb 5, 2024
1 parent 564c69e commit 2896a79
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 78 deletions.
2 changes: 1 addition & 1 deletion project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
addSbtPlugin("com.codecommit" %% "sbt-github-packages" % "0.5.3")
addSbtPlugin("org.wartremover" %% "sbt-wartremover" % "3.1.5")
addSbtPlugin("org.scalameta" %% "sbt-scalafmt" % "2.5.2")
addSbtPlugin("com.disneystreaming.smithy4s" %% "smithy4s-sbt-codegen" % "0.18.3")
addSbtPlugin("com.disneystreaming.smithy4s" %% "smithy4s-sbt-codegen" % "0.18.7")
addSbtPlugin("com.typesafe.play" %% "sbt-plugin" % "2.9.1")
addSbtPlugin("org.scoverage" %% "sbt-scoverage" % "2.0.9")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ package de.innfactory.smithy4play
import smithy4s.capability.instances.either._
import smithy4s.codecs.Writer.CachedCompiler
import smithy4s.codecs._
import smithy4s.http.{ HttpRequest, HttpResponse, HttpRestSchema, Metadata, MetadataError }
import smithy4s.http.{HttpResponse, HttpRestSchema, Metadata, MetadataError}
import smithy4s.json.Json
import smithy4s.kinds.PolyFunction
import smithy4s.schema.CachedSchemaCompiler
import smithy4s.xml.Xml
import smithy4s.{ codecs, Blob }
import smithy4s.{Blob, codecs}

object CodecDecider {

Expand All @@ -24,16 +24,14 @@ object CodecDecider {

def encoder(
contentType: Seq[String]
): CachedSchemaCompiler[codecs.BlobEncoder] = {
println(contentType)
): CachedSchemaCompiler[codecs.BlobEncoder] =
contentType match {
case Seq("application/json") => jsonEncoder
case Seq("application/xml") => Xml.encoders
case _ =>
CachedSchemaCompiler
.getOrElse(smithy4s.codecs.StringAndBlobCodecs.encoders, jsonEncoder)
}
}

def requestDecoder(
contentType: Seq[String]
Expand Down Expand Up @@ -65,7 +63,7 @@ object CodecDecider {
_ => true
)

def httpMessageDecoder(
def httpResponseDecoder(
contentType: Seq[String]
): CachedSchemaCompiler[Decoder[Either[Throwable, *], HttpResponse[Blob], *]] =
HttpRestSchema.combineDecoderCompilers[Either[Throwable, *], HttpResponse[Blob]](
Expand Down Expand Up @@ -127,15 +125,13 @@ object CodecDecider {

def decoder(
contentType: Seq[String]
): CachedSchemaCompiler[BlobDecoder] = {
println(contentType)
): CachedSchemaCompiler[BlobDecoder] =
contentType match {
case Seq("application/json") => jsonDecoder
case Seq("application/xml") => Xml.decoders
case _ =>
CachedSchemaCompiler
.getOrElse(smithy4s.codecs.StringAndBlobCodecs.decoders, jsonDecoder)
}
}

}
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
package de.innfactory.smithy4play

import cats.MonadThrow
import cats.data.{ EitherT, Kleisli }
import cats.implicits.{ toFunctorOps, toTraverseOps }
import cats.data.{EitherT, Kleisli}
import de.innfactory.smithy4play
import de.innfactory.smithy4play.middleware.MiddlewareBase
import fs2.Compiler.Target.{ forConcurrent, forSync }
import play.api.mvc._
import smithy4s.capability.MonadThrowLike
import smithy4s.codecs.{ Decoder, PayloadError }
import smithy4s.codecs.PayloadError
import smithy4s.http._
import smithy4s.kinds.FunctorInterpreter
import smithy4s.schema.Schema
import smithy4s.{ Blob, Endpoint, Service }
import smithy4s.{Blob, Endpoint, Service}

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

class SmithyPlayEndpoint[Alg[_[_, _, _, _, _]], F[_] <: ContextRoute[_], Op[
_,
Expand Down Expand Up @@ -70,16 +66,21 @@ class SmithyPlayEndpoint[Alg[_[_, _, _, _, _]], F[_] <: ContextRoute[_], Op[
}
.getOrElse(Action(NotFound("404")))

private def mapToEndpointResult(statusCode: Int)(o: O): EndpointRequest = {
private def mapToEndpointResult(statusCode: Int)(o: O): HttpResponse[Blob] = {
val outputMetadata = outputMetadataEncoder.encode(o)
val outputHeaders = outputMetadata.headers.map { case (k, v) =>
(k.toString.toLowerCase, v.mkString(""))
}
val contentType = outputHeaders.getOrElse("content-type", "application/json")
val outputHeaders = outputMetadata.headers
val contentType = outputHeaders.getOrElse(CaseInsensitive("content-type"), Seq("application/json"))
CodecDecider
.requestEncoder(Seq(contentType))
.httpMessageEncoder(contentType)
.fromSchema(outputSchema)
.write(PlayHttpRequest(Blob.empty, Metadata.empty.copy(statusCode = Some(statusCode))), o)
.write(
HttpResponse(
statusCode = statusCode,
headers = outputHeaders.updated(CaseInsensitive("content-type"), contentType),
body = Blob.empty
),
o
)
}

private def getPathParams(
Expand Down Expand Up @@ -119,10 +120,8 @@ class SmithyPlayEndpoint[Alg[_[_, _, _, _, _]], F[_] <: ContextRoute[_], Op[
}
}.leftMap {
case error: PayloadError =>
println(error)
Smithy4PlayError("expected: " + error.expected, smithy4play.Status(Map.empty, 500))
case error: MetadataError =>
println(error)
Smithy4PlayError(error.getMessage(), smithy4play.Status(Map.empty, 500))
}

Expand All @@ -136,12 +135,12 @@ class SmithyPlayEndpoint[Alg[_[_, _, _, _, _]], F[_] <: ContextRoute[_], Op[
private def handleFailure(error: ContextRouteError): Result =
Results.Status(error.status.statusCode)(error.toJson).withHeaders(error.status.headers.toList: _*)

private def handleSuccess(output: EndpointRequest): Result = {
val status = Results.Status(output.metadata.statusCode.getOrElse(200))
private def handleSuccess(output: HttpResponse[Blob]): Result = {
val status = Results.Status(output.statusCode)
val outputHeadersWithoutContentType =
output.metadata.headers.-(CaseInsensitive("content-type")).toList.map(h => (h._1.toString, h._2.head))
output.headers.-(CaseInsensitive("content-type")).toList.map(h => (h._1.toString, h._2.head))
val contentType =
output.metadata.headers.getOrElse(CaseInsensitive("content-type"), Seq("application/json"))
output.headers.getOrElse(CaseInsensitive("content-type"), Seq("application/json"))

if (!output.body.isEmpty) {
status(output.body.toArray)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@ package smithy4play
package client

import cats.implicits._
import smithy4s.codecs.{ BlobEncoder, PayloadDecoder, PayloadEncoder, PayloadError }
import smithy4s.codecs.PayloadError
import smithy4s.http._
import smithy4s.json.Json.payloadCodecs
import smithy4s.schema.CachedSchemaCompiler
import smithy4s.xml.Xml
import smithy4s.{ Blob, Endpoint, Schema }
import smithy4s.{Blob, Endpoint, Schema}

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

private[smithy4play] class SmithyPlayClientEndpoint[Op[_, _, _, _, _], I, E, O, SI, SO](
endpoint: Endpoint[Op, I, E, O, SI, SO],
Expand All @@ -26,7 +23,7 @@ private[smithy4play] class SmithyPlayClientEndpoint[Op[_, _, _, _, _], I, E, O,
private implicit val outputSchema: Schema[O] = endpoint.output

private val inputMetadataEncoder =
Metadata.Encoder.fromSchema(inputSchema)
Metadata.Encoder.fromSchema(HttpRestSchema.OnlyMetadata(inputSchema).schema)

def send(
): ClientResponse[O] = {
Expand All @@ -36,16 +33,12 @@ private[smithy4play] class SmithyPlayClientEndpoint[Op[_, _, _, _, _], I, E, O,
val contentTypeOpt = headers.get(CaseInsensitive("content-type"))
val contentType = contentTypeOpt.getOrElse(Seq("application/json"))
val headersWithAuth = if (additionalHeaders.isDefined) headers.combine(additionalHeaders.get) else headers
val headersCombined =
if (contentTypeOpt.isDefined) headersWithAuth
else headers.combine(Map(CaseInsensitive("content-type") -> contentType))
println("headers2", headersWithAuth)
val code = httpEndpoint.code
val response =
client.send(
httpEndpoint.method.toString,
path,
headersCombined,
headersWithAuth.updated(CaseInsensitive("content-type"), contentType),
writeInputToBlob(input, contentType)
)
decodeResponse(response, code)
Expand All @@ -62,9 +55,7 @@ private[smithy4play] class SmithyPlayClientEndpoint[Op[_, _, _, _, _], I, E, O,
): ClientResponse[O] =
for {
res <- response
_ = println(res, expectedCode, additionalSuccessCodes)
output <- if ((additionalSuccessCodes :+ expectedCode).contains(res.statusCode)) {
println("success")
handleSuccess(res)
} else handleError(res)
} yield output
Expand All @@ -73,7 +64,8 @@ private[smithy4play] class SmithyPlayClientEndpoint[Op[_, _, _, _, _], I, E, O,
Future {
val headers = response.headers.map(x => (x._1, x._2))
val contentType = headers.getOrElse(CaseInsensitive("content-type"), Seq("application/json"))
val codec = CodecDecider.httpMessageDecoder(contentType)
val codec = CodecDecider.httpResponseDecoder(contentType)

codec
.fromSchema(outputSchema)
.decode(response)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
package de.innfactory.smithy4play.middleware

import cats.data.Kleisli
import de.innfactory.smithy4play.{ EndpointRequest, RouteResult, RoutingContext }
import de.innfactory.smithy4play.{RouteResult, RoutingContext}
import play.api.Logger
import smithy4s.Blob
import smithy4s.http.HttpResponse

trait MiddlewareBase {

val logger: Logger = Logger("smithy4play")

protected def logic(
r: RoutingContext,
next: RoutingContext => RouteResult[EndpointRequest]
): RouteResult[EndpointRequest]
next: RoutingContext => RouteResult[HttpResponse[Blob]]
): RouteResult[HttpResponse[Blob]]

protected def skipMiddleware(r: RoutingContext): Boolean = false

def middleware(
f: RoutingContext => RouteResult[EndpointRequest]
): Kleisli[RouteResult, RoutingContext, EndpointRequest] =
f: RoutingContext => RouteResult[HttpResponse[Blob]]
): Kleisli[RouteResult, RoutingContext, HttpResponse[Blob]] =
Kleisli { r =>
if (skipMiddleware(r)) f(r)
else logic(r, f)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package de.innfactory.smithy4play.middleware

import cats.data.EitherT
import de.innfactory.smithy4play
import de.innfactory.smithy4play.{ EndpointRequest, RouteResult, RoutingContext, Smithy4PlayError }
import de.innfactory.smithy4play.{RouteResult, RoutingContext, Smithy4PlayError}
import smithy.api
import smithy.api.{ Auth, HttpBearerAuth }
import smithy.api.{Auth, HttpBearerAuth}
import smithy4s.Blob
import smithy4s.http.HttpResponse

import javax.inject.{ Inject, Singleton }
import scala.concurrent.{ ExecutionContext, Future }
import javax.inject.{Inject, Singleton}
import scala.concurrent.{ExecutionContext, Future}

@Singleton
class ValidateAuthMiddleware @Inject() (implicit
Expand All @@ -29,9 +31,9 @@ class ValidateAuthMiddleware @Inject() (implicit

override def logic(
r: RoutingContext,
next: RoutingContext => RouteResult[EndpointRequest]
): RouteResult[EndpointRequest] =
EitherT.leftT[Future, EndpointRequest](
next: RoutingContext => RouteResult[HttpResponse[Blob]]
): RouteResult[HttpResponse[Blob]] =
EitherT.leftT[Future, HttpResponse[Blob]](
Smithy4PlayError("Unauthorized", status = smithy4play.Status(Map.empty, 401))
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package de.innfactory

import cats.data.{EitherT, Kleisli}
import cats.data.{ EitherT, Kleisli }
import de.innfactory.smithy4play.client.SmithyPlayClientEndpointErrorResponse
import org.slf4j
import play.api.Logger
import play.api.libs.json.{JsValue, Json, OFormat}
import play.api.mvc.{Headers, RequestHeader}
import play.api.libs.json.{ JsValue, Json, OFormat }
import play.api.mvc.{ Headers, RequestHeader }
import smithy4s.Blob
import smithy4s.http.{CaseInsensitive, HttpEndpoint, HttpResponse, Metadata}
import smithy4s.http.{ CaseInsensitive, HttpEndpoint, HttpResponse, Metadata }

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.annotation.{ compileTimeOnly, StaticAnnotation }
import scala.concurrent.Future
import scala.language.experimental.macros

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package controller.middlewares

import de.innfactory.smithy4play.middleware.MiddlewareBase
import de.innfactory.smithy4play.{ EndpointRequest, RouteResult, RoutingContext, Status }
import smithy4s.http.Metadata
import de.innfactory.smithy4play.{RouteResult, RoutingContext}
import smithy4s.Blob
import smithy4s.http.HttpResponse
import testDefinitions.test.ChangeStatusCode

import javax.inject.Inject
Expand All @@ -15,11 +16,11 @@ class ChangeStatusCodeMiddleware @Inject() (implicit executionContext: Execution

override protected def logic(
r: RoutingContext,
next: RoutingContext => RouteResult[EndpointRequest]
): RouteResult[EndpointRequest] = {
next: RoutingContext => RouteResult[HttpResponse[Blob]]
): RouteResult[HttpResponse[Blob]] = {
val res = next(r)
res.map { r =>
r.copy(metadata = Metadata.empty.copy(statusCode = Some(269)))
r.copy(statusCode = 269)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package controller.middlewares

import de.innfactory.smithy4play.middleware.MiddlewareBase
import de.innfactory.smithy4play.{ EndpointRequest, RouteResult, RoutingContext }
import de.innfactory.smithy4play.{RouteResult, RoutingContext}
import smithy4s.Blob
import smithy4s.http.HttpResponse
import testDefinitions.test.DisableTestMiddleware

import javax.inject.{ Inject, Singleton }
import javax.inject.{Inject, Singleton}
import scala.concurrent.ExecutionContext

@Singleton
Expand All @@ -15,14 +17,14 @@ class DisableAbleMiddleware @Inject() (implicit executionContext: ExecutionConte

override protected def logic(
r: RoutingContext,
next: RoutingContext => RouteResult[EndpointRequest]
): RouteResult[EndpointRequest] = {
next: RoutingContext => RouteResult[HttpResponse[Blob]]
): RouteResult[HttpResponse[Blob]] = {
logger.info("[DisableAbleMiddleware.logic1]")
val r1 = r.copy(attributes = r.attributes + ("Not" -> "Disabled"))
val res = next(r1)
logger.info("[DisableAbleMiddleware.logic2]")
res.map { r =>
logger.info(s"[DisableAbleMiddleware.logic3] ${r.metadata.headers.toString()}")
logger.info(s"[DisableAbleMiddleware.logic3] ${r.headers.toString()}")
r
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package controller.middlewares

import de.innfactory.smithy4play.middleware.MiddlewareBase
import de.innfactory.smithy4play.{ EndpointRequest, RouteResult, RoutingContext, Status }
import smithy4s.http.CaseInsensitive
import de.innfactory.smithy4play.{RouteResult, RoutingContext}
import smithy4s.Blob
import smithy4s.http.{CaseInsensitive, HttpResponse}

import javax.inject.Inject
import scala.concurrent.ExecutionContext
Expand All @@ -11,8 +12,8 @@ class TestMiddlewareImpl @Inject() (implicit executionContext: ExecutionContext)

override protected def logic(
r: RoutingContext,
next: RoutingContext => RouteResult[EndpointRequest]
): RouteResult[EndpointRequest] = {
next: RoutingContext => RouteResult[HttpResponse[Blob]]
): RouteResult[HttpResponse[Blob]] = {
logger.info("[TestMiddleware.logic1]")
val r1 = r.copy(attributes = r.attributes + ("Test" -> "Test"))
val res = next(r1)
Expand Down
1 change: 0 additions & 1 deletion smithy4playTest/test/models/TestBase.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ trait TestBase extends PlaySpec with BaseOneAppPerSuite with FakeApplicationFact
headers: Map[CaseInsensitive, Seq[String]],
result: EndpointRequest
): Future[HttpResponse[Blob]] = {
println("headers:", headers.toList.flatMap(headers => headers._2.map(v => (headers._1, v))))
val baseRequest: FakeRequest[AnyContentAsEmpty.type] = FakeRequest(method, path)
.withHeaders(headers.toList.flatMap(headers => headers._2.map(v => (headers._1.toString, v))): _*)
val res =
Expand Down

0 comments on commit 2896a79

Please sign in to comment.