akka.http.scaladsl.model.HttpEntity Scala Examples

The following examples show how to use akka.http.scaladsl.model.HttpEntity. 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: ExecuteAfterResponse.scala    From opencensus-scala   with Apache License 2.0 6 votes vote down vote up
package io.opencensus.scala.akka.http.utils

import akka.NotUsed
import akka.http.scaladsl.model.{HttpEntity, HttpResponse}
import akka.stream.scaladsl.Flow
import akka.stream.stage.{GraphStage, GraphStageLogic, InHandler, OutHandler}
import akka.stream.{Attributes, FlowShape, Inlet, Outlet}

object ExecuteAfterResponse {

  private class AfterResponseFlow[Element](
      onFinish: () => Unit,
      onFailure: Throwable => Unit
  ) extends GraphStage[FlowShape[Element, Element]] {
    private val in  = Inlet[Element]("in")
    private val out = Outlet[Element]("out")

    override def createLogic(inheritedAttributes: Attributes): GraphStageLogic =
      new GraphStageLogic(shape) with InHandler with OutHandler {
        def onPush(): Unit = push(out, grab(in))
        def onPull(): Unit = pull(in)

        setHandler(in, this)
        setHandler(out, this)

        override def onUpstreamFinish(): Unit = {
          onFinish()
          super.onUpstreamFinish()
        }
        override def onUpstreamFailure(ex: Throwable): Unit = {
          onFailure(ex)
          super.onUpstreamFailure(ex)
        }
      }

    override val shape = FlowShape(in, out)
  }

  private object AfterResponseFlow {
    def apply[Element](
        onFinish: () => Unit,
        onFailure: Throwable => Unit
    ): Flow[Element, Element, NotUsed] =
      Flow.fromGraph(new AfterResponseFlow(onFinish, onFailure))
  }

  def onComplete(
      response: HttpResponse,
      onFinish: () => Unit,
      onFailure: Throwable => Unit
  ): HttpResponse = {

    response.copy(
      entity = if (response.status.allowsEntity) {
        response.entity.transformDataBytes(
          AfterResponseFlow(onFinish, onFailure)
        )
      } else {
        onFinish()
        HttpEntity.Empty
      }
    )
  }
} 
Example 2
Source File: UiRoute.scala    From vamp   with Apache License 2.0 5 votes vote down vote up
package io.vamp.http_api

import akka.http.scaladsl.model.HttpEntity
import akka.http.scaladsl.model.StatusCodes._
import io.vamp.common.http.HttpApiDirectives
import io.vamp.common.{ Config, Namespace }

trait UiRoute {
  this: HttpApiDirectives ⇒

  private val index = Config.string("vamp.http-api.ui.index")
  private val directory = Config.string("vamp.http-api.ui.directory")

  def uiRoutes(implicit namespace: Namespace) = path("") {
    encodeResponse {
      if (index().isEmpty) notFound else getFromFile(index())
    }
  } ~ pathPrefix("") {
    encodeResponse {
      if (directory().isEmpty) notFound else getFromDirectory(directory())
    }
  }

  def notFound = respondWith(NotFound, HttpEntity("The requested resource could not be found."))
} 
Example 3
Source File: Aws4AuthenticatorSpec.scala    From vinyldns   with Apache License 2.0 5 votes vote down vote up
package vinyldns.api.route

import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpRequest}
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec

class Aws4AuthenticatorSpec extends AnyWordSpec with Matchers {

  "getting canonical headers" should {
    "pull the content type" in {
      val entity = HttpEntity(ContentTypes.`application/json`, "")
      val req = HttpRequest(
        entity = entity
      )

      val canonicalHeaders = new Aws4Authenticator().canonicalHeaders(req, Set("content-type"))
      canonicalHeaders.keys should contain("content-type")
      canonicalHeaders("content-type") should contain("application/json")
    }
    "pull the content-length" in {
      val entity = HttpEntity(ContentTypes.`application/json`, "")
      val req = HttpRequest(
        entity = entity
      )

      val canonicalHeaders = new Aws4Authenticator().canonicalHeaders(req, Set("content-length"))
      canonicalHeaders.keys should contain("content-length")
      canonicalHeaders("content-length") should contain("0")
    }
  }
} 
Example 4
Source File: RoutedServiceSpec.scala    From service-container   with Apache License 2.0 5 votes vote down vote up
package com.github.vonnagy.service.container.http.routing

import akka.actor._
import akka.http.scaladsl.model.{HttpEntity, MediaTypes, StatusCodes}
import akka.http.scaladsl.server.{Directives, Route}
import akka.testkit.{TestActorRef, TestProbe}
import com.github.vonnagy.service.container.Specs2RouteTest
import com.github.vonnagy.service.container.http.{DefaultMarshallers, RejectionResponse}
import org.specs2.mutable.Specification

class RoutedServiceSpec extends Specification with Directives with Specs2RouteTest {

  case class TestEntity(id: Int, name: String)

  val probe = new TestProbe(system)
  val httpAct = TestActorRef(Props(new Actor with RoutedService with DefaultMarshallers {
    def receive = routeReceive
  }), "http")

  val svc = httpAct.underlyingActor.asInstanceOf[RoutedService]

  def echoComplete[T]: T => Route = { x ⇒ complete(x.toString) }

  "The RoutedService" should {

    "allow for routes to be added after the system is already loaded" in {
      // This should create the actor and register the endpoints
      val r = new RoutedEndpoints {
        def route = {
          path("test2") {
            complete("test2")
          }
        }
      }

      probe.send(httpAct, AddRoute(r))
      probe.expectMsg(RouteAdded)

      Get("/test2") ~> svc.buildRoute(svc.routes) ~> check {
        responseAs[String] must be equalTo "test2"
      }
    }

    "respond with UnprocessableEntity for requests resulting in a MalformedFormFieldRejection" in {

      implicit val unmarsh = svc.jsonUnmarshaller[TestEntity]
      implicit val rejMarsh = svc.jsonUnmarshaller[RejectionResponse]

      val postRoute = new RoutedEndpoints {
        def route = {
          post {
            path("test4") {
              entity(as[TestEntity]) {
                echoComplete
              }
            }
          }
        }
      }

      probe.send(httpAct, AddRoute(postRoute))
      probe.expectMsg(RouteAdded)

      import svc.defaultJsonFormats
      val ent = TestEntity(100, "product")

      Post("/test4", HttpEntity(MediaTypes.`application/json`, svc.serialization.write(ent))) ~>
        handleRejections(svc.rejectionHandler)(svc.buildRoute(svc.routes)) ~> check {
        status === StatusCodes.UnprocessableEntity
        mediaType === MediaTypes.`application/json`
        responseAs[RejectionResponse] must not beNull
      }
    }

    "respond with RejectionResponse for requests that error out" in {

      implicit val rejMarsh = svc.jsonUnmarshaller[RejectionResponse]

      val postRoute = new RoutedEndpoints {
        def route = {
          get {
            path("test5") { ctx => throw new Exception("test") }
          }
        }
      }

      probe.send(httpAct, AddRoute(postRoute))
      probe.expectMsg(RouteAdded)

      Get("/test5") ~>
        Route.seal(svc.buildRoute(svc.routes))(svc.routeSettings,
          exceptionHandler = svc.exceptionHandler,
          rejectionHandler = svc.rejectionHandler) ~> check {

        mediaType === MediaTypes.`application/json`
        responseAs[RejectionResponse] must not beNull
      }
    }
  }

} 
Example 5
Source File: ControllerSpec.scala    From akka-ddd-cqrs-es-example   with MIT License 5 votes vote down vote up
package com.github.j5ik2o.bank.adaptor.util

import akka.http.scaladsl.model.{ HttpEntity, MediaTypes }
import akka.http.scaladsl.testkit.ScalatestRouteTest
import akka.testkit.TestKitBase
import akka.util.ByteString
import com.github.j5ik2o.scalatestplus.db.{ MySQLdConfig, UserWithPassword }
import com.wix.mysql.distribution.Version.v5_6_21
import io.circe.Encoder
import io.circe.syntax._
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.prop.PropertyChecks
import org.scalatest.time.{ Millis, Seconds, Span }
import org.scalatest.{ BeforeAndAfterAll, FreeSpecLike, Matchers }

import scala.concurrent.duration._

object ControllerSpec {

  implicit class JsonOps[A](val self: A) extends AnyVal {
    def toEntity(implicit enc: Encoder[A]): HttpEntity.Strict =
      HttpEntity(MediaTypes.`application/json`, ByteString(self.asJson.noSpaces))
  }

}

abstract class ControllerSpec
    extends FreeSpecLike
    with PropertyChecks
    with Matchers
    with BeforeAndAfterAll
    with ScalaFutures
    with FlywayWithMySQLSpecSupport
    with ScalatestRouteTest
    with TestKitBase {
  override implicit val patienceConfig: PatienceConfig =
    PatienceConfig(timeout = Span(10, Seconds), interval = Span(200, Millis))

  override def afterAll: Unit = cleanUp()

  override protected lazy val mySQLdConfig: MySQLdConfig = MySQLdConfig(
    version = v5_6_21,
    port = Some(12345),
    userWithPassword = Some(UserWithPassword("bank", "passwd")),
    timeout = Some((30 seconds) * sys.env.getOrElse("SBT_TEST_TIME_FACTOR", "1").toDouble)
  )

} 
Example 6
Source File: Routes.scala    From akka-ddd-cqrs-es-example   with MIT License 5 votes vote down vote up
package com.github.j5ik2o.bank.adaptor.controller

import akka.actor.ActorSystem
import akka.http.scaladsl.model.{ ContentTypes, HttpEntity, HttpResponse }
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import akka.stream.Materializer
import cats.syntax.either._
import com.github.j5ik2o.bank.adaptor.generator.IdGenerator
import com.github.j5ik2o.bank.domain.model.BankAccountId
import com.github.j5ik2o.bank.useCase.{ BankAccountAggregateUseCase, BankAccountReadModelUseCase }
import org.hashids.Hashids

object Routes {

  trait ResponseJson {
    val isSuccessful: Boolean
    val errorMessages: Seq[String]
  }

  case class OpenBankAccountRequestJson(name: String)

  case class OpenBankAccountResponseJson(id: String, errorMessages: Seq[String] = Seq.empty) extends ResponseJson {
    override val isSuccessful: Boolean = errorMessages.isEmpty
  }

  case class UpdateBankAccountRequestJson(name: String)

  case class UpdateBankAccountResponseJson(id: String, errorMessages: Seq[String] = Seq.empty) extends ResponseJson {
    override val isSuccessful: Boolean = errorMessages.isEmpty
  }

  case class AddBankAccountEventRequestJson(`type`: String, amount: Long, currencyCode: String)

  case class AddBankAccountEventResponseJson(id: String, errorMessages: Seq[String] = Seq.empty) extends ResponseJson {
    override val isSuccessful: Boolean = errorMessages.isEmpty
  }

  case class CloseBankAccountRequestJson(id: String)

  case class CloseBankAccountResponseJson(id: String, errorMessages: Seq[String] = Seq.empty) extends ResponseJson {
    override val isSuccessful: Boolean = errorMessages.isEmpty
  }

  case class BankAccountEventJson(`type`: String, amount: Long, currencyCode: String, createAt: Long)

  case class ResolveBankAccountEventsResponseJson(id: String,
                                                  values: Seq[BankAccountEventJson],
                                                  errorMessages: Seq[String] = Seq.empty)
      extends ResponseJson {
    override val isSuccessful: Boolean = errorMessages.isEmpty
  }

  case class ValidationErrorsResponseJson(errorMessages: Seq[String]) extends ResponseJson {
    override val isSuccessful: Boolean = false
  }

  implicit class HashidsStringOps(val self: String) extends AnyVal {
    def decodeFromHashid(implicit hashIds: Hashids): Either[Throwable, Long] = {
      Either.catchNonFatal(hashIds.decode(self)(0))
    }
  }

  implicit class HashidsLongOps(val self: Long) extends AnyVal {
    def encodeToHashid(implicit hashIds: Hashids): Either[Throwable, String] =
      Either.catchNonFatal(hashIds.encode(self))
  }

}

case class Routes(bankAccountIdGenerator: IdGenerator[BankAccountId],
                  bankAccountAggregateUseCase: BankAccountAggregateUseCase,
                  bankAccountReadModelUseCase: BankAccountReadModelUseCase)(
    implicit system: ActorSystem,
    mat: Materializer
) extends BankAccountController {

  implicit val ec = system.dispatcher

  def root: Route = RouteLogging.default.httpLogRequestResult {
    pathEndOrSingleSlash {
      get {
        index()
      }
    } ~ toBankAccountRoutes
  }

  private def index() = complete(
    HttpResponse(
      entity = HttpEntity(
        ContentTypes.`text/plain(UTF-8)`,
        "Wellcome to Bank API"
      )
    )
  )

} 
Example 7
Source File: MetronomeFacade.scala    From metronome   with Apache License 2.0 5 votes vote down vote up
package dcos.metronome.integrationtest.utils

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.client.RequestBuilding.{Get, Post}
import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpRequest, HttpResponse}
import akka.stream.Materializer
import com.mesosphere.utils.http.RestResult

import scala.concurrent.Await.result
import scala.concurrent.Future
import scala.concurrent.duration.{FiniteDuration, _}

class MetronomeFacade(val url: String, implicit val waitTime: FiniteDuration = 30.seconds)(implicit
    val system: ActorSystem,
    mat: Materializer
) {

  import scala.concurrent.ExecutionContext.Implicits.global

  //info --------------------------------------------------
  def info(): RestResult[HttpResponse] = {
    result(request(Get(s"$url/info")), waitTime)
  }

  def createJob(jobDef: String): RestResult[HttpResponse] = {
    val e = HttpEntity(ContentTypes.`application/json`, jobDef)
    result(request(Post(s"$url/v1/jobs", e)), waitTime)
  }

  def startRun(jobId: String): RestResult[HttpResponse] = {
    val e = HttpEntity(ContentTypes.`application/json`, "")
    result(request(Post(s"$url/v1/jobs/${jobId}/runs", e)), waitTime)
  }

  def getJob(jobId: String): RestResult[HttpResponse] = {
    result(request(Get(s"$url/v1/jobs/${jobId}")), waitTime)
  }

  def getJobs(): RestResult[HttpResponse] = {
    result(request(Get(s"$url/v1/jobs")), waitTime)
  }

  def getRuns(jobId: String): RestResult[HttpResponse] = {
    result(request(Get(s"$url/v1/jobs/${jobId}/runs")), waitTime)
  }

  private[this] def request(request: HttpRequest): Future[RestResult[HttpResponse]] = {
    Http(system).singleRequest(request).flatMap { response =>
      response.entity.toStrict(waitTime).map(_.data.decodeString("utf-8")).map(RestResult(response, _))
    }
  }

} 
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: Json4sJacksonSpec.scala    From squbs   with Apache License 2.0 5 votes vote down vote up
package org.squbs.marshallers.json

import akka.actor.ActorSystem
import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model.{HttpEntity, MediaTypes, MessageEntity}
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.ActorMaterializer
import org.json4s._
import org.scalatest.{AsyncFlatSpec, BeforeAndAfterAll, Matchers}

class Json4sJacksonSpec extends AsyncFlatSpec with Matchers with BeforeAndAfterAll {

  import de.heikoseeberger.akkahttpjson4s.Json4sSupport._

  implicit val system = ActorSystem("Json4sJacksonSpec")
  implicit val mat = ActorMaterializer()
  implicit val serialization = jackson.Serialization

  "NotTypeHints Example (case class)" should "have correct behaviour of read/write" in {
    implicit val formats = DefaultFormats.withHints(NoTypeHints)
    val playInfo = PlayerInfo("d", "k", 30)
    val entity = HttpEntity(MediaTypes.`application/json`, """{"firstName":"d","lastName":"k","age":30}""")
    Marshal(playInfo).to[MessageEntity] map { _ shouldBe entity }
    Unmarshal(entity).to[PlayerInfo] map { _ shouldBe playInfo }
  }

  "NotTypeHints Example (case class contain the other case class)" should "have correct behaviour of read/write" in {
    implicit val formats = DefaultFormats.withHints(NoTypeHints)
    val name = Player("d", "k")
    val playInfo = PlayerInfo2(name, 30)
    val entity = HttpEntity(MediaTypes.`application/json`, """{"name":{"firstName":"d","lastName":"k"},"age":30}""")
    Marshal(playInfo).to[MessageEntity] map { _ shouldBe entity }
    Unmarshal(entity).to[PlayerInfo2] map { _ shouldBe playInfo }
  }

  "ShortTypeHints Example (inheritance)" should "have correct behaviour of read/write" in {
    implicit val formats = DefaultFormats.withHints(ShortTypeHints(classOf[Dog] :: classOf[Fish] :: Nil))
    val animals = Animals(Dog("pluto") :: Fish(1.2) :: Nil)
    val entity = HttpEntity(MediaTypes.`application/json`,
      """{"animals":[{"jsonClass":"Dog","name":"pluto"},{"jsonClass":"Fish","weight":1.2}]}""")
    Marshal(animals).to[MessageEntity] map { _ shouldBe entity }
    Unmarshal(entity).to[Animals] map { _ shouldBe animals }
  }

  "FullTypeHints Example (inheritance)" should "have correct behaviour of read/write" in {
    implicit val formats = DefaultFormats.withHints(FullTypeHints(classOf[Dog] :: classOf[Fish] :: Nil))
    val animals = Animals(Dog("lucky") :: Fish(3.4) :: Nil)
    val entity = HttpEntity(MediaTypes.`application/json`,
      """{"animals":[{"jsonClass":"org.squbs.marshallers.json.Dog","name":"lucky"},""" +
      """{"jsonClass":"org.squbs.marshallers.json.Fish","weight":3.4}]}""")
    Marshal(animals).to[MessageEntity] map { _ shouldBe entity }
    Unmarshal(entity).to[Animals] map { _ shouldBe animals }
  }

  "Custom Example (inheritance)" should "have correct behaviour of read/write" in {
    implicit val formats = new Formats {
      val dateFormat = DefaultFormats.lossless.dateFormat
      override val typeHints = FullTypeHints(classOf[Fish] :: classOf[Dog] :: Nil)
      override val typeHintFieldName = "$type$"
    }
    val animals = Animals(Dog("lucky") :: Fish(3.4) :: Nil)
    val entity = HttpEntity(MediaTypes.`application/json`,
      """{"animals":[{"$type$":"org.squbs.marshallers.json.Dog","name":"lucky"},""" +
      """{"$type$":"org.squbs.marshallers.json.Fish","weight":3.4}]}""")
    Marshal(animals).to[MessageEntity] map { _ shouldBe entity }
    Unmarshal(entity).to[Animals] map { _ shouldBe animals }
  }

  override protected def afterAll(): Unit = system.terminate()
}

case class Player(firstName: String, lastName: String)
case class PlayerInfo(firstName: String, lastName: String, age: Int)
case class PlayerInfo2(name: Player, age: Int)

trait Animal
case class Dog(name: String) extends Animal
case class Fish(weight: Double) extends Animal
case class Animals(animals: List[Animal]) 
Example 10
Source File: Json4sNativeSpec.scala    From squbs   with Apache License 2.0 5 votes vote down vote up
package org.squbs.marshallers.json

import akka.actor.ActorSystem
import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model.{HttpEntity, MediaTypes, MessageEntity}
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.ActorMaterializer
import org.json4s._
import org.scalatest.{AsyncFlatSpec, BeforeAndAfterAll, Matchers}

class Json4sNativeSpec extends AsyncFlatSpec with Matchers with BeforeAndAfterAll {

  import de.heikoseeberger.akkahttpjson4s.Json4sSupport._

  implicit val system = ActorSystem("Json4sNativeSpec")
  implicit val mat = ActorMaterializer()
  implicit val serialization = native.Serialization

  "NoTypeHints Example (case class)" should "have correct behaviour of read/write" in {
    implicit val formats = DefaultFormats.withHints(NoTypeHints)
    val playInfo = PlayerInfo("d", "k", 30)
    val entity = HttpEntity(MediaTypes.`application/json`, """{"firstName":"d","lastName":"k","age":30}""")
    Marshal(playInfo).to[MessageEntity] map { _ shouldBe entity }
    Unmarshal(entity).to[PlayerInfo] map { _ shouldBe playInfo }
  }

  "NoTypeHints Example (case class contain the other case class)" should "have correct behaviour of read/write" in {
    implicit val formats = DefaultFormats.withHints(NoTypeHints)
    val name = Player("d", "k")
    val playInfo = PlayerInfo2(name, 30)
    val entity = HttpEntity(MediaTypes.`application/json`, """{"name":{"firstName":"d","lastName":"k"},"age":30}""")
    Marshal(playInfo).to[MessageEntity] map { _ shouldBe entity }
    Unmarshal(entity).to[PlayerInfo2] map { _ shouldBe playInfo }
  }

  "ShortTypeHints Example (inheritance)" should "have correct behaviour of read/write" in {
    implicit val formats = DefaultFormats.withHints(ShortTypeHints(classOf[Dog] :: classOf[Fish] :: Nil))
    val animals = Animals(Dog("pluto") :: Fish(1.2) :: Nil)
    val entity = HttpEntity(MediaTypes.`application/json`,
      """{"animals":[{"jsonClass":"Dog","name":"pluto"},{"jsonClass":"Fish","weight":1.2}]}""")
    Marshal(animals).to[MessageEntity] map { _ shouldBe entity }
    Unmarshal(entity).to[Animals] map { _ shouldBe animals }
  }

  "FullTypeHints Example (inheritance)" should "have correct behaviour of read/write" in {
    implicit val formats = DefaultFormats.withHints(FullTypeHints(classOf[Dog] :: classOf[Fish] :: Nil))
    val animals = Animals(Dog("lucky") :: Fish(3.4) :: Nil)
    val entity = HttpEntity(MediaTypes.`application/json`,
      """{"animals":[{"jsonClass":"org.squbs.marshallers.json.Dog","name":"lucky"},""" +
      """{"jsonClass":"org.squbs.marshallers.json.Fish","weight":3.4}]}""")
    Marshal(animals).to[MessageEntity] map { _ shouldBe entity }
    Unmarshal(entity).to[Animals] map { _ shouldBe animals }
  }

  "Custom Example (inheritance)" should "have correct behaviour of read/write" in {
    implicit val formats = new Formats {
      val dateFormat: DateFormat = DefaultFormats.lossless.dateFormat
      override val typeHints = FullTypeHints(classOf[Fish] :: classOf[Dog] :: Nil)
      override val typeHintFieldName = "$type$"
    }
    val animals = Animals(Dog("lucky") :: Fish(3.4) :: Nil)
    val entity = HttpEntity(MediaTypes.`application/json`,
      """{"animals":[{"$type$":"org.squbs.marshallers.json.Dog","name":"lucky"},""" +
      """{"$type$":"org.squbs.marshallers.json.Fish","weight":3.4}]}""")
    Marshal(animals).to[MessageEntity] map { _ shouldBe entity }
    Unmarshal(entity).to[Animals] map { _ shouldBe animals }
  }
} 
Example 11
Source File: JacksonMapperSpec.scala    From squbs   with Apache License 2.0 5 votes vote down vote up
package org.squbs.marshallers.json

import akka.actor.ActorSystem
import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model.{HttpEntity, MediaTypes, MessageEntity}
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.ActorMaterializer
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility
import com.fasterxml.jackson.annotation.PropertyAccessor
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import org.scalatest.{AsyncFlatSpec, BeforeAndAfterAll, Matchers}
import org.squbs.marshallers.json.TestData._

class JacksonMapperSpec extends AsyncFlatSpec with Matchers with BeforeAndAfterAll {

  import JacksonMapperSupport._

  implicit val system = ActorSystem("JacksonMapperSpec")
  implicit val mat = ActorMaterializer()
  JacksonMapperSupport.setDefaultMapper(new ObjectMapper().registerModule(DefaultScalaModule))

  it should "marshal and unmarshal standard case classes" in {
    val entity = HttpEntity(MediaTypes.`application/json`, fullTeamJson)
    Marshal(fullTeam).to[MessageEntity] map { _ shouldBe entity }
    Unmarshal(entity).to[Team] map { _ shouldBe fullTeam }
  }

  it should "marshal and unmarshal Scala non-case classes" in {
    val entity = HttpEntity(MediaTypes.`application/json`, fullTeamJson)
    Marshal(fullTeamNonCaseClass).to[MessageEntity] map { _ shouldBe entity }
    Unmarshal(entity).to[TeamNonCaseClass] map { _ shouldBe fullTeamNonCaseClass }
  }

  it should "marshal and unmarshal Scala class with Java Bean members" in {
    val entity = HttpEntity(MediaTypes.`application/json`, fullTeamJson)
    Marshal(fullTeamWithBeanMember).to[MessageEntity] map { _ shouldBe entity }
    Unmarshal(entity).to[TeamWithBeanMember] map { _ shouldBe fullTeamWithBeanMember }
  }

  it should "marshal and unmarshal Java Bean with case class members" in {
    val entity = HttpEntity(MediaTypes.`application/json`, fullTeamJson)
    Marshal(fullTeamWithCaseClassMember).to[MessageEntity] map { _ shouldBe entity }
    Unmarshal(entity).to[TeamBeanWithCaseClassMember] map { _ shouldBe fullTeamWithCaseClassMember }
  }

  it should "marshal and unmarshal Java Bean" in {
    val fieldMapper = new ObjectMapper().setVisibility(PropertyAccessor.FIELD, Visibility.ANY)
      .registerModule(DefaultScalaModule)
    JacksonMapperSupport.register[TeamWithPrivateMembers](fieldMapper)
    val entity = HttpEntity(MediaTypes.`application/json`, fullTeamJson)
    Marshal(fullTeamWithPrivateMembers).to[MessageEntity] map { _ shouldBe entity }
    Unmarshal(entity).to[TeamWithPrivateMembers] map { _ shouldBe fullTeamWithPrivateMembers }
  }

  it should "Marshal and unmarshal Jackson annotated Java subclasses" in {
    JacksonMapperSupport.register[PageData](new ObjectMapper)
    val entity = HttpEntity(MediaTypes.`application/json`, pageTestJson)
    Marshal(pageTest).to[MessageEntity] map { _ shouldBe entity }
    Unmarshal(entity).to[PageData] map { _ shouldBe pageTest }
  }
} 
Example 12
Source File: JavaFlowSvcSpec.scala    From squbs   with Apache License 2.0 5 votes vote down vote up
package org.squbs.unicomplex

import akka.actor.ActorSystem
import akka.http.scaladsl.model.HttpEntity.Chunked
import akka.http.scaladsl.model.{ContentTypes, HttpEntity, StatusCodes}
import akka.pattern._
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Keep, Sink, Source}
import akka.testkit.TestKit
import com.typesafe.config.ConfigFactory
import org.scalatest.{AsyncFlatSpecLike, BeforeAndAfterAll, Matchers}
import org.squbs.lifecycle.GracefulStop
import org.squbs.unicomplex.Timeouts._

object JavaFlowSvcSpec {

  val classPaths = Array(getClass.getClassLoader.getResource("classpaths/JavaFlowSvc").getPath)

  val config = ConfigFactory.parseString(
    s"""
       |default-listener.bind-port = 0
       |squbs {
       |  actorsystem-name = JavaFlowSvcSpec
       |  ${JMX.prefixConfig} = true
       |}
    """.stripMargin
  )

  val boot = UnicomplexBoot(config)
    .createUsing {(name, config) => ActorSystem(name, config)}
    .scanComponents(classPaths)
    .initExtensions.start()
}

class JavaFlowSvcSpec extends TestKit(
  JavaFlowSvcSpec.boot.actorSystem) with AsyncFlatSpecLike with BeforeAndAfterAll with Matchers {

  implicit val am = ActorMaterializer()

  val portBindingsF = (Unicomplex(system).uniActor ? PortBindings).mapTo[Map[String, Int]]
  val portF = portBindingsF map { bindings => bindings("default-listener") }

  override def afterAll(): Unit = {
    Unicomplex(system).uniActor ! GracefulStop
  }

  it should "handle a normal request" in {
    for {
      port <- portF
      response <- entityAsString(s"http://127.0.0.1:$port/javaflowsvc/ping")
    } yield {
      response shouldBe "pong"
    }
  }

  it should "handle a chunked request and be able to provide a chunked response" in {
    val requestChunks = Source.single("Hi this is a test")
      .mapConcat { s => s.split(' ').toList }
      .map(HttpEntity.ChunkStreamPart(_))

    for {
      port <- portF
      response <- post(s"http://127.0.0.1:$port/javaflowsvc/chunks",
                       Chunked(ContentTypes.`text/plain(UTF-8)`, requestChunks))
      responseString <- response.entity.dataBytes.map(_.utf8String).toMat(Sink.fold("") { _ + _})(Keep.right).run()
    } yield {
      response.entity shouldBe 'chunked
      responseString should be("Received 5 chunks and 13 bytes.\r\nThis is the last chunk!")
    }
  }

  it should "get an InternalServerError with blank response if Flow collapses" in {
    for {
      port <- portF
      errResp <- get(s"http://127.0.0.1:$port/javaflowsvc/throwit")
      respEntity <- errResp.entity.toStrict(awaitMax)
    } yield {
      errResp.status shouldBe StatusCodes.InternalServerError
      respEntity.data.utf8String shouldBe 'empty
    }
  }
} 
Example 13
Source File: JacksonSupport.scala    From asura   with MIT License 5 votes vote down vote up
package asura.core.util

import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model.MediaTypes._
import akka.http.scaladsl.model.{HttpEntity, HttpRequest}
import akka.http.scaladsl.unmarshalling.FromRequestUnmarshaller
import akka.stream.Materializer
import asura.common.util.JsonUtils
import com.sksamuel.elastic4s.Indexable

import scala.concurrent.duration._
import scala.concurrent.{ExecutionContext, Future}
import scala.reflect.ClassTag

object JacksonSupport extends JsonUtils {

  val mapper = JsonUtils.mapper

  implicit def JacksonMarshaller: ToEntityMarshaller[AnyRef] = {
    Marshaller.withFixedContentType(`application/json`) { obj =>
      HttpEntity(`application/json`, mapper.writeValueAsString(obj).getBytes("UTF-8"))
    }
  }

  implicit def jacksonUnmarshaller[T <: AnyRef](implicit c: ClassTag[T]): FromRequestUnmarshaller[T] = {
    new FromRequestUnmarshaller[T] {
      override def apply(request: HttpRequest)(implicit ec: ExecutionContext, materializer: Materializer): Future[T] = {
        request.entity.toStrict(5 seconds).map(_.data.decodeString("UTF-8")).map { str =>
          mapper.readValue(str, c.runtimeClass).asInstanceOf[T]
        }
      }
    }
  }

  implicit def jacksonJsonIndexable[T]: Indexable[T] = {
    new Indexable[T] {
      override def json(t: T): String = mapper.writeValueAsString(t)
    }
  }
} 
Example 14
Source File: EntityUtils.scala    From asura   with MIT License 5 votes vote down vote up
package asura.core.http

import java.net.URLEncoder

import akka.http.scaladsl.model.{ContentType, ContentTypes, HttpEntity, RequestEntity}
import akka.util.ByteString
import asura.common.util.{LogUtils, StringUtils}
import asura.core.es.model.{HttpCaseRequest, KeyValueObject}
import asura.core.http.UriUtils.UTF8
import asura.core.runtime.RuntimeContext
import asura.core.util.JacksonSupport
import com.fasterxml.jackson.core.`type`.TypeReference
import com.typesafe.scalalogging.Logger

object EntityUtils {

  val logger = Logger("EntityUtils")

  def toEntity(cs: HttpCaseRequest, context: RuntimeContext): RequestEntity = {
    val request = cs.request
    var contentType: ContentType = ContentTypes.`text/plain(UTF-8)`
    var byteString: ByteString = ByteString.empty
    if (StringUtils.isNotEmpty(request.contentType) && null != request.body && request.body.nonEmpty) {
      request.contentType match {
        case HttpContentTypes.JSON =>
          contentType = ContentTypes.`application/json`
          val body = request.body.find(_.contentType == HttpContentTypes.JSON)
          if (body.nonEmpty) {
            byteString = ByteString(context.renderBodyAsString(body.get.data))
          }
        case HttpContentTypes.X_WWW_FORM_URLENCODED =>
          contentType = ContentTypes.`application/x-www-form-urlencoded`
          val body = request.body.find(_.contentType == HttpContentTypes.X_WWW_FORM_URLENCODED)
          if (body.nonEmpty) {
            var bodyStr: String = null
            try {
              val sb = StringBuilder.newBuilder
              val params = JacksonSupport.parse(body.get.data, new TypeReference[Seq[KeyValueObject]]() {})
              for (pair <- params if (pair.enabled && StringUtils.isNotEmpty(pair.key))) {
                val rendered = context.renderBodyAsString(pair.value)
                sb.append(pair.key).append("=").append(URLEncoder.encode(rendered, UTF8)).append("&")
              }
              if (sb.nonEmpty) {
                sb.deleteCharAt(sb.length - 1)
              }
              bodyStr = sb.toString
            } catch {
              case t: Throwable =>
                val errLog = LogUtils.stackTraceToString(t)
                logger.warn(errLog)
                bodyStr = errLog
            }
            byteString = ByteString(bodyStr)
          }
        case HttpContentTypes.TEXT_PLAIN =>
          contentType = ContentTypes.`text/plain(UTF-8)`
          val body = request.body.find(_.contentType == HttpContentTypes.TEXT_PLAIN)
          if (body.nonEmpty) {
            byteString = ByteString(context.renderBodyAsString(body.get.data))
          }
        case _ =>
      }
    }
    HttpEntity(contentType, byteString)
  }
} 
Example 15
Source File: HealthEndpoint.scala    From akka-http-health   with MIT License 5 votes vote down vote up
package io.github.lhotari.akka.http.health

import java.util.concurrent.atomic.AtomicBoolean

import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpResponse, StatusCodes}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route

import scala.concurrent.{ExecutionContext, Future}

trait HealthEndpoint {

  protected lazy val checkers = createCheckers

  protected def createCheckers = {
    Seq(new LowDiskSpaceDetector(), new LowMemoryDetector())
  }

  private lazy val successResponse: HttpResponse = createSuccessResponse

  protected def decorateResponse(response: HttpResponse) = response

  protected def createSuccessResponse = {
    decorateResponse(HttpResponse(entity = HttpEntity(ContentTypes.`text/plain(UTF-8)`, "OK")))
  }

  private lazy val errorResponse: HttpResponse = createErrorResponse

  protected def createErrorResponse = {
    decorateResponse(HttpResponse(status = StatusCodes.ServiceUnavailable))
  }

  private val started = new AtomicBoolean(false)

  def createHealthRoute(endpoint: String = HealthEndpoint.DefaultEndpoint)(implicit executor: ExecutionContext): Route =
    get {
      path(endpoint) {
        completeHealthCheck
      }
    }

  def completeHealthCheck(implicit executor: ExecutionContext) = {
    complete {
      Future {
        if (isHealthy()) successResponse else errorResponse
      }
    }
  }

  def start(): Unit = {
    if (started.compareAndSet(false, true)) {
      checkers.foreach(_.start())
    }
  }

  def stop(): Unit = {
    if (started.compareAndSet(true, false)) {
      checkers.foreach(_.stop())
    }
  }

  def isHealthy() = {
    start()
    checkers.forall(_.isHealthy())
  }
}

object HealthEndpoint extends HealthEndpoint {
  lazy val defaultHealthChecker = new HealthEndpoint {}

  val DefaultEndpoint: String = "health"

  def createDefaultHealthRoute(endpoint: String = DefaultEndpoint)(implicit executor: ExecutionContext): Route = {
    defaultHealthChecker.createHealthRoute(endpoint)
  }
} 
Example 16
Source File: AkkaHttpActionAdapterTest.scala    From akka-http-pac4j   with Mozilla Public License 2.0 5 votes vote down vote up
package com.stackstate.pac4j

import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpRequest, HttpResponse}
import org.scalatest.{Matchers, WordSpecLike}
import akka.http.scaladsl.model.StatusCodes._
import akka.util.ByteString
import com.stackstate.pac4j.AkkaHttpActionAdapterTest.ActionInt
import com.stackstate.pac4j.http.AkkaHttpActionAdapter
import com.stackstate.pac4j.store.ForgetfulSessionStorage
import org.pac4j.core.exception.http.{
  BadRequestAction,
  ForbiddenAction,
  FoundAction,
  HttpAction,
  NoContentAction,
  OkAction,
  StatusAction,
  UnauthorizedAction
}
import org.scalatest.concurrent.ScalaFutures

class AkkaHttpActionAdapterTest extends WordSpecLike with Matchers with ScalaFutures {
  "AkkaHttpActionAdapter" should {
    "convert 200 to OK" in withContext { context =>
      AkkaHttpActionAdapter.adapt(new OkAction(""), context).futureValue.response shouldEqual HttpResponse(
        OK,
        Nil,
        HttpEntity(ContentTypes.`application/octet-stream`, ByteString(""))
      )
    }
    "convert 401 to Unauthorized" in withContext { context =>
      AkkaHttpActionAdapter.adapt(UnauthorizedAction.INSTANCE, context).futureValue.response shouldEqual HttpResponse(Unauthorized)
      context.getChanges.cookies.map(_.name) shouldBe List(AkkaHttpWebContext.DEFAULT_COOKIE_NAME)
    }
    "convert 302 to SeeOther (to support login flow)" in withContext { context =>
      val r = AkkaHttpActionAdapter.adapt(new FoundAction("/login"), context).futureValue.response
      r.status shouldEqual SeeOther
      r.headers.head.value() shouldEqual "/login"
      context.getChanges.cookies.map(_.name) shouldBe List(AkkaHttpWebContext.DEFAULT_COOKIE_NAME)
    }
    "convert 400 to BadRequest" in withContext { context =>
      AkkaHttpActionAdapter.adapt(BadRequestAction.INSTANCE, context).futureValue.response shouldEqual HttpResponse(BadRequest)
    }
    "convert 201 to Created" in withContext { context =>
      AkkaHttpActionAdapter.adapt(201.action(), context).futureValue.response shouldEqual HttpResponse(Created)
    }
    "convert 403 to Forbidden" in withContext { context =>
      AkkaHttpActionAdapter.adapt(ForbiddenAction.INSTANCE, context).futureValue.response shouldEqual HttpResponse(Forbidden)
    }
    "convert 204 to NoContent" in withContext { context =>
      AkkaHttpActionAdapter.adapt(NoContentAction.INSTANCE, context).futureValue.response shouldEqual HttpResponse(NoContent)
    }
    "convert 200 to OK with content set from the context" in withContext { context =>
      AkkaHttpActionAdapter.adapt(new OkAction("content"), context).futureValue.response shouldEqual HttpResponse
        .apply(OK, Nil, HttpEntity(ContentTypes.`application/octet-stream`, ByteString("content")))
    }
    "convert 200 to OK with content type set from the context" in withContext { context =>
      context.setResponseContentType("application/json")
      AkkaHttpActionAdapter.adapt(new OkAction(""), context).futureValue.response shouldEqual HttpResponse
        .apply(OK, Nil, HttpEntity(ContentTypes.`application/json`, ByteString("")))
    }
  }

  def withContext(f: AkkaHttpWebContext => Unit): Unit = {
    f(AkkaHttpWebContext(HttpRequest(), Seq.empty, new ForgetfulSessionStorage, AkkaHttpWebContext.DEFAULT_COOKIE_NAME))
  }
}

object AkkaHttpActionAdapterTest {
  implicit class ActionInt(val i: Int) extends AnyVal {
    def action(): HttpAction = new StatusAction(i)
  }
} 
Example 17
Source File: AkkaHttpActionAdapter.scala    From akka-http-pac4j   with Mozilla Public License 2.0 5 votes vote down vote up
package com.stackstate.pac4j.http

import akka.http.scaladsl.model.{HttpEntity, HttpHeader, HttpResponse, StatusCodes, Uri}
import org.pac4j.core.context.HttpConstants
import org.pac4j.core.http.adapter.HttpActionAdapter
import akka.http.scaladsl.model.StatusCodes._
import akka.http.scaladsl.model.headers.Location
import akka.http.scaladsl.server.RouteResult
import akka.http.scaladsl.server.RouteResult.Complete
import com.stackstate.pac4j.AkkaHttpWebContext
import org.pac4j.core.exception.http.{
  BadRequestAction,
  ForbiddenAction,
  FoundAction,
  HttpAction,
  NoContentAction,
  OkAction,
  SeeOtherAction,
  TemporaryRedirectAction,
  UnauthorizedAction
}

import scala.concurrent.Future

object AkkaHttpActionAdapter extends HttpActionAdapter[Future[RouteResult], AkkaHttpWebContext] {
  override def adapt(action: HttpAction, context: AkkaHttpWebContext): Future[Complete] = {
    Future.successful(Complete(action match {
      case _: UnauthorizedAction =>
        // XHR requests don't receive a TEMP_REDIRECT but a UNAUTHORIZED. The client can handle this
        // to trigger the proper redirect anyway, but for a correct flow the session cookie must be set
        context.addResponseSessionCookie()
        HttpResponse(Unauthorized)
      case _: BadRequestAction =>
        HttpResponse(BadRequest)
      case _ if action.getCode == HttpConstants.CREATED =>
        HttpResponse(Created)
      case _: ForbiddenAction =>
        HttpResponse(Forbidden)
      case a: FoundAction =>
        context.addResponseSessionCookie()
        HttpResponse(SeeOther, headers = List[HttpHeader](Location(Uri(a.getLocation))))
      case a: SeeOtherAction =>
        context.addResponseSessionCookie()
        HttpResponse(SeeOther, headers = List[HttpHeader](Location(Uri(a.getLocation))))
      case a: OkAction =>
        val contentBytes = a.getContent.getBytes
        val entity = context.getContentType.map(ct => HttpEntity(ct, contentBytes)).getOrElse(HttpEntity(contentBytes))
        HttpResponse(OK, entity = entity)
      case _: NoContentAction =>
        HttpResponse(NoContent)
      case _ if action.getCode == 500 =>
        HttpResponse(InternalServerError)
      case _ =>
        HttpResponse(StatusCodes.getForKey(action.getCode).getOrElse(custom(action.getCode, "")))
    }))
  }
} 
Example 18
Source File: GrpcMarshallingSpec.scala    From akka-grpc   with Apache License 2.0 5 votes vote down vote up
package akka.grpc.scaladsl

import akka.actor.ActorSystem
import akka.grpc.internal.{ AbstractGrpcProtocol, GrpcProtocolNative, Gzip }
import akka.grpc.scaladsl.headers.`Message-Encoding`
import akka.http.scaladsl.model.{ HttpEntity, HttpRequest }
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.Sink
import io.grpc.{ Status, StatusException }
import io.grpc.testing.integration.messages.{ BoolValue, SimpleRequest }
import io.grpc.testing.integration.test.TestService
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec

import scala.collection.immutable
import scala.concurrent.{ Await, Future }
import scala.concurrent.duration._

class GrpcMarshallingSpec extends AnyWordSpec with Matchers {
  "The scaladsl GrpcMarshalling" should {
    val message = SimpleRequest(responseCompressed = Some(BoolValue(true)))
    implicit val serializer = TestService.Serializers.SimpleRequestSerializer
    implicit val system = ActorSystem()
    implicit val mat = ActorMaterializer()
    val awaitTimeout = 10.seconds
    val zippedBytes =
      AbstractGrpcProtocol.encodeFrameData(
        AbstractGrpcProtocol.fieldType(Gzip),
        Gzip.compress(serializer.serialize(message)))

    "correctly unmarshal a zipped object" in {
      val request = HttpRequest(
        headers = immutable.Seq(`Message-Encoding`("gzip")),
        entity = HttpEntity.Strict(GrpcProtocolNative.contentType, zippedBytes))

      val marshalled = Await.result(GrpcMarshalling.unmarshal(request), 10.seconds)
      marshalled.responseCompressed should be(Some(BoolValue(true)))
    }

    "correctly unmarshal a zipped stream" in {
      val request = HttpRequest(
        headers = immutable.Seq(`Message-Encoding`("gzip")),
        entity = HttpEntity.Strict(GrpcProtocolNative.contentType, zippedBytes ++ zippedBytes))

      val stream = Await.result(GrpcMarshalling.unmarshalStream(request), 10.seconds)
      val items = Await.result(stream.runWith(Sink.seq), 10.seconds)
      items(0).responseCompressed should be(Some(BoolValue(true)))
      items(1).responseCompressed should be(Some(BoolValue(true)))
    }

    // https://github.com/grpc/grpc/blob/master/doc/compression.md#compression-method-asymmetry-between-peers
    // test case 6
    "fail with INTERNAL when the compressed bit is on but the encoding is identity" in {
      val request = HttpRequest(
        headers = immutable.Seq(`Message-Encoding`("identity")),
        entity = HttpEntity.Strict(GrpcProtocolNative.contentType, zippedBytes))

      assertFailure(GrpcMarshalling.unmarshal(request), Status.Code.INTERNAL, "encoding")
    }

    // https://github.com/grpc/grpc/blob/master/doc/compression.md#compression-method-asymmetry-between-peers
    // test case 6
    "fail with INTERNAL when the compressed bit is on but the encoding is missing" in {
      val request = HttpRequest(entity = HttpEntity.Strict(GrpcProtocolNative.contentType, zippedBytes))

      assertFailure(GrpcMarshalling.unmarshal(request), Status.Code.INTERNAL, "encoding")
    }

    def assertFailure(failure: Future[_], expectedStatusCode: Status.Code, expectedMessageFragment: String): Unit = {
      val e = Await.result(failure.failed, awaitTimeout).asInstanceOf[StatusException]
      e.getStatus.getCode should be(expectedStatusCode)
      e.getStatus.getDescription should include(expectedMessageFragment)
    }
  }
} 
Example 19
Source File: GrpcResponseHelpers.scala    From akka-grpc   with Apache License 2.0 5 votes vote down vote up
package akka.grpc.internal

import akka.NotUsed
import akka.actor.ActorSystem
import akka.actor.ClassicActorSystemProvider
import akka.annotation.InternalApi
import akka.grpc.{ ProtobufSerializer, Trailers }
import akka.grpc.GrpcProtocol.{ GrpcProtocolWriter, TrailerFrame }
import akka.grpc.scaladsl.{ headers, GrpcExceptionHandler }
import akka.http.scaladsl.model.{ HttpEntity, HttpResponse }
import akka.http.scaladsl.model.HttpEntity.ChunkStreamPart
import akka.stream.Materializer
import akka.stream.scaladsl.Source
import io.grpc.Status

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


@InternalApi // consumed from generated classes so cannot be private
object GrpcResponseHelpers {
  def apply[T](e: Source[T, NotUsed])(
      implicit m: ProtobufSerializer[T],
      writer: GrpcProtocolWriter,
      system: ClassicActorSystemProvider): HttpResponse =
    GrpcResponseHelpers(e, Source.single(GrpcEntityHelpers.trailer(Status.OK)))

  def apply[T](e: Source[T, NotUsed], eHandler: ActorSystem => PartialFunction[Throwable, Trailers])(
      implicit m: ProtobufSerializer[T],
      writer: GrpcProtocolWriter,
      system: ClassicActorSystemProvider): HttpResponse =
    GrpcResponseHelpers(e, Source.single(GrpcEntityHelpers.trailer(Status.OK)), eHandler)

  def apply[T](e: Source[T, NotUsed], status: Future[Status])(
      implicit m: ProtobufSerializer[T],
      mat: Materializer,
      writer: GrpcProtocolWriter,
      system: ClassicActorSystemProvider): HttpResponse =
    GrpcResponseHelpers(e, status, GrpcExceptionHandler.defaultMapper _)

  def apply[T](
      e: Source[T, NotUsed],
      status: Future[Status],
      eHandler: ActorSystem => PartialFunction[Throwable, Trailers])(
      implicit m: ProtobufSerializer[T],
      mat: Materializer,
      writer: GrpcProtocolWriter,
      system: ClassicActorSystemProvider): HttpResponse = {
    implicit val ec: ExecutionContext = mat.executionContext
    GrpcResponseHelpers(
      e,
      Source.lazilyAsync(() => status.map(GrpcEntityHelpers.trailer)).mapMaterializedValue(_ => NotUsed),
      eHandler)
  }

  def apply[T](
      e: Source[T, NotUsed],
      trail: Source[TrailerFrame, NotUsed],
      eHandler: ActorSystem => PartialFunction[Throwable, Trailers] = GrpcExceptionHandler.defaultMapper)(
      implicit m: ProtobufSerializer[T],
      writer: GrpcProtocolWriter,
      system: ClassicActorSystemProvider): HttpResponse = {
    response(GrpcEntityHelpers(e, trail, eHandler))
  }

  private def response[T](entity: Source[ChunkStreamPart, NotUsed])(implicit writer: GrpcProtocolWriter) = {
    HttpResponse(
      headers = immutable.Seq(headers.`Message-Encoding`(writer.messageEncoding.name)),
      entity = HttpEntity.Chunked(writer.contentType, entity))
  }

  def status(trailer: Trailers)(implicit writer: GrpcProtocolWriter): HttpResponse =
    response(Source.single(writer.encodeFrame(GrpcEntityHelpers.trailer(trailer.status, trailer.metadata))))
} 
Example 20
Source File: GrpcRequestHelpers.scala    From akka-grpc   with Apache License 2.0 5 votes vote down vote up
package akka.grpc.internal

import akka.actor.ActorSystem
import akka.actor.ClassicActorSystemProvider
import akka.grpc.{ ProtobufSerializer, Trailers }
import akka.grpc.GrpcProtocol.GrpcProtocolWriter
import akka.http.scaladsl.model.HttpEntity.ChunkStreamPart
import akka.stream.scaladsl.Source
import akka.NotUsed
import akka.annotation.InternalApi
import akka.grpc.scaladsl.{ headers, GrpcExceptionHandler }
import akka.http.scaladsl.model.{ HttpEntity, HttpMethods, HttpRequest, Uri }
import io.grpc.Status

import scala.collection.immutable

@InternalApi
object GrpcRequestHelpers {

  def apply[T](
      uri: Uri,
      e: Source[T, NotUsed],
      eHandler: ActorSystem => PartialFunction[Throwable, Trailers] = GrpcExceptionHandler.defaultMapper)(
      implicit m: ProtobufSerializer[T],
      writer: GrpcProtocolWriter,
      system: ClassicActorSystemProvider): HttpRequest =
    request(uri, GrpcEntityHelpers(e, Source.single(GrpcEntityHelpers.trailer(Status.OK)), eHandler))

  private def request[T](uri: Uri, entity: Source[ChunkStreamPart, NotUsed])(
      implicit writer: GrpcProtocolWriter): HttpRequest = {
    HttpRequest(
      uri = uri,
      method = HttpMethods.POST,
      headers = immutable.Seq(
        headers.`Message-Encoding`(writer.messageEncoding.name),
        headers.`Message-Accept-Encoding`(Codecs.supportedCodecs.map(_.name).mkString(","))),
      entity = HttpEntity.Chunked(writer.contentType, entity))
  }

} 
Example 21
Source File: AkkaHttpHelpers.scala    From akka-viz   with MIT License 5 votes vote down vote up
package akkaviz.server

import akka.http.scaladsl.marshalling.{Marshal, Marshaller}
import akka.http.scaladsl.model.HttpEntity.ChunkStreamPart
import akka.http.scaladsl.model.{HttpEntity, HttpResponse, MediaTypes}
import akka.http.scaladsl.server.{Directives, StandardRoute}
import akka.stream.scaladsl.{Flow, Source}

import scala.concurrent.ExecutionContext

trait AkkaHttpHelpers {

  def asJsonArray[T](implicit m: Marshaller[T, String], ec: ExecutionContext): Flow[T, HttpEntity.ChunkStreamPart, _] = {
    Flow.apply[T]
      .mapAsync[String](4)(t => Marshal(t).to[String])
      .scan[Option[ChunkStreamPart]](None) {
        case (None, s: String) => Some(ChunkStreamPart(s))
        case (_, s: String)    => Some(ChunkStreamPart(s",${s}"))
      }.mapConcat(_.toList)
      .prepend(Source.single(ChunkStreamPart("[")))
      .concat(Source.single(ChunkStreamPart("]")))
  }

  def completeAsJson[T](source: Source[T, _])(implicit m: Marshaller[T, String], ec: ExecutionContext): StandardRoute = {
    Directives.complete(HttpResponse(
      entity = HttpEntity.Chunked(MediaTypes.`application/json`, source.via(asJsonArray))
    ))
  }
}

object AkkaHttpHelpers extends AkkaHttpHelpers 
Example 22
Source File: VinylDNSRouteTestHelper.scala    From vinyldns   with Apache License 2.0 5 votes vote down vote up
package vinyldns.api.route
import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpResponse, StatusCodes}
import akka.http.scaladsl.server.Directives.{complete, extractUnmatchedPath}
import akka.http.scaladsl.server.{MalformedRequestContentRejection, RejectionHandler}
import akka.http.scaladsl.testkit.ScalatestRouteTest
import org.json4s.MappingException

trait VinylDNSRouteTestHelper { this: ScalatestRouteTest =>
  import scala.concurrent.duration._
  import akka.http.scaladsl.testkit.RouteTestTimeout

  implicit val testTimeout = RouteTestTimeout(10.seconds)

  implicit def validationRejectionHandler: RejectionHandler =
    RejectionHandler
      .newBuilder()
      .handle {
        case MalformedRequestContentRejection(msg, MappingException(_, _)) =>
          complete(
            HttpResponse(
              status = StatusCodes.BadRequest,
              entity = HttpEntity(ContentTypes.`application/json`, msg)
            )
          )
      }
      .handleNotFound {
        extractUnmatchedPath { p =>
          complete((StatusCodes.NotFound, s"The requested path [$p] does not exist."))
        }
      }
      .result()
} 
Example 23
Source File: RoutingHelper.scala    From sumobot   with Apache License 2.0 5 votes vote down vote up
package com.sumologic.sumobot.http_frontend

import akka.http.scaladsl.model.headers._
import akka.http.scaladsl.model.{HttpEntity, HttpRequest, HttpResponse, ResponseEntity}
import akka.http.scaladsl.model.HttpMethods.{GET, HEAD}
import akka.stream.Materializer

case class RoutingHelper(origin: String)(implicit materializer: Materializer) {
  def withAllowOriginHeader(routing: PartialFunction[HttpRequest, HttpResponse]): PartialFunction[HttpRequest, HttpResponse] = {
    routing.andThen {
      response: HttpResponse =>
        val oldHeaders = response.headers.filter(header => header.isNot(`Access-Control-Allow-Origin`.lowercaseName)).toList
        val accessOrigin = if (origin == "*") {
          `Access-Control-Allow-Origin`.*
        } else `Access-Control-Allow-Origin`(origin)
        val newHeaders = oldHeaders :+ accessOrigin

        response.withHeaders(newHeaders)
    }
  }

  def withHeadRequests(routing: PartialFunction[HttpRequest, HttpResponse]): PartialFunction[HttpRequest, HttpResponse] = {
    routing.orElse {
      case request@HttpRequest(HEAD, _, _, _, _)
        if routing.isDefinedAt(request.withMethod(GET)) =>
        val response = routing(request.withMethod(GET))

        val oldEntity = response.entity
        val newEntity = HttpEntity(oldEntity.contentType, Array.empty[Byte])

        response.withEntity(newEntity)
    }
  }

  def withForbiddenFallback(routing: PartialFunction[HttpRequest, HttpResponse]): PartialFunction[HttpRequest, HttpResponse] = {
    routing.orElse {
      case invalid: HttpRequest =>
        invalid.discardEntityBytes()
        HttpResponse(403)
    }
  }
} 
Example 24
Source File: PropertiesApi.scala    From iep-apps   with Apache License 2.0 5 votes vote down vote up
package com.netflix.iep.archaius

import java.io.StringWriter
import java.util.Properties

import akka.actor.ActorRefFactory
import akka.http.scaladsl.model.HttpCharsets
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.model.HttpEntity
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.model.HttpResponse
import akka.http.scaladsl.model.MediaTypes
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.server.Route
import com.netflix.atlas.akka.CustomDirectives._
import com.netflix.atlas.akka.WebApi
import com.netflix.atlas.json.Json
import com.netflix.frigga.Names

class PropertiesApi(
  val propContext: PropertiesContext,
  implicit val actorRefFactory: ActorRefFactory
) extends WebApi {

  def routes: Route = {
    endpointPath("api" / "v1" / "property") {
      get {
        parameter("asg") { asg =>
          extractRequest { request =>
            val cluster = Names.parseName(asg).getCluster
            if (propContext.initialized) {
              val props = propContext.getClusterProps(cluster)
              complete(encode(request, props))
            } else {
              complete(HttpResponse(StatusCodes.ServiceUnavailable))
            }
          }
        }
      }
    }
  }

  private def encode(request: HttpRequest, props: List[PropertiesApi.Property]): HttpResponse = {
    val useJson = request.headers.exists(h => h.is("accept") && h.value == "application/json")
    if (useJson) {
      HttpResponse(
        StatusCodes.OK,
        entity = HttpEntity(MediaTypes.`application/json`, Json.encode(props))
      )
    } else {
      val ps = new Properties
      props.foreach { p =>
        ps.setProperty(p.key, p.value)
      }
      val writer = new StringWriter()
      ps.store(writer, s"count: ${ps.size}")
      writer.close()
      val entity =
        HttpEntity(MediaTypes.`text/plain`.toContentType(HttpCharsets.`UTF-8`), writer.toString)
      HttpResponse(StatusCodes.OK, entity = entity)
    }
  }
}

object PropertiesApi {
  case class Property(id: String, cluster: String, key: String, value: String, timestamp: Long)
} 
Example 25
Source File: SinkRouteHandler.scala    From ohara   with Apache License 2.0 5 votes vote down vote up
package oharastream.ohara.shabondi.sink

import java.time.{Duration => JDuration}
import java.util.concurrent.TimeUnit

import akka.actor.ActorSystem
import akka.http.scaladsl.model.{ContentTypes, HttpEntity, StatusCodes}
import akka.http.scaladsl.server.{ExceptionHandler, Route}
import com.typesafe.scalalogging.Logger
import oharastream.ohara.common.data.Row
import oharastream.ohara.common.util.Releasable
import oharastream.ohara.shabondi.common.{JsonSupport, RouteHandler, ShabondiUtils}
import org.apache.commons.lang3.StringUtils

import scala.collection.mutable.ArrayBuffer
import scala.compat.java8.DurationConverters._
import scala.concurrent.ExecutionContextExecutor
import scala.concurrent.duration.Duration
import spray.json.DefaultJsonProtocol._
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._

private[shabondi] object SinkRouteHandler {
  def apply(config: SinkConfig)(implicit actorSystem: ActorSystem) =
    new SinkRouteHandler(config)
}

private[shabondi] class SinkRouteHandler(config: SinkConfig)(implicit actorSystem: ActorSystem) extends RouteHandler {
  implicit private val contextExecutor: ExecutionContextExecutor = actorSystem.dispatcher

  private val log              = Logger(classOf[SinkRouteHandler])
  private[sink] val dataGroups = SinkDataGroups(config)

  def scheduleFreeIdleGroups(interval: JDuration, idleTime: JDuration): Unit =
    actorSystem.scheduler.scheduleWithFixedDelay(Duration(1, TimeUnit.SECONDS), interval.toScala) { () =>
      {
        log.trace("scheduled free group, total group: {} ", dataGroups.size)
        dataGroups.freeIdleGroup(idleTime)
      }
    }

  private val exceptionHandler = ExceptionHandler {
    case ex: Throwable =>
      log.error(ex.getMessage, ex)
      complete((StatusCodes.InternalServerError, ex.getMessage))
  }

  private def fullyPollQueue(queue: RowQueue): Seq[Row] = {
    val buffer    = ArrayBuffer.empty[Row]
    var item: Row = queue.poll()
    while (item != null) {
      buffer += item
      item = queue.poll()
    }
    buffer.toSeq
  }

  private def apiUrl = ShabondiUtils.apiUrl

  def route(): Route = handleExceptions(exceptionHandler) {
    path("groups" / Segment) { groupId =>
      get {
        if (StringUtils.isAlphanumeric(groupId)) {
          val group  = dataGroups.createIfAbsent(groupId)
          val result = fullyPollQueue(group.queue).map(row => JsonSupport.toRowData(row))
          complete(result)
        } else {
          val entity =
            HttpEntity(ContentTypes.`text/plain(UTF-8)`, "Illegal group name, only accept alpha and numeric.")
          complete(StatusCodes.NotAcceptable -> entity)
        }
      } ~ {
        complete(StatusCodes.MethodNotAllowed -> s"Unsupported method, please reference: $apiUrl")
      }
    } ~ {
      complete(StatusCodes.NotFound -> s"Please reference: $apiUrl")
    }
  }

  override def close(): Unit = {
    Releasable.close(dataGroups)
  }
} 
Example 26
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 27
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 28
Source File: ModelServiceSpec.scala    From full-scala-stack   with Apache License 2.0 5 votes vote down vote up
package api

import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model.{ContentType, ContentTypes, HttpEntity, HttpResponse, MessageEntity, RequestEntity}
import akka.http.scaladsl.testkit.ScalatestRouteTest
import dao.{CRUDOperations, MockRepository, Repository}
import de.heikoseeberger.akkahttpupickle.UpickleSupport
import mail.{CourierPostman, Postman}
import model.{SampleModelObject, SimpleSearch}
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
import routes.{ModelRoutes, SampleModelObjectRoute}
import upickle.default._
import util.ModelPickler
import zio.{IO, ZIO}
import zioslick.RepositoryException

import scala.concurrent.ExecutionContext


class ModelServiceSpec
  extends AnyWordSpec
    with Matchers
    with ScalatestRouteTest
    with ZIODirectives
  with UpickleSupport
    with ModelPickler
 {

  val objects = Seq(
    SampleModelObject(0, "Zero"),
    SampleModelObject(1, "One"),
    SampleModelObject(2, "Two"),
    SampleModelObject(3, "Three"),
    SampleModelObject(4, "Four"),
  )

  val service = new SampleModelObjectRoute  with MockRepository with CourierPostman with Config {
    override def repository: Repository.Service = new Repository.Service {
      override val sampleModelObjectOps: CRUDOperations[SampleModelObject, Int, SimpleSearch, Any] = new MockOps {
        override def search(search: Option[SimpleSearch])(
          implicit session: Any
        ): IO[RepositoryException, Seq[SampleModelObject]] = ZIO.succeed(objects)
        override def get(pk: Int)(implicit session: Any): IO[RepositoryException, Option[SampleModelObject]] =
          ZIO.succeed(objects.headOption)

      }
    }
  }

  //TODO test your route here, we would probably not have a test like the one below in reality, since it's super simple.
  "The Service" should  {
    "return one objects on a get" in {
      Get("/sampleModelObject/1") ~> service.crudRoute.route("") ~> check {
        val res = responseAs[Seq[SampleModelObject]].headOption

        println(res)
        res shouldEqual objects.headOption
      }
    }
    "return some objects on a search" in {
      Post("/sampleModelObject/search", HttpEntity(ContentTypes.`application/json`, write(SimpleSearch()))) ~> service.crudRoute.route("") ~> check {
        val str = responseAs[ujson.Value]
        val res = responseAs[Seq[SampleModelObject]]

        println(res)
        res shouldEqual objects
      }
    }
  }
} 
Example 29
Source File: ModelServiceIntegrationSpec.scala    From full-scala-stack   with Apache License 2.0 5 votes vote down vote up
package api

import akka.http.scaladsl.model.{ContentTypes, HttpEntity}
import akka.http.scaladsl.testkit.ScalatestRouteTest
import de.heikoseeberger.akkahttpupickle.UpickleSupport
import model.{SampleModelObject, SimpleSearch}
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.{AnyWordSpec, AnyWordSpecLike}
import routes.ModelRoutes
import upickle.default._
import util.ModelPickler

import scala.concurrent.ExecutionContext


class ModelServiceIntegrationSpec
  extends AnyWordSpec
    with Matchers
    with ScalatestRouteTest
    with ZIODirectives
  with UpickleSupport
    with ModelPickler
    {

  val service = new ModelRoutes with LiveEnvironment

  //TODO test your route here, we would probably not have a test like the one below in reality, since it's super simple.
      "The Service" should  {
        "return one objects on a get" in {
          Get("/api/sampleModelObject/1") ~> service.apiRoute("") ~> check {
            val res = responseAs[Seq[SampleModelObject]].headOption

            println(res)
            assert(res.nonEmpty)
          }
        }
        "return some objects on a search" in {
          Post("/api/sampleModelObject/search", HttpEntity(ContentTypes.`application/json`, write(SimpleSearch()))) ~> service.apiRoute("") ~> check {
            val str = responseAs[ujson.Value]
            val res = responseAs[Seq[SampleModelObject]]

            println(res)
            assert(res.nonEmpty)
          }
        }
      }

} 
Example 30
Source File: RedocAkkaHttp.scala    From tapir   with Apache License 2.0 5 votes vote down vote up
package sttp.tapir.redoc.akkahttp

import akka.http.scaladsl.model.{ContentTypes, HttpCharsets, HttpEntity, MediaType, StatusCodes}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route

class RedocAkkaHttp(title: String, yaml: String, yamlName: String = "docs.yaml", redocVersion: String = "2.0.0-rc.23") {
  lazy val html: String =
    s"""
       |<!DOCTYPE html>
       |<html>
       |<head>
       |  <title>${title}</title>
       |  <!-- needed for adaptive design -->
       |  <meta charset="utf-8"/>
       |  <meta name="viewport" content="width=device-width, initial-scale=1">
       |  <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
       |
       |  <!--
       |  ReDoc doesn't change outer page styles
       |  -->
       |  <style>
       |    body {
       |      margin: 0;
       |      padding: 0;
       |    }
       |  </style>
       |</head>
       |<body>
       |<redoc spec-url='${yamlName}' expand-responses="200,201"></redoc>
       |<script src="https://cdn.jsdelivr.net/npm/redoc@${redocVersion}/bundles/redoc.standalone.js"></script>
       |</body>
       |</html>
       |""".stripMargin

  def routes: Route = {
    get {
      pathEnd {
        redirectToTrailingSlashIfMissing(StatusCodes.MovedPermanently) {
          complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, html))
        }
      } ~ pathSingleSlash {
        complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, html))
      } ~ path(yamlName) {
        complete(HttpEntity(MediaType.textWithFixedCharset("yaml", HttpCharsets.`UTF-8`), yaml))
      }
    }
  }

} 
Example 31
Source File: FormSupportSpec.scala    From twitter4s   with Apache License 2.0 5 votes vote down vote up
package com.danielasfregola.twitter4s.http.serializers

import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpResponse}
import com.danielasfregola.twitter4s.exceptions.TwitterException
import com.danielasfregola.twitter4s.helpers.{AwaitableFuture, TestActorSystem, TestExecutionContext}
import org.specs2.mutable.SpecificationLike
import org.specs2.specification.Scope

import scala.concurrent.Future

class FormSupportSpec extends TestActorSystem with SpecificationLike with AwaitableFuture with TestExecutionContext {

  case class MyTest(a: String, b: String, c: String, d: Boolean)

  implicit object MyTestFromMap extends FromMap[MyTest] {
    def apply(m: Map[String, String]) =
      for {
        a <- m.get("a")
        b <- m.get("b")
        c <- m.get("c")
        d <- m.get("d")
      } yield MyTest(a, b, c, toBoolean(d))
  }

  abstract class FormSupportContext extends Scope

  def buildResponse(text: String): HttpResponse =
    HttpResponse(entity = HttpEntity.apply(ContentTypes.`text/html(UTF-8)`, text))

  "FormSupport" should {

    "unmarshall a well-formed text into a case class" in new FormSupportContext {
      val text = "a=hello&c=test&b=foobar&d=true"
      val result: Future[MyTest] = FormSupport.unmarshallText[MyTest](buildResponse(text))
      result.await === MyTest(a = "hello", b = "foobar", c = "test", d = true)
    }

    "throw TwitterException if text is not well formed" in new FormSupportContext {
      val text = "non-well-formed-string"
      val result: Future[MyTest] = FormSupport.unmarshallText[MyTest](buildResponse(text))
      result.await should throwA[TwitterException]
    }
  }
} 
Example 32
Source File: TwitterStatusClientSpec.scala    From twitter4s   with Apache License 2.0 5 votes vote down vote up
package com.danielasfregola.twitter4s.http.clients.streaming.statuses

import akka.http.scaladsl.model.{HttpEntity, HttpMethods}
import com.danielasfregola.twitter4s.entities.enums.Language
import com.danielasfregola.twitter4s.entities.{Coordinate, GeoBoundingBox}
import com.danielasfregola.twitter4s.helpers.ClientSpec

class TwitterStatusClientSpec extends ClientSpec {

  class TwitterStatusClientSpecContext extends StreamingClientSpecContext with TwitterStatusClient

  "Twitter Status Streaming Client" should {

    "start a filtered status stream" in new TwitterStatusClientSpecContext {
      val locationsFilter = Seq(GeoBoundingBox(Coordinate(-122.75, 36.8), Coordinate(-121.75, 37.8)))
      val result: Unit =
        when(
          filterStatuses(follow = Seq(1L, 2L, 3L),
                         tracks = Seq("trending", "other"),
                         locations = locationsFilter,
                         languages = Seq(Language.Hungarian, Language.Bengali))(dummyProcessing))
      when(
        filterStatuses(follow = Seq(1L, 2L, 3L),
                       tracks = Seq("trending", "other"),
                       languages = Seq(Language.Hungarian, Language.Bengali))(dummyProcessing))
        .expectRequest { request =>
          request.method === HttpMethods.POST
          request.uri.endpoint === "https://stream.twitter.com/1.1/statuses/filter.json"
          request.entity === HttpEntity(
            `application/x-www-form-urlencoded`,
            "filter_level=none&follow=1%2C2%2C3&language=hu%2Cbn&locations=-122.75%2C36.8%2C-121.75%2C37.8&stall_warnings=false&track=trending%2Cother"
          )
        }
        .respondWithOk
        .await
      result.isInstanceOf[Unit] should beTrue
    }

    "start a sample status stream" in new TwitterStatusClientSpecContext {
      val result: Unit =
        when(sampleStatuses(languages = Seq(Language.English))(dummyProcessing))
          .expectRequest { request =>
            request.method === HttpMethods.GET
            request.uri.endpoint === "https://stream.twitter.com/1.1/statuses/sample.json"
            request.uri.rawQueryString === Some("filter_level=none&language=en&stall_warnings=false")
          }
          .respondWithOk
          .await
      result.isInstanceOf[Unit] should beTrue
    }

    "start a firehose status stream" in new TwitterStatusClientSpecContext {
      val result: Unit =
        when(firehoseStatuses(languages = Seq(Language.Hungarian, Language.Bengali))(dummyProcessing))
          .expectRequest { request =>
            request.method === HttpMethods.GET
            request.uri.endpoint === "https://stream.twitter.com/1.1/statuses/firehose.json"
            request.uri.rawQueryString === Some("language=hu%2Cbn&stall_warnings=false")
          }
          .respondWithOk
          .await
      result.isInstanceOf[Unit] should beTrue
    }
  }
} 
Example 33
Source File: CommonClient.scala    From twitter4s   with Apache License 2.0 5 votes vote down vote up
package com.danielasfregola.twitter4s.http.clients

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpEntity, HttpRequest, HttpResponse}
import akka.stream.Materializer
import com.danielasfregola.twitter4s.exceptions.{Errors, TwitterException}
import com.danielasfregola.twitter4s.http.serializers.JsonSupport
import com.typesafe.scalalogging.LazyLogging
import org.json4s.native.Serialization

import scala.concurrent.Future
import scala.concurrent.duration._
import scala.util.Try

private[twitter4s] trait CommonClient extends JsonSupport with LazyLogging {

  def withLogRequest: Boolean
  def withLogRequestResponse: Boolean

  protected def connection(implicit request: HttpRequest, system: ActorSystem) = {
    val scheme = request.uri.scheme
    val host = request.uri.authority.host.toString
    val port = request.uri.effectivePort
    if (scheme == "https") Http().outgoingConnectionHttps(host, port)
    else Http().outgoingConnection(host, port)
  }

  protected def unmarshal[T](requestStartTime: Long, f: HttpResponse => Future[T])(implicit request: HttpRequest,
                                                                                   response: HttpResponse,
                                                                                   materializer: Materializer) = {
    implicit val ec = materializer.executionContext
    if (withLogRequestResponse) logRequestResponse(requestStartTime)

    if (response.status.isSuccess) f(response)
    else parseFailedResponse(response).flatMap(Future.failed)
  }

  protected def parseFailedResponse(response: HttpResponse)(implicit materializer: Materializer) = {
    implicit val ec = materializer.executionContext
    response.entity.toStrict(50 seconds).map { sink =>
      val body = sink.data.utf8String
      val errors = Try {
        Serialization.read[Errors](body)
      } getOrElse Errors(body)
      TwitterException(response.status, errors)
    }
  }

  // TODO - logRequest, logRequestResponse customisable?
  def logRequest(implicit request: HttpRequest, materializer: Materializer): HttpRequest = {
    implicit val ec = materializer.executionContext
    logger.info(s"${request.method.value} ${request.uri}")
    if (logger.underlying.isDebugEnabled) {
      for {
        requestBody <- toBody(request.entity)
      } yield logger.debug(s"${request.method.value} ${request.uri} | $requestBody")
    }
    request
  }

  def logRequestResponse(requestStartTime: Long)(implicit request: HttpRequest,
                                                 materializer: Materializer): HttpResponse => HttpResponse = {
    response =>
      implicit val ec = materializer.executionContext
      val elapsed = System.currentTimeMillis - requestStartTime
      logger.info(s"${request.method.value} ${request.uri} (${response.status}) | ${elapsed}ms")
      if (logger.underlying.isDebugEnabled) {
        for {
          responseBody <- toBody(response.entity)
        } yield
          logger.debug(
            s"${request.method.value} ${request.uri} (${response.status}) | ${response.headers.mkString(", ")} | $responseBody")
      }
      response
  }

  private def toBody(entity: HttpEntity)(implicit materializer: Materializer): Future[String] = {
    implicit val ec = materializer.executionContext
    entity.toStrict(5 seconds).map(_.data.decodeString("UTF-8"))
  }
} 
Example 34
Source File: JsonMarshallers.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.marshalling.{ToEntityMarshaller, ToResponseMarshaller}
import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpResponse, MediaTypes}
import com.google.openrtb.{BidRequest, BidResponse}
import io.circe.Encoder

object JsonMarshallers {

  import akka.http.scaladsl.marshalling.Marshaller._

  def bidRequestJsonMarshaller(implicit encoder: Encoder[BidRequest]): ToEntityMarshaller[BidRequest] =
    withFixedContentType(ContentTypes.`application/json`)(
      bidRequest => HttpEntity(MediaTypes.`application/json`, encoder.apply(bidRequest).toString)
    )

  def bidResponseJsonMarshaller(implicit encoder: Encoder[BidResponse]): ToEntityMarshaller[BidResponse] =
    withFixedContentType(ContentTypes.`application/json`)(
      bidResponse => HttpEntity(MediaTypes.`application/json`, encoder.apply(bidResponse).toString)
    )

  def bidRequestHttpJsonMarshaller(implicit encoder: Encoder[BidRequest]): ToResponseMarshaller[BidRequest] =
    withFixedContentType(ContentTypes.`application/json`)(
      bidRequest =>
        HttpResponse()
          .withEntity(HttpEntity(MediaTypes.`application/json`, encoder.apply(bidRequest).toString))
    )

  def bidResponseHttpJsonMarshaller(implicit encoder: Encoder[BidResponse]): ToResponseMarshaller[BidResponse] =
    withFixedContentType(ContentTypes.`application/json`)(
      bidResponse =>
        HttpResponse()
          .withEntity(HttpEntity(MediaTypes.`application/json`, encoder.apply(bidResponse).toString))
    )
} 
Example 35
Source File: ServerVersionRoute.scala    From learn-akka   with Apache License 2.0 5 votes vote down vote up
package com.allaboutscala.learn.akka.http.routes

import akka.http.scaladsl.model.{ContentTypes, HttpEntity}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import com.allaboutscala.learn.akka.http.jsonsupport.{JsonSupport, AkkaHttpRestServer}


class ServerVersion extends JsonSupport {

  def route(): Route = {
    path("server-version") {
      get {
        val serverVersion = "1.0.0.0"
        complete(HttpEntity(ContentTypes.`text/plain(UTF-8)`, serverVersion))
      }
    }
  }



  def routeAsJson(): Route = {
    path("server-version-json") {
      get {
        val jsonResponse =
          """
            |{
            | "app": "Akka HTTP REST Server",
            | "version": "1.0.0.0"
            |}
          """.stripMargin
        complete(HttpEntity(ContentTypes.`application/json`, jsonResponse))
      }
    }
  }



  def routeAsJsonEncoding(): Route = {
    path("server-version-json-encoding") {
      get {
        val server = AkkaHttpRestServer("Akka HTTP REST Server", "1.0.0.0")
        complete(server)
      }
    }
  }
} 
Example 36
Source File: StatsApi.scala    From iep-apps   with Apache License 2.0 5 votes vote down vote up
package com.netflix.iep.lwc

import akka.http.scaladsl.model.HttpEntity
import akka.http.scaladsl.model.HttpResponse
import akka.http.scaladsl.model.MediaTypes
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import com.netflix.atlas.akka.CustomDirectives._
import com.netflix.atlas.akka.WebApi
import com.netflix.atlas.json.Json


class StatsApi(evaluator: ExpressionsEvaluator) extends WebApi {

  override def routes: Route = {
    endpointPathPrefix("api" / "v1" / "stats") {
      get {
        val stats = Json.encode(evaluator.stats)
        val entity = HttpEntity(MediaTypes.`application/json`, stats)
        val response = HttpResponse(StatusCodes.OK, Nil, entity)
        complete(response)
      }
    }
  }
} 
Example 37
Source File: ExplainApi.scala    From iep-apps   with Apache License 2.0 5 votes vote down vote up
package com.netflix.atlas.druid

import akka.actor.ActorRefFactory
import akka.http.scaladsl.model.HttpEntity
import akka.http.scaladsl.model.HttpResponse
import akka.http.scaladsl.model.MediaTypes
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.server.RouteResult
import akka.pattern.ask
import akka.util.Timeout
import com.netflix.atlas.akka.CustomDirectives._
import com.netflix.atlas.akka.WebApi
import com.netflix.atlas.druid.ExplainApi.ExplainRequest
import com.netflix.atlas.eval.graph.Grapher
import com.netflix.atlas.json.Json
import com.netflix.atlas.webapi.GraphApi.DataRequest
import com.typesafe.config.Config

import scala.concurrent.duration._

class ExplainApi(config: Config, implicit val actorRefFactory: ActorRefFactory) extends WebApi {

  private val grapher: Grapher = Grapher(config)

  private val dbRef = actorRefFactory.actorSelection("/user/db")

  private implicit val ec = actorRefFactory.dispatcher

  override def routes: Route = {
    endpointPath("explain" / "v1" / "graph") {
      get { ctx =>
        val graphCfg = grapher.toGraphConfig(ctx.request)
        dbRef
          .ask(ExplainRequest(DataRequest(graphCfg)))(Timeout(10.seconds))
          .map { response =>
            val json = Json.encode(response)
            val entity = HttpEntity(MediaTypes.`application/json`, json)
            RouteResult.Complete(HttpResponse(StatusCodes.OK, entity = entity))
          }
      }
    }
  }
}

object ExplainApi {
  case class ExplainRequest(dataRequest: DataRequest)
} 
Example 38
Source File: UpdateApi.scala    From iep-apps   with Apache License 2.0 5 votes vote down vote up
package com.netflix.atlas.aggregator

import javax.inject.Inject
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.model.HttpEntity
import akka.http.scaladsl.model.HttpResponse
import akka.http.scaladsl.model.MediaTypes
import akka.http.scaladsl.model.StatusCode
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.server.Route
import com.fasterxml.jackson.core.JsonParser
import com.netflix.atlas.akka.CustomDirectives._
import com.netflix.atlas.akka.WebApi
import com.netflix.atlas.core.validation.ValidationResult
import com.netflix.atlas.eval.stream.Evaluator
import com.typesafe.scalalogging.StrictLogging

class UpdateApi @Inject()(
  evaluator: Evaluator,
  aggrService: AtlasAggregatorService
) extends WebApi
    with StrictLogging {

  import UpdateApi._

  require(aggrService != null, "no binding for aggregate registry")

  def routes: Route = {
    endpointPath("api" / "v4" / "update") {
      post {
        parseEntity(customJson(p => processPayload(p, aggrService))) { response =>
          complete(response)
        }
      }
    }
  }
}

object UpdateApi {
  private val decoder = PayloadDecoder.default

  private[aggregator] def processPayload(
    parser: JsonParser,
    service: AtlasAggregatorService
  ): HttpResponse = {
    val result = decoder.decode(parser, service)
    createResponse(result.numDatapoints, result.failures)
  }

  private val okResponse = {
    val entity = HttpEntity(MediaTypes.`application/json`, "{}")
    HttpResponse(StatusCodes.OK, entity = entity)
  }

  private def createErrorResponse(status: StatusCode, msg: FailureMessage): HttpResponse = {
    val entity = HttpEntity(MediaTypes.`application/json`, msg.toJson)
    HttpResponse(status, entity = entity)
  }

  private def createResponse(numDatapoints: Int, failures: List[ValidationResult]): HttpResponse = {
    if (failures.isEmpty) {
      okResponse
    } else {
      val numFailures = failures.size
      if (numDatapoints > numFailures) {
        // Partial failure
        val msg = FailureMessage.partial(failures, numFailures)
        createErrorResponse(StatusCodes.Accepted, msg)
      } else {
        // All datapoints dropped
        val msg = FailureMessage.error(failures, numFailures)
        createErrorResponse(StatusCodes.BadRequest, msg)
      }
    }
  }
} 
Example 39
Source File: TestServer.scala    From typed-schema   with Apache License 2.0 5 votes vote down vote up
package ru.tinkoff.tschema.examples

import java.util.Locale

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpResponse}
import akka.http.scaladsl.server.Directives.{complete, get, pathPrefix, _}
import akka.stream.ActorMaterializer
import cats.instances.list._
import cats.syntax.foldable._
import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport._
import io.circe.Printer
import ru.tinkoff.tschema.swagger.{OpenApiInfo, PathDescription}

object TestServer {

  implicit val system = ActorSystem()
  implicit val mat = ActorMaterializer()
  import system.dispatcher

  val descriptions =
    PathDescription.utf8I18n("swagger", Locale.forLanguageTag("ru"))

  val modules = List[ExampleModule](
    TestModule,
    VersionModule,
    FiltersModule,
    FormFieldsModule,
    Authorize,
    CustomAuth,
    MultiParameters,
    ProxyModule
  ).combineAll

  private[this] implicit val printer: Printer =
    Printer.noSpaces.copy(dropNullValues = true)

  val route =
    pathPrefix("api") {
      modules.route
    } ~
      path("swagger")(
        get(
          complete(
            modules.swag
              .describe(descriptions)
              .make(OpenApiInfo())
              .addServer("/api")
          )
        )
      ) ~
      pathPrefix("webjars")(
        getFromResourceDirectory("META-INF/resources/webjars")
      ) ~
      path("swagger.php")(
        complete(
          HttpResponse(
            entity = HttpEntity(
              contentType = ContentTypes.`text/html(UTF-8)`,
              string = SwaggerIndex.index.render
            )
          )
        )
      )
  def main(args: Array[String]): Unit = {
    for (_ <- Http().bindAndHandle(route, "localhost", 8081))
      println("server started at http://localhost:8081/swagger.php")
  }

} 
Example 40
Source File: ServeSpec.scala    From typed-schema   with Apache License 2.0 5 votes vote down vote up
package ru.tinkoff.tschema.akkaHttp

import akka.http.scaladsl.model.Multipart.FormData
import akka.http.scaladsl.model.Uri.Query
import akka.http.scaladsl.model.{HttpEntity, Uri}
import akka.http.scaladsl.server.MissingQueryParamRejection
import akka.http.scaladsl.testkit.ScalatestRouteTest
import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport._
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
import ru.tinkoff.tschema.syntax

class ServeSpec extends AnyWordSpec with Matchers with ScalatestRouteTest {
  trait Small

  import ru.tinkoff.tschema.syntax._
  val dsl = syntax

  val intAnswer = 42

  object handler {
    val int = 42

    def repeat(body: String, n: Int) = body * n

    def multiply(x: Long, y: Double) = f"result is ${x * y}%.2f"

    def size(args: List[Int]) = args.size

    def min(args: List[Int]) = args.min
  }

  def api = (keyPrefix("int") :> get :> complete[Int]) ~
    (keyPrefix("repeat") :> reqBody[String] :> queryParam[Int]("n") :> post :> complete[String]) ~
    (keyPrefix("multiply") :> formField[Long]("x") :> formField[Double]("y") :> post :> complete[String]) ~
    (keyPrefix("size") :> queryParams[Option[Int]]("args") :> post :> complete[Int]) ~
    (keyPrefix("min") :> queryParams[Int]("args") :> post :> complete[Int])

  val route = MkRoute(api)(handler)

  "Simple service" should {
    "return a simple int" in {
      Get("/int") ~> route ~> check {
        responseAs[Int] shouldEqual intAnswer
      }
    }

    "multiply string by n times" in {
      Post(Uri("/repeat").withQuery(Query("n" -> "5")), "batman") ~> route ~> check {
        responseAs[String] shouldEqual ("batman" * 5)
      }
    }

    "multiply numbers from formdata" in {
      Post(Uri("/multiply"), FormData(Map("x" -> HttpEntity("3"), "y" -> HttpEntity("1.211")))) ~>
        route ~>
        check {
          responseAs[String] shouldEqual f"result is ${3.63}%.2f"
        }
    }

    "return size of empty args" in {
      Post(Uri("/size")) ~> route ~> check {
        responseAs[Int] shouldEqual 0
      }
    }

    "return size of non empty args" in {
      Post(Uri("/size").withQuery(Query(List("1", "2", "3").map("args" -> _): _*))) ~> route ~> check {
        responseAs[Int] shouldEqual 3
      }
    }

    "return min of non empty args" in {
      Post(Uri("/min").withQuery(Query(List("3", "1", "2").map("args" -> _): _*))) ~> route ~> check {
        responseAs[Int] shouldEqual 1
      }
    }

    "reject on min with empty args" in {
      Post(Uri("/min")) ~> route ~> check {
        rejection shouldEqual MissingQueryParamRejection("args")
      }
    }
  }
} 
Example 41
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 42
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 43
Source File: ArchiveRoutes.scala    From nexus-kg   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.kg.routes

import akka.http.scaladsl.model.StatusCodes.{Created, OK}
import akka.http.scaladsl.model.headers.Accept
import akka.http.scaladsl.model.{HttpEntity, MediaTypes}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import ch.epfl.bluebrain.nexus.admin.client.types.Project
import ch.epfl.bluebrain.nexus.iam.client.types._
import ch.epfl.bluebrain.nexus.kg.KgError.{InvalidOutputFormat, UnacceptedResponseContentType}
import ch.epfl.bluebrain.nexus.kg.archives.Archive._
import ch.epfl.bluebrain.nexus.kg.config.AppConfig
import ch.epfl.bluebrain.nexus.kg.directives.AuthDirectives.hasPermission
import ch.epfl.bluebrain.nexus.kg.directives.PathDirectives._
import ch.epfl.bluebrain.nexus.kg.directives.ProjectDirectives._
import ch.epfl.bluebrain.nexus.kg.directives.QueryDirectives.outputFormat
import ch.epfl.bluebrain.nexus.kg.marshallers.instances._
import ch.epfl.bluebrain.nexus.kg.resources._
import ch.epfl.bluebrain.nexus.kg.resources.syntax._
import ch.epfl.bluebrain.nexus.kg.routes.OutputFormat.Tar
import ch.epfl.bluebrain.nexus.rdf.Iri.AbsoluteIri
import io.circe.Json
import kamon.instrumentation.akka.http.TracingDirectives.operationName
import monix.eval.Task
import monix.execution.Scheduler.Implicits.global

class ArchiveRoutes private[routes] (archives: Archives[Task])(
    implicit acls: AccessControlLists,
    project: Project,
    caller: Caller,
    config: AppConfig
) {

  private val responseType = MediaTypes.`application/x-tar`

  
  def routes(id: AbsoluteIri): Route = {
    val resId = Id(project.ref, id)
    concat(
      // Create archive
      (put & pathEndOrSingleSlash) {
        operationName(s"/${config.http.prefix}/archives/{org}/{project}/{id}") {
          (hasPermission(write) & projectNotDeprecated) {
            entity(as[Json]) { source =>
              complete(archives.create(resId, source).value.runWithStatus(Created))
            }
          }
        }
      },
      // Fetch archive
      (get & outputFormat(strict = true, Tar) & pathEndOrSingleSlash) {
        case Tar                           => getArchive(resId)
        case format: NonBinaryOutputFormat => getResource(resId)(format)
        case other                         => failWith(InvalidOutputFormat(other.toString))

      }
    )
  }

  private def getResource(resId: ResId)(implicit format: NonBinaryOutputFormat): Route =
    completeWithFormat(archives.fetch(resId).value.runWithStatus(OK))

  private def getArchive(resId: ResId): Route = {
    parameter("ignoreNotFound".as[Boolean] ? false) { ignoreNotFound =>
      onSuccess(archives.fetchArchive(resId, ignoreNotFound).value.runToFuture) {
        case Right(source) =>
          headerValueByType[Accept](()) { accept =>
            if (accept.mediaRanges.exists(_.matches(responseType)))
              complete(HttpEntity(responseType, source))
            else
              failWith(
                UnacceptedResponseContentType(
                  s"File Media Type '$responseType' does not match the Accept header value '${accept.mediaRanges.mkString(", ")}'"
                )
              )
          }
        case Left(err) => complete(err)
      }
    }
  }
}

object ArchiveRoutes {
  final def apply(archives: Archives[Task])(
      implicit acls: AccessControlLists,
      caller: Caller,
      project: Project,
      config: AppConfig
  ): ArchiveRoutes = new ArchiveRoutes(archives)
} 
Example 44
Source File: CreateDonutTest.scala    From learn-akka   with Apache License 2.0 5 votes vote down vote up
package com.allaboutscala.learn.akka.http

import akka.http.scaladsl.model.{HttpEntity, HttpMethods, HttpRequest, MediaTypes}
import akka.http.scaladsl.testkit.ScalatestRouteTest
import akka.util.ByteString
import com.allaboutscala.learn.akka.http.routes.DonutRoutes
import org.scalatest.{Matchers, WordSpec}


class CreateDonutTest
  extends WordSpec
    with Matchers
    with ScalatestRouteTest {

  val donutRoutes = new DonutRoutes().route()

  "Donut API" should {
    "Create a valid Donut when posting JSON to /create-donut path" in {
      val jsonDonutInput = ByteString("""{"name":"plain donut", "price":1.50}""")
      val httpPostCreateDonut = HttpRequest(
        uri = "http://localhost:8080/create-donut",
        method = HttpMethods.POST,
        entity = HttpEntity(MediaTypes.`application/json`, jsonDonutInput))

      httpPostCreateDonut ~> donutRoutes ~> check {
        status.isSuccess() shouldEqual true
        status.intValue() shouldEqual 201
        status.reason shouldEqual "Created"
      }
    }
  }

} 
Example 45
Source File: AkkaHTTPClient.scala    From learn-akka   with Apache License 2.0 5 votes vote down vote up
package com.allaboutscala.learn.akka.client

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{MediaTypes, HttpEntity, HttpMethods, HttpRequest}
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.ActorMaterializer
import akka.util.ByteString
import com.allaboutscala.learn.akka.http.jsonsupport.{Donuts, JsonSupport}

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


object AkkaHttpClient extends App with JsonSupport {

  implicit val system = ActorSystem("akka-http-donuts-client")
  implicit val materializer = ActorMaterializer()
  implicit val ec = system.dispatcher

  // HTTP GET request
  val donutsUri = "http://localhost:8080/donuts"
  val donutsHttpRequest = HttpRequest(
    uri = donutsUri,
    method = HttpMethods.GET
  )

  val donutsResponse = Http().singleRequest(donutsHttpRequest)
  donutsResponse
    .onComplete {
      case Success(donutsResponse) =>
        println(s"Raw HttpResponse = $donutsResponse")

        // You obviously should not block using Await.result(...) and use flatMap or other similar future sequencing mechanics
        val donutsF: Future[Donuts] = Unmarshal(donutsResponse).to[Donuts]
        val donuts: Donuts = Await.result(donutsF, 5.second)
        println(s"Unmarshalled HttpResponse to Case Class = $donuts")


      case Failure(e) => println(s"Failed to HTTP GET $donutsUri, error = ${e.getMessage}")
    }

  Thread.sleep(3000)



  // HTTP POST request
  val jsonDonutInput = ByteString("""{"name":"plain donut", "price":1.50}""")
  val httpPostCreateDonut = HttpRequest(
    uri = "http://localhost:8080/create-donut",
    method = HttpMethods.POST,
    entity = HttpEntity(MediaTypes.`application/json`, jsonDonutInput))

  val createDonutF = for {
    response <- Http().singleRequest(httpPostCreateDonut)
    _        = println(s"Akka HTTP request status = ${response.status}")
    if response.status.isSuccess()
    output   <- Unmarshal(response).to[String]
  } yield println(s"HTTP POST request output = $output")

  Await.result(createDonutF, 5.second)


  system.terminate()
} 
Example 46
Source File: HttpRequestConversionSupport.scala    From rokku   with Apache License 2.0 5 votes vote down vote up
package com.ing.wbaa.rokku.proxy.persistence.serializers

import java.net.InetAddress

import akka.http.scaladsl.model.HttpHeader.ParsingResult
import akka.http.scaladsl.model.{ HttpEntity, HttpHeader, HttpMethod, HttpMethods, HttpProtocol, HttpRequest, RemoteAddress, Uri }
import com.ing.wbaa.rokku.proxy.data.{ UserAssumeRole, UserRawJson }
import spray.json.DefaultJsonProtocol

import scala.collection.immutable

trait HttpRequestConversionSupport extends DefaultJsonProtocol {

  case class SimplifiedRemoteAddress(host: String) {
    def toRemoteAddr: RemoteAddress = {
      val a = host.split(":")
      RemoteAddress(InetAddress.getByName(a(0)), Some(a(1).toInt))
    }
  }

  case class SimplifiedHttpRequest(method: String, uri: String, headers: List[String], entity: String, httpProtocol: String)

  implicit val httpRequestF = jsonFormat5(SimplifiedHttpRequest)
  implicit val userRoleF = jsonFormat1(UserAssumeRole)
  implicit val userSTSF = jsonFormat5(UserRawJson)
  implicit val remoteAddressF = jsonFormat1(SimplifiedRemoteAddress)

  private[persistence] def convertAkkaHeadersToStrings(headers: Seq[HttpHeader]): List[String] = headers.map(h => s"${h.name()}=${h.value()}").toList

  private def convertStringsToAkkaHeaders(headers: List[String]): immutable.Seq[HttpHeader] = headers.map { p =>
    val kv = p.split("=")
    HttpHeader.parse(kv(0), kv(1)) match {
      case ParsingResult.Ok(header, _) => header
      case ParsingResult.Error(error)  => throw new Exception(s"Unable to convert to HttpHeader: ${error.summary}")
    }
  }

  private def httpMethodFrom(m: String): HttpMethod = m match {
    case "GET"    => HttpMethods.GET
    case "HEAD"   => HttpMethods.HEAD
    case "PUT"    => HttpMethods.PUT
    case "POST"   => HttpMethods.POST
    case "DELETE" => HttpMethods.DELETE
  }

  private[persistence] def toAkkaHttpRequest(s: SimplifiedHttpRequest): HttpRequest =
    HttpRequest(
      httpMethodFrom(s.method),
      Uri(s.uri),
      convertStringsToAkkaHeaders(s.headers),
      HttpEntity(s.entity),
      HttpProtocol(s.httpProtocol)
    )
} 
Example 47
Source File: CounterTest.scala    From endpoints4s   with MIT License 5 votes vote down vote up
package quickstart

import java.net.ServerSocket

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpMethods, HttpRequest, StatusCodes}
import akka.http.scaladsl.server.Directives._
import org.scalatest.BeforeAndAfterAll

import scala.concurrent.Await
import scala.concurrent.duration.DurationInt
import org.scalatest.freespec.AsyncFreeSpec

class CounterTest extends AsyncFreeSpec with BeforeAndAfterAll {

  implicit val actorSystem: ActorSystem = ActorSystem()
  val routes = CounterServer.routes ~ DocumentationServer.routes
  val interface = "0.0.0.0"
  val port = findOpenPort()
  val server = Http().bindAndHandle(routes, interface, port)

  override protected def afterAll(): Unit = {
    Await.result(
      Await.result(server, 10.seconds).terminate(3.seconds),
      15.seconds
    )
    Await.result(actorSystem.terminate(), 5.seconds)
    super.afterAll()
  }

  "CounterServer" - {
    "Query counter value" in {
      for {
        response <- Http().singleRequest(
          HttpRequest(uri = uri("/current-value"))
        )
        entity <- response.entity.toStrict(1.second)
      } yield {
        assert(response.status == StatusCodes.OK)
        assert(entity.contentType == ContentTypes.`application/json`)
        assert(entity.data.utf8String == "{\"value\":0}")
      }
    }
    "Increment counter value" in {
      val request =
        HttpRequest(
          method = HttpMethods.POST,
          uri = uri("/increment"),
          entity = HttpEntity(ContentTypes.`application/json`, "{\"step\":1}")
        )
      for {
        response <- Http().singleRequest(request)
      } yield {
        assert(response.status == StatusCodes.OK)
      }
    }
    "Query API documentation" in {
      for {
        response <- Http().singleRequest(
          HttpRequest(uri = uri("/documentation.json"))
        )
        entity <- response.entity.toStrict(1.second)
      } yield {
        assert(response.status == StatusCodes.OK)
        assert(entity.contentType == ContentTypes.`application/json`)
      }
    }
  }

  def findOpenPort(): Int = {
    val socket = new ServerSocket(0)
    try socket.getLocalPort
    finally if (socket != null) socket.close()
  }

  def uri(suffix: String) = s"http://$interface:$port$suffix"

} 
Example 48
Source File: DisjunctionMarshaller.scala    From akka-http-test   with Apache License 2.0 5 votes vote down vote up
package com.github.dnvriend.component.simpleserver.marshaller

import akka.http.scaladsl.marshalling.{ Marshaller, ToResponseMarshaller }
import akka.http.scaladsl.model.{ HttpEntity, _ }
import com.github.dnvriend.component.simpleserver.marshaller.DisjunctionMarshaller.{ ErrorMessage, FatalError }
import spray.json.JsonWriter

import scalaz.Scalaz._
import scalaz._

object DisjunctionMarshaller {
  trait ErrorMessage { def description: String }
  trait FatalError extends ErrorMessage
  trait NonFatalError extends ErrorMessage
}

trait DisjunctionMarshaller {
  type DisjunctionNel[A, +B] = Disjunction[NonEmptyList[A], B]

  implicit def disjunctionMarshaller[A1, A2, B](implicit m1: Marshaller[A1, B], m2: Marshaller[A2, B]): Marshaller[Disjunction[A1, A2], B] = Marshaller { implicit ec =>
    {
      case -\/(a1) => m1(a1)
      case \/-(a2) => m2(a2)
    }
  }

  implicit def errorDisjunctionMarshaller[A](implicit w1: JsonWriter[A], w2: JsonWriter[List[String]]): ToResponseMarshaller[DisjunctionNel[String, A]] =
    Marshaller.withFixedContentType(MediaTypes.`application/json`) {
      case -\/(errors) => HttpResponse(
        status = StatusCodes.BadRequest,
        entity = HttpEntity(ContentType(MediaTypes.`application/json`), w2.write(errors.toList).compactPrint)
      )
      case \/-(success) => HttpResponse(entity = HttpEntity(ContentType(MediaTypes.`application/json`), w1.write(success).compactPrint))
    }

  implicit def errorMessageDisjunctionMarshaller[A <: ErrorMessage, B](implicit w1: JsonWriter[B], w2: JsonWriter[List[String]]): ToResponseMarshaller[DisjunctionNel[A, B]] = {
    def createResponseWithStatusCode(code: StatusCode, errors: List[ErrorMessage]) = HttpResponse(
      status = code,
      entity = HttpEntity(ContentType(MediaTypes.`application/json`), w2.write(errors.map(_.description)).compactPrint)
    )
    Marshaller.withFixedContentType(MediaTypes.`application/json`) {
      case -\/(errors) if errors.toList.exists(_.isInstanceOf[FatalError]) => createResponseWithStatusCode(StatusCodes.InternalServerError, errors.toList)
      case -\/(errors)                                                     => createResponseWithStatusCode(StatusCodes.BadRequest, errors.toList)
      case \/-(success)                                                    => HttpResponse(entity = HttpEntity(ContentType(MediaTypes.`application/json`), w1.write(success).compactPrint))
    }
  }
}

trait ValidationMarshaller {
  implicit def validationMarshaller[A1, A2, B](implicit m1: Marshaller[A1, B], m2: Marshaller[A2, B]): Marshaller[Validation[A1, A2], B] = Marshaller { implicit ec =>
    {
      case Failure(a1) => m1(a1)
      case Success(a2) => m2(a2)
    }
  }

  implicit def errorValidationMarshaller[A](implicit w1: JsonWriter[A], w2: JsonWriter[List[String]]): ToResponseMarshaller[ValidationNel[String, A]] =
    Marshaller.withFixedContentType(MediaTypes.`application/json`) {
      case Failure(errors) => HttpResponse(
        status = StatusCodes.BadRequest,
        entity = HttpEntity(ContentType(MediaTypes.`application/json`), w2.write(errors.toList).compactPrint)
      )
      case Success(success) => HttpResponse(entity = HttpEntity(ContentType(MediaTypes.`application/json`), w1.write(success).compactPrint))
    }

  implicit def errorMessageValidationMarshaller[A <: ErrorMessage, B](implicit w1: JsonWriter[B], w2: JsonWriter[List[String]]): ToResponseMarshaller[ValidationNel[A, B]] = {
    def createResponseWithStatusCode(code: StatusCode, errors: List[ErrorMessage]) = HttpResponse(
      status = code,
      entity = HttpEntity(ContentType(MediaTypes.`application/json`), w2.write(errors.map(_.description)).compactPrint)
    )
    Marshaller.withFixedContentType(MediaTypes.`application/json`) {
      case Failure(errors) if errors.toList.exists(_.isInstanceOf[FatalError]) => createResponseWithStatusCode(StatusCodes.InternalServerError, errors.toList)
      case Failure(errors)                                                     => createResponseWithStatusCode(StatusCodes.BadRequest, errors.toList)
      case Success(success)                                                    => HttpResponse(entity = HttpEntity(ContentType(MediaTypes.`application/json`), w1.write(success).compactPrint))
    }
  }
} 
Example 49
Source File: AkkaHttpBackend.scala    From drunk   with Apache License 2.0 5 votes vote down vote up
package com.github.jarlakxen.drunk.backend

import scala.collection.immutable
import scala.concurrent.{ExecutionContext, Future}
import akka.actor.ActorSystem
import akka.http.scaladsl.{Http, HttpExt}
import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpHeader, HttpMethods, HttpRequest, Uri}
import akka.stream.ActorMaterializer

class AkkaHttpBackend private[AkkaHttpBackend] (
  uri: Uri,
  headers: immutable.Seq[HttpHeader],
  httpExt: HttpExt
)(override implicit val as: ActorSystem, override implicit val mat: ActorMaterializer)
    extends AkkaBackend {

  def send(body: String): Future[(Int, String)] = {
    implicit val ec: ExecutionContext = as.dispatcher

    val req = HttpRequest(HttpMethods.POST, uri, headers, HttpEntity(ContentTypes.`application/json`, body))

    val res = httpExt.singleRequest(req)

    res.flatMap { hr =>
      val code = hr.status.intValue()

      val charsetFromHeaders = encodingFromContentType(hr.entity.contentType.toString).getOrElse("utf-8")
      val decodedResponse = decodeResponse(hr)
      val stringBody = bodyToString(decodedResponse, charsetFromHeaders)

      if (code >= 200 && code < 300) {
        stringBody.map { body =>
          hr.discardEntityBytes()
          (code, body)
        }
      } else {
        stringBody.flatMap { body =>
          hr.discardEntityBytes()
          Future.failed(new RuntimeException(s"${uri.toString} return $code with body: $body"))
        }
      }
    }
  }

}

object AkkaHttpBackend {
  val ContentTypeHeader = "Content-Type"

  def apply(
    uri: Uri,
    headers: immutable.Seq[HttpHeader] = Nil,
    httpExt: Option[HttpExt] = None
  )(implicit as: ActorSystem, mat: ActorMaterializer): AkkaHttpBackend = {

    val http = httpExt.getOrElse { Http(as) }
    new AkkaHttpBackend(uri, headers, http)
  }
} 
Example 50
Source File: ApiTests.scala    From openwhisk   with Apache License 2.0 5 votes vote down vote up
package org.apache.openwhisk.core.monitoring.metrics

import akka.http.scaladsl.model.headers.HttpEncodings._
import akka.http.scaladsl.model.headers.{`Accept-Encoding`, `Content-Encoding`, HttpEncoding, HttpEncodings}
import akka.http.scaladsl.model.{HttpCharsets, HttpEntity, HttpResponse}
import akka.http.scaladsl.testkit.ScalatestRouteTest
import kamon.prometheus.PrometheusReporter
import org.apache.openwhisk.core.monitoring.metrics.OpenWhiskEvents.MetricConfig
import org.junit.runner.RunWith
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.junit.JUnitRunner
import org.scalatest.matchers.Matcher
import org.scalatest.{BeforeAndAfterAll, FlatSpec, Matchers}
import pureconfig.loadConfigOrThrow
import io.prometheus.client.CollectorRegistry
import pureconfig.generic.auto._

import scala.concurrent.duration.DurationInt

@RunWith(classOf[JUnitRunner])
class ApiTests
    extends FlatSpec
    with Matchers
    with ScalatestRouteTest
    with EventsTestHelper
    with ScalaFutures
    with BeforeAndAfterAll {
  implicit val timeoutConfig = PatienceConfig(1.minute)

  private var api: PrometheusEventsApi = _
  private var consumer: EventConsumer = _

  override protected def beforeAll(): Unit = {
    super.beforeAll()
    CollectorRegistry.defaultRegistry.clear()
    val metricConfig = loadConfigOrThrow[MetricConfig](system.settings.config, "user-events")
    val mericRecorder = PrometheusRecorder(new PrometheusReporter, metricConfig)
    consumer = createConsumer(56754, system.settings.config, mericRecorder)
    api = new PrometheusEventsApi(consumer, createExporter())
  }

  protected override def afterAll(): Unit = {
    consumer.shutdown().futureValue
    super.afterAll()
  }

  behavior of "EventsApi"

  it should "respond ping request" in {
    Get("/ping") ~> api.routes ~> check {
      //Due to retries using a random port does not immediately result in failure
      handled shouldBe true
    }
  }

  it should "respond metrics request" in {
    Get("/metrics") ~> `Accept-Encoding`(gzip) ~> api.routes ~> check {
      contentType.charsetOption shouldBe Some(HttpCharsets.`UTF-8`)
      contentType.mediaType.params("version") shouldBe "0.0.4"
      response should haveContentEncoding(gzip)
    }
  }

  private def haveContentEncoding(encoding: HttpEncoding): Matcher[HttpResponse] =
    be(encoding) compose {
      (_: HttpResponse).header[`Content-Encoding`].map(_.encodings.head).getOrElse(HttpEncodings.identity)
    }

  private def createExporter(): PrometheusExporter = () => HttpEntity(PrometheusExporter.textV4, "foo".getBytes)
} 
Example 51
Source File: Prometheus.scala    From openwhisk   with Apache License 2.0 5 votes vote down vote up
package org.apache.openwhisk.common
import java.nio.charset.StandardCharsets.UTF_8

import akka.http.scaladsl.model.{ContentType, HttpCharsets, HttpEntity, MediaType}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import kamon.Kamon
import kamon.prometheus.PrometheusReporter

class KamonPrometheus extends AutoCloseable {
  private val reporter = new PrometheusReporter
  private val v4: ContentType = ContentType.apply(
    MediaType.textWithFixedCharset("plain", HttpCharsets.`UTF-8`).withParams(Map("version" -> "0.0.4")))
  Kamon.registerModule("prometheus", reporter)

  def route: Route = path("metrics") {
    get {
      encodeResponse {
        complete(getReport())
      }
    }
  }

  private def getReport() = HttpEntity(v4, reporter.scrapeData().getBytes(UTF_8))

  override def close(): Unit = reporter.stop()
}

object MetricsRoute {
  private val impl =
    if (TransactionId.metricsKamon && TransactionId.metricConfig.prometheusEnabled) Some(new KamonPrometheus)
    else None

  def apply(): Route = impl.map(_.route).getOrElse(reject)
} 
Example 52
Source File: SwaggerValidator.scala    From openwhisk   with Apache License 2.0 5 votes vote down vote up
package common.rest

import scala.collection.JavaConverters._

import akka.http.scaladsl.model.HttpEntity
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.model.HttpResponse
import com.atlassian.oai.validator.SwaggerRequestResponseValidator
import com.atlassian.oai.validator.model.SimpleRequest
import com.atlassian.oai.validator.model.SimpleResponse
import com.atlassian.oai.validator.report.ValidationReport
import com.atlassian.oai.validator.whitelist.ValidationErrorsWhitelist
import com.atlassian.oai.validator.whitelist.rule.WhitelistRules

trait SwaggerValidator {
  private val specWhitelist = ValidationErrorsWhitelist
    .create()
    .withRule(
      "Ignore action and trigger payloads",
      WhitelistRules.allOf(
        WhitelistRules.messageContains("Object instance has properties which are not allowed by the schema"),
        WhitelistRules.anyOf(
          WhitelistRules.pathContains("/web/"),
          WhitelistRules.pathContains("/actions/"),
          WhitelistRules.pathContains("/triggers/")),
        WhitelistRules.methodIs(io.swagger.models.HttpMethod.POST)))
    .withRule(
      "Ignore invalid action kinds",
      WhitelistRules.allOf(
        WhitelistRules.messageContains("kind"),
        WhitelistRules.messageContains("Instance value"),
        WhitelistRules.messageContains("not found"),
        WhitelistRules.pathContains("/actions/"),
        WhitelistRules.methodIs(io.swagger.models.HttpMethod.PUT)))
    .withRule(
      "Ignore tests that check for invalid DELETEs and PUTs on actions",
      WhitelistRules.anyOf(
        WhitelistRules.messageContains("DELETE operation not allowed on path '/api/v1/namespaces/_/actions/'"),
        WhitelistRules.messageContains("PUT operation not allowed on path '/api/v1/namespaces/_/actions/'")))

  private val specValidator = SwaggerRequestResponseValidator
    .createFor("apiv1swagger.json")
    .withWhitelist(specWhitelist)
    .build()

  
  def validateRequestAndResponse(request: HttpRequest, response: HttpResponse): Seq[String] = {
    val specRequest = {
      val builder = new SimpleRequest.Builder(request.method.value, request.uri.path.toString())
      val body = strictEntityBodyAsString(request.entity)
      val withBody =
        if (body.isEmpty) builder
        else
          builder
            .withBody(body)
            .withHeader("content-type", request.entity.contentType.value)
      val withHeaders = request.headers.foldLeft(builder)((b, header) => b.withHeader(header.name, header.value))
      val andQuery =
        request.uri.query().foldLeft(withHeaders) { case (b, (key, value)) => b.withQueryParam(key, value) }
      andQuery.build()
    }

    val specResponse = {
      val builder = SimpleResponse.Builder
        .status(response.status.intValue)
      val body = strictEntityBodyAsString(response.entity)
      val withBody =
        if (body.isEmpty) builder
        else
          builder
            .withBody(body)
            .withHeader("content-type", response.entity.contentType.value)
      val withHeaders = response.headers.foldLeft(builder)((b, header) => b.withHeader(header.name, header.value))
      withHeaders.build()
    }

    specValidator
      .validate(specRequest, specResponse)
      .getMessages
      .asScala
      .filter(m => m.getLevel == ValidationReport.Level.ERROR)
      .map(_.toString)
      .toSeq
  }

  def strictEntityBodyAsString(entity: HttpEntity): String = entity match {
    case s: HttpEntity.Strict => s.data.utf8String
    case _                    => ""
  }
} 
Example 53
Source File: TestRegistry.scala    From akka-http-metrics   with Apache License 2.0 5 votes vote down vote up
package fr.davit.akka.http.metrics.core

import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model.HttpEntity

import scala.collection.mutable
import scala.concurrent.duration.FiniteDuration

object TestRegistry {
  implicit val marshaller: ToEntityMarshaller[TestRegistry] = Marshaller.opaque(_ => HttpEntity.Empty)

  private def keyer(dimensions: Seq[Dimension]): String = dimensions.mkString(":")

  class TestCounter extends Counter {
    protected val acc = mutable.Map[String, Long]()

    override def inc(dimensions: Seq[Dimension] = Seq.empty): Unit = {
      val key = keyer(dimensions)
      acc.get(key) match {
        case Some(v) => acc += (key -> (v + 1))
        case None    => acc += (key -> 1)
      }
    }

    def value(dimensions: Seq[Dimension] = Seq.empty): Long = acc.getOrElse(keyer(dimensions), 0)
  }

  class TestGauge extends TestCounter with Gauge {
    override def dec(dimensions: Seq[Dimension] = Seq.empty): Unit = {
      val key = keyer(dimensions)
      acc.get(key) match {
        case Some(v) => acc += (key -> (v - 1))
        case None    => acc += (key -> -1)
      }
    }
  }

  class TestTimer extends Timer {
    protected val acc = mutable.Map[String, List[FiniteDuration]]()

    override def observe(duration: FiniteDuration, dimensions: Seq[Dimension] = Seq.empty): Unit = {
      val key = keyer(dimensions)
      acc.get(key) match {
        case Some(vs) => acc += (key -> (duration :: vs))
        case None     => acc += (key -> (duration :: Nil))
      }
    }

    def values(dimensions: Seq[Dimension] = Seq.empty): List[FiniteDuration] = acc.getOrElse(keyer(dimensions), Nil)
  }

  final class TestHistogram extends Histogram {
    protected val acc = mutable.Map[String, List[Long]]()

    override def update[T](value: T, dimensions: Seq[Dimension] = Seq.empty)(implicit numeric: Numeric[T]): Unit = {
      val key = keyer(dimensions)
      acc.get(key) match {
        case Some(vs) => acc += (key -> (numeric.toLong(value) :: vs))
        case None     => acc += (key -> (numeric.toLong(value) :: Nil))
      }
    }

    def values(dimensions: Seq[Dimension] = Seq.empty): List[Long] = acc.getOrElse(keyer(dimensions), Nil)
  }

}

final class TestRegistry(settings: HttpMetricsSettings = HttpMetricsSettings.default)
    extends HttpMetricsRegistry(settings) {

  import TestRegistry._

  override val active = new TestGauge

  override val requests = new TestCounter

  override val receivedBytes = new TestHistogram

  override val responses = new TestCounter

  override val errors = new TestCounter

  override val duration = new TestTimer

  override val sentBytes = new TestHistogram

  override val connected = new TestGauge

  override val connections = new TestCounter
} 
Example 54
Source File: PrometheusMarshallers.scala    From akka-http-metrics   with Apache License 2.0 5 votes vote down vote up
package fr.davit.akka.http.metrics.prometheus.marshalling

import java.io.StringWriter

import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model.{ContentType, HttpCharsets, HttpEntity, MediaTypes}
import fr.davit.akka.http.metrics.prometheus.PrometheusRegistry
import io.prometheus.client.exporter.common.TextFormat

trait PrometheusMarshallers {

  val PrometheusContentType: ContentType = {
    MediaTypes.`text/plain` withParams Map("version" -> "0.0.4") withCharset HttpCharsets.`UTF-8`
  }

  implicit val marshaller: ToEntityMarshaller[PrometheusRegistry] = {
    Marshaller.opaque { registry =>
      val output = new StringWriter()
      try {
        TextFormat.write004(output, registry.underlying.metricFamilySamples)
        HttpEntity(output.toString).withContentType(PrometheusContentType)
      } finally {
        output.close()
      }
    }
  }
}

object PrometheusMarshallers extends PrometheusMarshallers 
Example 55
Source File: DropwizardMarshallers.scala    From akka-http-metrics   with Apache License 2.0 5 votes vote down vote up
package fr.davit.akka.http.metrics.dropwizard.marshalling

import java.io.StringWriter

import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model.{ContentTypes, HttpEntity}
import com.fasterxml.jackson.databind.ObjectMapper
import fr.davit.akka.http.metrics.dropwizard.DropwizardRegistry

trait DropwizardMarshallers {

  implicit val registryToEntityMarshaller: ToEntityMarshaller[DropwizardRegistry] = {

    val writer = new ObjectMapper().writer()

    Marshaller.opaque { registry =>
      val output = new StringWriter()
      try {
        writer.writeValue(output, registry.underlying)
        HttpEntity(output.toString).withContentType(ContentTypes.`application/json`)
      } finally {
        output.close()
      }
    }
  }
}

object DropwizardMarshallers extends DropwizardMarshallers 
Example 56
Source File: AccessTokenSpec.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

import akka.actor.ActorSystem
import akka.http.scaladsl.model.{ HttpEntity, HttpResponse, StatusCodes }
import akka.http.scaladsl.model.ContentTypes.`application/json`
import akka.stream.{ ActorMaterializer, Materializer }
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.time.{ Millis, Seconds, Span }
import org.scalatest.{ BeforeAndAfterAll, DiagrammedAssertions, FlatSpec }

import scala.concurrent.{ Await, ExecutionContext }
import scala.concurrent.duration.Duration

class AccessTokenSpec extends FlatSpec with DiagrammedAssertions with ScalaFutures with BeforeAndAfterAll {
  implicit val system: ActorSystem        = ActorSystem()
  implicit val ec: ExecutionContext       = system.dispatcher
  implicit val materializer: Materializer = ActorMaterializer()
  implicit val defaultPatience: PatienceConfig =
    PatienceConfig(timeout = Span(5, Seconds), interval = Span(700, Millis))

  override def afterAll(): Unit = {
    Await.ready(system.terminate(), Duration.Inf)
  }

  behavior of "AccessToken"

  it should "apply from HttpResponse" in {
    val accessToken  = "xxx"
    val tokenType    = "bearer"
    val expiresIn    = 86400
    val refreshToken = "yyy"

    val httpResponse = HttpResponse(
      status = StatusCodes.OK,
      headers = Nil,
      entity = HttpEntity(
        `application/json`,
        s"""
           |{
           |  "access_token": "$accessToken",
           |  "token_type": "$tokenType",
           |  "expires_in": $expiresIn,
           |  "refresh_token": "$refreshToken"
           |}
         """.stripMargin
      )
    )

    val result = AccessToken(httpResponse)

    whenReady(result) { token =>
      assert(token.accessToken == accessToken)
      assert(token.tokenType == tokenType)
      assert(token.expiresIn == expiresIn)
      assert(token.refreshToken.contains(refreshToken))
    }
  }
} 
Example 57
Source File: ChunkedEntities.scala    From endpoints4s   with MIT License 5 votes vote down vote up
package endpoints4s.akkahttp.client

import akka.http.scaladsl.model.{ContentType, ContentTypes, HttpEntity}
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 encoder = stringCodec(codec)
    chunkedRequestEntity(
      ContentTypes.`application/json`,
      a => ByteString.fromString(encoder.encode(a))
    )
  }

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

} 
Example 58
Source File: HttpRequestSerializer.scala    From rokku   with Apache License 2.0 5 votes vote down vote up
package com.ing.wbaa.rokku.proxy.persistence.serializers

import java.nio.charset.Charset

import akka.http.scaladsl.model.{ HttpEntity, HttpRequest, RemoteAddress }
import akka.serialization.SerializerWithStringManifest
import com.ing.wbaa.rokku.proxy.data.{ User, UserRawJson }
import com.ing.wbaa.rokku.proxy.persistence.{ CurrentRequestsState, ExecutedRequestEvt }
import spray.json._

class HttpRequestSerializer extends SerializerWithStringManifest with HttpRequestConversionSupport {
  override def identifier: Int = 197642

  val Utf8 = Charset.forName("UTF-8")
  val HttpRequestManifest = classOf[ExecutedRequestEvt].getName
  val HttpRequestsManifest = classOf[CurrentRequestsState].getName

  def simplifiedHttpRequestString(e: HttpRequest) =
    SimplifiedHttpRequest(
      e.method.value,
      e.uri.toString(),
      convertAkkaHeadersToStrings(e.headers),
      HttpEntity.Empty.withContentType(e.entity.contentType).toString(),
      e.protocol.value
    ).toJson.toString

  def userSTSString(u: User) =
    UserRawJson(
      u.userName.value,
      Option(u.userGroups.map(g => g.value)),
      u.accessKey.value,
      u.secretKey.value,
      Option(u.userRole.value)).toJson.toString

  def remoteIPString(a: RemoteAddress) = SimplifiedRemoteAddress(a.value).toJson.toString()

  def toExecutedRequestEvt(r: String) = {
    val Array(hr, u, ip) = r.split("[|]")
    val httpRequest = toAkkaHttpRequest(hr.parseJson.convertTo[SimplifiedHttpRequest])
    val userSTS = User(u.parseJson.convertTo[UserRawJson])
    val simplifiedRemoteAddress = ip.parseJson.convertTo[SimplifiedRemoteAddress]

    ExecutedRequestEvt(httpRequest, userSTS, simplifiedRemoteAddress.toRemoteAddr)
  }

  override def manifest(o: AnyRef): String = o.getClass.getName

  override def toBinary(o: AnyRef): Array[Byte] =
    o match {
      case r: ExecutedRequestEvt =>
        s"${simplifiedHttpRequestString(r.httpRequest)}|${userSTSString(r.userSTS)}|${remoteIPString(r.clientIPAddress)}".getBytes(Utf8)

      case c: CurrentRequestsState =>
        c.requests.map { re =>
          s"${simplifiedHttpRequestString(re.httpRequest)}|${userSTSString(re.userSTS)}|${remoteIPString(re.clientIPAddress)}"
        }.mkString("|-").getBytes(Utf8)

      case e: IllegalArgumentException =>
        throw new IllegalArgumentException(s"Unable to serialize to bytes, class: ${o.getClass} ${e.getMessage}")
    }

  override def fromBinary(bytes: Array[Byte], manifest: String): AnyRef = {
    manifest match {
      case s: String if s == HttpRequestManifest =>
        val storedRequest = new String(bytes, Utf8)
        toExecutedRequestEvt(storedRequest)

      case s: String if s == HttpRequestsManifest =>
        val storedRequests = new String(bytes, Utf8)
        val requestsList: List[String] = storedRequests.split("[|-]{2}").toList
        CurrentRequestsState(requestsList.map(toExecutedRequestEvt))

      case _ => throw new IllegalArgumentException(s"Unable to de-serialize from bytes for manifest: $manifest")
    }
  }
} 
Example 59
Source File: EncryBaseApiRoute.scala    From EncryCore   with GNU General Public License v3.0 5 votes vote down vote up
package encry.api.http.routes

import akka.http.scaladsl.model.{ContentTypes, HttpEntity, StatusCodes}
import akka.http.scaladsl.server.{Directive, Directive1, Route}
import encry.api.http.ApiRoute
import io.circe.Json
import org.encryfoundation.common.crypto.encoding.Base58Check
import org.encryfoundation.common.modifiers.mempool.transaction.EncryAddress.Address
import org.encryfoundation.common.utils.Algos
import org.encryfoundation.common.utils.TaggedTypes.{ADKey, ModifierId}

import scala.concurrent.{ExecutionContextExecutor, Future}
import scala.util.Success

trait EncryBaseApiRoute extends ApiRoute {

  implicit val ec: ExecutionContextExecutor = context.dispatcher

  protected def toJsonResponse(js: Json): Route = {
    val resp = complete(HttpEntity(ContentTypes.`application/json`, js.spaces2))
    withCors(resp)
  }

  protected def toJsonResponse(fn: Future[Json]): Route = onSuccess(fn) { toJsonResponse }

  protected def toJsonOptionalResponse(fn: Future[Option[Json]]): Route = {
    onSuccess(fn) {
      case Some(v) => toJsonResponse(v)
      case None => withCors(complete(StatusCodes.NotFound))
    }
  }

  val paging: Directive[(Int, Int)] = parameters("offset".as[Int] ? 0, "limit".as[Int] ? 50)

  val modifierId: Directive1[ModifierId] = pathPrefix(Segment).flatMap { h =>
    Algos.decode(h) match {
      case Success(header) => provide(ModifierId @@ header)
      case _ => reject
    }
  }

  implicit class OkJsonResp(fn: Future[Json]) {
    def okJson(): Route = toJsonResponse(fn)
  }

  implicit class OkJsonOptResp(fn: Future[Option[Json]]) {
    def okJson(): Route = toJsonOptionalResponse(fn)
  }
} 
Example 60
Source File: FooBarActor.scala    From reliable-http-client   with Apache License 2.0 5 votes vote down vote up
package rhttpc.sample

import akka.actor._
import akka.http.scaladsl.model.{HttpEntity, HttpResponse}
import rhttpc.akkapersistence.ReliableFSM
import rhttpc.client.subscription.SubscriptionManager

import scala.concurrent.duration._

private class FooBarActor(protected val id: String, protected val subscriptionManager: SubscriptionManager, client: DelayedEchoClient) extends ReliableFSM[FooBarState, FooBarData] {
  import context.dispatcher

  override protected def persistenceCategory: String = FooBarActor.persistenceCategory

  startWith(InitState, EmptyData)

  when(InitState) {
    case Event(SendMsg(msg), _) =>
      client.requestResponse(msg) pipeTo this
      goto(WaitingForResponseState) replyingAfterSave()
  }
  
  when(WaitingForResponseState) {
    case Event(httpResponse: HttpResponse, _) =>
      self forward httpResponse.entity.asInstanceOf[HttpEntity.Strict].data.utf8String
      stay()
    case Event("foo", _) => goto(FooState) acknowledgingAfterSave()
    case Event("bar", _) => goto(BarState) acknowledgingAfterSave()
  }

  when(FooState, stateTimeout = 5 minutes) {
    case Event(StateTimeout, _) => stop()
  }

  when(BarState, stateTimeout = 5 minutes) {
    case Event(StateTimeout, _) => stop()
  }

  whenUnhandled {
    case Event(CurrentState, _) =>
      sender() ! stateName
      stay()
    case Event(StopYourself, _) =>
      stop()
  }
}

object FooBarActor {
  val persistenceCategory = "foobar"
  
  def props(id: String, subscriptionManager: SubscriptionManager, client: DelayedEchoClient): Props = Props(new FooBarActor(id, subscriptionManager, client))
}

sealed trait FooBarState

case object InitState extends FooBarState
case object WaitingForResponseState extends FooBarState
case object FooState extends FooBarState
case object BarState extends FooBarState

sealed trait FooBarData

case object EmptyData extends FooBarData

case class SendMsg(msg: String)
case object CurrentState
case object StopYourself 
Example 61
Source File: ReliableHttpProxyFactory.scala    From reliable-http-client   with Apache License 2.0 5 votes vote down vote up
package rhttpc.akkahttp.proxy

import akka.NotUsed
import akka.actor._
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpEntity, HttpRequest, HttpResponse}
import akka.stream.Materializer
import akka.stream.scaladsl.{Flow, Sink, Source}
import org.slf4j.LoggerFactory
import rhttpc.client.protocol.{Correlated, Request}
import rhttpc.client.proxy._

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

object ReliableHttpProxyFactory {

  private lazy val logger = LoggerFactory.getLogger(getClass)

  def send(successRecognizer: SuccessHttpResponseRecognizer, batchSize: Int, parallelConsumers: Int)
          (request: Request[HttpRequest])
          (implicit actorSystem: ActorSystem, materialize: Materializer): Future[HttpResponse] = {
    import actorSystem.dispatcher
    send(prepareHttpFlow(batchSize * parallelConsumers), successRecognizer)(request.correlated)
  }

  private def prepareHttpFlow(parallelism: Int)
                             (implicit actorSystem: ActorSystem, materialize: Materializer):
    Flow[(HttpRequest, String), HttpResponse, NotUsed] = {

    import actorSystem.dispatcher
    Http().superPool[String]().mapAsync(parallelism) {
      case (tryResponse, id) =>
        tryResponse match {
          case Success(response) =>
            response.toStrict(1 minute)
          case Failure(ex) =>
            Future.failed(ex)
        }
    }
  }

  private def send(httpFlow: Flow[(HttpRequest, String), HttpResponse, Any], successRecognizer: SuccessHttpResponseRecognizer)
                  (corr: Correlated[HttpRequest])
                  (implicit ec: ExecutionContext, materialize: Materializer): Future[HttpResponse] = {
    import collection.JavaConverters._
    logger.debug(
      s"""Sending request for ${corr.correlationId} to ${corr.msg.getUri()}. Headers:
         |${corr.msg.getHeaders().asScala.toSeq.map(h => "  " + h.name() + ": " + h.value()).mkString("\n")}
         |Body:
         |${corr.msg.entity.asInstanceOf[HttpEntity.Strict].data.utf8String}""".stripMargin
    )
    val logResp = logResponse(corr) _
    val responseFuture = Source.single((corr.msg, corr.correlationId)).via(httpFlow).runWith(Sink.head)
    responseFuture.onComplete {
      case Failure(ex) =>
        logger.error(s"Got failure for ${corr.correlationId} to ${corr.msg.getUri()}", ex)
      case Success(_) =>
    }
    for {
      response <- responseFuture
      transformedToFailureIfNeed <- {
        if (successRecognizer.isSuccess(response)) {
          logResp(response, "success response")
          Future.successful(response)
        } else {
          logResp(response, "response recognized as non-success")
          Future.failed(NonSuccessResponse)
        }
      }
    } yield transformedToFailureIfNeed
  }

  private def logResponse(corr: Correlated[HttpRequest])
                         (response: HttpResponse, additionalInfo: String): Unit = {
    import collection.JavaConverters._
    logger.debug(
      s"""Got $additionalInfo for ${corr.correlationId} to ${corr.msg.getUri()}. Status: ${response.status.value}. Headers:
         |${response.getHeaders().asScala.toSeq.map(h => "  " + h.name() + ": " + h.value()).mkString("\n")}
         |Body:
         |${response.entity.asInstanceOf[HttpEntity.Strict].data.utf8String}""".stripMargin
    )
  }

} 
Example 62
Source File: LogCollectorRoutes.scala    From pulse   with Apache License 2.0 5 votes vote down vote up
package io.phdata.pulse.logcollector

import akka.http.scaladsl.common.EntityStreamingSupport
import akka.http.scaladsl.model.{ ContentTypes, HttpEntity, StatusCodes }
import akka.http.scaladsl.server.Directives._
import com.typesafe.scalalogging.LazyLogging
import io.phdata.pulse.common.domain.{ LogEvent, TimeseriesRequest }


    post {
      // create a streaming Source from the incoming json string
      entity(as[TimeseriesRequest]) { eventRequest =>
        kuduService
          .map { client =>
            eventRequest.payload.map(event => client.save(eventRequest.table_name, List(event)))
          }
          .getOrElse(complete(StatusCodes.NotImplemented))

        complete(HttpEntity(ContentTypes.`application/json`, "ok"))
      }
    }
  }

} 
Example 63
Source File: AuthRouteTest.scala    From akka-http-rest   with MIT License 5 votes vote down vote up
package me.archdev.http.routes

import akka.http.scaladsl.model.{HttpEntity, MediaTypes}
import akka.http.scaladsl.server.Route
import me.archdev.BaseServiceTest
import me.archdev.restapi.core.auth.AuthService
import me.archdev.restapi.http.routes.AuthRoute
import org.mockito.Mockito._

import scala.concurrent.Future

class AuthRouteTest extends BaseServiceTest {

  "AuthRoute" when {

    "POST /auth/signIn" should {

      "return 200 and token if sign in successful" in new Context {
        when(authService.signIn("test", "test")).thenReturn(Future.successful(Some("token")))
        val requestEntity = HttpEntity(MediaTypes.`application/json`, s"""{"login": "test", "password": "test"}""")

        Post("/auth/signIn", requestEntity) ~> authRoute ~> check {
          responseAs[String] shouldBe "\"token\""
          status.intValue() shouldBe 200
        }
      }

      "return 400 if signIn unsuccessful" in new Context {
        when(authService.signIn("test", "test")).thenReturn(Future.successful(None))
        val requestEntity = HttpEntity(MediaTypes.`application/json`, s"""{"login": "test", "password": "test"}""")

        Post("/auth/signIn", requestEntity) ~> authRoute ~> check {
          status.intValue() shouldBe 400
        }
      }

    }

    "POST /auth/signUp" should {

      "return 201 and token" in new Context {
        when(authService.signUp("test", "test", "test")).thenReturn(Future.successful("token"))
        val requestEntity = HttpEntity(MediaTypes.`application/json`, s"""{"username": "test", "email": "test", "password": "test"}""")

        Post("/auth/signUp", requestEntity) ~> authRoute ~> check {
          responseAs[String] shouldBe "\"token\""
          status.intValue() shouldBe 201
        }
      }

    }

  }

  trait Context {
    val authService: AuthService = mock[AuthService]
    val authRoute: Route = new AuthRoute(authService).route
  }

} 
Example 64
Source File: OrderBookHttpInfo.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http

import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpResponse, StatusCodes}
import com.wavesplatform.dex.actors.OrderBookAskAdapter
import com.wavesplatform.dex.actors.orderbook.AggregatedOrderBookActor.Depth
import com.wavesplatform.dex.api.http.entities.MatcherResponse.toHttpResponse
import com.wavesplatform.dex.api.http.entities.{HttpMarketStatus, HttpOrderBook, OrderBookUnavailable, SimpleResponse}
import com.wavesplatform.dex.domain.asset.{Asset, AssetPair}
import com.wavesplatform.dex.model.MatcherModel.{DecimalsFormat, Denormalized}
import com.wavesplatform.dex.time.Time
import play.api.libs.json.Json

import scala.concurrent.{ExecutionContext, Future}

class OrderBookHttpInfo(settings: OrderBookHttpInfo.Settings, askAdapter: OrderBookAskAdapter, time: Time, assetDecimals: Asset => Option[Int])(
    implicit ec: ExecutionContext) {

  private val marketStatusNotFound = toHttpResponse(
    SimpleResponse(StatusCodes.NotFound, Json.obj("message" -> "There is no information about this asset pair"))
  )

  def getMarketStatus(assetPair: AssetPair): Future[HttpResponse] =
    askAdapter.getMarketStatus(assetPair).map {
      case Left(e) => toHttpResponse(OrderBookUnavailable(e))
      case Right(maybeMarketStatus) =>
        maybeMarketStatus match {
          case Some(ms) => toHttpResponse(SimpleResponse(HttpMarketStatus fromMarketStatus ms))
          case None     => marketStatusNotFound
        }
    }

  def getHttpView(assetPair: AssetPair, format: DecimalsFormat, depth: Option[Depth]): Future[HttpResponse] =
    askAdapter.getHttpView(assetPair, format, settings.nearestBigger(depth)).map {
      case Right(x) => x.getOrElse(getDefaultHttpView(assetPair, format))
      case Left(e)  => toHttpResponse(OrderBookUnavailable(e))
    }

  private def getDefaultHttpView(assetPair: AssetPair, format: DecimalsFormat): HttpResponse = {
    val entity = HttpOrderBook(time.correctedTime(), assetPair, Seq.empty, Seq.empty, assetPairDecimals(assetPair, format))
    HttpResponse(
      entity = HttpEntity(
        ContentTypes.`application/json`,
        HttpOrderBook.toJson(entity)
      )
    )
  }

  private def assetPairDecimals(assetPair: AssetPair, format: DecimalsFormat): Option[(Depth, Depth)] = format match {
    case Denormalized => assetDecimals(assetPair.amountAsset).zip(assetDecimals(assetPair.priceAsset)).headOption
    case _            => None
  }
}

object OrderBookHttpInfo {
  case class Settings(depthRanges: List[Int], defaultDepth: Option[Int]) {
    def nearestBigger(to: Option[Int]): Int =
      to.orElse(defaultDepth)
        .flatMap(desiredDepth => depthRanges.find(_ >= desiredDepth))
        .getOrElse(depthRanges.max)
  }
} 
Example 65
Source File: HttpV1OrderBook.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import java.nio.charset.StandardCharsets

import akka.http.scaladsl.model.{HttpEntity, HttpResponse}
import io.swagger.annotations.ApiModelProperty
import play.api.libs.json.{Json, Reads}

case class HttpV1OrderBook(@ApiModelProperty(value = "Timestamp of the last Order Book update") timestamp: Long,
                           @ApiModelProperty(
                             value = "List of aggregated denormalized bid levels [price, amount]",
                             dataType = "[[Ljava.lang.String;",
                             example = """[ [ "1.18", "43800.00000000" ], [ "1.17", "52187.00000000" ], [ "1.16", "809.00000000" ] ]"""
                           ) bids: List[HttpV1LevelAgg],
                           @ApiModelProperty(
                             value = "List of aggregated denormalized ask levels [price, amount]",
                             dataType = "[[Ljava.lang.String;",
                             example = """[ [ "1.19", "2134.00000000" ], [ "1.20", "747.00000000" ] ]"""
                           ) asks: List[HttpV1LevelAgg])

object HttpV1OrderBook {

  implicit val httpV1OrderBookReads: Reads[HttpV1OrderBook] = Json.reads

  def fromHttpResponse(response: HttpResponse): HttpV1OrderBook =
    Json.parse(response.entity.asInstanceOf[HttpEntity.Strict].getData().decodeString(StandardCharsets.UTF_8)).as[HttpV1OrderBook]
} 
Example 66
Source File: Server.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.http

import java.time.Instant

import scala.language.postfixOps
import scala.concurrent.{Await, ExecutionContext, Future}
import scala.concurrent.duration.Duration
import scala.util.{Failure, Success}
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpResponse, StatusCodes}
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.server.Directives._
import akka.stream.ActorMaterializer
import com.typesafe.config.ConfigFactory
import org.apache.s2graph.core.S2Graph
import org.slf4j.LoggerFactory

object Server extends App
  with S2GraphTraversalRoute
  with S2GraphAdminRoute
  with S2GraphMutateRoute
  with S2GraphQLRoute {

  implicit val system: ActorSystem = ActorSystem("S2GraphHttpServer")
  implicit val materializer: ActorMaterializer = ActorMaterializer()
  implicit val executionContext: ExecutionContext = system.dispatcher

  val config = ConfigFactory.load()

  override val s2graph = new S2Graph(config)
  override val logger = LoggerFactory.getLogger(this.getClass)

  val port = sys.props.get("http.port").fold(8000)(_.toInt)
  val interface = sys.props.get("http.interface").fold("0.0.0.0")(identity)

  val startAt = System.currentTimeMillis()

  def uptime = System.currentTimeMillis() - startAt

  def serverHealth = s"""{ "port": ${port}, "interface": "${interface}", "started_at": ${Instant.ofEpochMilli(startAt)}, "uptime": "${uptime} millis" """

  def health = HttpResponse(status = StatusCodes.OK, entity = HttpEntity(ContentTypes.`application/json`, serverHealth))

  // Allows you to determine routes to expose according to external settings.
  lazy val routes: Route = concat(
    pathPrefix("graphs")(traversalRoute),
    pathPrefix("mutate")(mutateRoute),
    pathPrefix("admin")(adminRoute),
    pathPrefix("graphql")(graphqlRoute),
    get(complete(health))
  )

  val binding: Future[Http.ServerBinding] = Http().bindAndHandle(routes, interface, port)
  binding.onComplete {
    case Success(bound) => logger.info(s"Server online at http://${bound.localAddress.getHostString}:${bound.localAddress.getPort}/")
    case Failure(e) => logger.error(s"Server could not start!", e)
  }

  scala.sys.addShutdownHook { () =>
    s2graph.shutdown()
    system.terminate()
    logger.info("System terminated")
  }

  Await.result(system.whenTerminated, Duration.Inf)
} 
Example 67
Source File: S2GraphMutateRoute.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.http

import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpResponse, StatusCodes}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.{ExceptionHandler, Route}
import com.fasterxml.jackson.core.JsonParseException
import org.apache.s2graph.core.rest.RequestParser
import org.apache.s2graph.core.storage.MutateResponse
import org.apache.s2graph.core.{GraphElement, S2Graph}
import org.slf4j.LoggerFactory
import play.api.libs.json.{JsValue, Json}

import scala.concurrent.{ExecutionContext, Future}

trait S2GraphMutateRoute extends PlayJsonSupport {

  val s2graph: S2Graph
  val logger = LoggerFactory.getLogger(this.getClass)

  lazy val parser = new RequestParser(s2graph)

  lazy val exceptionHandler = ExceptionHandler {
    case ex: JsonParseException => complete(StatusCodes.BadRequest -> ex.getMessage)
    case ex: java.lang.IllegalArgumentException => complete(StatusCodes.BadRequest -> ex.getMessage)
  }

  lazy val mutateVertex = path("vertex" / Segments) { params =>
    implicit val ec = s2graph.ec

    val (operation, serviceNameOpt, columnNameOpt) = params match {
      case operation :: serviceName :: columnName :: Nil => (operation, Option(serviceName), Option(columnName))
      case operation :: Nil => (operation, None, None)
      case _ => throw new RuntimeException("invalid params")
    }

    entity(as[JsValue]) { payload =>
      val future = vertexMutate(payload, operation, serviceNameOpt, columnNameOpt).map(Json.toJson(_))

      complete(future)
    }
  }

  lazy val mutateEdge = path("edge" / Segment) { operation =>
    implicit val ec = s2graph.ec

    entity(as[JsValue]) { payload =>
      val future = edgeMutate(payload, operation, withWait = true).map(Json.toJson(_))

      complete(future)
    }
  }

  def vertexMutate(jsValue: JsValue,
                   operation: String,
                   serviceNameOpt: Option[String] = None,
                   columnNameOpt: Option[String] = None,
                   withWait: Boolean = true)(implicit ec: ExecutionContext): Future[Seq[Boolean]] = {
    val vertices = parser.toVertices(jsValue, operation, serviceNameOpt, columnNameOpt)

    val verticesToStore = vertices.filterNot(_.isAsync)

    s2graph.mutateVertices(verticesToStore, withWait).map(_.map(_.isSuccess))
  }

  def edgeMutate(elementsWithTsv: Seq[(GraphElement, String)], withWait: Boolean)(implicit ec: ExecutionContext): Future[Seq[Boolean]] = {
    val elementWithIdxs = elementsWithTsv.zipWithIndex
    val (elementSync, elementAsync) = elementWithIdxs.partition { case ((element, tsv), idx) => !element.isAsync }

    val retToSkip = elementAsync.map(_._2 -> MutateResponse.Success)
    val (elementsToStore, _) = elementSync.map(_._1).unzip
    val elementsIdxToStore = elementSync.map(_._2)

    s2graph.mutateElements(elementsToStore, withWait).map { mutateResponses =>
      elementsIdxToStore.zip(mutateResponses) ++ retToSkip
    }.map(_.sortBy(_._1).map(_._2.isSuccess))
  }

  def edgeMutate(jsValue: JsValue, operation: String, withWait: Boolean)(implicit ec: ExecutionContext): Future[Seq[Boolean]] = {
    val edgesWithTsv = parser.parseJsonFormat(jsValue, operation)
    edgeMutate(edgesWithTsv, withWait)
  }

  // expose routes
  lazy val mutateRoute: Route =
    post {
      concat(
        handleExceptions(exceptionHandler) {
          mutateVertex
        },
        handleExceptions(exceptionHandler) {
          mutateEdge
        }
      )
    }

} 
Example 68
Source File: MinimalHttpServer.scala    From Akka-Cookbook   with MIT License 5 votes vote down vote up
package com.packt.chapter9

import akka.http.scaladsl.model.{ContentTypes, HttpEntity}
import akka.http.scaladsl.server.HttpApp
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.settings.ServerSettings
import com.typesafe.config.ConfigFactory

object MinimalHttpServer extends HttpApp {
  def route =
    pathPrefix("v1") {
      path("id" / Segment) { id =>
        get {
          complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, s"<h1>Hello $id from Akka Http!</h1>"))
        } ~
        post {
          entity(as[String]) { entity =>
            complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, s"<b>Thanks $id for posting your message <i>$entity</i></b>"))
          }
        }
      }
    }
}

object MinimalHttpServerApplication extends App {
  MinimalHttpServer.startServer("0.0.0.0", 8088, ServerSettings(ConfigFactory.load))
} 
Example 69
Source File: UserEndpointFeature.scala    From akka-http-microservice-templates   with MIT License 5 votes vote down vote up
package features

import akka.http.scaladsl.model.{ContentTypes, HttpEntity, StatusCodes}
import akka.http.scaladsl.testkit.ScalatestRouteTest
import modules.AllModulesTest
import org.scalatest.{BeforeAndAfterAll, FeatureSpec, Matchers}

class UserEndpointFeature
  extends FeatureSpec
    with Matchers
    with ScalatestRouteTest
    with BeforeAndAfterAll {

  val modules = new AllModulesTest

  val routes = modules.endpoints.routes

  val httpEntity: (String) => HttpEntity.Strict = (str: String) => HttpEntity(ContentTypes.`application/json`, str)

  feature("user api") {
    scenario("success creation") {
      val validUser =
        """
          {
            "username": "gabfssilva",
            "age": 24
          }
        """

      Post(s"/api/users", httpEntity(validUser)) ~> routes ~> check {
        status shouldBe StatusCodes.Created
      }
    }

    scenario("success get after success creation") {
      val validUser =
        """
          {
            "username": "gabfssilva",
            "age": 24
          }
        """

      Post(s"/api/users", httpEntity(validUser)) ~> routes ~> check {
        status shouldBe StatusCodes.Created

        Get(header("Location").orNull.value()) ~> routes ~> check {
          status shouldBe StatusCodes.OK
        }
      }
    }


    scenario("invalid id on get") {
      Get(s"/api/users/1") ~> routes ~> check {
        status shouldBe StatusCodes.BadRequest
      }
    }

    scenario("no body") {
      Post(s"/api/users", httpEntity("{}")) ~> routes ~> check {
        status shouldBe StatusCodes.BadRequest
      }
    }

    scenario("body without age") {
      val invalidUser =
        """
        {
          "username": "gabfssilva"
        }
        """

      Post(s"/api/users", httpEntity(invalidUser)) ~> routes ~> check {
        status shouldBe StatusCodes.BadRequest
      }
    }

    scenario("body without username") {
      val invalidUser =
        """
        {
          "age": 24
        }
        """

      Post(s"/api/users", httpEntity(invalidUser)) ~> routes ~> check {
        status shouldBe StatusCodes.BadRequest
      }
    }
  }
} 
Example 70
Source File: UserEndpointFeature.scala    From akka-http-microservice-templates   with MIT License 5 votes vote down vote up
package features

import akka.http.scaladsl.model.{ContentTypes, HttpEntity, StatusCodes}
import akka.http.scaladsl.testkit.ScalatestRouteTest
import modules.AllModules
import org.scalatest.{BeforeAndAfterAll, FeatureSpec, Matchers}
import utils.EmbeddedPostgreSQL

class UserEndpointFeature
  extends FeatureSpec
    with Matchers
    with ScalatestRouteTest
    with BeforeAndAfterAll {

  val modules = new AllModules

  override def beforeAll(): Unit = {
    EmbeddedPostgreSQL.start
  }

  override def afterAll(): Unit = {
    EmbeddedPostgreSQL.stop
  }

  val routes = modules.endpoints.routes

  val httpEntity: (String) => HttpEntity.Strict = (str: String) => HttpEntity(ContentTypes.`application/json`, str)

  feature("user api") {
    scenario("success creation") {
      val validUser =
        """
          {
            "username": "gabfssilva",
            "age": 24
          }
        """

      Post(s"/api/users", httpEntity(validUser)) ~> routes ~> check {
        status shouldBe StatusCodes.Created
      }
    }

    scenario("success get after success creation") {
      val validUser =
        """
          {
            "username": "gabfssilva",
            "age": 24
          }
        """

      Post(s"/api/users", httpEntity(validUser)) ~> routes ~> check {
        status shouldBe StatusCodes.Created

        Get(header("Location").orNull.value()) ~> routes ~> check {
          status shouldBe StatusCodes.OK
        }
      }
    }


    scenario("invalid id on get") {
      Get(s"/api/users/asd") ~> routes ~> check {
        status shouldBe StatusCodes.NotFound
      }
    }

    scenario("no body") {
      Post(s"/api/users", httpEntity("{}")) ~> routes ~> check {
        status shouldBe StatusCodes.BadRequest
      }
    }

    scenario("body without age") {
      val invalidUser =
        """
        {
          "username": "gabfssilva"
        }
        """

      Post(s"/api/users", httpEntity(invalidUser)) ~> routes ~> check {
        status shouldBe StatusCodes.BadRequest
      }
    }

    scenario("body without username") {
      val invalidUser =
        """
        {
          "age": 24
        }
        """

      Post(s"/api/users", httpEntity(invalidUser)) ~> routes ~> check {
        status shouldBe StatusCodes.BadRequest
      }
    }
  }
} 
Example 71
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 72
Source File: JsonLdCirceSupport.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.storage

import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model.MediaTypes.`application/json`
import akka.http.scaladsl.model.{ContentTypeRange, HttpEntity}
import ch.epfl.bluebrain.nexus.commons.http.RdfMediaTypes
import ch.epfl.bluebrain.nexus.storage.JsonLdCirceSupport.{sortKeys, OrderedKeys}
import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport
import io.circe.syntax._
import io.circe.{Encoder, Json, JsonObject, Printer}

import scala.collection.immutable.Seq


  def sortKeys(json: Json)(implicit keys: OrderedKeys): Json = {

    implicit val customStringOrdering: Ordering[String] = new Ordering[String] {
      private val middlePos = keys.withPosition("")

      private def position(key: String): Int = keys.withPosition.getOrElse(key, middlePos)

      override def compare(x: String, y: String): Int = {
        val posX = position(x)
        val posY = position(y)
        if (posX == middlePos && posY == middlePos) x compareTo y
        else posX compareTo posY
      }
    }

    def canonicalJson(json: Json): Json =
      json.arrayOrObject[Json](json, arr => Json.fromValues(arr.map(canonicalJson)), obj => sorted(obj).asJson)

    def sorted(jObj: JsonObject): JsonObject =
      JsonObject.fromIterable(jObj.toVector.sortBy(_._1).map { case (k, v) => k -> canonicalJson(v) })

    canonicalJson(json)
  }
} 
Example 73
Source File: ErrorDirectivesSpec.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.commons.http.directives

import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model.{HttpEntity, HttpResponse, StatusCodes}
import akka.util.ByteString
import ch.epfl.bluebrain.nexus.commons.circe.ContextUri
import ch.epfl.bluebrain.nexus.commons.http.RdfMediaTypes
import ch.epfl.bluebrain.nexus.commons.http.directives.ErrorDirectives._
import ch.epfl.bluebrain.nexus.commons.http.directives.ErrorDirectivesSpec.CustomError
import ch.epfl.bluebrain.nexus.rdf.syntax.iri._
import ch.epfl.bluebrain.nexus.util.ActorSystemFixture
import io.circe.generic.auto._
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpecLike

import scala.concurrent.duration._

class ErrorDirectivesSpec
    extends ActorSystemFixture("ErrorDirectivesSpec")
    with AnyWordSpecLike
    with Matchers
    with ScalaFutures {

  implicit override val patienceConfig = PatienceConfig(3.seconds, 100.millis)

  "A ErrorDirectives" should {
    import system.dispatcher
    implicit val statusFromJson: StatusFrom[CustomError] = StatusFrom((_: CustomError) => StatusCodes.NotFound)
    implicit val contextUri: ContextUri                  = ContextUri(url"http://localhost.com/error/")

    "marshall error JSON-LD" in {
      val error      = CustomError("some error")
      val jsonString = s"""{"@context":"${contextUri.value}","message":"${error.message}"}"""
      Marshal(error).to[HttpResponse].futureValue shouldEqual HttpResponse(
        status = StatusCodes.NotFound,
        entity = HttpEntity.Strict(RdfMediaTypes.`application/ld+json`, ByteString(jsonString, "UTF-8"))
      )
    }
  }

}

object ErrorDirectivesSpec {
  final case class CustomError(message: String)
} 
Example 74
Source File: ArchiveRoutes.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.kg.routes

import akka.http.scaladsl.model.StatusCodes.{Created, OK}
import akka.http.scaladsl.model.headers.Accept
import akka.http.scaladsl.model.{HttpEntity, MediaTypes}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import ch.epfl.bluebrain.nexus.admin.client.types.Project
import ch.epfl.bluebrain.nexus.iam.acls.Acls
import ch.epfl.bluebrain.nexus.iam.realms.Realms
import ch.epfl.bluebrain.nexus.iam.types.Caller
import ch.epfl.bluebrain.nexus.iam.types.Identity.Subject
import ch.epfl.bluebrain.nexus.kg.KgError.{InvalidOutputFormat, UnacceptedResponseContentType}
import ch.epfl.bluebrain.nexus.kg.archives.Archive._
import ch.epfl.bluebrain.nexus.kg.directives.PathDirectives._
import ch.epfl.bluebrain.nexus.kg.directives.ProjectDirectives._
import ch.epfl.bluebrain.nexus.kg.directives.QueryDirectives.outputFormat
import ch.epfl.bluebrain.nexus.kg.marshallers.instances._
import ch.epfl.bluebrain.nexus.kg.resources._
import ch.epfl.bluebrain.nexus.kg.resources.syntax._
import ch.epfl.bluebrain.nexus.kg.routes.OutputFormat.Tar
import ch.epfl.bluebrain.nexus.rdf.Iri.AbsoluteIri
import ch.epfl.bluebrain.nexus.rdf.Iri.Path._
import ch.epfl.bluebrain.nexus.service.config.ServiceConfig
import ch.epfl.bluebrain.nexus.service.directives.AuthDirectives
import io.circe.Json
import kamon.instrumentation.akka.http.TracingDirectives.operationName
import monix.eval.Task
import monix.execution.Scheduler.Implicits.global

class ArchiveRoutes private[routes] (archives: Archives[Task], acls: Acls[Task], realms: Realms[Task])(implicit
    project: Project,
    caller: Caller,
    config: ServiceConfig
) extends AuthDirectives(acls, realms) {

  private val responseType              = MediaTypes.`application/x-tar`
  private val projectPath               = project.organizationLabel / project.label
  implicit private val subject: Subject = caller.subject

  
  def routes(id: AbsoluteIri): Route = {
    val resId = Id(project.ref, id)
    concat(
      // Create archive
      (put & pathEndOrSingleSlash) {
        operationName(s"/${config.http.prefix}/archives/{org}/{project}/{id}") {
          (authorizeFor(projectPath, write) & projectNotDeprecated) {
            entity(as[Json]) { source =>
              complete(archives.create(resId, source).value.runWithStatus(Created))
            }
          }
        }
      },
      // Fetch archive
      (get & outputFormat(strict = true, Tar) & pathEndOrSingleSlash) {
        case Tar                           => getArchive(resId)
        case format: NonBinaryOutputFormat => getResource(resId)(format)
        case other                         => failWith(InvalidOutputFormat(other.toString))

      }
    )
  }

  private def getResource(resId: ResId)(implicit format: NonBinaryOutputFormat): Route =
    completeWithFormat(archives.fetch(resId).value.runWithStatus(OK))

  private def getArchive(resId: ResId): Route = {
    (parameter("ignoreNotFound".as[Boolean] ? false) & extractCallerAcls(anyProject)) { (ignoreNotFound, acls) =>
      onSuccess(archives.fetchArchive(resId, ignoreNotFound)(acls, caller).value.runToFuture) {
        case Right(source) =>
          headerValueByType[Accept](()) { accept =>
            if (accept.mediaRanges.exists(_.matches(responseType)))
              complete(HttpEntity(responseType, source))
            else
              failWith(
                UnacceptedResponseContentType(
                  s"File Media Type '$responseType' does not match the Accept header value '${accept.mediaRanges.mkString(", ")}'"
                )
              )
          }
        case Left(err)     => complete(err)
      }
    }
  }
} 
Example 75
Source File: AdminService.scala    From heimdallr   with Apache License 2.0 5 votes vote down vote up
package chat.admin

import scala.concurrent.ExecutionContext
import akka.actor._
import akka.stream.ActorMaterializer
import akka.http.scaladsl.model.{ContentTypes, HttpEntity}
import akka.http.scaladsl.server.Directives._
import chat.{HealthyService, WebService}

class AdminService(healthy: HealthyService)
                  (implicit system: ActorSystem, mat: ActorMaterializer, dispatcher: ExecutionContext)
  extends WebService
    with CommonApi {

  private var chatSuper: ActorRef = null
  private val servicePort = 8090
  private val serviceRoute= //<- adjustable depended on client url
    get {
      pathPrefix("health") {
        path("up") {
          healthy.start()
          httpRespJson( "200 OK" )
        } ~
          path("down") {
            healthy.stop()
            httpRespJson( "200 OK" )
          }
        path("view") {
          var result: String = ""
          if(chatSuper != null) {
            chatSuper ! "akka://heimdallr/user/*"
            chatSuper ! "akka://heimdallr/user/cs/*"
            result = "200 OK"
          }
          else {
            result = "ChatSupervisor ActorRef is NULL"
          }
          httpRespJson(result)
        }
      }
    }

  def httpRespJson(body: String) = {
    complete( HttpEntity(ContentTypes.`application/json`, body+"\r\n") )
  }

  def setChatSupervisorActorRef(actorRef: ActorRef) = {
    chatSuper = actorRef
  }

  def start(): Unit = {
    log.debug( "Admin Server staring ..." )
    serviceBind(this.getClass.getSimpleName, serviceRoute, servicePort)
  }

  def stop(): Unit = {
    serviceUnbind(this.getClass.getSimpleName)
  }
} 
Example 76
Source File: AkkaBodyBuilder.scala    From chronicler   with Apache License 2.0 5 votes vote down vote up
package com.github.fsanaulla.chronicler.akka.shared.handlers

import java.nio.file.Path

import akka.http.scaladsl.model.{HttpEntity, MediaTypes, RequestEntity}
import akka.stream.scaladsl.FileIO
import com.github.fsanaulla.chronicler.core.alias.ErrorOr
import com.github.fsanaulla.chronicler.core.components.BodyBuilder
import com.github.fsanaulla.chronicler.core.either
import com.github.fsanaulla.chronicler.core.either.EitherOps
import com.github.fsanaulla.chronicler.core.model.{Appender, InfluxWriter, Point}

class AkkaBodyBuilder extends BodyBuilder[RequestEntity] with Appender {
  override def fromFile(filePath: Path, enc: String): RequestEntity =
    HttpEntity(
      MediaTypes.`application/octet-stream`,
      FileIO
        .fromPath(filePath)
    )

  override def fromString(string: String): RequestEntity =
    HttpEntity(string)

  override def fromStrings(strings: Seq[String]): RequestEntity =
    HttpEntity(strings.mkString("\n"))

  override def fromPoint(point: Point): RequestEntity =
    HttpEntity(point.serialize)

  override def fromPoints(points: Seq[Point]): RequestEntity =
    HttpEntity(points.map(_.serialize).mkString("\n"))

  override def fromT[T](meas: String, t: T)(implicit wr: InfluxWriter[T]): ErrorOr[RequestEntity] =
    wr.write(t).mapRight(append(meas, _))

  override def fromSeqT[T](
      meas: String,
      ts: Seq[T]
    )(implicit wr: InfluxWriter[T]
    ): ErrorOr[RequestEntity] =
    either.seq(ts.map(wr.write)).mapRight(append(meas, _))
} 
Example 77
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 78
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 79
Source File: TlsGatewaySystemTest.scala    From affinity   with Apache License 2.0 5 votes vote down vote up
package io.amient.affinity.core.http

import akka.http.scaladsl.model.HttpMethods.GET
import akka.http.scaladsl.model.StatusCodes._
import akka.http.scaladsl.model.{HttpEntity, HttpResponse}
import io.amient.affinity.AffinityActorSystem
import io.amient.affinity.core.actor.GatewayHttp
import io.amient.affinity.core.cluster.Node
import io.amient.affinity.core.http.RequestMatchers.HTTP
import io.amient.affinity.core.util.AffinityTestBase
import org.scalatest.{BeforeAndAfterAll, FlatSpec, Matchers}


class TlsGateway extends GatewayHttp {
  override def handle: Receive = {
    case HTTP(GET, _, _, response) => response.success(HttpResponse(OK, entity = "Hello World"))
  }
}


class TlsGatewaySystemTest extends FlatSpec with AffinityTestBase with BeforeAndAfterAll with Matchers {

  def config = configure("tlstests")

  val system = AffinityActorSystem.create(config)

  val node = new Node(config)

  override def beforeAll: Unit = try {
    node.start()
    node.awaitClusterReady()
  } finally {
    super.beforeAll()
  }

  override def afterAll(): Unit = try {
    node.shutdown()
  } finally {
    super.afterAll()
  }

  "HTTPS Requests" should "be handled correctly as TLS" in {
    node.https_get("/tls-hello").entity should equal(HttpEntity("Hello World"))
  }

} 
Example 80
Source File: FileUploadStream.scala    From introduction-to-akkahttp   with Apache License 2.0 5 votes vote down vote up
package com.shashank.akkahttp.basic.routing

import akka.http.scaladsl.model.{ContentTypes, HttpEntity, Multipart, StatusCodes}
import akka.http.scaladsl.server.Directives._
import akka.stream.scaladsl.Framing
import akka.util.ByteString

import scala.concurrent.Future



object FileUploadStream extends BaseSpec{

  def main(args: Array[String]) {

    val route =
      extractRequestContext { ctx =>
        implicit val materializer = ctx.materializer
        implicit val ec = ctx.executionContext
 
        fileUpload("csv") {
          case (metadata, byteSource) =>
            val sumF: Future[Int] =
            // sum the numbers as they arrive so that we can
            byteSource.via(Framing.delimiter(ByteString("\n"), 1024))
              .mapConcat(_.utf8String.split(",").toVector)
              .map(_.toInt)
              .runFold(0) { (acc, n) => acc + n }
              onSuccess(sumF) { sum => complete(s"Sum: $sum") }
        }
      }

    //Test file upload stream
    val multipartForm =
      Multipart.FormData(Multipart.FormData.BodyPart.Strict(
        "csv",
        HttpEntity(ContentTypes.`text/plain(UTF-8)`, "2,3,5\n7,11,13,17,23\n29,31,37\n"),
        Map("filename" -> "primes.csv")))
 
    Post("/", multipartForm) ~> route ~> check {
      status shouldEqual StatusCodes.OK
      responseAs[String] shouldEqual "Sum: 178"
    }

    system.terminate()
  }

}
//File upload direct
//curl --form "[email protected]" http://<host>:<port> 
Example 81
Source File: ApiVersionRoute.scala    From scala-for-beginners   with Apache License 2.0 5 votes vote down vote up
package com.allaboutscala.donutstore.httpserver.routes


import akka.http.scaladsl.model.{ContentTypes, HttpEntity}
import akka.http.scaladsl.server.Directives.{complete, get, path, _}
import akka.http.scaladsl.server._
import com.allaboutscala.donutstore.config.DonutStoreConfig
import com.allaboutscala.donutstore.data.DataApi

import scala.util.Try



class ApiVersionRoute extends HttpRoute {
  import spray.json._

  override def routes()(implicit config: DonutStoreConfig, dataApi: DataApi): Route = {
    val apiVersion =
      s"""
         |{
         | "app": "${config.app}",
         | "version": "${config.httpServer.apiVersion}"
         |}""".stripMargin

    path("api-version") {
      get {
        parameter("prettyPrint" ? "true") { prettyPrint => // the prettyPrint parameter is optional and we also default to true
          val shouldPrettyPrint = Try(prettyPrint.toBoolean).getOrElse(true) // we'll default to pretty print
        val apiVersionOutput = if (shouldPrettyPrint) apiVersion.parseJson.prettyPrint else apiVersion.parseJson.toString
          complete(HttpEntity(ContentTypes.`application/json`, apiVersionOutput))
        }
      }
    }
  }
} 
Example 82
Source File: ApiVersionRoute.scala    From scala-for-beginners   with Apache License 2.0 5 votes vote down vote up
package com.allaboutscala.donutstore.routes


import akka.http.scaladsl.model.{ContentTypes, HttpEntity}
import akka.http.scaladsl.server.Directives.{complete, get, path, _}
import akka.http.scaladsl.server.Route
import com.allaboutscala.donutstore.config.DonutStoreConfig
import com.allaboutscala.donutstore.data.DataApi

import scala.util.Try



class ApiVersionRoute extends HttpRoute {
  import spray.json._

  override def routes()(implicit config: DonutStoreConfig, dataApi: DataApi): Route = {
    val apiVersion =
      s"""
         |{
         | "app": "${config.app}",
         | "version": "${config.httpServer.apiVersion}"
         |}""".stripMargin

    path("api-version") {
      get {
        parameter("prettyPrint" ? "true") { prettyPrint => // the prettyPrint parameter is optional and we also default to true
          val shouldPrettyPrint = Try(prettyPrint.toBoolean).getOrElse(true) // we'll default to pretty print
          val apiVersionOutput = if (shouldPrettyPrint) apiVersion.parseJson.prettyPrint else apiVersion.parseJson.toString
          complete(HttpEntity(ContentTypes.`application/json`, apiVersionOutput))
        }
      }
    }
  }
} 
Example 83
Source File: HomeActor.scala    From sns   with Apache License 2.0 5 votes vote down vote up
package me.snov.sns.actor

import akka.actor.{Actor, Props}
import akka.http.scaladsl.model.{HttpEntity, HttpResponse}

object HomeActor {
  def props = Props[HomeActor]

  case class CmdHello()
}

class HomeActor extends Actor {
  import me.snov.sns.actor.HomeActor._

  def hello = HttpResponse(entity = HttpEntity("Hello, Akka"))

  override def receive = {
    case CmdHello => sender ! hello
    case _ => sender ! HttpResponse(500, entity = "Invalid message")
  }
} 
Example 84
Source File: FileDirective.scala    From akka-http-file-server   with Apache License 2.0 5 votes vote down vote up
package akkahttp

import java.io.File

import akka.http.scaladsl.model.{HttpEntity, MediaTypes, Multipart}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server._
import akka.stream.Materializer
import akka.stream.io.{SynchronousFileSink, SynchronousFileSource}

import scala.concurrent.{ExecutionContext, Future}


object FileDirective {

  //form field name
  type Name = String

  case class FileInfo(fileName: String, targetFile: String, length: Long)

  private def uploadFileImpl(implicit mat: Materializer, ec: ExecutionContext): Directive1[Future[Map[Name, FileInfo]]] = {
    Directive[Tuple1[Future[Map[Name, FileInfo]]]] { inner =>
      entity(as[Multipart.FormData]) { (formdata: Multipart.FormData) =>
        val fileNameMap = formdata.parts.mapAsync(1) { p =>
          if (p.filename.isDefined) {
            val targetPath = File.createTempFile(s"userfile_${p.name}_${p.filename.getOrElse("")}", "")
            val written = p.entity.dataBytes.runWith(SynchronousFileSink(targetPath))
            written.map(written => 
              Map(p.name -> FileInfo(p.filename.get, targetPath.getAbsolutePath, written)))
          } else {
            Future(Map.empty[Name, FileInfo])
          }
        }.runFold(Map.empty[Name, FileInfo])((set, value) => set ++ value)
        inner(Tuple1(fileNameMap))
      }
    }
  }

  def uploadFile: Directive1[Map[Name, FileInfo]] = {
    Directive[Tuple1[Map[Name, FileInfo]]] { inner =>
      extractMaterializer {implicit mat =>
        extractExecutionContext {implicit ec =>
          uploadFileImpl(mat, ec) { filesFuture =>
            ctx => {
              filesFuture.map(map => inner(Tuple1(map))).flatMap(route => route(ctx))
            }
          }
        }
      }
    }
  }

  def downloadFile(file: String): Route = {
    val f = new File(file)
    val responseEntity = HttpEntity(
      MediaTypes.`application/octet-stream`,
      f.length,
      SynchronousFileSource(f, chunkSize = 262144))
    complete(responseEntity)
  }
} 
Example 85
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 86
Source File: JsonEntities.scala    From endpoints4s   with MIT License 5 votes vote down vote up
package endpoints4s.akkahttp.server

import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
import akka.http.scaladsl.model.{HttpEntity, MediaTypes}
import akka.http.scaladsl.server.{Directive1, Directives}
import akka.http.scaladsl.unmarshalling.{
  FromEntityUnmarshaller,
  FromRequestUnmarshaller,
  Unmarshaller
}
import endpoints4s.{Codec, Decoder, Encoder, Invalid, Valid, Validated, algebra}


trait JsonEntitiesFromEncodersAndDecoders
    extends algebra.JsonEntities
    with EndpointsWithCustomErrors {

  type JsonRequest[A] = Decoder[String, A]
  type JsonResponse[A] = Encoder[A, String]

  def jsonRequest[A](implicit decoder: Decoder[String, A]): RequestEntity[A] =
    JsonEntities.decodeJsonRequest(this)(decoder)

  def jsonResponse[A](implicit encoder: Encoder[A, String]): ResponseEntity[A] =
    JsonEntities.encodeJsonResponse(encoder)

}

private object JsonEntities {

  def decodeJsonRequest[A](
      endpoints: EndpointsWithCustomErrors
  )(decoder: Decoder[String, A]): Directive1[A] = {
    implicit val fromEntityUnmarshaller: FromEntityUnmarshaller[Validated[A]] =
      Unmarshaller.stringUnmarshaller
        .forContentTypes(MediaTypes.`application/json`)
        .map(data => decoder.decode(data))
    Directives.entity[Validated[A]](implicitly).flatMap {
      case Valid(a)     => Directives.provide(a)
      case inv: Invalid => endpoints.handleClientErrors(inv)
    }
  }

  def encodeJsonResponse[A](
      encoder: Encoder[A, String]
  ): ToEntityMarshaller[A] =
    Marshaller.withFixedContentType(MediaTypes.`application/json`) { value =>
      HttpEntity(MediaTypes.`application/json`, encoder.encode(value))
    }

} 
Example 87
Source File: BuiltInErrors.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.{HttpEntity, MediaTypes}
import endpoints4s.{Invalid, algebra}


trait BuiltInErrors extends algebra.BuiltInErrors {
  this: EndpointsWithCustomErrors =>

  def clientErrorsResponseEntity: ResponseEntity[Invalid] =
    Marshaller.withFixedContentType(MediaTypes.`application/json`) { invalid =>
      HttpEntity(
        MediaTypes.`application/json`,
        endpoints4s.ujson.codecs.invalidCodec.encode(invalid)
      )
    }

  def serverErrorResponseEntity: ResponseEntity[Throwable] =
    clientErrorsResponseEntity.compose(throwable => Invalid(throwable.getMessage))

} 
Example 88
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 89
Source File: EndpointsSettings.scala    From endpoints4s   with MIT License 5 votes vote down vote up
package endpoints4s.akkahttp.client

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpEntity, HttpRequest, HttpResponse, Uri}
import akka.stream.Materializer
import akka.stream.scaladsl.{Flow, Sink, Source}

import scala.concurrent.Future
import scala.concurrent.duration._
import scala.util.Try

final case class EndpointsSettings(
    requestExecutor: AkkaHttpRequestExecutor,
    baseUri: Uri = Uri("/"),
    toStrictTimeout: FiniteDuration = 2.seconds,
    stringContentExtractor: HttpEntity.Strict => String = _.data.utf8String
)

trait AkkaHttpRequestExecutor {
  def apply(request: HttpRequest): Future[HttpResponse]
}

object AkkaHttpRequestExecutor {
  def cachedHostConnectionPool(host: String, port: Int)(implicit
      system: ActorSystem,
      materializer: Materializer
  ): AkkaHttpRequestExecutor =
    default(Http().cachedHostConnectionPool[Int](host, port))

  def default(
      poolClientFlow: Flow[
        (HttpRequest, Int),
        (Try[HttpResponse], Int),
        Http.HostConnectionPool
      ]
  )(implicit materializer: Materializer): AkkaHttpRequestExecutor =
    new AkkaHttpRequestExecutor {
      override def apply(request: HttpRequest): Future[HttpResponse] =
        Source
          .single(request -> 1)
          .via(poolClientFlow)
          .map(_._1.get)
          .runWith(Sink.head)
    }
}