akka.http.scaladsl.server.Directives.complete Scala Examples
The following examples show how to use akka.http.scaladsl.server.Directives.complete.
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: QueryDirectivesSpec.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.admin.directives import java.net.URLEncoder import java.util.UUID import akka.http.scaladsl.model.StatusCodes import akka.http.scaladsl.server.Directives.{complete, get} import akka.http.scaladsl.server.Route import akka.http.scaladsl.testkit.ScalatestRouteTest import ch.epfl.bluebrain.nexus.admin.routes.SearchParams import ch.epfl.bluebrain.nexus.admin.routes.SearchParams.Field import ch.epfl.bluebrain.nexus.commons.http.JsonLdCirceSupport._ import ch.epfl.bluebrain.nexus.rdf.Iri.AbsoluteIri import ch.epfl.bluebrain.nexus.rdf.implicits._ import ch.epfl.bluebrain.nexus.service.config.ServiceConfig.HttpConfig import ch.epfl.bluebrain.nexus.service.config.Settings import ch.epfl.bluebrain.nexus.service.routes.Routes import ch.epfl.bluebrain.nexus.util.EitherValues import io.circe.generic.auto._ import org.mockito.IdiomaticMockito import org.scalatest.concurrent.ScalaFutures import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpecLike class QueryDirectivesSpec extends AnyWordSpecLike with ScalatestRouteTest with Matchers with ScalaFutures with EitherValues with IdiomaticMockito { private def genIri: AbsoluteIri = url"http://nexus.example.com/${UUID.randomUUID()}" private def encode(url: AbsoluteIri): String = URLEncoder.encode(url.asString, "UTF-8") private val config = Settings(system).serviceConfig implicit private val http: HttpConfig = config.http private def routes(inner: Route): Route = Routes.wrap(inner) "Query directives" should { "handle query params" in { val createdBy = genIri val updatedBy = genIri val type1 = genIri val type2 = genIri def projectParams = Routes.wrap( (get & QueryDirectives.searchParamsProjects) { params => complete(StatusCodes.OK -> params) } ) Get("/") ~> routes(projectParams) ~> check { responseAs[SearchParams] shouldEqual SearchParams.empty } Get( s"/?rev=1&deprecated=true&label=myLabel&type=${encode(type1)}&type=${encode(type2)}&createdBy=${encode(createdBy)}&updatedBy=${encode(updatedBy)}" ) ~> routes(projectParams) ~> check { responseAs[SearchParams] shouldEqual SearchParams( rev = Some(1L), deprecated = Some(true), projectLabel = Some(Field("myLabel", exactMatch = false)), types = Set(type1, type2), createdBy = Some(createdBy), updatedBy = Some(updatedBy) ) } } } }
Example 2
Source File: RestServiceInMemory.scala From kafka-with-akka-streams-kafka-streams-tutorial with Apache License 2.0 | 5 votes |
package com.lightbend.scala.akkastream.queryablestate.inmemory import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.http.scaladsl.server.Directives.{complete, get, path} import akka.http.scaladsl.server.Route import akka.stream.ActorMaterializer import scala.concurrent.ExecutionContextExecutor // import akka.util.timeout // See usage below. import com.lightbend.scala.akkastream.modelserver.stage.ModelStateStore import com.lightbend.scala.modelServer.model.ModelToServeStats import de.heikoseeberger.akkahttpjackson.JacksonSupport object RestServiceInMemory { // Serve model status: http://localhost:5500/state def startRest(service: ModelStateStore)(implicit system: ActorSystem, materializer: ActorMaterializer): Unit = { implicit val executionContext: ExecutionContextExecutor = system.dispatcher // Use with HTTP methods that accept an implicit timeout argument // implicit val timeout = Timeout(10.seconds) val host = "127.0.0.1" val port = 5500 val routes = QueriesAkkaHttpResource.storeRoutes(service) Http().bindAndHandle(routes, host, port) map { binding => println(s"Starting models observer on port ${binding.localAddress}") } recover { case ex => println(s"Models observer could not bind to $host:$port - ${ex.getMessage}") } } } object QueriesAkkaHttpResource extends JacksonSupport { def storeRoutes(service: ModelStateStore): Route = get { path("state") { val info: ModelToServeStats = service.getCurrentServingInfo complete(info) } } }
Example 3
Source File: RestServiceActors.scala From kafka-with-akka-streams-kafka-streams-tutorial with Apache License 2.0 | 5 votes |
package com.lightbend.scala.akkastream.queryablestate.actors import akka.http.scaladsl.Http import akka.http.scaladsl.server.Directives.{complete, get, onSuccess, path} import akka.actor.{ActorRef, ActorSystem} import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.Route import akka.pattern.ask import akka.stream.ActorMaterializer import akka.util.Timeout import com.lightbend.scala.akkastream.modelserver.actors.{GetModels, GetModelsResult, GetState} import com.lightbend.scala.modelServer.model.ModelToServeStats import de.heikoseeberger.akkahttpjackson.JacksonSupport import scala.concurrent.ExecutionContextExecutor import scala.concurrent.duration._ object RestServiceActors { // See http://localhost:5500/models // Then select a model shown and try http://localhost:5500/state/<model>, e.g., http://localhost:5500/state/wine def startRest(modelserver: ActorRef)(implicit system: ActorSystem, materializer: ActorMaterializer): Unit = { implicit val executionContext: ExecutionContextExecutor = system.dispatcher // Use with HTTP methods that accept an implicit timeout argument // implicit val timeout = Timeout(10.seconds) val host = "127.0.0.1" val port = 5500 val routes: Route = QueriesAkkaHttpResource.storeRoutes(modelserver) Http().bindAndHandle(routes, host, port) map { binding => println(s"Starting models observer on port ${binding.localAddress}") } recover { case ex => println(s"Models observer could not bind to $host:$port - ${ex.getMessage}") } } } object QueriesAkkaHttpResource extends JacksonSupport { implicit val askTimeout: Timeout = Timeout(30.seconds) def storeRoutes(modelserver: ActorRef): Route = get { path("state"/Segment) { datatype => onSuccess(modelserver ? GetState(datatype)) { case info: ModelToServeStats => complete(info) } } ~ path("models") { onSuccess(modelserver ? GetModels()) { case models: GetModelsResult => complete(models) } } } }
Example 4
Source File: TestServer.scala From typed-schema with Apache License 2.0 | 5 votes |
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 5
Source File: Routable.scala From typed-schema with Apache License 2.0 | 5 votes |
package ru.tinkoff.tschema.akkaHttp import akka.http.scaladsl.marshalling.ToResponseMarshaller import akka.http.scaladsl.server.Directives.complete import akka.http.scaladsl.server.Route import scala.annotation.implicitNotFound import scala.concurrent.Future @implicitNotFound("could not route ${Res} knowing that result should be ${Out}") trait Routable[Res, Out] { def route(res: => Res): Route } object Routable { implicit def single[A](implicit marshaller: ToResponseMarshaller[A]): Routable[A, A] = complete(_) implicit def future[A](implicit marshaller: ToResponseMarshaller[A]): Routable[Future[A], A] = complete(_) } @implicitNotFound("could not route ${Res} knowing that result should be ${Out}") trait RoutableIn[In, Res, Out] { def route(in: In, res: => Res): Route } object RoutableIn { implicit def byRoutable[Res, Out, In](implicit routable: Routable[Res, Out]): RoutableIn[In, Res, Out] = (_, res) => routable.route(res) }
Example 6
Source File: package.scala From nexus-kg with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.kg import akka.http.scaladsl.model.StatusCode import akka.http.scaladsl.server.Directives.complete import akka.http.scaladsl.server.{MalformedQueryParamRejection, Route} import cats.Functor import cats.data.{EitherT, OptionT} import cats.instances.future._ import ch.epfl.bluebrain.nexus.iam.client.types._ import ch.epfl.bluebrain.nexus.kg.marshallers.instances._ import ch.epfl.bluebrain.nexus.kg.resources.Rejection.NotFound.notFound import ch.epfl.bluebrain.nexus.kg.resources.{Ref, Rejection, ResourceV} import ch.epfl.bluebrain.nexus.kg.routes.OutputFormat.{DOT, Triples} import ch.epfl.bluebrain.nexus.rdf.Iri.AbsoluteIri import monix.execution.Scheduler.Implicits.global import scala.concurrent.Future package object routes { private[routes] def completeWithFormat( fetched: Future[Either[Rejection, (StatusCode, ResourceV)]] )(implicit format: NonBinaryOutputFormat): Route = completeWithFormat(EitherT(fetched)) private def completeWithFormat( fetched: EitherT[Future, Rejection, (StatusCode, ResourceV)] )(implicit format: NonBinaryOutputFormat): Route = format match { case f: JsonLDOutputFormat => implicit val format = f complete(fetched.value) case Triples => implicit val format = Triples complete(fetched.map { case (status, resource) => status -> resource.value.graph.ntriples }.value) case DOT => implicit val format = DOT complete(fetched.map { case (status, resource) => status -> resource.value.graph.dot() }.value) } private[routes] val read: Permission = Permission.unsafe("resources/read") private[routes] val schemaError = MalformedQueryParamRejection("schema", "The provided schema does not match the schema on the Uri") private[routes] implicit class FOptionSyntax[F[_], A](private val fOpt: F[Option[A]]) extends AnyVal { def toNotFound(id: AbsoluteIri)(implicit F: Functor[F]): EitherT[F, Rejection, A] = OptionT(fOpt).toRight(notFound(Ref(id))) } }
Example 7
Source File: GlobalEventRoutes.scala From nexus-kg with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.kg.routes import akka.actor.ActorSystem import akka.http.scaladsl.marshalling.sse.EventStreamMarshalling._ import akka.http.scaladsl.server.Directives.complete import akka.http.scaladsl.server.Route import ch.epfl.bluebrain.nexus.iam.client.config.IamClientConfig import ch.epfl.bluebrain.nexus.iam.client.types.{AccessControlLists, Caller, Permission} import ch.epfl.bluebrain.nexus.kg.config.AppConfig import ch.epfl.bluebrain.nexus.kg.directives.AuthDirectives._ import ch.epfl.bluebrain.nexus.kg.persistence.TaggingAdapter import ch.epfl.bluebrain.nexus.kg.resources.Event.JsonLd._ import kamon.instrumentation.akka.http.TracingDirectives.operationName class GlobalEventRoutes(acls: AccessControlLists, caller: Caller)(implicit as: ActorSystem, config: AppConfig) extends EventCommonRoutes { private val read: Permission = Permission.unsafe("events/read") private implicit val acl: AccessControlLists = acls private implicit val c: Caller = caller private implicit val iamConf: IamClientConfig = config.iam.iamClient def routes: Route = lastEventId { offset => operationName(s"/${config.http.prefix}/events") { hasPermissionOnRoot(read).apply { complete(source(TaggingAdapter.EventTag, offset)) } } } }
Example 8
Source File: VinylDNSRouteTestHelper.scala From vinyldns with Apache License 2.0 | 5 votes |
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 9
Source File: ValidatingDirectives.scala From Conseil with Apache License 2.0 | 5 votes |
package tech.cryptonomic.conseil.api.directives import akka.http.scaladsl.model.StatusCodes.Unauthorized import akka.http.scaladsl.server.Directive import akka.http.scaladsl.server.Directives.{complete, onComplete, optionalHeaderValueByName, provide} import tech.cryptonomic.conseil.api.security.Security.SecurityApi import scala.util.Success class ValidatingDirectives(securityApi: SecurityApi) { val validateApiKey: Directive[Tuple1[String]] = optionalHeaderValueByName("apikey").tflatMap[Tuple1[String]] { apiKeyTuple => val apiKey = apiKeyTuple match { case Tuple1(key) => key case _ => None } onComplete(securityApi.validateApiKey(apiKey)).flatMap { case Success(true) => provide(apiKey.getOrElse("")) case _ => complete((Unauthorized, apiKey.fold("Missing API key") { _ => "Incorrect API key" })) } } }
Example 10
Source File: ValidationRoute.scala From ohara with Apache License 2.0 | 5 votes |
package oharastream.ohara.configurator.route import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ import akka.http.scaladsl.model.{ContentTypes, _} import akka.http.scaladsl.server import akka.http.scaladsl.server.Directives.{as, complete, entity, path, pathPrefix, put, _} import oharastream.ohara.agent.WorkerCollie import oharastream.ohara.client.configurator.ConnectorApi import oharastream.ohara.client.configurator.ConnectorApi.Creation import oharastream.ohara.client.configurator.ValidationApi._ import oharastream.ohara.configurator.store.DataStore import scala.concurrent.ExecutionContext private[configurator] object ValidationRoute { def apply( implicit dataStore: DataStore, workerCollie: WorkerCollie, executionContext: ExecutionContext ): server.Route = pathPrefix(VALIDATION_KIND) { path(ConnectorApi.KIND) { put { entity(as[Creation])( req => complete( connectorAdmin(req.workerClusterKey) { (_, connectorAdmin) => connectorAdmin .connectorValidator() .settings(req.plain) .className(req.className) // the topic name is composed by group and name. However, the kafka topic is still a pure string. // Hence, we can't just push Ohara topic "key" to kafka topic "name". // The name of topic is a required for connector and hence we have to fill the filed when starting // connector. .topicKeys(req.topicKeys) // add the connector key manually since the arguments exposed to user is "group" and "name" than "key" .connectorKey(req.key) .run() }.map(settingInfo => HttpEntity(ContentTypes.`application/json`, settingInfo.toJsonString)) ) ) } } } }
Example 11
Source File: package.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.kg import akka.http.scaladsl.model.StatusCode import akka.http.scaladsl.server.Directives.complete import akka.http.scaladsl.server.{MalformedQueryParamRejection, Route} import cats.Functor import cats.data.{EitherT, OptionT} import cats.instances.future._ import ch.epfl.bluebrain.nexus.iam.types.Permission import ch.epfl.bluebrain.nexus.kg.marshallers.instances._ import ch.epfl.bluebrain.nexus.kg.resources.Rejection.NotFound.notFound import ch.epfl.bluebrain.nexus.kg.resources.{Ref, Rejection, ResourceV} import ch.epfl.bluebrain.nexus.kg.routes.OutputFormat.{DOT, Triples} import ch.epfl.bluebrain.nexus.rdf.Iri.AbsoluteIri import monix.execution.Scheduler.Implicits.global import scala.concurrent.Future package object routes { private[routes] def completeWithFormat( fetched: Future[Either[Rejection, (StatusCode, ResourceV)]] )(implicit format: NonBinaryOutputFormat): Route = completeWithFormat(EitherT(fetched)) private def completeWithFormat( fetched: EitherT[Future, Rejection, (StatusCode, ResourceV)] )(implicit format: NonBinaryOutputFormat): Route = format match { case f: JsonLDOutputFormat => implicit val format = f complete(fetched.value) case Triples => implicit val format = Triples complete(fetched.map { case (status, resource) => status -> resource.value.graph.ntriples }.value) case DOT => implicit val format = DOT complete(fetched.map { case (status, resource) => status -> resource.value.graph.dot() }.value) } private[routes] val read: Permission = Permission.unsafe("resources/read") private[routes] val schemaError = MalformedQueryParamRejection("schema", "The provided schema does not match the schema on the Uri") implicit private[routes] class FOptionSyntax[F[_], A](private val fOpt: F[Option[A]]) extends AnyVal { def toNotFound(id: AbsoluteIri)(implicit F: Functor[F]): EitherT[F, Rejection, A] = OptionT(fOpt).toRight(notFound(Ref(id))) } }
Example 12
Source File: GlobalEventRoutes.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.kg.routes import akka.actor.ActorSystem import akka.http.scaladsl.marshalling.sse.EventStreamMarshalling._ import akka.http.scaladsl.server.Directives.complete import akka.http.scaladsl.server.Route import ch.epfl.bluebrain.nexus.iam.acls.Acls import ch.epfl.bluebrain.nexus.iam.realms.Realms import ch.epfl.bluebrain.nexus.iam.types.{Caller, Permission} import ch.epfl.bluebrain.nexus.kg.persistence.TaggingAdapter import ch.epfl.bluebrain.nexus.kg.resources.Event.JsonLd._ import ch.epfl.bluebrain.nexus.service.config.ServiceConfig import ch.epfl.bluebrain.nexus.service.directives.AuthDirectives import kamon.instrumentation.akka.http.TracingDirectives.operationName import monix.eval.Task import monix.execution.Scheduler.Implicits.global class GlobalEventRoutes(acls: Acls[Task], realms: Realms[Task], caller: Caller)(implicit override val as: ActorSystem, override val config: ServiceConfig ) extends AuthDirectives(acls, realms) with EventCommonRoutes { private val read: Permission = Permission.unsafe("events/read") def routes: Route = lastEventId { offset => operationName(s"/${config.http.prefix}/events") { authorizeFor(permission = read)(caller) { complete(source(TaggingAdapter.EventTag, offset)) } } } }
Example 13
Source File: ApiVersionRoute.scala From scala-for-beginners with Apache License 2.0 | 5 votes |
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 14
Source File: ApiVersionRoute.scala From scala-for-beginners with Apache License 2.0 | 5 votes |
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 15
Source File: Routes.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
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 16
Source File: Routes.scala From Pi-Akka-Cluster with Apache License 2.0 | 5 votes |
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 17
Source File: HTTPResponseStream.scala From akka_streams_tutorial with MIT License | 5 votes |
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() } } }