mirror of https://github.com/dapr/quickstarts.git
145 lines
4.1 KiB
Go
145 lines
4.1 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"time"
|
|
|
|
"github.com/dapr/go-sdk/client"
|
|
"github.com/dapr/go-sdk/workflow"
|
|
)
|
|
|
|
var (
|
|
stateStoreName = "statestore"
|
|
workflowComponent = "dapr"
|
|
workflowName = "OrderProcessingWorkflow"
|
|
defaultItemName = "cars"
|
|
)
|
|
|
|
func main() {
|
|
fmt.Println("*** Welcome to the Dapr Workflow console app sample!")
|
|
fmt.Println("*** Using this app, you can place orders that start workflows.")
|
|
|
|
w, err := workflow.NewWorker()
|
|
if err != nil {
|
|
log.Fatalf("failed to start worker: %v", err)
|
|
}
|
|
|
|
if err := w.RegisterWorkflow(OrderProcessingWorkflow); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
if err := w.RegisterActivity(NotifyActivity); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
if err := w.RegisterActivity(RequestApprovalActivity); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
if err := w.RegisterActivity(VerifyInventoryActivity); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
if err := w.RegisterActivity(ProcessPaymentActivity); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
if err := w.RegisterActivity(UpdateInventoryActivity); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
if err := w.Start(); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
daprClient, err := client.NewClient()
|
|
if err != nil {
|
|
log.Fatalf("failed to initialise dapr client: %v", err)
|
|
}
|
|
wfClient, err := workflow.NewClient(workflow.WithDaprClient(daprClient))
|
|
if err != nil {
|
|
log.Fatalf("failed to initialise workflow client: %v", err)
|
|
}
|
|
|
|
inventory := []InventoryItem{
|
|
{ItemName: "paperclip", PerItemCost: 5, Quantity: 100},
|
|
{ItemName: "cars", PerItemCost: 15000, Quantity: 100},
|
|
{ItemName: "computers", PerItemCost: 500, Quantity: 100},
|
|
}
|
|
if err := restockInventory(daprClient, inventory); err != nil {
|
|
log.Fatalf("failed to restock: %v", err)
|
|
}
|
|
|
|
fmt.Println("==========Begin the purchase of item:==========")
|
|
|
|
itemName := defaultItemName
|
|
orderQuantity := 10
|
|
|
|
totalCost := inventory[1].PerItemCost * orderQuantity
|
|
|
|
orderPayload := OrderPayload{
|
|
ItemName: itemName,
|
|
Quantity: orderQuantity,
|
|
TotalCost: totalCost,
|
|
}
|
|
|
|
id, err := wfClient.ScheduleNewWorkflow(context.Background(), workflowName, workflow.WithInput(orderPayload))
|
|
if err != nil {
|
|
log.Fatalf("failed to start workflow: %v", err)
|
|
}
|
|
|
|
approvalSought := false
|
|
|
|
startTime := time.Now()
|
|
|
|
for {
|
|
timeDelta := time.Since(startTime)
|
|
metadata, err := wfClient.FetchWorkflowMetadata(context.Background(), id)
|
|
if err != nil {
|
|
log.Fatalf("failed to fetch workflow: %v", err)
|
|
}
|
|
if (metadata.RuntimeStatus == workflow.StatusCompleted) || (metadata.RuntimeStatus == workflow.StatusFailed) || (metadata.RuntimeStatus == workflow.StatusTerminated) {
|
|
fmt.Printf("Workflow completed - result: %v\n", metadata.RuntimeStatus.String())
|
|
break
|
|
}
|
|
if timeDelta.Seconds() >= 10 {
|
|
metadata, err := wfClient.FetchWorkflowMetadata(context.Background(), id)
|
|
if err != nil {
|
|
log.Fatalf("failed to fetch workflow: %v", err)
|
|
}
|
|
if totalCost > 50000 && !approvalSought && ((metadata.RuntimeStatus != workflow.StatusCompleted) || (metadata.RuntimeStatus != workflow.StatusFailed) || (metadata.RuntimeStatus != workflow.StatusTerminated)) {
|
|
approvalSought = true
|
|
promptForApproval(id)
|
|
}
|
|
}
|
|
// Sleep before the next iteration
|
|
time.Sleep(time.Second)
|
|
}
|
|
|
|
fmt.Println("Purchase of item is complete")
|
|
}
|
|
|
|
// promptForApproval is an example case. There is no user input required here due to this being for testing purposes only.
|
|
// It would be perfectly valid to add a wait here or display a prompt to continue the process.
|
|
func promptForApproval(id string) {
|
|
wfClient, err := workflow.NewClient()
|
|
if err != nil {
|
|
log.Fatalf("failed to initialise wfClient: %v", err)
|
|
}
|
|
if err := wfClient.RaiseEvent(context.Background(), id, "manager_approval"); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func restockInventory(daprClient client.Client, inventory []InventoryItem) error {
|
|
for _, item := range inventory {
|
|
itemSerialized, err := json.Marshal(item)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
fmt.Printf("adding base stock item: %s\n", item.ItemName)
|
|
if err := daprClient.SaveState(context.Background(), stateStoreName, item.ItemName, itemSerialized, nil); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|