/http_api/src/main/scala/io/vamp/http_api/HttpApiBootstrap.scala

https://github.com/magneticio/vamp · Scala · 110 lines · 86 code · 24 blank · 0 comment · 2 complexity · 682e85a844481a2e70645d1faa3cd111 MD5 · raw file

  1. package io.vamp.http_api
  2. import java.io.FileInputStream
  3. import java.security.{ KeyStore, SecureRandom }
  4. import javax.net.ssl.{ KeyManagerFactory, SSLContext, TrustManagerFactory }
  5. import akka.actor.{ ActorRef, ActorSystem, Props }
  6. import akka.http.scaladsl.Http.ServerBinding
  7. import akka.http.scaladsl.server.Route
  8. import akka.http.scaladsl.{ ConnectionContext, Http }
  9. import akka.stream.{ ActorMaterializer, Materializer }
  10. import akka.util.Timeout
  11. import io.vamp.common.akka.{ ActorBootstrap, IoC }
  12. import io.vamp.common.{ Config, Namespace }
  13. import io.vamp.http_api.ws.WebSocketActor
  14. import scala.concurrent.{ ExecutionContext, Future }
  15. class HttpApiBootstrap extends ActorBootstrap {
  16. private var binding: Option[ServerBinding] = None
  17. protected def routes(implicit namespace: Namespace, actorSystem: ActorSystem, materializer: Materializer): Route = new HttpApiRoute().allRoutes
  18. def createActors(implicit actorSystem: ActorSystem, namespace: Namespace, timeout: Timeout): Future[List[ActorRef]] = {
  19. IoC.createActor(Props(classOf[WebSocketActor], true, true, 2)).map(_ :: Nil)(actorSystem.dispatcher)
  20. }
  21. override def start(implicit actorSystem: ActorSystem, namespace: Namespace, timeout: Timeout): Future[Unit] = {
  22. implicit lazy val materializer: ActorMaterializer = ActorMaterializer()
  23. implicit val executionContext: ExecutionContext = actorSystem.dispatcher
  24. super.start.flatMap { _
  25. val (interface, port) = (Config.string("vamp.http-api.interface")(), Config.int("vamp.http-api.port")())
  26. val sslEnabled = Config.has("vamp.http-api.ssl")(namespace)() && Config.boolean("vamp.http-api.ssl")()
  27. lazy val validSslConfig = sslEnabled &&
  28. Config.has("vamp.http-api.certificate")(namespace)() &&
  29. new java.io.File(Config.string("vamp.http-api.certificate")()).exists
  30. sslEnabled match {
  31. case true if !validSslConfig
  32. logger.error("SSL enabled, but invalid configuration (check certificate)")
  33. binding = None
  34. Future.successful(())
  35. case true
  36. logger.info(s"Binding: https://$interface:$port")
  37. val certificatePath = Config.string("vamp.http-api.certificate")()
  38. val https = httpsContext(certificatePath)
  39. Http().setDefaultServerHttpContext(https)
  40. try {
  41. Http().bindAndHandle(routes, interface, port, connectionContext = https).map { handle binding = Option(handle) }
  42. }
  43. catch {
  44. case e: Exception
  45. e.printStackTrace()
  46. Future.failed(e)
  47. }
  48. case _
  49. logger.info(s"Binding: http://$interface:$port")
  50. try {
  51. Http().bindAndHandle(routes, interface, port).map { handle binding = Option(handle) }
  52. }
  53. catch {
  54. case e: Exception
  55. e.printStackTrace()
  56. Future.failed(e)
  57. }
  58. }
  59. }
  60. }
  61. override def restart(implicit actorSystem: ActorSystem, namespace: Namespace, timeout: Timeout): Future[Unit] = Future.successful(())
  62. override def stop(implicit actorSystem: ActorSystem, namespace: Namespace): Future[Unit] = {
  63. implicit val executionContext: ExecutionContext = actorSystem.dispatcher
  64. binding.map { server
  65. info(s"Unbinding API")
  66. server.unbind().flatMap { _
  67. Http().shutdownAllConnectionPools()
  68. super.stop
  69. }
  70. } getOrElse super.stop
  71. }
  72. private def httpsContext(certificatePath: String) = {
  73. val password = Array[Char]()
  74. val keyStore = KeyStore.getInstance("PKCS12")
  75. val certificate = new FileInputStream(certificatePath)
  76. keyStore.load(certificate, password)
  77. certificate.close()
  78. val keyManagerFactory = KeyManagerFactory.getInstance("SunX509")
  79. keyManagerFactory.init(keyStore, password)
  80. val trustManagerFactory = TrustManagerFactory.getInstance("SunX509")
  81. trustManagerFactory.init(keyStore)
  82. val sslContext = SSLContext.getInstance("TLS")
  83. sslContext.init(keyManagerFactory.getKeyManagers, trustManagerFactory.getTrustManagers, new SecureRandom)
  84. ConnectionContext.https(sslContext)
  85. }
  86. }