/src/main/scala/sangria/gateway/http/GatewayServer.scala

https://github.com/OlegIlyenko/graphql-gateway · Scala · 89 lines · 69 code · 19 blank · 1 comment · 4 complexity · 8c115f6a53d53224071d83667adef48d MD5 · raw file

  1. package sangria.gateway.http
  2. import language.postfixOps
  3. import akka.actor.ActorSystem
  4. import akka.http.scaladsl.Http
  5. import akka.stream.ActorMaterializer
  6. import play.api.libs.ws.ahc.StandaloneAhcWSClient
  7. import play.shaded.ahc.org.asynchttpclient.DefaultAsyncHttpClient
  8. import sangria.gateway.AppConfig
  9. import sangria.gateway.http.client.PlayHttpClient
  10. import sangria.gateway.schema.materializer.GatewayMaterializer
  11. import sangria.gateway.schema.materializer.directive._
  12. import sangria.gateway.schema.{ReloadableSchemaProvider, StaticSchemaProvider}
  13. import sangria.gateway.util.Logging
  14. import scala.util.{Failure, Success}
  15. import scala.util.control.NonFatal
  16. class GatewayServer extends Logging {
  17. implicit val system: ActorSystem = ActorSystem("sangria-server")
  18. implicit val materializer: ActorMaterializer = ActorMaterializer()
  19. import system.dispatcher
  20. //val client = new AkkaHttpClient
  21. val client = new PlayHttpClient(new StandaloneAhcWSClient(new DefaultAsyncHttpClient))
  22. val directiveProviders = Map(
  23. "http" new HttpDirectiveProvider(client),
  24. "graphql" new GraphQLDirectiveProvider,
  25. "faker" new FakerDirectiveProvider,
  26. "basic" new BasicDirectiveProvider)
  27. def startup(config: AppConfig) =
  28. try {
  29. val gatewayMaterializer = new GatewayMaterializer(filterDirectives(config, directiveProviders))
  30. val schemaProvider =
  31. if (config.watch.enabled)
  32. new ReloadableSchemaProvider(config, client, gatewayMaterializer)
  33. else
  34. new StaticSchemaProvider(config, client, gatewayMaterializer)
  35. schemaProvider.schemaInfo // trigger initial schema load at startup
  36. val routing = new GraphQLRouting(config, schemaProvider)
  37. Http().bindAndHandle(routing.route, config.bindHost, config.port).andThen {
  38. case Success(_)
  39. logger.info(s"Server started on ${config.bindHost}:${config.port}")
  40. if (config.watch.enabled)
  41. logger.info(s"Watching files at following path: ${config.watch.allFiles.mkString(", ")}. Looking for files: ${config.watch.allGlobs.mkString(", ")}.")
  42. case Failure(_)
  43. shutdown()
  44. }
  45. } catch {
  46. case NonFatal(error)
  47. logger.error("Error during server startup", error)
  48. shutdown()
  49. }
  50. def shutdown(): Unit = {
  51. logger.info("Shutting down server")
  52. system.terminate()
  53. }
  54. private def filterDirectives(config: AppConfig, providers: Map[String, DirectiveProvider]) = {
  55. val includes = config.allIncludeDirectives.fold(Set.empty[String])(_.toSet)
  56. val excludes = config.allExcludeDirectives.fold(Set.empty[String])(_.toSet)
  57. val initial = providers.toVector
  58. val withIncludes =
  59. if (config.allIncludeDirectives.nonEmpty)
  60. initial.filter(dp includes contains dp._1)
  61. else
  62. initial
  63. val withExcludes =
  64. if (config.allExcludeDirectives.nonEmpty)
  65. withIncludes.filterNot(dp excludes contains dp._1)
  66. else
  67. withIncludes
  68. withExcludes.map(_._2)
  69. }
  70. }