forked from ing-bank/baker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Main.scala
69 lines (57 loc) · 2.56 KB
/
Main.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package webshop.webservice
import akka.actor.ActorSystem
import akka.cluster.Cluster
import cats.effect.concurrent.Ref
import cats.effect.{ExitCode, IO, IOApp, Resource}
import com.ing.baker.runtime.akka.AkkaBaker
import com.ing.baker.runtime.akka.internal.CachingInteractionManager
import com.ing.baker.runtime.scaladsl._
import com.typesafe.config.ConfigFactory
import org.http4s.server.blaze.BlazeServerBuilder
import org.log4s.Logger
import scala.concurrent.ExecutionContext
object Main extends IOApp {
case class SystemResources(actorSystem: ActorSystem, baker: Baker, app: WebShopService, port: Int, shuttingDown: Ref[IO, Boolean])
val logger: Logger = org.log4s.getLogger
val system: Resource[IO, SystemResources] = {
implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.global
Resource.make(
for {
actorSystem <- IO { ActorSystem("CheckoutService") }
config <- IO { ConfigFactory.load() }
baker <- IO { AkkaBaker(config, actorSystem, CachingInteractionManager(List(
InteractionInstance.unsafeFrom(new ReserveItemsInstance()),
InteractionInstance.unsafeFrom(new MakePaymentInstance()),
InteractionInstance.unsafeFrom(new ShipItemsInstance())
))) }
checkoutRecipeId <- WebShopBaker.initRecipes(baker)(timer, actorSystem.dispatcher)
sd <- Ref.of[IO, Boolean](false)
webShopBaker = new WebShopBaker(baker, checkoutRecipeId)(actorSystem.dispatcher)
memoryDumpPath = config.getString("service.memory-dump-path")
httpPort = config.getInt("bakery-component.http-api-port")
app = new WebShopService(webShopBaker, memoryDumpPath)
resources = SystemResources(actorSystem, baker, app, httpPort, sd)
} yield resources
)(resources =>
IO(logger.info("Shutting down the Checkout Service...")) *>
terminateCluster(resources) *>
terminateActorSystem(resources)
)
}
def terminateCluster(resources: SystemResources): IO[Unit] =
IO {
val cluster = Cluster(resources.actorSystem)
cluster.leave(cluster.selfAddress)
}
def terminateActorSystem(resources: SystemResources): IO[Unit] =
IO.fromFuture(IO { resources.actorSystem.terminate() }).void
override def run(args: List[String]): IO[ExitCode] = {
system.flatMap { r =>
sys.addShutdownHook(r.baker.gracefulShutdown())
BlazeServerBuilder[IO](ExecutionContext.global)
.bindHttp(r.port, "0.0.0.0")
.withHttpApp(r.app.buildHttpService(r.shuttingDown))
.resource
}.use(_ => IO.never).as(ExitCode.Success)
}
}