akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport Scala Examples

The following examples show how to use akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport. 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: Main.scala    From Pi-Akka-Cluster   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.akka_oled

import akka.NotUsed
import akka.actor.typed.scaladsl.Behaviors
import akka.actor.typed.scaladsl.adapter.TypedActorSystemOps
import akka.actor.typed.{ActorSystem, Behavior, Terminated}
import akka.cluster.ddata.LWWMapKey
import akka.http.scaladsl.Http
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.management.scaladsl.AkkaManagement
import akka.stream.Materializer
import akkapi.cluster.{ClusterStatusTracker, OledClusterVisualizer, OledDriver, Settings}
import spray.json.DefaultJsonProtocol

object Main extends SprayJsonSupport with DefaultJsonProtocol {

  case class NodeStatus(status: String)

  implicit val transactionFormat = jsonFormat1(NodeStatus)

  def apply(settings: Settings): Behavior[NotUsed] = Behaviors.setup { ctx =>

    val oledDriver = ctx.spawn(OledDriver(settings), "oled-driver")
    oledDriver ! OledDriver.RegisterView("Cluster State", 0)
    oledDriver ! OledDriver.RegisterView("Distributed Data State", 1)

    val clusterView = ctx.spawn(OledClusterVisualizer(0, settings, oledDriver), "oled-cluster-view")
    val clusterStatusTracker = ctx.spawn(ClusterStatusTracker(settings, None), "cluster-status-tracker")
    clusterStatusTracker ! ClusterStatusTracker.SubscribeVisualiser(clusterView)

    val ddataTracker = ctx.spawn(
      DistributedDataTracker(1, LWWMapKey[String, String]("cache"), oledDriver),
      "oled-ddata-view")

    val routes = new Routes(ddataTracker)(ctx.system)

    implicit val untypedSystem: akka.actor.ActorSystem = ctx.system.toClassic
    implicit val mat: Materializer = Materializer.createMaterializer(ctx.system.toClassic)
    Http()(ctx.system.toClassic).bindAndHandle(routes.route,
      settings.config.getString("cluster-node-configuration.external-ip"), 8080)

    Behaviors.receiveSignal {
      case (_, Terminated(_)) =>
        Behaviors.stopped
    }
  }
}

object DisplayDistributedDataMain {
  def main(args: Array[String]): Unit = {
    val settings = Settings()
    val system = ActorSystem[NotUsed](Main(settings), "akka-oled", settings.config)

    // Start Akka HTTP Management extension
    AkkaManagement(system).start()
  }
} 
Example 2
Source File: RestPi.scala    From apache-spark-test   with Apache License 2.0 5 votes vote down vote up
package com.github.dnvriend

import akka.actor.ActorSystem
import akka.event.{ Logging, LoggingAdapter }
import akka.http.scaladsl._
import akka.http.scaladsl.common.{ EntityStreamingSupport, JsonEntityStreamingSupport }
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.server.{ Directives, Route }
import akka.stream.scaladsl.{ Flow, Source }
import akka.stream.{ ActorMaterializer, Materializer }
import akka.util.ByteString
import com.github.dnvriend.spark.CalculatePi
import org.apache.spark.SparkContext
import org.apache.spark.sql.SparkSession
import spray.json.DefaultJsonProtocol

import scala.concurrent.{ ExecutionContext, Future }

object RestPi extends App with Directives with SprayJsonSupport with DefaultJsonProtocol {
  implicit val system: ActorSystem = ActorSystem()
  implicit val mat: Materializer = ActorMaterializer()
  implicit val ec: ExecutionContext = system.dispatcher
  implicit val log: LoggingAdapter = Logging(system, this.getClass)

  val spark = SparkSession.builder()
    .config("spark.sql.warehouse.dir", "file:/tmp/spark-warehouse")
    .config("spark.scheduler.mode", "FAIR")
    .config("spark.sql.crossJoin.enabled", "true")
    .master("local") // use as many threads as cores
    .appName("RestPi") // The appName parameter is a name for your application to show on the cluster UI.
    .getOrCreate()

  final case class Pi(pi: Double)

  implicit val piJsonFormat = jsonFormat1(Pi)
  val start = ByteString.empty
  val sep = ByteString("\n")
  val end = ByteString.empty
  implicit val jsonStreamingSupport: JsonEntityStreamingSupport = EntityStreamingSupport.json()
    .withFramingRenderer(Flow[ByteString].intersperse(start, sep, end))
    .withParallelMarshalling(parallelism = 8, unordered = true)

  def sparkContext: SparkContext = spark.newSession().sparkContext

  def calculatePi(num: Long = 1000000, slices: Int = 2): Future[Double] =
    Future(CalculatePi(sparkContext, num, slices)).map(count => slices.toDouble * count / (num - 1))

  val route: Route =
    pathEndOrSingleSlash {
      complete(calculatePi().map(Pi))
    } ~ path("pi" / LongNumber / IntNumber) { (num, slices) =>
      complete(calculatePi(num, slices).map(Pi))
    } ~ path("stream" / "pi" / LongNumber) { num =>
      complete(Source.fromFuture(calculatePi()).map(Pi)
        .flatMapConcat(Source.repeat).take(num))
    }

  Http().bindAndHandle(route, "0.0.0.0", 8008)

  sys.addShutdownHook {
    spark.stop()
    system.terminate()
  }
} 
Example 3
Source File: EchoEnumeratumService.scala    From swagger-akka-http-sample   with Apache License 2.0 5 votes vote down vote up
package com.example.akka.echoenumeratum

import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.server.{Directives, Route}
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.media.{Content, Schema}
import io.swagger.v3.oas.annotations.parameters.RequestBody
import io.swagger.v3.oas.annotations.responses.ApiResponse
import javax.ws.rs.core.MediaType
import javax.ws.rs.{Consumes, POST, Path, Produces}
import pl.iterators.kebs.json.{KebsEnumFormats, KebsSpray}
import spray.json.{DefaultJsonProtocol, RootJsonFormat}

@Path("/echoenumeratum")
object EchoEnumeratumService extends Directives with SprayJsonSupport with DefaultJsonProtocol
  with KebsSpray with KebsEnumFormats {

  case class EchoEnumeratum(enumValue: SizeEnum)

  implicit val echoEnumeratumFormat: RootJsonFormat[EchoEnumeratum] = jsonFormatN[EchoEnumeratum]

  val route: Route = echo

  @POST
  @Consumes(Array(MediaType.APPLICATION_JSON))
  @Produces(Array(MediaType.APPLICATION_JSON))
  @Operation(summary = "Echo Enumeratum", description = "Echo Enumeratum",
    requestBody = new RequestBody(content = Array(new Content(schema = new Schema(implementation = classOf[EchoEnumeratum])))),
    responses = Array(
      new ApiResponse(responseCode = "200", description = "Echo Enumeratum",
        content = Array(new Content(schema = new Schema(implementation = classOf[EchoEnumeratum])))),
      new ApiResponse(responseCode = "400", description = "Bad Request"))
  )
  def echo: Route =
    path("echoenumeratum") {
      post {
        entity(as[EchoEnumeratum]) { request =>
          complete(request)
        }
      }
    }

} 
Example 4
Source File: StatsEndpoint.scala    From akka-kubernetes-tests   with Apache License 2.0 5 votes vote down vote up
package akka.kubernetes.soak
import akka.actor.{ActorRef, ActorSystem}
import akka.event.Logging
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.server.{Directives, Route}
import spray.json.DefaultJsonProtocol
import akka.pattern.ask
import akka.util.Timeout

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

// collect your json format instances into a support trait:
trait StatsJsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
  implicit val testResultFormat = jsonFormat2(TestResult)
  implicit val testResultsFormat = jsonFormat7(TestResults)
}

class StatsEndpoint(system: ActorSystem, client: ActorRef) extends Directives with StatsJsonSupport {
  private implicit val askTimeout = Timeout(5.seconds)
  private val log = Logging(system, getClass)

  val route: Route =
    path("stats") {
      get {
        onComplete(client.ask(GetTestResults()).mapTo[TestResults]) {
          case Failure(t) =>
            log.error(t, "Failed to get test results")
            complete(StatusCodes.InternalServerError)
          case Success(value) =>
            complete(value)
        }
      }
    }

} 
Example 5
Source File: ValidationDirectivesSpec.scala    From squbs   with Apache License 2.0 5 votes vote down vote up
package org.squbs.pattern.validation

import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server._
import akka.http.scaladsl.server.directives.MethodDirectives
import akka.http.scaladsl.testkit.ScalatestRouteTest
import org.scalatest.{FunSpecLike, Matchers}
import org.squbs.pattern.validation.ValidationDirectives.{validate => _}
import spray.json.{DefaultJsonProtocol, RootJsonFormat}

object MyJsonProtocol extends SprayJsonSupport with DefaultJsonProtocol {
  implicit val PersonFormat: RootJsonFormat[Person] = jsonFormat4(Person)
}

class ValidationDirectivesSpec extends FunSpecLike with Matchers with ScalatestRouteTest{

  val ValidationPassed = "Validation Passed"

  import MyJsonProtocol._
  import org.squbs.pattern.validation.SampleValidators._

  val route: Route =
    (path("person") & MethodDirectives.post) {
      entity(as[Person]) { person =>
        import ValidationDirectives._
        validate(person) {
          complete(ValidationPassed)
        }
      }
    }

  describe("ValidationDirectives") {

    it(s"should return [$ValidationPassed] string with 200 for a valid content without middle name") {
      Post("/person", Person("John", "Smith", age = 25)) ~> route ~> check {
        status shouldEqual StatusCodes.OK
        responseAs[String] shouldEqual ValidationPassed
      }
    }

    it(s"should return [$ValidationPassed] string with 200 for a valid content with middle name") {
      Post("/person", Person("John", "Smith", Some("Mike"), age = 25)) ~> route ~> check {
        status shouldEqual StatusCodes.OK
        responseAs[String] shouldEqual ValidationPassed
      }
    }

    it("should reject with Last Name") {
      Post("/person", Person("John", "", age = 25)) ~> route ~> check {
        rejections shouldEqual List(ValidationRejection("Last Name"))
      }
    }

    it("should reject with middleName") {
      Post("/person", Person("John", "Smith", Some(""), age = 25)) ~> route ~> check {
        rejections shouldEqual List(ValidationRejection("middleName"))
      }
    }

    it("should reject with Last Name, middleName, age") {
      Post("/person", Person("John", "", Some(""), age = -1)) ~> route ~> check {
        rejections shouldEqual List(ValidationRejection("Last Name, middleName, age"))
      }
    }
  }

} 
Example 6
Source File: LeagueService.scala    From eventsourcing-intro   with Apache License 2.0 5 votes vote down vote up
package eu.reactivesystems.league.api

import akka.Done
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.server.Directives

import scala.concurrent.Future


trait LeagueService extends Directives with SprayJsonSupport {


    val routes = pathPrefix("league") {
      path(Segment / "club") { leagueId =>
        post {
          entity(as[Club]) { club =>
            complete(addClub(leagueId, club))
          }
        }
      } ~
        path(Segment / "game") { leagueId =>
          post {
            entity(as[Game]) { game =>
              complete(addGame(leagueId, game))
            }
          } ~
            put {
              entity(as[Game]) { game =>
                complete(changeGame(leagueId, game))
              }
            }
        }
    }


    def addClub(leagueId: String, club: Club): Future[Done]
    def addGame(leagueId: String, game: Game): Future[Done]
    def changeGame(leagueId: String, game: Game): Future[Done]

} 
Example 7
Source File: ClusterHttpManagementProtocol.scala    From akka-management   with Apache License 2.0 5 votes vote down vote up
package akka.management.cluster

import scala.collection.immutable

import akka.annotation.InternalApi
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import spray.json.DefaultJsonProtocol
import spray.json.RootJsonFormat

final case class ClusterUnreachableMember(node: String, observedBy: immutable.Seq[String])
final case class ClusterMember(node: String, nodeUid: String, status: String, roles: Set[String])
object ClusterMember {
  implicit val clusterMemberOrdering: Ordering[ClusterMember] = Ordering.by(_.node)
}
final case class ClusterMembers(
    selfNode: String,
    members: Set[ClusterMember],
    unreachable: immutable.Seq[ClusterUnreachableMember],
    leader: Option[String],
    oldest: Option[String],
    oldestPerRole: Map[String, String])
final case class ClusterHttpManagementMessage(message: String)
final case class ShardRegionInfo(shardId: String, numEntities: Int)
final case class ShardDetails(regions: immutable.Seq[ShardRegionInfo])


@InternalApi private[akka] object ClusterHttpManagementOperation {
  def fromString(value: String): Option[ClusterHttpManagementOperation] =
    Vector(Down, Leave, Join).find(_.toString.equalsIgnoreCase(value))
}

trait ClusterHttpManagementJsonProtocol extends SprayJsonSupport with DefaultJsonProtocol {
  implicit val clusterUnreachableMemberFormat: RootJsonFormat[ClusterUnreachableMember] =
    jsonFormat2(ClusterUnreachableMember)
  implicit val clusterMemberFormat: RootJsonFormat[ClusterMember] = jsonFormat4(ClusterMember.apply)
  implicit val clusterMembersFormat: RootJsonFormat[ClusterMembers] = jsonFormat6(ClusterMembers)
  implicit val clusterMemberMessageFormat: RootJsonFormat[ClusterHttpManagementMessage] =
    jsonFormat1(ClusterHttpManagementMessage)
  implicit val shardRegionInfoFormat: RootJsonFormat[ShardRegionInfo] = jsonFormat2(ShardRegionInfo)
  implicit val shardDetailsFormat: RootJsonFormat[ShardDetails] = jsonFormat1(ShardDetails)
} 
Example 8
Source File: HttpBootstrapJsonProtocol.scala    From akka-management   with Apache License 2.0 5 votes vote down vote up
package akka.management.cluster.bootstrap.contactpoint

import akka.actor.{ Address, AddressFromURIString }
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import spray.json.{ DefaultJsonProtocol, JsString, JsValue, RootJsonFormat }

trait HttpBootstrapJsonProtocol extends SprayJsonSupport with DefaultJsonProtocol {
  import HttpBootstrapJsonProtocol._

  implicit object AddressFormat extends RootJsonFormat[Address] {
    override def read(json: JsValue): Address = json match {
      case JsString(s) => AddressFromURIString.parse(s)
      case invalid     => throw new IllegalArgumentException(s"Illegal address value! Was [$invalid]")
    }

    override def write(obj: Address): JsValue = JsString(obj.toString)
  }
  implicit val SeedNodeFormat: RootJsonFormat[SeedNode] = jsonFormat1(SeedNode)
  implicit val ClusterMemberFormat: RootJsonFormat[ClusterMember] = jsonFormat4(ClusterMember)
  implicit val ClusterMembersFormat: RootJsonFormat[SeedNodes] = jsonFormat2(SeedNodes)
}

object HttpBootstrapJsonProtocol extends DefaultJsonProtocol {

  final case class SeedNode(address: Address)

  // we use Address since we want to know which protocol is being used (tcp, artery, artery-tcp etc)
  final case class ClusterMember(node: Address, nodeUid: Long, status: String, roles: Set[String])
  implicit val clusterMemberOrdering: Ordering[ClusterMember] = Ordering.by(_.node)

  final case class SeedNodes(selfNode: Address, seedNodes: Set[ClusterMember])

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

import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.marshallers.xml.ScalaXmlSupport
import spray.json.DefaultJsonProtocol
import scala.xml._

case class Item(id: Int, quantity: Int, unitPrice: Double, percentageDiscount: Option[Double])

case class Order(id: String, timestamp: Long, items: List[Item], deliveryPrice: Double, metadata: Map[String, String])

case class GrandTotal(id: String, amount: Double)

trait OrderJsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
  implicit val itemFormat = jsonFormat4(Item)
  implicit val orderFormat = jsonFormat5(Order)
  implicit val grandTotalFormat = jsonFormat2(GrandTotal)
}

trait OrderXmlSupport extends ScalaXmlSupport {
  implicit def grandTotalToXML(g: GrandTotal): NodeSeq =
    <grandTotal><id>{g.id}</id><amount>{g.amount}</amount></grandTotal>

  implicit def orderToXML(o: Order): NodeSeq =
    <order>
      <id>{o.id}</id>
      <timestamp>{o.timestamp}</timestamp>
      <deliveryPrice>{o.deliveryPrice}</deliveryPrice>
      <items>{o.items.map(itemToXML)}</items>
      <metadata>{o.metadata.map(keyValueToXML)}</metadata>
    </order>

  implicit def orderFromXML(xmlOrder: NodeSeq): Order = {
    val id = (xmlOrder \ "id").text
    val timestamp = (xmlOrder \ "timestamp").text.toLong
    val deliveryPrice = (xmlOrder \ "deliveryPrice").text.toDouble
    val items = (xmlOrder \ "item").map(itemFromXML).toList
    val metadata = keyValueFromXML(xmlOrder \ "metadata")
    Order(id, timestamp, items, deliveryPrice, metadata)
  }

  private def keyValueFromXML(xml: NodeSeq) = {
    xml.flatMap {
      case e: Elem => e.child
      case _ => NodeSeq.Empty
    }.map(x => x.label -> x.text).toMap
  }

  private def keyValueToXML(kv: (String, String)) =
    Elem(null, kv._1, Null, TopScope, false, Text(kv._2))

  private def itemFromXML(xmlItem: NodeSeq): Item = {
    val id = (xmlItem \ "id").text.toInt
    val quantity = (xmlItem \ "quantity").text.toInt
    val unitPrice = (xmlItem \ "unitPrice").text.toDouble
    val percentageDiscount =
      if ((xmlItem \ "percentageDiscount").isEmpty) None
      else Some((xmlItem \ "percentageDiscount").text.toDouble)

    Item(id, quantity, unitPrice, percentageDiscount)
  }

  private def itemToXML(i: Item) =
    <item>
      <id>{i.id}</id>
      <quantity>{i.quantity}</quantity>
      <unitPrice>{i.unitPrice}</unitPrice>
      {if (i.percentageDiscount.isDefined) <percentageDiscount>{i.percentageDiscount.get}</percentageDiscount>}
    </item>
} 
Example 10
Source File: NodeRoutes.scala    From scalachain   with MIT License 5 votes vote down vote up
package com.elleflorio.scalachain.api

import com.elleflorio.scalachain.actor.Node._
import akka.actor.{ActorRef, ActorSystem}
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.model._
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import akka.pattern.ask
import akka.util.Timeout
import com.elleflorio.scalachain.blockchain.{Chain, Transaction}
import com.elleflorio.scalachain.cluster.ClusterManager.GetMembers
import com.elleflorio.scalachain.utils.JsonSupport._

import scala.concurrent.Future
import scala.concurrent.duration._

trait NodeRoutes extends SprayJsonSupport {

  implicit def system: ActorSystem

  def node: ActorRef
  def clusterManager: ActorRef

  implicit lazy val timeout = Timeout(5.seconds)

  lazy val statusRoutes: Route = pathPrefix("status") {
    concat(
      pathEnd {
        concat(
          get {
            val statusFuture: Future[Chain] = (node ? GetStatus).mapTo[Chain]
            onSuccess(statusFuture) { status =>
              complete(StatusCodes.OK, status)
            }
          }
        )
      },
      pathPrefix("members") {
        concat(
          pathEnd {
            concat(
              get {
                val membersFuture: Future[List[String]] = (clusterManager ? GetMembers).mapTo[List[String]]
                onSuccess(membersFuture) { members =>
                  complete(StatusCodes.OK, members)
                }
              }
            )
          }
        )
      }
    )
  }

  lazy val transactionRoutes: Route = pathPrefix("transactions") {
    concat(
      pathEnd {
        concat(
          get {
            val transactionsRetrieved: Future[List[Transaction]] =
              (node ? GetTransactions).mapTo[List[Transaction]]
            onSuccess(transactionsRetrieved) { transactions =>
              complete(transactions.toList)
            }
          },
          post {
            entity(as[Transaction]) { transaction =>
              val transactionCreated: Future[Int] =
                (node ? AddTransaction(transaction)).mapTo[Int]
              onSuccess(transactionCreated) { done =>
                complete((StatusCodes.Created, done.toString))
              }
            }
          }
        )
      }
    )
  }

  lazy val mineRoutes: Route = pathPrefix("mine") {
    concat(
      pathEnd {
        concat(
          get {
            node ! Mine
            complete(StatusCodes.OK)
          }
        )
      }
    )
  }

} 
Example 11
Source File: Routes.scala    From Pi-Akka-Cluster   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.akka_oled

import akka.actor.typed.ActorSystem
import akka.cluster.sharding.typed.scaladsl.ClusterSharding
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.server.Directives.{as, complete, concat, entity, get, onSuccess, pathPrefix, post, _}
import akka.http.scaladsl.server.Route
import akka.util.Timeout
import com.lightbend.akka_oled.ClientEntity.{Get, PostPoints}
import com.lightbend.akka_oled.Main.AddPoints

import scala.concurrent.duration._

object Routes {

  case class NodeStatus(status: String)

}

class Routes(sharding: ClusterSharding)(implicit system: ActorSystem[_]) extends SprayJsonSupport {
  implicit val timeout: Timeout = 8.seconds
  implicit val scheduler = system.scheduler

  lazy val route: Route =
    pathPrefix("user" / "[0-9a-zA-Z]+".r) { username =>
      concat(
        get {
          val entityRef = sharding.entityRefFor(ClientEntity.TypeKey, username)
          onSuccess(entityRef ? Get(username)) {
            value: Int => complete(value.toString + "\n")
          }
        },
        post {
          entity(as[AddPoints]) { transaction =>
            val entityRef = sharding.entityRefFor(ClientEntity.TypeKey, username)
            onSuccess(entityRef ? PostPoints(username, transaction.points)) {
              result => complete(result)
            }
          }
        }
      )
    }

} 
Example 12
Source File: Main.scala    From Pi-Akka-Cluster   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.akka_oled

import akka.NotUsed
import akka.actor.typed.scaladsl.Behaviors
import akka.actor.typed.scaladsl.adapter.TypedActorSystemOps
import akka.actor.typed.{ActorSystem, Behavior, Terminated}
import akka.cluster.sharding.typed.scaladsl.{ClusterSharding, Entity}
import akka.http.scaladsl.Http
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.management.scaladsl.AkkaManagement
import akka.persistence.typed.PersistenceId
import akka.stream.Materializer
import akkapi.cluster.{ClusterStatusTracker, OledClusterVisualizer, OledDriver, Settings}
import spray.json._

import scala.concurrent.ExecutionContextExecutor

object Main extends SprayJsonSupport with DefaultJsonProtocol {

  case class AddPoints(points: Int)

  implicit val transactionFormat = jsonFormat1(AddPoints)

  def apply(settings: Settings): Behavior[NotUsed] = Behaviors.setup { ctx =>
    implicit val system = ctx.system
    implicit val untypedSystem: akka.actor.ActorSystem = ctx.system.toClassic
    implicit val ec: ExecutionContextExecutor = ctx.system.executionContext

    val oledDriver = ctx.spawn(OledDriver(settings), "oled-driver")
    oledDriver ! OledDriver.RegisterView("Cluster State", 0)
    oledDriver ! OledDriver.RegisterView("Sharding State", 1)

    val clusterView = ctx.spawn(OledClusterVisualizer(0, settings, oledDriver), "oled-cluster-view")
    val clusterStatusTracker = ctx.spawn(ClusterStatusTracker(settings, None), "cluster-status-tracker")
    clusterStatusTracker ! ClusterStatusTracker.SubscribeVisualiser(clusterView)

    val shardVisualizer = ctx.spawn(OledShardingVisualizer(1, oledDriver), "oled-sharding-view")

    val sharding = ClusterSharding(ctx.system)
    sharding.init(Entity(typeKey = ClientEntity.TypeKey) { entityContext =>
      ClientEntity(entityContext.entityId,
        PersistenceId(entityContext.entityTypeKey.name, entityContext.entityId),
        shardVisualizer)
    })
    val tracker = ctx.spawn(ShardStateTracker(shardVisualizer), "oled-sharding-tracker")
    ctx.spawn(ShardStateScheduler(sharding.shardState, tracker), "oled-sharding-scheduler")

    val routes = new Routes(sharding)

    //materializer
    Materializer.createMaterializer(ctx.system.toClassic)
    implicit val mat: Materializer = Materializer.createMaterializer(ctx.system.toClassic)
    Http()(ctx.system.toClassic).bindAndHandle(routes.route,
      settings.config.getString("cluster-node-configuration.external-ip"), 8080)

    Behaviors.receiveSignal {
      case (_, Terminated(_)) =>
        Behaviors.stopped
    }
  }
}

object DisplayClusterShardingMain {
  def main(args: Array[String]): Unit = {
    val settings = Settings()
    val system = ActorSystem[NotUsed](Main(settings), "akka-oled", settings.config)

    // Start Akka HTTP Management extension
    AkkaManagement(system).start()
  }
} 
Example 13
Source File: Routes.scala    From Pi-Akka-Cluster   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.akka_oled

import akka.actor.typed.scaladsl.AskPattern._
import akka.actor.typed.{ActorRef, ActorSystem}
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.server.Directives.{as, complete, concat, entity, get, onSuccess, pathPrefix, post, _}
import akka.http.scaladsl.server.Route
import akka.util.Timeout
import com.lightbend.akka_oled.DistributedDataTracker.{Get, UpdateStatus}
import com.lightbend.akka_oled.Main.NodeStatus

import scala.concurrent.duration._

class Routes(tracker: ActorRef[DistributedDataTracker.Command])(implicit system: ActorSystem[_]) extends SprayJsonSupport {
  implicit val timeout: Timeout = 8.seconds

  val route: Route =
    pathPrefix("status" / "[0-9a-zA-Z]+".r) {
      node =>
        concat(
          get {
            onSuccess(tracker.ask[String](Get(node, _))) {
              value => complete(value + "\n")
            }
          },
          post {
            entity(as[NodeStatus]) { status =>
              tracker ! UpdateStatus(node, status.status)
              complete("Ok\n")
            }
          }
        )
    }

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

package com.daml.navigator

import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import spray.json.DefaultJsonProtocol

case class ApplicationInfo(
    id: String,
    name: String,
    version: String
)

trait ApplicationInfoJsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
  implicit val applicationInfoFormat = jsonFormat3(ApplicationInfo)
} 
Example 15
Source File: TryRoute.scala    From akka-http-test   with Apache License 2.0 5 votes vote down vote up
package com.github.dnvriend.component.simpleserver.route

import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.server.{ Directives, Route }
import spray.json.DefaultJsonProtocol

import scala.util.Try

object TryRoute extends Directives with SprayJsonSupport with DefaultJsonProtocol {
  def route: Route = {
    pathPrefix("try") {
      (get & path("failure")) {
        complete(Try((1 / 0).toString))
      } ~
        (get & path("success")) {
          complete(Try(1.toString))
        }
    }
  }
} 
Example 16
Source File: JsonStreamingRoute.scala    From akka-http-test   with Apache License 2.0 5 votes vote down vote up
package com.github.dnvriend.component.simpleserver.route

import akka.event.LoggingAdapter
import akka.http.scaladsl.common.{ EntityStreamingSupport, JsonEntityStreamingSupport }
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.server.{ Directives, Route }
import akka.stream.Materializer
import akka.stream.scaladsl.Flow
import akka.util.ByteString
import com.github.dnvriend.component.repository.PersonRepository
import com.github.dnvriend.component.simpleserver.dto.http.Person
import com.github.dnvriend.component.simpleserver.marshaller.Marshallers

import scala.concurrent.ExecutionContext

object JsonStreamingRoute extends Directives with SprayJsonSupport with Marshallers {
  val start = ByteString.empty
  val sep = ByteString("\n")
  val end = ByteString.empty

  implicit val jsonStreamingSupport: JsonEntityStreamingSupport = EntityStreamingSupport.json()
    .withFramingRenderer(Flow[ByteString].intersperse(start, sep, end))
    .withParallelMarshalling(parallelism = 8, unordered = true)

  def route(dao: PersonRepository)(implicit mat: Materializer, ec: ExecutionContext): Route =
    path("stream" / IntNumber) { numberOfPersons =>
      (get & pathEnd) {
        complete(dao.people(numberOfPersons))
      }
    } ~
      (post & path("stream") & entity(asSourceOf[Person])) { people =>
        val total = people.log("people").runFold(0) { case (c, _) => c + 1 }
        complete(total.map(n => s"Received $n number of person"))
      }
} 
Example 17
Source File: RestRoute.scala    From akka-http-test   with Apache License 2.0 5 votes vote down vote up
package com.github.dnvriend.component.highlevelserver.route

import akka.actor.ActorRef
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.marshalling.ToResponseMarshaller
import akka.http.scaladsl.model.{ StatusCodes, Uri }
import akka.http.scaladsl.server.{ Directives, Route }
import akka.http.scaladsl.unmarshalling.FromRequestUnmarshaller
import akka.pattern.ask
import akka.util.Timeout
import com.github.dnvriend.component.highlevelserver.dto.PersonWithId
import com.github.dnvriend.component.highlevelserver.marshaller.Marshaller
import com.github.dnvriend.component.simpleserver.dto.http.Person

import scala.concurrent.Future

// see: akka.http.scaladsl.marshalling.ToResponseMarshallable
// see: akka.http.scaladsl.marshalling.PredefinedToResponseMarshallers
object RestRoute extends Directives with SprayJsonSupport with Marshaller {
  def routes(personDb: ActorRef)(implicit timeout: Timeout, trmSingle: ToResponseMarshaller[PersonWithId], trmList: ToResponseMarshaller[List[PersonWithId]], fru: FromRequestUnmarshaller[Person]): Route = {
    pathEndOrSingleSlash {
      redirect(Uri("/api/person"), StatusCodes.PermanentRedirect)
    } ~
      pathPrefix("api" / "person") {
        get {
          path(IntNumber) { id =>
            println(s"PathEndsInNumber=$id")
            complete((personDb ? "findAll").mapTo[List[PersonWithId]])
          } ~
            pathEndOrSingleSlash {
              parameter("foo") { foo =>
                println(s"foo=$foo")
                complete((personDb ? "findAll").mapTo[List[PersonWithId]])
              } ~
                parameter('bar) { bar =>
                  println(s"bar=$bar")
                  complete((personDb ? "findAll").mapTo[List[PersonWithId]])
                } ~
                complete((personDb ? "findAll").mapTo[List[PersonWithId]])
            }
        } ~
          (post & pathEndOrSingleSlash & entity(as[Person])) { person =>
            complete((personDb ? person).mapTo[PersonWithId])
          }
      } ~
      path("failure") {
        pathEnd {
          complete(Future.failed[String](new RuntimeException("Simulated Failure")))
        }
      } ~
      path("success") {
        pathEnd {
          complete(Future.successful("Success!!"))
        }
      }
  }
} 
Example 18
Source File: JsonSupport.scala    From Learn-Scala-Programming   with MIT License 5 votes vote down vote up
package ch14

import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import ch14.Commands._
import ch14.Events._
import spray.json.{DefaultJsonProtocol, RootJsonFormat}
import stamina.StaminaAkkaSerializer
import stamina.json._

trait JsonSupport extends SprayJsonSupport {

  import DefaultJsonProtocol._

  type RJF[T] = RootJsonFormat[T]

  implicit val createArticleJF: RJF[CreateArticle] = jsonFormat2(CreateArticle)
  implicit val deleteArticleJF: RJF[DeleteArticle] = jsonFormat1(DeleteArticle)
  implicit val purchaseJF: RJF[PurchaseArticles] = jsonFormat1(PurchaseArticles)
  implicit val restockJF: RJF[RestockArticles] = jsonFormat1(RestockArticles)

  implicit val createdJF: RJF[ArticleCreated] = jsonFormat2(ArticleCreated)
  implicit val deletedJF: RJF[ArticleDeleted] = jsonFormat1(ArticleDeleted)
  implicit val pJF: RJF[ArticlesPurchased] = jsonFormat1(ArticlesPurchased)
  implicit val reJF: RJF[ArticlesRestocked] = jsonFormat1(ArticlesRestocked)

  implicit val invJF: RJF[Inventory] = jsonFormat1(Inventory)

}

object PersistenceSupport extends JsonSupport {
  val v1createdP = persister[ArticleCreated]("article-created")
  val v1deletedP = persister[ArticleDeleted]("article-deleted")
  val v1purchasedP = persister[ArticlesPurchased]("articles-purchased")
  val v1restockedP = persister[ArticlesRestocked]("articles-restocked")
  val v1inventoryP = persister[Inventory]("inventory")
}

import PersistenceSupport._

class EventSerializer
    extends StaminaAkkaSerializer(v1createdP,
                                  v1deletedP,
                                  v1purchasedP,
                                  v1restockedP,
                                  v1inventoryP) 
Example 19
Source File: DropwizardMarshallersSpec.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 akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.testkit.ScalatestRouteTest
import fr.davit.akka.http.metrics.core.HttpMetricsRegistry.StatusGroupDimension
import fr.davit.akka.http.metrics.core.scaladsl.server.HttpMetricsDirectives._
import fr.davit.akka.http.metrics.dropwizard.DropwizardRegistry
import org.scalatest.BeforeAndAfterAll
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import spray.json.{DefaultJsonProtocol, JsValue}

import scala.concurrent.duration._

class DropwizardMarshallersSpec extends AnyFlatSpec with Matchers with ScalatestRouteTest with BeforeAndAfterAll {

  private case class JsonResponse(metrics: Map[String, JsValue])

  private trait Fixture extends SprayJsonSupport with DefaultJsonProtocol with DropwizardMarshallers {
    implicit val metricsFormat = jsonFormat1(JsonResponse)

    val registry = DropwizardRegistry()
    registry.underlying.counter("other.metric")
  }

  override def afterAll(): Unit = {
    cleanUp()
    super.afterAll()
  }

  "DropwizardMarshallers" should "expose metrics as json format" in new Fixture {
    // use metrics so they appear in the report
    val dimensions = Seq(StatusGroupDimension(StatusCodes.OK))
    registry.requests.inc()
    registry.receivedBytes.update(10)
    registry.active.inc()
    registry.responses.inc(dimensions)
    registry.errors.inc()
    registry.duration.observe(1.second, dimensions)
    registry.sentBytes.update(10)

    Get() ~> metrics(registry) ~> check {
      val json = responseAs[JsonResponse]
      // println(json)
      json.metrics.keys should contain theSameElementsAs Seq(
        "akka.http.requests.active",
        "akka.http.requests",
        "akka.http.requests.bytes",
        "akka.http.responses{status=2xx}",
        "akka.http.responses.errors",
        "akka.http.responses.duration{status=2xx}",
        "akka.http.responses.bytes",
        "other.metric"
      ).toSet
    }
  }

} 
Example 20
Source File: JsonSupport.scala    From darwin   with Apache License 2.0 5 votes vote down vote up
package it.agilelab.darwin.server.rest

import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import org.apache.avro.Schema
import spray.json.{DefaultJsonProtocol, JsObject, JsString, JsValue, JsonParser, PrettyPrinter, RootJsonFormat}

trait JsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
  implicit val printer: PrettyPrinter.type = PrettyPrinter

  implicit val schemaFormat: RootJsonFormat[Schema] = new RootJsonFormat[Schema] {

    override def write(obj: Schema): JsValue = JsonParser(obj.toString(true))

    override def read(json: JsValue): Schema = new Schema.Parser().parse(json.prettyPrint)
  }

  implicit val schemaWithIdFormat: RootJsonFormat[(Long, Schema)] = new RootJsonFormat[(Long, Schema)] {

    override def write(obj: (Long, Schema)): JsValue = JsObject(Map(
      "id" -> JsString(obj._1.toString),
      "schema" -> schemaFormat.write(obj._2)
    ))

    override def read(json: JsValue): (Long, Schema) = json match {
      case JsObject(fields) =>
        val id = fields.get("id") match {
          case Some(JsString(number)) => number
          case _ => throw new Exception("Id field should be a long")
        }

        val schema = fields.get("schema") match {
          case Some(x@JsObject(_)) => x
          case _ => throw new Exception("schema should be an object")
        }

        (id.toLong, schemaFormat.read(schema))
      case _ => throw new Exception("should be an object")
    }
  }
} 
Example 21
Source File: AWSMessageEvent.scala    From rokku   with Apache License 2.0 5 votes vote down vote up
package com.ing.wbaa.rokku.proxy.data

import java.time.Instant

import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.model.{ HttpMethod, StatusCode }
import com.ing.wbaa.rokku.proxy.handler.parsers.RequestParser.{ AWSRequestType, MultipartRequestType }
import com.ing.wbaa.rokku.proxy.provider.aws.{ S3ObjectAction, s3MultipartUpload, s3MultipartUploadComplete }
import spray.json.DefaultJsonProtocol

case class Records(records: List[AWSMessageEvent])

case class UserIdentity(principalId: String)

case class RequestParameters(sourceIPAddress: String)

case class ResponseElements(`x-amz-request-id`: String, `x-amz-id-2`: String)

case class OwnerIdentity(principalId: String)

case class BucketProps(name: String, ownerIdentity: OwnerIdentity, arn: String)

case class ObjectProps(key: String, size: Int, eTag: String, versionId: String, sequencer: String)

case class S3(s3SchemaVersion: String, configurationId: String, bucket: BucketProps, `object`: ObjectProps)

case class AWSMessageEvent(
    eventVersion: String,
    eventSource: String,
    awsRegion: String,
    eventTime: String,
    eventName: String,
    userIdentity: UserIdentity,
    requestParameters: RequestParameters,
    responseElements: ResponseElements,
    s3: S3
)

trait AWSMessageEventJsonSupport extends SprayJsonSupport with DefaultJsonProtocol {

  implicit val ownerIdentityFormat = jsonFormat1(OwnerIdentity)
  implicit val bucketFormat = jsonFormat3(BucketProps)
  implicit val objectPropsFormat = jsonFormat5(ObjectProps)
  implicit val s3Format = jsonFormat4(S3)
  implicit val userIdentityFormat = jsonFormat1(UserIdentity)
  implicit val requestParametersFormat = jsonFormat1(RequestParameters)
  implicit val responseElementsFormat = jsonFormat2(ResponseElements)
  implicit val AWSMessageEventFormat = jsonFormat9(AWSMessageEvent)
  implicit val recordsFormat = jsonFormat1(Records)

  import spray.json._

  def prepareAWSMessage(s3Request: S3Request, method: HttpMethod, principalId: String,
      userIPs: UserIps, s3Action: S3ObjectAction,
      requestId: RequestId, responseStatus: StatusCode, awsRequest: AWSRequestType): Option[JsValue] = {

    val toMultipartRequest: AWSRequestType => Option[MultipartRequestType] = {
      case r: MultipartRequestType => Some(r)
      case _                       => None
    }

    val uploadId: Option[String] = toMultipartRequest(awsRequest).map(_.uploadId)
    val multipartOrS3Action = toMultipartRequest(awsRequest) match {
      case Some(r) => if (r.completeMultipartUpload) s3MultipartUploadComplete(method.value) else s3MultipartUpload(method.value)
      case None    => s3Action
    }

    for {
      bucketPath <- s3Request.s3BucketPath
      s3object <- s3Request.s3Object
    } yield Records(List(AWSMessageEvent(
      "2.1",
      "rokku:s3",
      "us-east-1",
      Instant.now().toString,
      multipartOrS3Action.value,
      UserIdentity(principalId),
      RequestParameters(userIPs.toString),
      ResponseElements(requestId.value, responseStatus.value),
      S3("1.0", "",
        BucketProps(bucketPath, OwnerIdentity(""), ""),
        ObjectProps(s3object, 0, "", "", uploadId.getOrElse("")))))
    ).toJson
  }

} 
Example 22
Source File: HydraJsonSupport.scala    From hydra   with Apache License 2.0 5 votes vote down vote up
package hydra.core.marshallers

import java.io.{PrintWriter, StringWriter}
import java.util.UUID

import akka.actor.ActorPath
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.model.StatusCode
import hydra.common.util.Resource._
import org.joda.time.DateTime
import org.joda.time.format.ISODateTimeFormat
import spray.json.{JsString, _}

import scala.util.{Failure, Success, Try}


  implicit def tryWriter[R: JsonWriter]: RootJsonWriter[Try[R]] =
    new RootJsonWriter[Try[R]] {

      override def write(responseTry: Try[R]): JsValue = {
        responseTry match {
          case Success(r) => JsObject("success" -> r.toJson)
          case Failure(t) => JsObject("failure" -> t.toJson)
        }
      }
    }

  implicit object StreamTypeFormat extends RootJsonFormat[StreamType] {

    def read(json: JsValue): StreamType = json match {
      case JsString("Notification") => Notification
      case JsString("History")      => History
      case JsString("CurrentState") => CurrentState
      case JsString("Telemetry")    => Telemetry
      case _ => {
        import scala.reflect.runtime.{universe => ru}
        val tpe = ru.typeOf[StreamType]
        val clazz = tpe.typeSymbol.asClass
        throw new DeserializationException(
          s"expected a streamType of ${clazz.knownDirectSubclasses}, but got $json"
        )
      }
    }

    def write(obj: StreamType): JsValue = {
      JsString(obj.toString)
    }
  }

  implicit val genericErrorFormat = jsonFormat2(GenericError)

  implicit val topicCreationMetadataFormat = jsonFormat8(TopicMetadataRequest)

  implicit val genericSchemaFormat = jsonFormat2(GenericSchema)

}

case class GenericError(status: Int, errorMessage: String)

case class TopicMetadataRequest(
    schema: JsObject,
    streamType: StreamType,
    derived: Boolean,
    deprecated: Option[Boolean],
    dataClassification: String,
    contact: String,
    additionalDocumentation: Option[String],
    notes: Option[String]
)

case class GenericSchema(name: String, namespace: String) {
  def subject = s"$namespace.$name"
}

sealed trait StreamType
case object Notification extends StreamType
case object CurrentState extends StreamType
case object History extends StreamType
case object Telemetry extends StreamType 
Example 23
Source File: HydraIngestJsonSupportSpec.scala    From hydra   with Apache License 2.0 5 votes vote down vote up
package hydra.ingest.http

import akka.actor.ActorPath
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import hydra.core.HydraException
import hydra.core.ingest.IngestionReport
import hydra.core.protocol.{
  IngestorCompleted,
  IngestorError,
  IngestorStatus,
  InvalidRequest
}
import hydra.ingest.IngestorInfo
import org.joda.time.DateTime
import org.scalatest.matchers.should.Matchers
import org.scalatest.funspec.AnyFunSpecLike

class HydraIngestJsonSupportSpec
    extends Matchers
    with AnyFunSpecLike
    with HydraIngestJsonSupport
    with SprayJsonSupport {

  import spray.json._

  describe("Hydra Json Support") {
    it("converts IngestorInfo objects") {
      val time = DateTime.now
      val info = IngestorInfo(
        "test",
        "test",
        ActorPath.fromString("akka://hydra/test/ingestor"),
        time
      )
      val expectedValue =
        s"""{"name":"test","group":"test","path":"akka://hydra/test/ingestor",
          "registeredAt":${time.toJson}}""".parseJson
      info.toJson shouldBe expectedValue
    }

    it("converts IngestorStatus objects") {
      val st = InvalidRequest(new IllegalArgumentException("error"))
        .asInstanceOf[IngestorStatus]
      val stn = InvalidRequest(new IllegalArgumentException())
        .asInstanceOf[IngestorStatus]
      st.toJson shouldBe """{"code":400,"message":"error"}""".parseJson
      stn.toJson shouldBe """{"code":400,"message":"Unknown error."}""".parseJson
      intercept[NotImplementedError] {
        """{"code":400,"message":"error"}""".parseJson.convertTo[IngestorStatus]
      }
    }

    it("converts IngestorError objects with no message") {
      val st = IngestorError(new IllegalArgumentException("error"))
        .asInstanceOf[IngestorStatus]
      val stn = IngestorError(new IllegalArgumentException(""))
        .asInstanceOf[IngestorStatus]
      val stnCause = IngestorError(
        new HydraException("hydra", new IllegalArgumentException("underlying"))
      ).asInstanceOf[IngestorStatus]
      st.toJson shouldBe """{"code":503,"message":"error"}""".parseJson
      stn.toJson shouldBe """{"code":503,"message":""}""".parseJson
      stnCause.toJson shouldBe """{"code":503,"message":"hydra: underlying"}""".parseJson
    }

    it("converts IngestionReport objects") {
      val report =
        IngestionReport("a123", Map("testIngestor" -> IngestorCompleted), 200)
      val json = report.toJson.asJsObject.fields

      val pjson =
        """{"correlationId":"a123","ingestors":{"testIngestor":{"code":200,"message":"OK"}}}""".parseJson.asJsObject.fields

      json("correlationId") shouldBe pjson("correlationId")
      json("ingestors") shouldBe pjson("ingestors")

      intercept[NotImplementedError] {
        """{"correlationId":"1","ingestors":{"testIngestor":{"code":200,
          "message":"OK"}}}""".parseJson.convertTo[IngestionReport]
      }
    }

    it("converts IngestionReport without any ingestors") {
      val report = IngestionReport("1", Map.empty, 200)
      val json = report.toJson.asJsObject.fields

      val pjson =
        """{"correlationId":"1","ingestors":{}}""".parseJson.asJsObject.fields

      json("correlationId") shouldBe pjson("correlationId")
      json("ingestors") shouldBe pjson("ingestors")

    }
  }

} 
Example 24
Source File: JsonSupport.scala    From akka-http-slick-sample   with MIT License 5 votes vote down vote up
package net.softler.data.model

import java.sql.Timestamp
import java.time.Instant
import java.util.UUID

import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import spray.json.{DefaultJsonProtocol, JsNumber, JsString, JsValue, JsonFormat, RootJsonFormat}

trait BaseJsonProtocol extends DefaultJsonProtocol {
  implicit val timestampFormat: JsonFormat[Timestamp] = new JsonFormat[Timestamp] {
    override def write(obj: Timestamp): JsValue = JsNumber(obj.getTime)

    override def read(json: JsValue): Timestamp = json match {
      case JsNumber(x) => Timestamp.from(Instant.ofEpochMilli(x.toLong))
      case _ =>
        throw new IllegalArgumentException(
          s"Can not parse json value [$json] to a timestamp object")
    }
  }

  implicit val uuidJsonFormat: JsonFormat[UUID] = new JsonFormat[UUID] {
    override def write(x: UUID): JsValue = JsString(x.toString)

    override def read(value: JsValue): UUID = value match {
      case JsString(x) => UUID.fromString(x)
      case x =>
        throw new IllegalArgumentException("Expected UUID as JsString, but got " + x.getClass)
    }
  }
}


trait JsonProtocol extends SprayJsonSupport with BaseJsonProtocol {
  implicit val userFormat: RootJsonFormat[User] = jsonFormat10(User)
} 
Example 25
Source File: HTTPResponseStream.scala    From akka_streams_tutorial   with MIT License 5 votes vote down vote up
package akkahttp

import akka.NotUsed
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.common.{EntityStreamingSupport, JsonEntityStreamingSupport}
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.model._
import akka.http.scaladsl.server.Directives.{complete, get, logRequestResult, path, _}
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.ThrottleMode
import akka.stream.scaladsl.{Flow, Sink, Source}
import com.typesafe.config.ConfigFactory
import spray.json.DefaultJsonProtocol

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


object HTTPResponseStream extends App with DefaultJsonProtocol with SprayJsonSupport {
  implicit val system = ActorSystem("HTTPResponseStream")
  implicit val executionContext = system.dispatcher

  //JSON Protocol and streaming support
  final case class ExamplePerson(name: String)

  implicit def examplePersonFormat = jsonFormat1(ExamplePerson.apply)

  implicit val jsonStreamingSupport: JsonEntityStreamingSupport = EntityStreamingSupport.json()

  val (address, port) = ("127.0.0.1", 8080)
  server(address, port)
  client(address, port)

  def client(address: String, port: Int): Unit = {
    val requestParallelism = ConfigFactory.load.getInt("akka.http.host-connection-pool.max-connections")

    val requests: Source[HttpRequest, NotUsed] = Source
      .fromIterator(() =>
        Range(0, requestParallelism).map(i => HttpRequest(uri = Uri(s"http://$address:$port/download/$i"))).iterator
      )

    // Run singleRequest and completely consume response elements
    def runRequestDownload(req: HttpRequest) =
      Http()
        .singleRequest(req)
        .flatMap { response =>
          val unmarshalled: Future[Source[ExamplePerson, NotUsed]] = Unmarshal(response).to[Source[ExamplePerson, NotUsed]]
          val source: Source[ExamplePerson, Future[NotUsed]] = Source.futureSource(unmarshalled)
          source.via(processorFlow).runWith(printSink)
        }

    requests
      .mapAsync(requestParallelism)(runRequestDownload)
      .runWith(Sink.ignore)
  }


  val printSink = Sink.foreach[ExamplePerson] { each: ExamplePerson => println(s"Client processed element: $each") }

  val processorFlow: Flow[ExamplePerson, ExamplePerson, NotUsed] = Flow[ExamplePerson].map {
    each: ExamplePerson => {
      //println(s"Process: $each")
      each
    }
  }


  def server(address: String, port: Int): Unit = {

    def routes: Route = logRequestResult("httpecho") {
      path("download" / Segment) { id: String =>
        get {
          println(s"Server received request with id: $id, stream response...")
          extractRequest { r: HttpRequest =>
            val finishedWriting = r.discardEntityBytes().future
            onComplete(finishedWriting) { done =>
              //Limit response by appending eg .take(5)
              val responseStream: Stream[ExamplePerson] = Stream.continually(ExamplePerson(s"request:$id"))
              complete(Source(responseStream).throttle(1, 1.second, 1, ThrottleMode.shaping))
            }
          }
        }
      }
    }

    val bindingFuture = Http().bindAndHandle(routes, address, port)
    bindingFuture.onComplete {
      case Success(b) =>
        println("Server started, listening on: " + b.localAddress)
      case Failure(e) =>
        println(s"Server could not bind to: $address:$port. Exception message: ${e.getMessage}")
        system.terminate()
    }
  }
}