forked from ing-bank/baker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
WebShopBaker.scala
106 lines (92 loc) · 3.99 KB
/
WebShopBaker.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package webshop.webservice
import java.util.UUID
import cats.effect.{ContextShift, IO, Timer}
import com.ing.baker.compiler.RecipeCompiler
import com.ing.baker.il.CompiledRecipe
import com.ing.baker.runtime.common.RecipeRecord
import com.ing.baker.runtime.scaladsl.{Baker, EventInstance, InteractionInstance}
import org.log4s.{Logger, getLogger}
import webshop.webservice.CheckoutFlowIngredients.{Item, PaymentInformation, ShippingAddress}
import scala.concurrent.ExecutionContext
object WebShopBaker {
val logger: Logger = getLogger("webshop.webservice")
val checkoutFlowCompiledRecipe: CompiledRecipe =
RecipeCompiler.compileRecipe(CheckoutFlowRecipe.recipe)
def initRecipes(baker: Baker)(implicit time: Timer[IO], ec: ExecutionContext): IO[String] = {
implicit val cs = IO.contextShift(ec)
IO.fromFuture(IO(for {
checkoutRecipeId <- baker.addRecipe(RecipeRecord.of(checkoutFlowCompiledRecipe))
_ = println(Console.GREEN + "V3 Checkout Recipe ID :: " + checkoutRecipeId + Console.RESET)
_ <- baker.registerEventListener((name, event) => {
logger.info(s"$name => ${event.providedIngredients}")
})
} yield checkoutRecipeId))
}
}
class WebShopBaker(baker: Baker, checkoutRecipeId: String)(implicit ec: ExecutionContext) extends WebShop {
import WebShopBaker.logger
private implicit val cs: ContextShift[IO] = IO.contextShift(ec)
override def createCheckoutOrder(items: List[String]): IO[String] = {
IO.fromFuture(IO {
val orderId: String = UUID.randomUUID().toString
val event = EventInstance.unsafeFrom(
CheckoutFlowEvents.OrderPlaced(items.map(Item)))
for {
_ <- baker.bake(checkoutRecipeId, orderId)
status <- baker.fireEventAndResolveWhenReceived(orderId, event)
_ = logger.info(s"${event.name}[$orderId]: $status")
} yield orderId
})
}
override def addCheckoutAddressInfo(orderId: String, address: String): IO[Option[String]] =
IO.fromFuture(IO {
val event = EventInstance.unsafeFrom(
CheckoutFlowEvents.ShippingAddressReceived(ShippingAddress(address)))
for {
status <- baker.fireEventAndResolveWhenReceived(orderId, event)
_ = logger.info(s"${event.name}[$orderId]: $status")
} yield None
})
override def addCheckoutPaymentInfo(orderId: String, paymentInfo: String): IO[Option[String]] =
IO.fromFuture(IO {
val event = EventInstance.unsafeFrom(
CheckoutFlowEvents.PaymentInformationReceived(PaymentInformation(paymentInfo)))
for {
status <- baker.fireEventAndResolveWhenReceived(orderId, event)
_ = logger.info(s"${event.name}[$orderId]: $status")
} yield None
})
override def pollOrderStatus(orderId: String): IO[OrderStatus] =
IO.fromFuture(IO {
for {
state <- baker.getRecipeInstanceState(orderId)
/*
_ = println
_ = println("EVENTS")
_ = state.events.foreach(println)
_ = println
_ = println("INGREDIENTS")
_ = state.ingredients.foreach(println)
*/
eventNames = state.events.map(_.name)
status = {
if(eventNames.contains("ShippingConfirmed"))
OrderStatus.Complete
else if(eventNames.contains("PaymentFailed"))
OrderStatus.PaymentFailed
else if(eventNames.contains("OrderHadUnavailableItems"))
OrderStatus.UnavailableItems(state.ingredients("unavailableItems").as[List[Item]].map(_.itemId))
else if(eventNames.containsSlice(List("ShippingAddressReceived", "PaymentInformationReceived")))
OrderStatus.ProcessingPayment
else if(eventNames.contains("PaymentSuccessful"))
OrderStatus.ShippingItems
else
OrderStatus.InfoPending(List("ShippingAddressReceived", "PaymentInformationReceived")
.filterNot(eventNames.contains)
.map(_.replace("Received", "")))
}
} yield status
})
override def gracefulShutdown: IO[Unit] =
IO { baker.gracefulShutdown() }
}