diff --git a/smithy4play/src/main/scala/de/innfactory/smithy4play/SmithyPlayEndpoint.scala b/smithy4play/src/main/scala/de/innfactory/smithy4play/SmithyPlayEndpoint.scala index c1f82e1e..6a8faf1c 100644 --- a/smithy4play/src/main/scala/de/innfactory/smithy4play/SmithyPlayEndpoint.scala +++ b/smithy4play/src/main/scala/de/innfactory/smithy4play/SmithyPlayEndpoint.scala @@ -1,20 +1,20 @@ package de.innfactory.smithy4play import akka.util.ByteString -import cats.data.{EitherT, Kleisli} +import cats.data.{ EitherT, Kleisli } import cats.implicits.toBifunctorOps import de.innfactory.smithy4play import de.innfactory.smithy4play.middleware.MiddlewareBase import play.api.mvc._ -import smithy4s.codecs.{PayloadError, StringAndBlobCodecs} -import smithy4s.http.{HttpEndpoint, HttpResponse, Metadata, PathParams} +import smithy4s.codecs.{ PayloadError, StringAndBlobCodecs } +import smithy4s.http.{ HttpEndpoint, HttpResponse, Metadata, PathParams } import smithy4s.json.Json import smithy4s.kinds.FunctorInterpreter -import smithy4s.schema.{CachedSchemaCompiler, Schema} -import smithy4s.xml.{Xml, XmlDecodeError} -import smithy4s.{Blob, Endpoint, Service} +import smithy4s.schema.{ CachedSchemaCompiler, Schema } +import smithy4s.xml.{ Xml, XmlDecodeError } +import smithy4s.{ Blob, Endpoint, Service } -import scala.concurrent.{ExecutionContext, Future} +import scala.concurrent.{ ExecutionContext, Future } class SmithyPlayEndpoint[Alg[_[_, _, _, _, _]], F[_] <: ContextRoute[_], Op[ _, @@ -112,8 +112,8 @@ class SmithyPlayEndpoint[Alg[_[_, _, _, _, _]], F[_] <: ContextRoute[_], Op[ EitherT( Future { val contentType = request.contentType.getOrElse("application/json") - val x = inputMetadataDecoder.decode(metadata) - val codecs = contentType match { + val x = inputMetadataDecoder.decode(metadata) + val codecs = contentType match { case "application/json" => (blob: Blob) => Json.read(blob)(inputSchema) case "application/xml" => (blob: Blob) => Xml.read(blob)(inputSchema) case _ => @@ -124,8 +124,8 @@ class SmithyPlayEndpoint[Alg[_[_, _, _, _, _]], F[_] <: ContextRoute[_], Op[ .decode(blob) } codecs(Blob(request.body.asBytes().getOrElse(ByteString.empty).toByteBuffer)).leftMap { - case error: PayloadError => Smithy4PlayError(error.expected, smithy4play.Status(Map.empty, 400)) - case error: XmlDecodeError => Smithy4PlayError(error.getMessage(), smithy4play.Status(Map.empty, 400)) + case error: PayloadError => Smithy4PlayError(error.expected, smithy4play.Status(Map.empty, 500)) + case error: XmlDecodeError => Smithy4PlayError(error.getMessage(), smithy4play.Status(Map.empty, 500)) } } ) diff --git a/smithy4play/src/main/scala/de/innfactory/smithy4play/client/SmithyPlayClientEndpoint.scala b/smithy4play/src/main/scala/de/innfactory/smithy4play/client/SmithyPlayClientEndpoint.scala index c5704b1e..04e8dd48 100644 --- a/smithy4play/src/main/scala/de/innfactory/smithy4play/client/SmithyPlayClientEndpoint.scala +++ b/smithy4play/src/main/scala/de/innfactory/smithy4play/client/SmithyPlayClientEndpoint.scala @@ -2,13 +2,16 @@ package de.innfactory package smithy4play package client import cats.implicits._ -import smithy4s.codecs.{ PayloadError, StringAndBlobCodecs } -import smithy4s.http.{ CaseInsensitive, HttpEndpoint, Metadata, MetadataError } +import smithy4s.codecs.{PayloadError, StringAndBlobCodecs} +import smithy4s.http.{CaseInsensitive, HttpEndpoint, Metadata, MetadataError} import smithy4s.json.Json -import smithy4s.xml.{ Xml, XmlDecodeError } -import smithy4s.{ Blob, Endpoint, Schema } +import smithy4s.json.Json.payloadCodecs +import smithy4s.schema.CachedSchemaCompiler +import smithy4s.xml.internals.XmlEncoder +import smithy4s.xml.{Xml, XmlDecodeError, XmlDocument} +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], @@ -33,12 +36,35 @@ private[smithy4play] class SmithyPlayClientEndpoint[Op[_, _, _, _, _], I, E, O, val metadata = inputMetadataEncoder.encode(input) val path = buildPath(metadata) val headers = metadata.headers.map(x => (x._1.toString.toLowerCase, x._2)) + val contentType = headers.getOrElse("content-type", Seq("application/json")) val headersWithAuth = if (additionalHeaders.isDefined) headers.combine(additionalHeaders.get) else headers val code = httpEndpoint.code - val response = client.send(httpEndpoint.method.toString, path, headersWithAuth, Json.writeBlob(input)) + val response = + client.send( + httpEndpoint.method.toString, + path, + headersWithAuth.combine(Map("content-type" -> contentType)), + writeInputToBlob(input, contentType) + ) decodeResponse(response, code) } + private def writeInputToBlob(input: I, contentType: Seq[String]): Blob = { + //TODO: Use Correct Encoders for Json and Xml and fix StringAndBlobCodecs + contentType match { + case Seq("application/json") => Json.writeBlob(input) + case Seq("application/xml") => Xml.write(input) + case _ => + StringAndBlobCodecs.encoders + .fromSchema(inputSchema) + .map(_.encode(input)) + .getOrElse({ + logger.info("sending empty blob") + Blob.empty + }) + } + } + private def decodeResponse( response: Future[SmithyClientResponse], expectedCode: Int