/eclair-node/src/main/scala/fr/acinq/eclair/Boot.scala

https://github.com/ACINQ/eclair · Scala · 98 lines · 62 code · 11 blank · 25 comment · 6 complexity · 39b9e9a5841abf5453cfaa486aea4d19 MD5 · raw file

  1. /*
  2. * Copyright 2019 ACINQ SAS
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package fr.acinq.eclair
  17. import java.io.File
  18. import akka.actor.ActorSystem
  19. import akka.http.scaladsl.Http
  20. import akka.stream.{ActorMaterializer, BindFailedException}
  21. import fr.acinq.eclair.api.Service
  22. import grizzled.slf4j.Logging
  23. import kamon.Kamon
  24. import scala.concurrent.ExecutionContext
  25. import scala.util.{Failure, Success}
  26. /**
  27. * Created by PM on 25/01/2016.
  28. */
  29. object Boot extends App with Logging {
  30. try {
  31. val datadir = new File(System.getProperty("eclair.datadir", System.getProperty("user.home") + "/.eclair"))
  32. val config = NodeParams.loadConfiguration(datadir)
  33. val plugins = Plugin.loadPlugins(args.map(new File(_)))
  34. plugins.foreach(plugin => logger.info(s"loaded plugin ${plugin.getClass.getSimpleName}"))
  35. implicit val system: ActorSystem = ActorSystem("eclair-node", config)
  36. implicit val ec: ExecutionContext = system.dispatcher
  37. val pluginParams = plugins.flatMap(_.params)
  38. val setup = new Setup(datadir, pluginParams)
  39. if (config.getBoolean("eclair.enable-kamon")) {
  40. Kamon.init(config)
  41. }
  42. plugins.foreach(_.onSetup(setup))
  43. setup.bootstrap onComplete {
  44. case Success(kit) =>
  45. startApiServiceIfEnabled(kit)
  46. plugins.foreach(_.onKit(kit))
  47. case Failure(t) => onError(t)
  48. }
  49. } catch {
  50. case t: Throwable => onError(t)
  51. }
  52. /**
  53. * Starts the http APIs service if enabled in the configuration
  54. *
  55. * @param kit
  56. * @param system
  57. * @param ec
  58. */
  59. def startApiServiceIfEnabled(kit: Kit)(implicit system: ActorSystem, ec: ExecutionContext) = {
  60. val config = system.settings.config.getConfig("eclair")
  61. if(config.getBoolean("api.enabled")){
  62. logger.info(s"json API enabled on port=${config.getInt("api.port")}")
  63. implicit val materializer = ActorMaterializer()
  64. val apiPassword = config.getString("api.password") match {
  65. case "" => throw EmptyAPIPasswordException
  66. case valid => valid
  67. }
  68. val apiRoute = new Service {
  69. override val actorSystem = system
  70. override val mat = materializer
  71. override val password = apiPassword
  72. override val eclairApi: Eclair = new EclairImpl(kit)
  73. }.route
  74. Http().bindAndHandle(apiRoute, config.getString("api.binding-ip"), config.getInt("api.port")).recover {
  75. case _: BindFailedException => onError(TCPBindException(config.getInt("api.port")))
  76. }
  77. } else {
  78. logger.info("json API disabled")
  79. }
  80. }
  81. def onError(t: Throwable): Unit = {
  82. val errorMsg = if (t.getMessage != null) t.getMessage else t.getClass.getSimpleName
  83. System.err.println(s"fatal error: $errorMsg")
  84. logger.error(s"fatal error: $errorMsg", t)
  85. System.exit(1)
  86. }
  87. }