/lib/src/main/scala/com/lightbend/kafka/scala/iq/http/InteractiveQueryHttpService.scala

https://github.com/lightbend/kafka-streams-query · Scala · 78 lines · 49 code · 20 blank · 9 comment · 0 complexity · 4b4e4bfc5ca517873725682828b16a56 MD5 · raw file

  1. /**
  2. * Copyright (C) 2018 Lightbend Inc. <https://www.lightbend.com>
  3. */
  4. package com.lightbend.kafka.scala.iq
  5. package http
  6. import akka.actor.ActorSystem
  7. import akka.http.scaladsl.server.Directives
  8. import akka.http.scaladsl.Http
  9. import akka.http.scaladsl.model.{ HttpRequest, HttpResponse }
  10. import akka.http.scaladsl.model.StatusCodes._
  11. import akka.http.scaladsl.server.ExceptionHandler
  12. import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport
  13. import akka.stream.ActorMaterializer
  14. import akka.stream.scaladsl.Flow
  15. import org.apache.kafka.streams.state.HostInfo
  16. import scala.concurrent.{ Future, ExecutionContext}
  17. import scala.util.{ Success, Failure }
  18. import com.typesafe.scalalogging.LazyLogging
  19. /**
  20. * The interactive http query service. Offers APIs to start and stop the service.
  21. */
  22. abstract class InteractiveQueryHttpService(hostInfo: HostInfo,
  23. actorSystem: ActorSystem,
  24. actorMaterializer: ActorMaterializer,
  25. ec: ExecutionContext)
  26. extends Directives with FailFastCirceSupport with LazyLogging {
  27. implicit val _actorSystem = actorSystem
  28. implicit val _actorMaterializer = actorMaterializer
  29. implicit val _ec = ec
  30. val myExceptionHandler = ExceptionHandler {
  31. case ex: Exception =>
  32. extractUri { uri =>
  33. logger.error(s"Request to $uri could not be handled normally", ex)
  34. complete(HttpResponse(InternalServerError, entity = "Request Failed!"))
  35. }
  36. }
  37. // define the routes
  38. val routes: Flow[HttpRequest, HttpResponse, Any]
  39. var bindingFuture: Future[Http.ServerBinding] = _
  40. // start the http server
  41. def start(): Unit = {
  42. bindingFuture = Http().bindAndHandle(routes, hostInfo.host, hostInfo.port)
  43. bindingFuture.onComplete {
  44. case Success(serverBinding) =>
  45. logger.info(s"Server bound to ${serverBinding.localAddress} ")
  46. case Failure(ex) =>
  47. logger.error(s"Failed to bind to ${hostInfo.host}:${hostInfo.port}!", ex)
  48. actorSystem.terminate()
  49. }
  50. }
  51. // stop the http server
  52. def stop(): Unit = {
  53. logger.info("Stopping the http server")
  54. bindingFuture
  55. .flatMap(_.unbind())
  56. .onComplete(_ => actorSystem.terminate())
  57. }
  58. }