akka.http.scaladsl.unmarshalling.Unmarshaller Scala Examples

The following examples show how to use akka.http.scaladsl.unmarshalling.Unmarshaller. 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: GenCodecSupportSpec.scala    From akka-http-json   with Apache License 2.0 5 votes vote down vote up
package de.heikoseeberger.akkahttpavsystemgencodec

import akka.actor.ActorSystem
import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model.ContentTypes.`application/json`
import akka.http.scaladsl.model._
import akka.http.scaladsl.unmarshalling.Unmarshaller.UnsupportedContentTypeException
import akka.http.scaladsl.unmarshalling.{ Unmarshal, Unmarshaller }
import akka.stream.Materialzer
import com.avsystem.commons.serialization.GenCodec
import org.scalatest.{ AsyncWordSpec, BeforeAndAfterAll, Matchers }

import scala.concurrent.Await
import scala.concurrent.duration.DurationInt

object GenCodecSupportSpec {

  final object Foo {
    implicit val codec: GenCodec[Foo] = GenCodec.materialize[Foo]
  }

  final case class Foo(bar: String) {
    require(bar == "bar", "bar must be 'bar'!")
  }
}

final class GenCodecSupportSpec extends AsyncWordSpec with Matchers with BeforeAndAfterAll {
  import GenCodecSupport._
  import GenCodecSupportSpec._

  private implicit val system = ActorSystem()
  private implicit val mat    = Materialzer()

  "GenCodecSupport" should {
    "enable marshalling and unmarshalling of case classes" in {
      val foo = Foo("bar")
      Marshal(foo)
        .to[RequestEntity]
        .flatMap(Unmarshal(_).to[Foo])
        .map(_ shouldBe foo)
    }

    "provide proper error messages for requirement errors" in {
      val entity = HttpEntity(MediaTypes.`application/json`, """{ "bar": "baz" }""")
      Unmarshal(entity)
        .to[Foo]
        .failed
        .map(_ should have message "requirement failed: bar must be 'bar'!")
    }

    "fail with NoContentException when unmarshalling empty entities" in {
      val entity = HttpEntity.empty(`application/json`)
      Unmarshal(entity)
        .to[Foo]
        .failed
        .map(_ shouldBe Unmarshaller.NoContentException)
    }

    "fail with UnsupportedContentTypeException when Content-Type is not `application/json`" in {
      val entity = HttpEntity("""{ "bar": "bar" }""")
      Unmarshal(entity)
        .to[Foo]
        .failed
        .map(_ shouldBe UnsupportedContentTypeException(`application/json`))
    }

    "allow unmarshalling with passed in Content-Types" in {
      val foo = Foo("bar")
      val `application/json-home` =
        MediaType.applicationWithFixedCharset("json-home", HttpCharsets.`UTF-8`, "json-home")

      final object CustomGenCodecSupport extends GenCodecSupport {
        override def unmarshallerContentTypes = List(`application/json`, `application/json-home`)
      }
      import CustomGenCodecSupport._

      val entity = HttpEntity(`application/json-home`, """{ "bar": "bar" }""")
      Unmarshal(entity).to[Foo].map(_ shouldBe foo)
    }
  }

  override protected def afterAll() = {
    Await.ready(system.terminate(), 42.seconds)
    super.afterAll()
  }
} 
Example 2
Source File: AkkaHttpLambdaHandlerSpec.scala    From scala-server-lambda   with MIT License 5 votes vote down vote up
package io.github.howardjohn.lambda.akka

import akka.actor.ActorSystem
import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model.MediaTypes.`application/json`
import akka.http.scaladsl.model.headers.RawHeader
import akka.http.scaladsl.model.{HttpEntity, StatusCodes}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, Unmarshaller}
import akka.stream.ActorMaterializer
import io.circe.parser.decode
import io.circe.syntax._
import io.circe.{Decoder, Encoder}
import io.github.howardjohn.lambda.LambdaHandlerBehavior
import io.github.howardjohn.lambda.LambdaHandlerBehavior._
import org.scalatest.{BeforeAndAfterAll, FeatureSpec, GivenWhenThen}

import scala.concurrent.Future

class AkkaHttpLambdaHandlerSpec
    extends FeatureSpec
    with LambdaHandlerBehavior
    with GivenWhenThen
    with BeforeAndAfterAll {

  implicit val system: ActorSystem = ActorSystem("test")
  implicit val materializer: ActorMaterializer = ActorMaterializer()
  implicit val ec = scala.concurrent.ExecutionContext.Implicits.global

  val route: Route =
    path("hello") {
      (get & parameter("times".as[Int] ? 1)) { times =>
        complete {
          Seq
            .fill(times)("Hello World!")
            .mkString(" ")
        }
      }
    } ~ path("long") {
      get {
        Thread.sleep(1000)
        complete("")
      }
    } ~ path("post") {
      post {
        entity(as[String]) { body =>
          complete(body)
        }
      }
    } ~ path("json") {
      post {
        import CirceJsonMarshalling._
        import io.circe.generic.auto._
        entity(as[JsonBody]) { entity =>
          complete(LambdaHandlerBehavior.jsonReturn.asJson)
        }
      }
    } ~ path("exception") {
      get {
        throw RouteException()
      }
    } ~ path("error") {
      get {
        complete(StatusCodes.InternalServerError)
      }
    } ~ path("header") {
      get {
        headerValueByName(inputHeader) { header =>
          respondWithHeaders(RawHeader(outputHeader, outputHeaderValue)) {
            complete(header)
          }
        }
      }
    }

  val handler = new AkkaHttpLambdaHandler(route)

  scenariosFor(behavior(handler))

  override def afterAll(): Unit = {
    materializer.shutdown()
    system.terminate()
  }
}


object CirceJsonMarshalling {
  implicit final def unmarshaller[A: Decoder]: FromEntityUnmarshaller[A] =
    Unmarshaller.stringUnmarshaller
      .forContentTypes(`application/json`)
      .flatMap { ctx => mat => json =>
        decode[A](json).fold(Future.failed, Future.successful)
      }

  implicit final def marshaller[A: Encoder]: ToEntityMarshaller[A] =
    Marshaller.withFixedContentType(`application/json`) { a =>
      HttpEntity(`application/json`, a.asJson.noSpaces)
    }
} 
Example 3
Source File: Issue121.scala    From guardrail   with MIT License 5 votes vote down vote up
package core.issues

import akka.http.scaladsl.model._
import akka.http.scaladsl.model.headers.RawHeader
import akka.http.scaladsl.server._
import akka.http.scaladsl.testkit.ScalatestRouteTest
import akka.http.scaladsl.unmarshalling.Unmarshaller
import cats.instances.future._
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.time.SpanSugar._
import org.scalatest.{ EitherValues, FunSuite, Matchers }
import scala.concurrent.Future
import io.circe._

class Issue121Suite extends FunSuite with Matchers with EitherValues with ScalaFutures with ScalatestRouteTest {
  override implicit val patienceConfig = PatienceConfig(10 seconds, 1 second)

  test("akka-http server can respond with 204") {
    import issues.issue121.server.akkaHttp.{ Handler, Resource }
    val route = Resource.routes(new Handler {
      override def deleteFoo(respond: Resource.DeleteFooResponse.type)(id: Long): Future[Resource.DeleteFooResponse] =
        Future.successful(respond.NoContent)
    })

    Delete("/entity").withEntity(FormData("id" -> "1234").toEntity) ~> route ~> check {
      status should equal(StatusCodes.NoContent)
      response.entity.contentType should equal(ContentTypes.NoContentType)
      response.entity.contentLengthOption should equal(Some(0))
    }
  }

  test("akka-http client can respond with 204") {
    import issues.issue121.client.akkaHttp.Client

    def noContentResponse: HttpRequest => Future[HttpResponse] = _ => Future.successful(HttpResponse(204))

    
    Client
      .httpClient(noContentResponse, "http://localhost:80")
      .deleteFoo(1234)
      .fold(
        _ => failTest("Error"),
        _.fold(
          handleNoContent = ()
        )
      )
      .futureValue
  }
} 
Example 4
Source File: Issue184.scala    From guardrail   with MIT License 5 votes vote down vote up
package core.issues

import akka.http.scaladsl.model._
import akka.http.scaladsl.model.headers.RawHeader
import akka.http.scaladsl.server._
import akka.http.scaladsl.testkit.ScalatestRouteTest
import akka.http.scaladsl.unmarshalling.Unmarshaller
import cats.instances.future._
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.time.SpanSugar._
import org.scalatest.{ EitherValues, FunSuite, Matchers }
import scala.concurrent.Future
import io.circe._


    Delete("/1234?query=2345")
      .withEntity(
        Multipart
          .FormData(
            Multipart.FormData.BodyPart.Strict("form", "3456")
          )
          .toEntity
      ) ~> route ~> check {
      response.status shouldBe (StatusCodes.NoContent)
    }
  }
} 
Example 5
Source File: RealmDirectives.scala    From nexus-iam   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.iam.directives

import akka.http.javadsl.server.Rejections.validationRejection
import akka.http.scaladsl.server.Directive1
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.PathMatchers.Segment
import akka.http.scaladsl.unmarshalling.Unmarshaller
import ch.epfl.bluebrain.nexus.iam.routes.SearchParams
import ch.epfl.bluebrain.nexus.iam.types.Label
import ch.epfl.bluebrain.nexus.rdf.Iri
import ch.epfl.bluebrain.nexus.rdf.Iri.AbsoluteIri

trait RealmDirectives {

  
  def searchParams: Directive1[SearchParams] =
    (parameter("deprecated".as[Boolean].?) &
      parameter("rev".as[Long].?) &
      parameter("createdBy".as[AbsoluteIri].?) &
      parameter("updatedBy".as[AbsoluteIri].?) &
      parameter("type".as[AbsoluteIri].*)).tmap {
      case (deprecated, rev, createdBy, updatedBy, types) =>
        SearchParams(deprecated, rev, createdBy, updatedBy, types.toSet)
    }

  private implicit def iriFromStringUnmarshaller: Unmarshaller[String, AbsoluteIri] =
    Unmarshaller.strict[String, AbsoluteIri] { string =>
      Iri.url(string) match {
        case Right(iri) => iri
        case x          => throw new IllegalArgumentException(s"'$x' is not a valid AbsoluteIri value")
      }
    }
}

object RealmDirectives extends RealmDirectives 
Example 6
Source File: SprayJsonSupport.scala    From mist   with Apache License 2.0 5 votes vote down vote up
package io.hydrosphere.mist.master.interfaces

import scala.language.implicitConversions
import akka.http.scaladsl.marshalling.{ ToEntityMarshaller, Marshaller }
import akka.http.scaladsl.unmarshalling.{ FromEntityUnmarshaller, Unmarshaller }
import akka.http.scaladsl.model.{ MediaTypes, HttpCharsets }

import spray.json._


trait SprayJsonSupport {
  implicit def sprayJsonUnmarshallerConverter[T](reader: RootJsonReader[T]): FromEntityUnmarshaller[T] =
    sprayJsonUnmarshaller(reader)
  implicit def sprayJsonUnmarshaller[T](implicit reader: RootJsonReader[T]): FromEntityUnmarshaller[T] =
    sprayJsValueUnmarshaller.map(jsonReader[T].read)
  implicit def sprayJsValueUnmarshaller: FromEntityUnmarshaller[JsValue] =
    Unmarshaller.byteStringUnmarshaller.mapWithCharset { (data, charset) ⇒
      val input =
        if (charset == HttpCharsets.`UTF-8`) ParserInput(data.toArray)
        else ParserInput(data.decodeString(charset.nioCharset.name)) // FIXME: identify charset by instance, not by name!
      JsonParser(input)
    }

  implicit def sprayJsonMarshallerConverter[T](writer: RootJsonWriter[T])(implicit printer: JsonPrinter = PrettyPrinter): ToEntityMarshaller[T] =
    sprayJsonMarshaller[T](writer, printer)
  implicit def sprayJsonMarshaller[T](implicit writer: RootJsonWriter[T], printer: JsonPrinter = PrettyPrinter): ToEntityMarshaller[T] =
    sprayJsValueMarshaller compose writer.write
  implicit def sprayJsValueMarshaller(implicit printer: JsonPrinter = PrettyPrinter): ToEntityMarshaller[JsValue] =
    Marshaller.StringMarshaller.wrap(MediaTypes.`application/json`)(printer)
}
object SprayJsonSupport extends SprayJsonSupport 
Example 7
Source File: GraphQLRequestUnmarshaller.scala    From graphql-gateway   with Apache License 2.0 5 votes vote down vote up
package sangria.gateway.http

import java.nio.charset.Charset

import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model._
import akka.http.scaladsl.model.headers.Accept
import akka.http.scaladsl.server.Directive0
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, Unmarshaller}
import akka.util.ByteString
import sangria.ast.Document
import sangria.parser.QueryParser
import sangria.renderer.{QueryRenderer, QueryRendererConfig}

import scala.collection.immutable.Seq

object GraphQLRequestUnmarshaller {
  val `application/graphql` = MediaType.applicationWithFixedCharset("graphql", HttpCharsets.`UTF-8`, "graphql")

  def explicitlyAccepts(mediaType: MediaType): Directive0 =
    headerValuePF {
      case Accept(ranges) if ranges.exists(range ⇒ !range.isWildcard && range.matches(mediaType)) ⇒ ranges
    }.flatMap(_ ⇒ pass)

  def includeIf(include: Boolean): Directive0 =
    if (include) pass
    else reject

  def unmarshallerContentTypes: Seq[ContentTypeRange] =
    mediaTypes.map(ContentTypeRange.apply)

  def mediaTypes: Seq[MediaType.WithFixedCharset] =
    List(`application/graphql`)

  implicit final def documentMarshaller(implicit config: QueryRendererConfig = QueryRenderer.Compact): ToEntityMarshaller[Document] =
    Marshaller.oneOf(mediaTypes: _*) { mediaType ⇒
      Marshaller.withFixedContentType(ContentType(mediaType)) { json ⇒
        HttpEntity(mediaType, QueryRenderer.render(json, config))
      }
    }

  
  implicit final val documentUnmarshaller: FromEntityUnmarshaller[Document] =
    Unmarshaller.byteStringUnmarshaller
      .forContentTypes(unmarshallerContentTypes: _*)
      .map {
        case ByteString.empty ⇒ throw Unmarshaller.NoContentException
        case data ⇒
          import sangria.parser.DeliveryScheme.Throw

          QueryParser.parse(data.decodeString(Charset.forName("UTF-8")))
      }
} 
Example 8
Source File: JsonSupport.scala    From akka-stream-json   with Apache License 2.0 5 votes vote down vote up
package de.knutwalker.akka.http

import de.knutwalker.akka.stream.JsonStreamParser

import akka.http.scaladsl.model.HttpEntity
import akka.http.scaladsl.model.MediaTypes.`application/json`
import akka.http.scaladsl.unmarshalling.{ FromEntityUnmarshaller, Unmarshaller }
import akka.http.scaladsl.util.FastFuture
import akka.stream.scaladsl.Sink
import akka.stream.stage.{ GraphStageLogic, GraphStageWithMaterializedValue, InHandler }
import akka.stream.{ AbruptStageTerminationException, Attributes, Inlet, SinkShape }

import jawn.Facade

import scala.concurrent.{ Future, Promise }
import java.util.NoSuchElementException

object JsonSupport extends JsonSupport {
  private def firstElementSink[J <: AnyRef]: Sink[J, Future[J]] =
    Sink.fromGraph(new FirstElementSinkStage[J])

  private final class FirstElementSinkStage[J <: AnyRef] extends GraphStageWithMaterializedValue[SinkShape[J], Future[J]] {
    private[this] val in: Inlet[J] = Inlet("firstElement.in")

    override val shape: SinkShape[J] = SinkShape.of(in)
    override protected def initialAttributes: Attributes = Attributes.name("firstElement")

    override def createLogicAndMaterializedValue(inheritedAttributes: Attributes): (GraphStageLogic, Future[J]) = {
      val p: Promise[J] = Promise()
      (new GraphStageLogic(shape) with InHandler {
        private[this] var element: J = null.asInstanceOf[J]

        override def preStart(): Unit = pull(in)

        def onPush(): Unit = {
          if (element eq null) {
            element = grab(in)
          }
          pull(in)
        }

        override def onUpstreamFinish(): Unit = {
          val el = element
          element = null.asInstanceOf[J]
          if (el ne null) {
            p.trySuccess(el)
          } else {
            p.tryFailure(new NoSuchElementException("No complete json entity consumed"))
          }
          completeStage()
        }

        override def onUpstreamFailure(ex: Throwable): Unit = {
          element = null.asInstanceOf[J]
          p.tryFailure(ex)
          failStage(ex)
        }

        override def postStop(): Unit = {
          if (!p.isCompleted) {
            p.failure(new AbruptStageTerminationException(this))
            ()
          }
        }

        setHandler(in, this)
      }, p.future)
    }

    override def toString: String = "FirstElementSinkStage"
  }
}

trait JsonSupport {

  implicit def jsonUnmarshaller[J <: AnyRef : Facade]: FromEntityUnmarshaller[J] =
    Unmarshaller.withMaterializer[HttpEntity, J](_ => implicit mat => {
      case HttpEntity.Strict(_, data) => FastFuture(JsonStreamParser.parse[J](data))
      case entity                     => entity.dataBytes.via(JsonStreamParser[J]).runWith(JsonSupport.firstElementSink[J])
    }).forContentTypes(`application/json`)
} 
Example 9
Source File: Json4sSupport.scala    From service-container   with Apache License 2.0 5 votes vote down vote up
package com.github.vonnagy.service.container.http.json

import java.lang.reflect.InvocationTargetException

import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model.MediaTypes.`application/json`
import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, Unmarshaller}
import akka.util.ByteString
import org.json4s.JsonAST.JValue
import org.json4s.{Formats, MappingException, Serialization}


  implicit def json4sMarshaller[A <: AnyRef](
                                              implicit serialization: Serialization,
                                              formats: Formats,
                                              shouldWritePretty: ShouldWritePretty = ShouldWritePretty.False
                                            ): ToEntityMarshaller[A] = {
    shouldWritePretty match {
      case ShouldWritePretty.False =>
        jsonStringMarshaller.compose(serialization.write[A])
      case ShouldWritePretty.True =>
        jsonStringMarshaller.compose(serialization.writePretty[A])
    }
  }

  implicit def json4sJValueMarshaller[A <: JValue](
                                                    implicit serialization: Serialization,
                                                    formats: Formats,
                                                    shouldWritePretty: ShouldWritePretty = ShouldWritePretty.False
                                                  ): ToEntityMarshaller[A] = {

    shouldWritePretty match {
      case ShouldWritePretty.False =>
        jsonStringMarshaller.compose(serialization.write[A])
      case ShouldWritePretty.True =>
        jsonStringMarshaller.compose(serialization.writePretty[A])
    }
  }
} 
Example 10
Source File: package.scala    From nexus-kg   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.kg

import akka.http.scaladsl.unmarshalling.Unmarshaller
import ch.epfl.bluebrain.nexus.admin.client.types.Project
import ch.epfl.bluebrain.nexus.commons.search.Sort
import ch.epfl.bluebrain.nexus.kg.directives.PathDirectives.toIri
import ch.epfl.bluebrain.nexus.rdf.Iri
import ch.epfl.bluebrain.nexus.rdf.Iri.AbsoluteIri

package object directives {

  private[directives] implicit def absoluteIriFromStringUnmarshaller(
      implicit project: Project
  ): Unmarshaller[String, AbsoluteIri] =
    Unmarshaller.strict[String, AbsoluteIri] { string =>
      toIriOrElseBase(string) match {
        case Some(iri) => iri
        case _         => throw new IllegalArgumentException(s"'$string' is not a valid AbsoluteIri value")
      }
    }

  private[directives] implicit def vocabAbsoluteIriFromStringUnmarshaller(
      implicit project: Project
  ): Unmarshaller[String, VocabAbsoluteIri] =
    Unmarshaller.strict[String, VocabAbsoluteIri] { string =>
      toIriOrElseVocab(string) match {
        case Some(iri) => VocabAbsoluteIri(iri)
        case _         => throw new IllegalArgumentException(s"'$string' is not a valid AbsoluteIri value")
      }
    }

  private[directives] implicit val sortFromStringUnmarshaller: Unmarshaller[String, Sort] =
    Unmarshaller.strict[String, Sort](Sort(_))

  private def toIriOrElseBase(s: String)(implicit project: Project): Option[AbsoluteIri] =
    toIri(s) orElse Iri.absolute(project.base.asString + s).toOption

  private def toIriOrElseVocab(s: String)(implicit project: Project): Option[AbsoluteIri] =
    toIri(s) orElse Iri.absolute(project.vocab.asString + s).toOption
} 
Example 11
Source File: GenCodecSupport.scala    From akka-http-json   with Apache License 2.0 5 votes vote down vote up
package de.heikoseeberger.akkahttpavsystemgencodec

import akka.http.scaladsl.marshalling.{ Marshaller, ToEntityMarshaller }
import akka.http.scaladsl.model.ContentTypeRange
import akka.http.scaladsl.model.MediaType
import akka.http.scaladsl.model.MediaTypes.`application/json`
import akka.http.scaladsl.unmarshalling.{ FromEntityUnmarshaller, Unmarshaller }
import akka.util.ByteString
import com.avsystem.commons.serialization.GenCodec
import com.avsystem.commons.serialization.json.{ JsonStringInput, JsonStringOutput }

import scala.collection.immutable.Seq

object GenCodecSupport extends GenCodecSupport {}

trait GenCodecSupport {

  def unmarshallerContentTypes: Seq[ContentTypeRange] =
    mediaTypes.map(ContentTypeRange.apply)

  def mediaTypes: Seq[MediaType.WithFixedCharset] =
    List(`application/json`)

  private val jsonStringUnmarshaller =
    Unmarshaller.byteStringUnmarshaller
      .forContentTypes(unmarshallerContentTypes: _*)
      .mapWithCharset {
        case (ByteString.empty, _) => throw Unmarshaller.NoContentException
        case (data, charset)       => data.decodeString(charset.nioCharset.name)
      }

  private val jsonStringMarshaller =
    Marshaller.oneOf(mediaTypes: _*)(Marshaller.stringMarshaller)

  
  implicit def marshaller[A: GenCodec]: ToEntityMarshaller[A] =
    jsonStringMarshaller.compose(JsonStringOutput.write(_))
} 
Example 12
Source File: FlatBuffersSupport.scala    From ForestFlow   with Apache License 2.0 5 votes vote down vote up
package ai.forestflow.akka.flatbuffers

import java.nio.ByteBuffer

import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model.{ContentTypeRange, MediaRange, MediaRanges, MediaType}
import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, Unmarshaller}
import com.google.flatbuffers.Table

import scala.collection.mutable
import scala.reflect.ClassTag

// application/octet-stream
trait FlatBuffersSupport {
  var myMap : mutable.Map[ClassTag[_], AnyRef => AnyRef] = mutable.Map.empty[ClassTag[_], AnyRef => AnyRef]
  private val applicableMediaTypes: List[ContentTypeRange] = List(
    MediaRanges.`*

    Unmarshaller.byteArrayUnmarshaller.forContentTypes(applicableMediaTypes: _*).map(b => fn(java.nio.ByteBuffer.wrap(b)).asInstanceOf[T])
  }

  implicit def flatBufferBinaryMarshaller[T <: Table](implicit tag: ClassTag[T]): ToEntityMarshaller[T]  = {
    println("marshalling something")
    val result = Marshaller.ByteArrayMarshaller.compose((c: T) => c.getByteBuffer.array())
    println("done")
    result
  }
} 
Example 13
Source File: JsoniterScalaSupportSpec.scala    From akka-http-json   with Apache License 2.0 5 votes vote down vote up
package de.heikoseeberger.akkahttpjsoniterscala

import akka.actor.ActorSystem
import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model.ContentTypes.{ `application/json`, `text/plain(UTF-8)` }
import akka.http.scaladsl.model._
import akka.http.scaladsl.unmarshalling.Unmarshaller.UnsupportedContentTypeException
import akka.http.scaladsl.unmarshalling.{ Unmarshal, Unmarshaller }
import akka.stream.scaladsl.{ Sink, Source }
import com.github.plokhotnyuk.jsoniter_scala.core.JsonValueCodec
import com.github.plokhotnyuk.jsoniter_scala.macros._
import org.scalatest.BeforeAndAfterAll

import scala.concurrent.Await
import scala.concurrent.duration.DurationInt
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AsyncWordSpec

object JsoniterScalaSupportSpec {

  final case class Foo(bar: String) {
    require(bar startsWith "bar", "bar must start with 'bar'!")
  }
}

final class JsoniterScalaSupportSpec extends AsyncWordSpec with Matchers with BeforeAndAfterAll {
  import JsoniterScalaSupport._
  import JsoniterScalaSupportSpec._

  private implicit val system: ActorSystem        = ActorSystem()
  private implicit val codec: JsonValueCodec[Foo] = JsonCodecMaker.make[Foo](CodecMakerConfig)

  "JsoniterScalaSupport" should {
    "should enable marshalling and unmarshalling" in {
      val foo = Foo("bar")
      Marshal(foo)
        .to[RequestEntity]
        .flatMap(Unmarshal(_).to[Foo])
        .map(_ shouldBe foo)
    }

    "enable streamed marshalling and unmarshalling for json arrays" in {
      val foos = (0 to 100).map(i => Foo(s"bar-$i")).toList

      Marshal(Source(foos))
        .to[RequestEntity]
        .flatMap(entity => Unmarshal(entity).to[SourceOf[Foo]])
        .flatMap(_.runWith(Sink.seq))
        .map(_ shouldBe foos)
    }

    "provide proper error messages for requirement errors" in {
      val entity = HttpEntity(MediaTypes.`application/json`, """{ "bar": "baz" }""")
      Unmarshal(entity)
        .to[Foo]
        .failed
        .map(_ should have message "requirement failed: bar must start with 'bar'!")
    }

    "fail with NoContentException when unmarshalling empty entities" in {
      val entity = HttpEntity.empty(`application/json`)
      Unmarshal(entity)
        .to[Foo]
        .failed
        .map(_ shouldBe Unmarshaller.NoContentException)
    }

    "fail with UnsupportedContentTypeException when Content-Type is not `application/json`" in {
      val entity = HttpEntity("""{ "bar": "bar" }""")
      Unmarshal(entity)
        .to[Foo]
        .failed
        .map(
          _ shouldBe UnsupportedContentTypeException(Some(`text/plain(UTF-8)`), `application/json`)
        )
    }

    "allow unmarshalling with passed in Content-Types" in {
      val foo = Foo("bar")
      val `application/json-home` =
        MediaType.applicationWithFixedCharset("json-home", HttpCharsets.`UTF-8`, "json-home")

      final object CustomJsoniterScalaSupport extends JsoniterScalaSupport {
        override def unmarshallerContentTypes: List[ContentTypeRange] =
          List(`application/json`, `application/json-home`)
      }
      import CustomJsoniterScalaSupport._

      val entity = HttpEntity(`application/json-home`, """{ "bar": "bar" }""")
      Unmarshal(entity).to[Foo].map(_ shouldBe foo)
    }
  }

  override protected def afterAll(): Unit = {
    Await.ready(system.terminate(), 42.seconds)
    super.afterAll()
  }
} 
Example 14
Source File: UpickleCustomizationSupport.scala    From akka-http-json   with Apache License 2.0 5 votes vote down vote up
package de.heikoseeberger.akkahttpupickle

import akka.http.javadsl.common.JsonEntityStreamingSupport
import akka.http.scaladsl.common.EntityStreamingSupport
import akka.http.scaladsl.marshalling.{ Marshaller, Marshalling, ToEntityMarshaller }
import akka.http.scaladsl.model.{ ContentTypeRange, HttpEntity, MediaType, MessageEntity }
import akka.http.scaladsl.model.MediaTypes.`application/json`
import akka.http.scaladsl.unmarshalling.{ FromEntityUnmarshaller, Unmarshal, Unmarshaller }
import akka.http.scaladsl.util.FastFuture
import akka.stream.scaladsl.{ Flow, Source }
import akka.util.ByteString
import UpickleCustomizationSupport._

import scala.collection.immutable.Seq
import scala.concurrent.Future
import scala.util.Try
import scala.util.control.NonFatal

// This companion object only exists for binary compatibility as adding methods with default implementations
// (including val's as they create synthetic methods) is not compatible.
private object UpickleCustomizationSupport {

  private def jsonStringUnmarshaller(support: UpickleCustomizationSupport) =
    Unmarshaller.byteStringUnmarshaller
      .forContentTypes(support.unmarshallerContentTypes: _*)
      .mapWithCharset {
        case (ByteString.empty, _) => throw Unmarshaller.NoContentException
        case (data, charset)       => data.decodeString(charset.nioCharset.name)
      }

  private def jsonSourceStringMarshaller(support: UpickleCustomizationSupport) =
    Marshaller.oneOf(support.mediaTypes: _*)(support.sourceByteStringMarshaller)

  private def jsonStringMarshaller(support: UpickleCustomizationSupport) =
    Marshaller.oneOf(support.mediaTypes: _*)(Marshaller.stringMarshaller)
}


  implicit def sourceMarshaller[A](implicit
      writes: apiInstance.Writer[A],
      support: JsonEntityStreamingSupport = EntityStreamingSupport.json()
  ): ToEntityMarshaller[SourceOf[A]] =
    jsonSourceStringMarshaller(this).compose(jsonSource[A])
} 
Example 15
Source File: UpickleSupportSpec.scala    From akka-http-json   with Apache License 2.0 5 votes vote down vote up
package de.heikoseeberger.akkahttpupickle

import akka.actor.ActorSystem
import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model.ContentTypes.{ `application/json`, `text/plain(UTF-8)` }
import akka.http.scaladsl.model._
import akka.http.scaladsl.unmarshalling.Unmarshaller.UnsupportedContentTypeException
import akka.http.scaladsl.unmarshalling.{ Unmarshal, Unmarshaller }
import akka.stream.scaladsl.{ Sink, Source }
import org.scalatest.BeforeAndAfterAll

import scala.concurrent.Await
import scala.concurrent.duration.DurationInt
import upickle.default.{ ReadWriter, macroRW }
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AsyncWordSpec

object UpickleSupportSpec {

  final object Foo {
    implicit val rw: ReadWriter[Foo] = macroRW
  }

  final case class Foo(bar: String) {
    require(bar startsWith "bar", "bar must start with 'bar'!")
  }
}

final class UpickleSupportSpec extends AsyncWordSpec with Matchers with BeforeAndAfterAll {
  import UpickleSupport._
  import UpickleSupportSpec._

  private implicit val system = ActorSystem()

  "UpickleSupport" should {
    "enable marshalling and unmarshalling of case classes" in {
      val foo = Foo("bar")
      Marshal(foo)
        .to[RequestEntity]
        .flatMap(Unmarshal(_).to[Foo])
        .map(_ shouldBe foo)
    }

    "enable streamed marshalling and unmarshalling for json arrays" in {
      val foos = (0 to 100).map(i => Foo(s"bar-$i")).toList

      Marshal(Source(foos))
        .to[RequestEntity]
        .flatMap(entity => Unmarshal(entity).to[SourceOf[Foo]])
        .flatMap(_.runWith(Sink.seq))
        .map(_ shouldBe foos)
    }

    "provide proper error messages for requirement errors" in {
      val entity = HttpEntity(MediaTypes.`application/json`, """{ "bar": "baz" }""")
      Unmarshal(entity)
        .to[Foo]
        .failed
        .map(_ should have message "requirement failed: bar must start with 'bar'!")
    }

    "fail with NoContentException when unmarshalling empty entities" in {
      val entity = HttpEntity.empty(`application/json`)
      Unmarshal(entity)
        .to[Foo]
        .failed
        .map(_ shouldBe Unmarshaller.NoContentException)
    }

    "fail with UnsupportedContentTypeException when Content-Type is not `application/json`" in {
      val entity = HttpEntity("""{ "bar": "bar" }""")
      Unmarshal(entity)
        .to[Foo]
        .failed
        .map(
          _ shouldBe UnsupportedContentTypeException(Some(`text/plain(UTF-8)`), `application/json`)
        )
    }

    "allow unmarshalling with passed in Content-Types" in {
      val foo = Foo("bar")
      val `application/json-home` =
        MediaType.applicationWithFixedCharset("json-home", HttpCharsets.`UTF-8`, "json-home")

      final object CustomUpickleSupport extends UpickleSupport {
        override def unmarshallerContentTypes = List(`application/json`, `application/json-home`)
      }
      import CustomUpickleSupport._

      val entity = HttpEntity(`application/json-home`, """{ "bar": "bar" }""")
      Unmarshal(entity).to[Foo].map(_ shouldBe foo)
    }
  }

  override protected def afterAll() = {
    Await.ready(system.terminate(), 42.seconds)
    super.afterAll()
  }
} 
Example 16
Source File: UpickleCustomizationSupportSpec.scala    From akka-http-json   with Apache License 2.0 5 votes vote down vote up
package de.heikoseeberger.akkahttpupickle

import akka.actor.ActorSystem
import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model.ContentTypes.{ `application/json`, `text/plain(UTF-8)` }
import akka.http.scaladsl.model._
import akka.http.scaladsl.unmarshalling.Unmarshaller.UnsupportedContentTypeException
import akka.http.scaladsl.unmarshalling.{ Unmarshal, Unmarshaller }
import akka.stream.scaladsl.{ Sink, Source }
import org.scalatest.BeforeAndAfterAll
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AsyncWordSpec
import upickle.AttributeTagged
import upickle.core.Visitor

import scala.concurrent.Await
import scala.concurrent.duration.DurationInt

final class UpickleCustomizationSupportSpec
    extends AsyncWordSpec
    with Matchers
    with BeforeAndAfterAll {

  private implicit val system = ActorSystem()

  object FooApi extends AttributeTagged {
    override implicit val IntWriter: FooApi.Writer[Int] = new Writer[Int] {
      override def write0[V](out: Visitor[_, V], v: Int): V = out.visitString("foo", -1)
    }
  }
  object UpickleFoo extends UpickleCustomizationSupport {
    override type Api = FooApi.type
    override def api: FooApi.type = FooApi
  }

  import UpickleFoo._

  "UpickleCustomizationSupport" should {
    "support custom configuration" in {
      Marshal(123)
        .to[RequestEntity]
        .flatMap(Unmarshal(_).to[String])
        .map(_ shouldBe "foo")
    }
  }

  override protected def afterAll() = {
    Await.ready(system.terminate(), 42.seconds)
    super.afterAll()
  }
} 
Example 17
Source File: CirceSupport.scala    From typed-schema   with Apache License 2.0 5 votes vote down vote up
package ru.tinkoff.tschema.utils.json

import akka.http.scaladsl.marshalling.{Marshaller, _}
import akka.http.scaladsl.model.MediaTypes._
import akka.http.scaladsl.model.{HttpEntity, HttpRequest}
import akka.http.scaladsl.unmarshalling.{Unmarshaller, _}
import io.circe._
import io.circe.parser._
import io.circe.syntax._
import cats.syntax.either._

import scala.concurrent.Future

object CirceSupport {
  val printer = Printer.noSpaces.copy(dropNullValues = true)

  def marshallResponse[T: Encoder]: ToResponseMarshaller[T] = Marshaller.fromToEntityMarshaller[T]()(marshallEntity)

  def unmarshallRequest[T: Decoder]: FromRequestUnmarshaller[T] =
    Unmarshaller
      .identityUnmarshaller[HttpRequest]
      .map(_.entity)
      .flatMap[T](unmarshallEntity[T]: Unmarshaller[HttpEntity, T])
      .asScala

  def marshallEntity[T: Encoder]: ToEntityMarshaller[T] =
    Marshaller.stringMarshaller(`application/json`).compose((_: T).asJson.printWith(printer))

  def unmarshallEntity[T: Decoder]: FromEntityUnmarshaller[T] =
    Unmarshaller.stringUnmarshaller
      .forContentTypes(`application/json`)
      .flatMap(implicit ec => _ => s => Future.fromTry(parse(s).toTry.flatMap(_.as[T].toTry)))

  object implicits {
    implicit def marshallResponseCirce[T: Encoder]: ToResponseMarshaller[T] = marshallResponse[T]

    implicit def unmarshallRequestCirce[T: Decoder]: FromRequestUnmarshaller[T] = unmarshallRequest[T]

    implicit def marshallEntityCirce[T: Encoder]: ToEntityMarshaller[T] = marshallEntity[T]

    implicit def unmarshallEntityCirce[T: Decoder]: FromEntityUnmarshaller[T] = unmarshallEntity[T]
  }

} 
Example 18
Source File: JsonUnmarshallers.scala    From scala-openrtb   with Apache License 2.0 5 votes vote down vote up
package com.powerspace.openrtb.akka.marshallers

import akka.http.scaladsl.model.{ContentTypeRange, ContentTypes, HttpRequest}
import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, FromRequestUnmarshaller, Unmarshaller}
import akka.stream.Materializer
import com.google.openrtb.{BidRequest, BidResponse}
import io.circe.Decoder

import scala.concurrent.{ExecutionContext, Future}
import io.circe.parser.decode

object JsonUnmarshallers {

  import akka.http.scaladsl.unmarshalling.PredefinedFromEntityUnmarshallers._

  def bidRequestJsonUnmarshaller(implicit decoder: Decoder[BidRequest]): FromEntityUnmarshaller[BidRequest] =
    stringUnmarshaller
      .forContentTypes(ContentTypeRange(ContentTypes.`application/json`))
      .map(implicit json => decode[BidRequest](json).handlingFailure)

  def bidResponseJsonUnmarshaller(implicit decoder: Decoder[BidResponse]): FromEntityUnmarshaller[BidResponse] =
    stringUnmarshaller
      .forContentTypes(ContentTypeRange(ContentTypes.`application/json`))
      .map(implicit json => decode[BidResponse](json).handlingFailure)

  def bidRequestHttpJsonUnmarshaller(implicit decoder: Decoder[BidRequest]): FromRequestUnmarshaller[BidRequest] =
    new FromRequestUnmarshaller[BidRequest]() {
      override def apply(
        value: HttpRequest)(implicit ec: ExecutionContext, materializer: Materializer): Future[BidRequest] =
        Unmarshaller
          .stringUnmarshaller(value.entity)
          .map(implicit json => decode[BidRequest](json).handlingFailure)
    }

  def bidResponseHttpJsonUnmarshaller(implicit decoder: Decoder[BidResponse]): FromRequestUnmarshaller[BidResponse] =
    new FromRequestUnmarshaller[BidResponse]() {
      override def apply(
        value: HttpRequest)(implicit ec: ExecutionContext, materializer: Materializer): Future[BidResponse] =
        Unmarshaller
          .stringUnmarshaller(value.entity)
          .map(implicit json => decode[BidResponse](json).handlingFailure)
    }

  implicit class DecodingResultEnhancement[T](decodingResult: Either[_ <: Exception, T]) {

    def handlingFailure(implicit json: String): T = decodingResult match {
      case Right(decoded) => decoded
      case Left(error) => throw new UnsupportedOperationException(error)
    }
  }

} 
Example 19
Source File: application.scala    From phobos   with Apache License 2.0 5 votes vote down vote up
package ru.tinkoff.phobos.akka_http.marshalling

import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model.{HttpCharsets, HttpEntity, MediaTypes}
import akka.http.scaladsl.unmarshalling.{FromResponseUnmarshaller, Unmarshaller}
import ru.tinkoff.phobos.decoding.XmlDecoder
import ru.tinkoff.phobos.encoding.XmlEncoder

object application {
  implicit def soapApplicationXmlMarshaller[T](implicit encoder: XmlEncoder[T]): ToEntityMarshaller[T] =
    Marshaller.withFixedContentType(MediaTypes.`application/xml` withCharset HttpCharsets.`UTF-8`) { body =>
      HttpEntity(MediaTypes.`application/xml` withCharset HttpCharsets.`UTF-8`, encoder.encode(body))
    }

  implicit def soapApplicationXmlUnmarshaller[T](implicit decoder: XmlDecoder[T]): FromResponseUnmarshaller[T] =
    Unmarshaller.messageUnmarshallerFromEntityUnmarshaller(Unmarshaller.stringUnmarshaller.map { str =>
      decoder.decode(str).fold(err => throw err, identity)
    })
} 
Example 20
Source File: text.scala    From phobos   with Apache License 2.0 5 votes vote down vote up
package ru.tinkoff.phobos.akka_http.marshalling

import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model.ContentTypes.`text/xml(UTF-8)`
import akka.http.scaladsl.model.HttpEntity
import akka.http.scaladsl.unmarshalling.{FromResponseUnmarshaller, Unmarshaller}
import ru.tinkoff.phobos.decoding.XmlDecoder
import ru.tinkoff.phobos.encoding.XmlEncoder

object text {
  implicit def soapTextXmlMarshaller[T](implicit encoder: XmlEncoder[T]): ToEntityMarshaller[T] =
    Marshaller.withFixedContentType(`text/xml(UTF-8)`) { body =>
      HttpEntity(`text/xml(UTF-8)`, encoder.encode(body))
    }

  implicit def soapTextXmlUnmarshaller[T](implicit decoder: XmlDecoder[T]): FromResponseUnmarshaller[T] =
    Unmarshaller.messageUnmarshallerFromEntityUnmarshaller(Unmarshaller.stringUnmarshaller.map { str =>
      decoder.decode(str).fold(err => throw err, identity)
    })
} 
Example 21
Source File: PlayJsonSupport.scala    From akka-cluster-manager   with MIT License 5 votes vote down vote up
package io.orkestra.cluster.management

import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model.HttpCharsets
import akka.http.scaladsl.model.MediaTypes.`application/json`
import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, Unmarshaller}
import akka.stream.Materializer
import play.api.libs.json._

import scala.concurrent.ExecutionContext
import scala.language.implicitConversions


trait PlayJsonSupport {

  type Printer = (JsValue ⇒ String)

  def read[T](jsValue: JsValue)(implicit reads: Reads[T]): T = {
    reads.reads(jsValue) match {
      case s: JsSuccess[T] ⇒ s.get
      case e: JsError ⇒ throw JsResultException(e.errors)
    }
  }

  implicit def playJsonUnmarshallerConverter[T](reads: Reads[T])(implicit ec: ExecutionContext, mat: Materializer): FromEntityUnmarshaller[T] =
    playJsonUnmarshaller(reads, ec, mat)

  implicit def playJsonUnmarshaller[T](implicit reads: Reads[T], ec: ExecutionContext, mat: Materializer): FromEntityUnmarshaller[T] =
    playJsValueUnmarshaller.map(read[T])

  implicit def playJsValueUnmarshaller(implicit ec: ExecutionContext, mat: Materializer): FromEntityUnmarshaller[JsValue] =
    Unmarshaller.byteStringUnmarshaller.forContentTypes(`application/json`).mapWithCharset { (data, charset) ⇒
      if (charset == HttpCharsets.`UTF-8`) Json.parse(data.toArray)
      else Json.parse(data.decodeString(charset.nioCharset.name)) // FIXME: identify charset by instance, not by name!
    }

  implicit def playJsonMarshallerConverter[T](writes: Writes[T])(implicit printer: Printer = Json.prettyPrint, ec: ExecutionContext): ToEntityMarshaller[T] =
    playJsonMarshaller[T](writes, printer, ec)

  implicit def playJsonMarshaller[T](implicit writes: Writes[T], printer: Printer = Json.prettyPrint, ec: ExecutionContext): ToEntityMarshaller[T] =
    playJsValueMarshaller[T].compose(writes.writes)

  implicit def playJsValueMarshaller[T](implicit writes: Writes[T], printer: Printer = Json.prettyPrint, ec: ExecutionContext): ToEntityMarshaller[JsValue] =
    Marshaller.StringMarshaller.wrap(`application/json`)(printer)
}

object PlayJsonSupport extends PlayJsonSupport 
Example 22
Source File: EventUnmarshaller.scala    From 006877   with MIT License 5 votes vote down vote up
package aia.stream

import scala.concurrent.{ ExecutionContext, Future }
import akka.NotUsed
import akka.stream.scaladsl.Framing
import akka.stream.scaladsl.JsonFraming
import akka.stream.Materializer
import akka.stream.scaladsl.Source

import akka.http.scaladsl.model.HttpCharsets._
import akka.http.scaladsl.model.MediaTypes._
import akka.http.scaladsl.model.headers.Accept
import akka.http.scaladsl.marshalling._
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
import akka.http.scaladsl.model._

import akka.util.ByteString
import spray.json._

import akka.http.scaladsl.unmarshalling.Unmarshaller
import akka.http.scaladsl.unmarshalling.Unmarshaller._

object EventUnmarshaller extends EventMarshalling {
  val supported = Set[ContentTypeRange](
    ContentTypes.`text/plain(UTF-8)`, 
    ContentTypes.`application/json`
  )

  def create(maxLine: Int, maxJsonObject: Int) = {
    new Unmarshaller[HttpEntity, Source[Event, _]] {
      def apply(entity: HttpEntity)(implicit ec: ExecutionContext, 
        materializer: Materializer): Future[Source[Event, _]] = {

        val future = entity.contentType match {
          case ContentTypes.`text/plain(UTF-8)` => 
            Future.successful(LogJson.textInFlow(maxLine))
          case ContentTypes.`application/json` =>
            Future.successful(LogJson.jsonInFlow(maxJsonObject))
          case other => 
            Future.failed(
              new UnsupportedContentTypeException(supported)
            )
        }
        future.map(flow => entity.dataBytes.via(flow))(ec)
      } 
    }.forContentTypes(supported.toList:_*)
  }
} 
Example 23
Source File: PlayJsonSupport.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.http

import java.nio.charset.Charset

import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model._
import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, Unmarshaller}
import akka.util.ByteString
import play.api.libs.json._

trait PlayJsonSupport {

  private val mediaTypes: Seq[MediaType.WithFixedCharset] =
    Seq(MediaType.applicationWithFixedCharset("json", HttpCharsets.`UTF-8`, "js"))

  private val unmarshallerContentTypes: Seq[ContentTypeRange] = mediaTypes.map(ContentTypeRange.apply)

  implicit val playJsonMarshaller: ToEntityMarshaller[JsValue] = {
    Marshaller.oneOf(mediaTypes: _*) { mediaType =>
      Marshaller.withFixedContentType(ContentType(mediaType)) {
        json => HttpEntity(mediaType, json.toString)
      }
    }
  }

  implicit val playJsonUnmarshaller: FromEntityUnmarshaller[JsValue] = {
    Unmarshaller.byteStringUnmarshaller
      .forContentTypes(unmarshallerContentTypes: _*)
      .map {
        case ByteString.empty => throw Unmarshaller.NoContentException
        case data => Json.parse(data.decodeString(Charset.forName("UTF-8")))
      }
  }

  trait ToPlayJson[T] {
    def toJson(msg: T): JsValue
  }

  import scala.language.reflectiveCalls

  object ToPlayJson {
    type ToPlayJsonReflective = {
      def toJson: JsValue
    }

    implicit def forToJson[A <: ToPlayJsonReflective] = new ToPlayJson[A] {
      def toJson(js: A) = js.toJson
    }

    implicit def forPlayJson[A <: JsValue] = new ToPlayJson[A] {
      def toJson(js: A) = js
    }
  }

  implicit object JsErrorJsonWriter extends Writes[JsError] {
    def writes(o: JsError): JsValue = Json.obj(
      "errors" -> JsArray(
        o.errors.map {
          case (path, validationErrors) => Json.obj(
            "path" -> Json.toJson(path.toString()),
            "validationErrors" -> JsArray(validationErrors.map(validationError => Json.obj(
              "message" -> JsString(validationError.message),
              "args" -> JsArray(validationError.args.map {
                case x: Int => JsNumber(x)
                case x => JsString(x.toString)
              })
            )))
          )
        }
      )
    )
  }

} 
Example 24
Source File: SangriaGraphQLSupport.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.http

import java.nio.charset.Charset

import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model._
import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, Unmarshaller}
import akka.util.ByteString
import sangria.ast.Document
import sangria.parser.QueryParser
import sangria.renderer.{QueryRenderer, QueryRendererConfig}

trait SangriaGraphQLSupport {
  private val mediaTypes: Seq[MediaType.WithFixedCharset] =
    Seq(MediaType.applicationWithFixedCharset("graphql", HttpCharsets.`UTF-8`, "graphql"))

  private val unmarshallerContentTypes: Seq[ContentTypeRange] = mediaTypes.map(ContentTypeRange.apply)

  implicit def documentMarshaller(implicit config: QueryRendererConfig = QueryRenderer.Compact): ToEntityMarshaller[Document] = {
    Marshaller.oneOf(mediaTypes: _*) {
      mediaType ⇒
        Marshaller.withFixedContentType(ContentType(mediaType)) {
          json ⇒ HttpEntity(mediaType, QueryRenderer.render(json, config))
        }
    }
  }

  implicit val documentUnmarshaller: FromEntityUnmarshaller[Document] = {
    Unmarshaller.byteStringUnmarshaller
      .forContentTypes(unmarshallerContentTypes: _*)
      .map {
        case ByteString.empty ⇒ throw Unmarshaller.NoContentException
        case data ⇒
          import sangria.parser.DeliveryScheme.Throw
          QueryParser.parse(data.decodeString(Charset.forName("UTF-8")))
      }
  }
} 
Example 25
Source File: ApiMarshallers.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http

import akka.http.scaladsl.marshalling.{Marshaller, PredefinedToEntityMarshallers, ToEntityMarshaller}
import akka.http.scaladsl.model.MediaTypes.{`application/json`, `text/plain`}
import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, PredefinedFromEntityUnmarshallers, Unmarshaller}
import akka.util.ByteString
import com.wavesplatform.dex.api.http.json.CustomJson
import com.wavesplatform.dex.domain.transaction.ExchangeTransaction
import play.api.libs.json._

import scala.util.control.Exception.nonFatalCatch
import scala.util.control.NoStackTrace

case class PlayJsonException(cause: Option[Throwable] = None, errors: Seq[(JsPath, Seq[JsonValidationError])] = Seq.empty)
    extends IllegalArgumentException(s"JSON parsing errors:\n${errors.mkString("\n")}", cause.orNull)
    with NoStackTrace

trait ApiMarshallers {

  implicit lazy val ExchangeTransactionJsonWrites: Writes[ExchangeTransaction] = Writes(_.json())

  private[this] lazy val jsonStringUnmarshaller =
    Unmarshaller.byteStringUnmarshaller
      .forContentTypes(`application/json`)
      .mapWithCharset {
        case (ByteString.empty, _) => throw Unmarshaller.NoContentException
        case (data, charset)       => data.decodeString(charset.nioCharset.name)
      }

  private[this] lazy val jsonStringMarshaller = Marshaller.stringMarshaller(`application/json`)

  private[this] lazy val customJsonStringMarshaller = Marshaller.stringMarshaller(CustomJson.jsonWithNumbersAsStrings)

  implicit def playJsonUnmarshaller[A](implicit reads: Reads[A]): FromEntityUnmarshaller[A] =
    jsonStringUnmarshaller.map { data =>
      val json = nonFatalCatch.withApply(t => throw PlayJsonException(cause = Some(t)))(Json.parse(data))

      json.validate[A] match {
        case JsSuccess(value, _) => value
        case JsError(errors)     => throw PlayJsonException(errors = errors)
      }
    }

  // preserve support for extracting plain strings from requests
  implicit val stringUnmarshaller: FromEntityUnmarshaller[String] = PredefinedFromEntityUnmarshallers.stringUnmarshaller
  implicit val intUnmarshaller: FromEntityUnmarshaller[Int]       = stringUnmarshaller.map(_.toInt)

  implicit def playJsonMarshaller[A](implicit writes: Writes[A], jsValueToString: JsValue => String = Json.stringify): ToEntityMarshaller[A] =
    Marshaller.oneOf(
      jsonStringMarshaller
        .compose(jsValueToString)
        .compose(writes.writes),
      customJsonStringMarshaller
        .compose(CustomJson.writeValueAsString)
        .compose(writes.writes)
    )

  // preserve support for using plain strings as request entities
  implicit val stringMarshaller = PredefinedToEntityMarshallers.stringMarshaller(`text/plain`)
}

object ApiMarshallers extends ApiMarshallers 
Example 26
Source File: ClickhouseHostHealth.scala    From clickhouse-scala-client   with GNU Lesser General Public License v3.0 5 votes vote down vote up
package com.crobox.clickhouse.balancing.discovery.health

import akka.NotUsed
import akka.actor.{ActorSystem, Cancellable}
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.http.scaladsl.settings.ConnectionPoolSettings
import akka.http.scaladsl.unmarshalling.Unmarshaller
import akka.stream.Materializer
import akka.stream.scaladsl.{Flow, Source}
import com.crobox.clickhouse.internal.ClickhouseResponseParser

import scala.concurrent.duration._
import scala.concurrent.{ExecutionContext, Future}
import scala.util.{Failure, Success, Try}

object ClickhouseHostHealth extends ClickhouseResponseParser {

  sealed trait ClickhouseHostStatus {
    val host: Uri
    val code: String
  }

  case class Alive(host: Uri) extends ClickhouseHostStatus { override val code: String = "ok" }

  case class Dead(host: Uri, reason: Throwable) extends ClickhouseHostStatus { override val code: String = "nok" }

  
  def healthFlow(host: Uri)(
      implicit system: ActorSystem,
      materializer: Materializer,
      executionContext: ExecutionContext
  ): Source[ClickhouseHostStatus, Cancellable] = {
    val healthCheckInterval: FiniteDuration =
      system.settings.config
        .getDuration("connection.health-check.interval")
        .getSeconds.seconds
    val healthCheckTimeout: FiniteDuration =
      system.settings.config
        .getDuration("connection.health-check.timeout")
        .getSeconds.seconds

    val healthCachedPool = Http(system).cachedHostConnectionPool[Int](
      host.authority.host.address(),
      host.effectivePort,
      settings = ConnectionPoolSettings(system)
        .withMaxConnections(1)
        .withMinConnections(1)
        .withMaxOpenRequests(2)
        .withMaxRetries(3)
        .withUpdatedConnectionSettings(
          _.withIdleTimeout(healthCheckTimeout + healthCheckInterval).withConnectingTimeout(healthCheckTimeout)
        )
    )
    Source
      .tick(0.milliseconds, healthCheckInterval, 0)
      .map(tick => {
        (HttpRequest(method = HttpMethods.GET, uri = host), tick)
      })
      .via(healthCachedPool)
      .via(parsingFlow(host))
  }

  private[health] def parsingFlow[T](
      host: Uri
  )(implicit ec: ExecutionContext, mat: Materializer): Flow[(Try[HttpResponse], T), ClickhouseHostStatus, NotUsed] =
    Flow[(Try[HttpResponse], T)].mapAsync(1) {
      case (Success(response @ akka.http.scaladsl.model.HttpResponse(StatusCodes.OK, _, _, _)), _) =>
        Unmarshaller.stringUnmarshaller(decodeResponse(response).entity)
          .map(splitResponse)
          .map(
            stringResponse =>
              if (stringResponse.equals(Seq("Ok."))) {
                Alive(host)
              } else {
                Dead(host, new IllegalArgumentException(s"Got wrong result $stringResponse"))
            }
          )
      case (Success(response), _) =>
        Future.successful(Dead(host, new IllegalArgumentException(s"Got response with status code ${response.status}")))
      case (Failure(ex), _) =>
        Future.successful(Dead(host, ex))
    }

} 
Example 27
Source File: ClickhouseResponseParser.scala    From clickhouse-scala-client   with GNU Lesser General Public License v3.0 5 votes vote down vote up
package com.crobox.clickhouse.internal

import akka.http.scaladsl.coding.{Deflate, Gzip, NoCoding}
import akka.http.scaladsl.model._
import akka.http.scaladsl.model.headers.{HttpEncoding, HttpEncodings}
import akka.http.scaladsl.unmarshalling.Unmarshaller
import akka.stream.Materializer
import akka.stream.scaladsl.SourceQueue
import com.crobox.clickhouse.internal.progress.QueryProgress.{QueryProgress, _}
import com.crobox.clickhouse.{ClickhouseChunkedException, ClickhouseException}

import scala.concurrent.{ExecutionContext, Future}
import scala.util.{Failure, Success}

private[clickhouse] trait ClickhouseResponseParser {

  protected def processClickhouseResponse(responseFuture: Future[HttpResponse],
                                          query: String,
                                          host: Uri,
                                          progressQueue: Option[SourceQueue[QueryProgress]])(
      implicit materializer: Materializer,
      executionContext: ExecutionContext
  ): Future[String] =
    responseFuture.flatMap { response =>
      decodeResponse(response) match {
        case HttpResponse(StatusCodes.OK, _, entity, _) =>
          Unmarshaller.stringUnmarshaller(entity).map(content => {
            if (content.contains("DB::Exception")) { //FIXME this is quite a fragile way to detect failures, hopefully nobody will have a valid exception string in the result. Check https://github.com/yandex/ClickHouse/issues/2999
              throw ClickhouseException("Found exception in the query return body",
                                        query,
                                        ClickhouseChunkedException(content),
                                        StatusCodes.OK)
            }
            content
          })
          .andThen {
            case Success(_) =>
              progressQueue.foreach(queue => {
                queue.offer(QueryFinished)
              })
            case Failure(exception) =>
              progressQueue.foreach(queue => {
                queue.offer(QueryFailed(exception))
              })
          }
        case HttpResponse(code, _, entity, _) =>
          progressQueue.foreach(_.offer(QueryRejected))
          Unmarshaller.stringUnmarshaller(entity).flatMap(
            response =>
              Future.failed(
                  ClickhouseException(s"Server [$host] returned code $code; $response", query, statusCode = code)
              )
          )
      }
    }

  protected def decodeResponse(response: HttpResponse): HttpResponse = {
    val decoder = response.encoding match {
      case HttpEncodings.gzip => Gzip
      case HttpEncodings.deflate => Deflate
      case HttpEncodings.identity => NoCoding
      case HttpEncoding(enc) => throw new IllegalArgumentException(s"Unsupported response encoding: $enc")
    }
    decoder.decodeMessage(response)
  }

  protected def splitResponse(response: String): Seq[String] =
    response.split("\n").toSeq
} 
Example 28
Source File: JsonUnmarshaller.scala    From akka-http-oauth2-client   with Apache License 2.0 5 votes vote down vote up
package com.github.dakatsuka.akka.http.oauth2.client.utils

import akka.http.scaladsl.model.ContentTypeRange
import akka.http.scaladsl.model.MediaTypes.`application/json`
import akka.http.scaladsl.unmarshalling.{ FromEntityUnmarshaller, Unmarshaller }
import akka.util.ByteString
import io.circe.{ jawn, Decoder, Json }

trait JsonUnmarshaller {
  def unmarshallerContentTypes: Seq[ContentTypeRange] =
    List(`application/json`)

  implicit def jsonUnmarshaller: FromEntityUnmarshaller[Json] =
    Unmarshaller.byteStringUnmarshaller
      .forContentTypes(unmarshallerContentTypes: _*)
      .map {
        case ByteString.empty => throw Unmarshaller.NoContentException
        case data             => jawn.parseByteBuffer(data.asByteBuffer).fold(throw _, identity)
      }

  implicit def unmarshaller[A: Decoder]: FromEntityUnmarshaller[A] = {
    def decode(json: Json) = implicitly[Decoder[A]].decodeJson(json).fold(throw _, identity)
    jsonUnmarshaller.map(decode)
  }
} 
Example 29
Source File: AkkaHttpCirceSupport.scala    From scalanda-v20   with MIT License 5 votes vote down vote up
package com.msilb.scalandav20.common

import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model.MediaTypes.`application/json`
import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, Unmarshaller}
import akka.util.ByteString
import io.circe._

object AkkaHttpCirceSupport extends AkkaHttpCirceSupport

trait AkkaHttpCirceSupport {

  private val jsonStringUnmarshaller =
    Unmarshaller.byteStringUnmarshaller
      .forContentTypes(`application/json`)
      .mapWithCharset {
        case (ByteString.empty, _) => throw Unmarshaller.NoContentException
        case (data, charset) => data.decodeString(charset.nioCharset.name)
      }

  private val jsonStringMarshaller = Marshaller.stringMarshaller(`application/json`)

  implicit def circeUnmarshaller[A](implicit decoder: Decoder[A]): FromEntityUnmarshaller[A] =
    jsonStringUnmarshaller.map(jawn.decode(_).fold(throw _, identity))

  implicit def circeToEntityMarshaller[A](implicit encoder: Encoder[A],
                                          printer: Json => String = Printer.noSpaces.copy(dropNullValues = true).pretty): ToEntityMarshaller[A] =
    jsonStringMarshaller.compose(printer).compose(encoder.apply)
} 
Example 30
Source File: ChunkedEntities.scala    From endpoints4s   with MIT License 5 votes vote down vote up
package endpoints4s.akkahttp.server

import akka.http.scaladsl.marshalling.Marshaller
import akka.http.scaladsl.model.{ContentType, ContentTypes, HttpEntity, HttpRequest, MessageEntity}
import akka.http.scaladsl.server.Directives
import akka.http.scaladsl.unmarshalling.Unmarshaller
import akka.stream.scaladsl.Source
import akka.util.ByteString
import endpoints4s.algebra

import scala.concurrent.Future


trait ChunkedJsonEntities
    extends algebra.ChunkedJsonEntities
    with ChunkedEntities
    with JsonEntitiesFromCodecs {

  def jsonChunksRequest[A](implicit
      codec: JsonCodec[A]
  ): RequestEntity[Chunks[A]] = {
    val decoder = stringCodec(codec)
    chunkedRequestEntity { byteString =>
      val string = byteString.utf8String
      decoder
        .decode(string)
        .toEither
        .left
        .map(errors => new Throwable(errors.mkString(". ")))
    }
  }

  def jsonChunksResponse[A](implicit
      codec: JsonCodec[A]
  ): ResponseEntity[Chunks[A]] = {
    val encoder = stringCodec(codec)
    chunkedResponseEntity(
      ContentTypes.`application/json`,
      a => ByteString(encoder.encode(a))
    )
  }

} 
Example 31
Source File: HttpMessageExtractors.scala    From wix-http-testkit   with MIT License 5 votes vote down vote up
package com.wix.e2e.http.client.extractors

import akka.http.scaladsl.model.{HttpEntity, HttpMessage}
import akka.http.scaladsl.unmarshalling.{Unmarshal, Unmarshaller}
import com.wix.e2e.http.WixHttpTestkitResources
import com.wix.e2e.http.api.Marshaller
import com.wix.e2e.http.utils.waitFor

import scala.concurrent.duration._

trait HttpMessageExtractors {
  implicit class HttpMessageExtractorsOps[M <: HttpMessage](message: M) {
    def extractAs[T : Manifest](implicit marshaller: Marshaller = Marshaller.Implicits.marshaller, atMost: FiniteDuration = 5.seconds): T = message.entity.extractAs[T]
    def extractAsString(implicit atMost: FiniteDuration = 5.seconds): String = message.entity.extractAsString
    def extractAsBytes(implicit atMost: FiniteDuration = 5.seconds): Array[Byte] = message.entity.extractAsBytes
  }

  implicit class HttpEntityExtractorsOps[E <: HttpEntity](entity: E) {
    def extractAs[T : Manifest](implicit marshaller: Marshaller = Marshaller.Implicits.marshaller, atMost: FiniteDuration = 5.seconds): T = marshaller.unmarshall[T](extract[String])
    def extractAsString(implicit atMost: FiniteDuration = 5.seconds): String = extract[String]
    def extractAsBytes(implicit atMost: FiniteDuration = 5.seconds): Array[Byte] = extract[Array[Byte]]

    import WixHttpTestkitResources.materializer
    private def extract[T](implicit um: Unmarshaller[E, T], atMost: FiniteDuration) = waitFor(Unmarshal(entity).to[T])(atMost)
  }
}

object HttpMessageExtractors extends HttpMessageExtractors 
Example 32
Source File: HttpCodec.scala    From daml   with Apache License 2.0 5 votes vote down vote up
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.daml.http.json

import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model.MediaTypes.`application/json`
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.ExceptionHandler
import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, Unmarshaller}
import com.daml.util.ExceptionOps._
import scalaz.std.stream.unfold
import scalaz.{@@, Tag}
import spray.json._

import scala.concurrent.{ExecutionContext, Future}


object HttpCodec {
  sealed trait JsonApi
  val JsonApi = Tag.of[JsonApi]

  implicit val jsonExceptionHandler: ExceptionHandler = ExceptionHandler {
    case e: DeserializationException =>
      complete(
        (
          StatusCodes.BadRequest,
          ResponseFormats.errorsJsObject(
            StatusCodes.BadRequest,
            s"JSON parser error: ${e.msg}" +: unfoldCauses(e.cause).map(_.description): _*)))
  }

  private[this] def unfoldCauses(t: Throwable): Seq[Throwable] =
    unfold(t)(tnq => Option(tnq) map (tnn => (tnn, tnn.getCause)))

  private[this] val simpleJsValueUnmarshaller =
    Unmarshaller[String, JsValue] { implicit ec: ExecutionContext => value =>
      Future(value.parseJson)
    }

  implicit val jsValueUnmarshaller: FromEntityUnmarshaller[JsValue] =
    (implicitly[FromEntityUnmarshaller[String]] andThen simpleJsValueUnmarshaller
      forContentTypes `application/json`)

  implicit val jsValueMarshaller: ToEntityMarshaller[JsValue] =
    Marshaller.combined((_: JsValue).compactPrint)(Marshaller.stringMarshaller(`application/json`))

  implicit def jsonCodecUnmarshaller[A: RootJsonReader]: FromEntityUnmarshaller[A @@ JsonApi] =
    JsonApi.subst[FromEntityUnmarshaller, A](jsValueUnmarshaller map (_.convertTo[A]))

  implicit def jsonCodecMarshaller[A: RootJsonWriter]: ToEntityMarshaller[A @@ JsonApi] =
    JsonApi.subst[ToEntityMarshaller, A](Marshaller.combined((_: A).toJson))
} 
Example 33
Source File: SpeedMeasurement.scala    From Akka-Cookbook   with MIT License 5 votes vote down vote up
package com.packt.chapter9

import akka.http.scaladsl.marshalling.{Marshaller, _}
import akka.http.scaladsl.model._
import akka.http.scaladsl.unmarshalling.{Unmarshaller, _}

object SpeedMeasurement {
  def unmarshall(str: String) = {
    str.split("\\s") match {
      case Array(timestamp, latitude, longitude, value) =>
        SpeedMeasurement(timestamp.toLong, latitude.toDouble, longitude.toDouble, value.toDouble)
    }
  }
}

case class SpeedMeasurement(timestamp: Long, latitude: Double, longitude: Double, value: Double) {
  val marshall = s"$timestamp $latitude $longitude $value"
}

trait SpeedMeasurementMarshallingHelper {
  val contentType = ContentType(MediaTypes.`text/tab-separated-values`, HttpCharsets.`UTF-8`)
  implicit val utf8TextSpaceMarshaller: ToEntityMarshaller[SpeedMeasurement] =
    Marshaller.withFixedContentType(contentType) { speedMeasurement ⇒ HttpEntity(contentType, speedMeasurement.marshall) }
  implicit val utf8TextSpaceUnmarshaller: FromEntityUnmarshaller[SpeedMeasurement] =
    Unmarshaller.stringUnmarshaller.map(SpeedMeasurement.unmarshall)
} 
Example 34
Source File: AkkaHttpMarshalling.scala    From telegram   with Apache License 2.0 5 votes vote down vote up
package com.bot4s.telegram.marshalling

import akka.http.scaladsl.marshalling.{Marshaller, Marshalling, ToEntityMarshaller}
import akka.http.scaladsl.model._
import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, Unmarshaller}
import com.bot4s.telegram.marshalling
import com.bot4s.telegram.methods.{JsonRequest, MultipartRequest, Request}
import com.bot4s.telegram.models.{AkkaInputFile, InputFile}
import io.circe.{Decoder, Encoder}


object AkkaHttpMarshalling {

  implicit def camelCaseJsonUnmarshaller[R](implicit decR: Decoder[R]): FromEntityUnmarshaller[R] = {
    Unmarshaller
      .stringUnmarshaller
      .forContentTypes(ContentTypes.`application/json`)
      .map(marshalling.fromJson[R])
  }

  implicit def underscore_case_marshaller[T <: Request[_]](implicit encT: Encoder[T]): ToEntityMarshaller[T] = {
    Marshaller.strict {
      request => request match {
        // JSON-only request
        case r: JsonRequest[_] =>
          Marshalling.Opaque(() => HttpEntity(ContentTypes.`application/json`, marshalling.toJson(request)))

        // Request with multipart payload
        case r: MultipartRequest[_] =>
          val files = r.getFiles
          val parts = files.map {
            case (camelKey, inputFile) =>
              val key = CaseConversions.snakenize(camelKey)
              inputFile match {
                case InputFile.FileId(id) => Multipart.FormData.BodyPart(key, HttpEntity(id))

                case InputFile.Contents(filename, contents) =>
                  Multipart.FormData.BodyPart(key, HttpEntity(ContentTypes.`application/octet-stream`, contents),
                    Map("filename" -> filename))

                case InputFile.Path(path) =>
                  Multipart.FormData.BodyPart.fromPath(key, MediaTypes.`application/octet-stream`, path)

                case AkkaInputFile.ByteString(filename, bytes) =>
                  Multipart.FormData.BodyPart(key, HttpEntity(MediaTypes.`application/octet-stream`, bytes),
                    Map("filename" -> filename))

                case other =>
                  throw new RuntimeException(s"InputFile $other not supported")
              }
          }

          val fields = io.circe.parser.parse(marshalling.toJson(request)).fold(throw _, _.asObject.map {
            _.toMap.mapValues {
              json =>
                json.asString.getOrElse(marshalling.printer.pretty(json))
            }
          })

          val params = fields.getOrElse(Map())
          val paramParts = params.map { case (key, value) => Multipart.FormData.BodyPart(key, HttpEntity(value)) }

          Marshalling.Opaque(() => Multipart.FormData((parts ++ paramParts): _*).toEntity())
      }
    }
  }
} 
Example 35
Source File: PhoneBookWebService.scala    From udash-demos   with GNU General Public License v3.0 5 votes vote down vote up
package io.udash.demos.rest.api

import akka.http.scaladsl.marshalling._
import akka.http.scaladsl.model.{HttpEntity, MediaTypes, StatusCodes}
import com.avsystem.commons.serialization.GenCodec
import io.udash.demos.rest.model._
import io.udash.demos.rest.services.{ContactService, InMemoryContactService, InMemoryPhoneBookService, PhoneBookService}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.{RequestContext, Route}
import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, Unmarshaller}
import com.avsystem.commons.serialization.json.{JsonStringInput, JsonStringOutput}


trait PhoneBookWebServiceSpec {
  private val staticsDir = "frontend/target/UdashStatics/WebContent"

  val phoneBookService: PhoneBookService
  val contactService: ContactService

  implicit def optionMarshaller[T](implicit codec: GenCodec[T]): ToResponseMarshaller[Option[T]] =
    gencodecMarshaller[Option[T]](GenCodec.optionCodec(codec))

  implicit def gencodecMarshaller[T](implicit codec: GenCodec[T]): ToEntityMarshaller[T] =
    Marshaller.withFixedContentType(MediaTypes.`application/json`) { value =>
      HttpEntity(MediaTypes.`application/json`, JsonStringOutput.write(value))
    }

  implicit def gencodecUnmarshaller[T](implicit codec: GenCodec[T]): FromEntityUnmarshaller[T] =
    Unmarshaller.stringUnmarshaller.forContentTypes(MediaTypes.`application/json`).map{ data =>
      JsonStringInput.read[T](data)
    }

  private def completeIfNonEmpty[T](ctx: RequestContext)(opt: Option[T])(implicit rm: ToResponseMarshaller[T]) =
    opt match {
      case Some(v) => complete(v)(ctx)
      case None => complete(StatusCodes.NotFound)(ctx)
    }

  val route: Route = {
    pathPrefix("scripts"){
      getFromDirectory(s"$staticsDir/scripts")
    } ~
    pathPrefix("assets"){
      getFromDirectory(s"$staticsDir/assets")
    } ~
    pathPrefix("api") {
      pathPrefix("book") {
        pathPrefix(Segment) { segment =>
          val bookId = PhoneBookId(segment.toInt)
          pathPrefix("contacts") {
            pathPrefix("count") {
              get {
                
            entity(as[Contact]) { contact =>
              complete { contactService.create(contact) }
            }
          }
      }
    } ~ get {
      getFromFile(s"$staticsDir/index.html")
    }
  }
}

class PhoneBookWebService() extends PhoneBookWebServiceSpec {
  override val phoneBookService: PhoneBookService = InMemoryPhoneBookService
  override val contactService: ContactService = InMemoryContactService
} 
Example 36
Source File: AkkaBodyUnmarshaller.scala    From chronicler   with Apache License 2.0 5 votes vote down vote up
package com.github.fsanaulla.chronicler.akka.shared.handlers

import akka.http.scaladsl.coding.Gzip
import akka.http.scaladsl.model.{HttpCharsets, HttpEntity}
import akka.http.scaladsl.unmarshalling.Unmarshaller
import akka.stream.Materializer
import akka.util.ByteString
import com.github.fsanaulla.chronicler.core.alias.ErrorOr
import com.github.fsanaulla.chronicler.core.jawn.RichJParser
import org.typelevel.jawn.ast.{JParser, JValue}

import scala.concurrent.{ExecutionContext, Future}

final class AkkaBodyUnmarshaller(compressed: Boolean)
  extends Unmarshaller[HttpEntity, ErrorOr[JValue]] {

  override def apply(
      value: HttpEntity
    )(implicit ec: ExecutionContext,
      mat: Materializer
    ): Future[ErrorOr[JValue]] = {

    // get encoding from response content type, otherwise use UTF-8 as default
    val encoding = value.contentType.charsetOption
      .getOrElse(HttpCharsets.`UTF-8`)
      .nioCharset()

    val srcBody = if (compressed) value.dataBytes.via(Gzip.decoderFlow) else value.dataBytes

    srcBody
      .runFold(ByteString.empty)(_ ++ _)
      .map(_.decodeString(encoding))
      .map(JParser.parseFromStringEither)
  }
} 
Example 37
Source File: QueryDirectives.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.admin.directives

import akka.http.scaladsl.server.Directive1
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.unmarshalling.Unmarshaller
import ch.epfl.bluebrain.nexus.admin.routes.SearchParams
import ch.epfl.bluebrain.nexus.admin.routes.SearchParams.Field
import ch.epfl.bluebrain.nexus.commons.search.FromPagination
import ch.epfl.bluebrain.nexus.rdf.Iri
import ch.epfl.bluebrain.nexus.rdf.Iri.AbsoluteIri
import ch.epfl.bluebrain.nexus.service.config.ServiceConfig.PaginationConfig


  def searchParamsOrgs: Directive1[SearchParams] =
    parameter("label".as[String].?).flatMap { label =>
      searchParams.map(_.copy(organizationLabel = label.filter(_.nonEmpty).map(Field(_))))
    }

  private def searchParams: Directive1[SearchParams] =
    (parameter("deprecated".as[Boolean].?) &
      parameter("rev".as[Long].?) &
      parameter("createdBy".as[AbsoluteIri].?) &
      parameter("updatedBy".as[AbsoluteIri].?) &
      parameter("type".as[AbsoluteIri].*)).tmap {
      case (deprecated, rev, createdBy, updatedBy, types) =>
        SearchParams(None, None, deprecated, rev, createdBy, updatedBy, types.toSet)
    }

  implicit private def iriFromStringUnmarshaller: Unmarshaller[String, AbsoluteIri] =
    Unmarshaller.strict[String, AbsoluteIri] { string =>
      Iri.url(string) match {
        case Right(iri) => iri
        case x          => throw new IllegalArgumentException(s"'$x' is not a valid AbsoluteIri value")
      }
    }
}

object QueryDirectives extends QueryDirectives 
Example 38
Source File: StringUnmarshaller.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.admin.directives

import akka.http.scaladsl.unmarshalling.{FromStringUnmarshaller, Unmarshaller}
import ch.epfl.bluebrain.nexus.admin.exceptions.AdminError.InvalidFormat
import com.typesafe.scalalogging.Logger
import io.circe.parser._
import io.circe.{Decoder, Json}

object StringUnmarshaller {

  private val logger = Logger[this.type]

  
  def unmarshallJson[A: Decoder]: FromStringUnmarshaller[A] =
    unmarshaller { value =>
      parse(value).left.map { err =>
        logger.warn(s"Failed to convert string '$value' to Json", err)
        InvalidFormat
      }
    }

  private def unmarshaller[A](
      f: String => Either[Throwable, Json]
  )(implicit dec: Decoder[A]): FromStringUnmarshaller[A] =
    Unmarshaller.strict[String, A] {
      case ""     => throw Unmarshaller.NoContentException
      case string =>
        f(string).flatMap(_.as[A]) match {
          case Right(value) => value
          case Left(err)    => throw new IllegalArgumentException(err)
        }
    }

} 
Example 39
Source File: package.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.kg

import akka.http.scaladsl.unmarshalling.Unmarshaller
import ch.epfl.bluebrain.nexus.admin.client.types.Project
import ch.epfl.bluebrain.nexus.commons.search.Sort
import ch.epfl.bluebrain.nexus.kg.directives.PathDirectives.toIri
import ch.epfl.bluebrain.nexus.rdf.Iri
import ch.epfl.bluebrain.nexus.rdf.Iri.AbsoluteIri

package object directives {

  implicit private[directives] def absoluteIriFromStringUnmarshaller(implicit
      project: Project
  ): Unmarshaller[String, AbsoluteIri] =
    Unmarshaller.strict[String, AbsoluteIri] { string =>
      toIriOrElseBase(string) match {
        case Some(iri) => iri
        case _         => throw new IllegalArgumentException(s"'$string' is not a valid AbsoluteIri value")
      }
    }

  implicit private[directives] def vocabAbsoluteIriFromStringUnmarshaller(implicit
      project: Project
  ): Unmarshaller[String, VocabAbsoluteIri] =
    Unmarshaller.strict[String, VocabAbsoluteIri] { string =>
      toIriOrElseVocab(string) match {
        case Some(iri) => VocabAbsoluteIri(iri)
        case _         => throw new IllegalArgumentException(s"'$string' is not a valid AbsoluteIri value")
      }
    }

  implicit private[directives] val sortFromStringUnmarshaller: Unmarshaller[String, Sort] =
    Unmarshaller.strict[String, Sort](Sort(_))

  private def toIriOrElseBase(s: String)(implicit project: Project): Option[AbsoluteIri] =
    toIri(s) orElse Iri.absolute(project.base.asString + s).toOption

  private def toIriOrElseVocab(s: String)(implicit project: Project): Option[AbsoluteIri] =
    toIri(s) orElse Iri.absolute(project.vocab.asString + s).toOption
} 
Example 40
Source File: RealmDirectives.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.iam.directives

import akka.http.javadsl.server.Rejections.validationRejection
import akka.http.scaladsl.server.Directive1
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.PathMatchers.Segment
import akka.http.scaladsl.unmarshalling.Unmarshaller
import ch.epfl.bluebrain.nexus.iam.routes.SearchParams
import ch.epfl.bluebrain.nexus.iam.types.Label
import ch.epfl.bluebrain.nexus.rdf.Iri
import ch.epfl.bluebrain.nexus.rdf.Iri.AbsoluteIri

trait RealmDirectives {

  
  def searchParams: Directive1[SearchParams] =
    (parameter("deprecated".as[Boolean].?) &
      parameter("rev".as[Long].?) &
      parameter("createdBy".as[AbsoluteIri].?) &
      parameter("updatedBy".as[AbsoluteIri].?) &
      parameter("type".as[AbsoluteIri].*)).tmap {
      case (deprecated, rev, createdBy, updatedBy, types) =>
        SearchParams(deprecated, rev, createdBy, updatedBy, types.toSet)
    }

  implicit private def iriFromStringUnmarshaller: Unmarshaller[String, AbsoluteIri] =
    Unmarshaller.strict[String, AbsoluteIri] { string =>
      Iri.url(string) match {
        case Right(iri) => iri
        case x          => throw new IllegalArgumentException(s"'$x' is not a valid AbsoluteIri value")
      }
    }
}

object RealmDirectives extends RealmDirectives 
Example 41
Source File: SealedOneofSupport.scala    From ForestFlow   with Apache License 2.0 5 votes vote down vote up
package ai.forestflow.scalapb

import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model.{ContentTypeRange, MediaRanges, MediaType}
import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, Unmarshaller}
import scalapb.GeneratedSealedOneof

import scala.reflect.ClassTag

// application/octet-stream
trait SealedOneofSupport {
  private val applicableMediaTypes: List[ContentTypeRange] = List(
    MediaRanges.`*/*`,
    MediaType.applicationBinary("octet-stream", MediaType.NotCompressible)
  )

  implicit def GeneratedSealedOneofBinaryUnmarshaller[T <: GeneratedSealedOneof]: FromEntityUnmarshaller[GeneratedSealedOneof]  = {
    Unmarshaller.byteArrayUnmarshaller.forContentTypes(applicableMediaTypes: _*).map(b =>  b.asInstanceOf[GeneratedSealedOneof].asMessage.companion.parseFrom(b).asInstanceOf[T])
  }

  implicit def GeneratedSealedOneofBinaryMarshaller[T <: GeneratedSealedOneof](implicit tag: ClassTag[T]): ToEntityMarshaller[T]  = {
    val result = Marshaller.ByteArrayMarshaller.compose((c: T) => c.asMessage.toByteArray)
    result
  }
}