Skip to content

Commit a60ff95

Browse files
Tihomir Surdilovicbrypete
andauthored
[0.6.x] cherry-pick todays approved prs (#295)
* Fix minor typos (#294) Signed-off-by: Bryan Peterson <[email protected]> * Online Food Ordering Example (#289) * Online Food Ordering Example Signed-off-by: Tihomir Surdilovic <[email protected]> * fixes per comments Signed-off-by: Tihomir Surdilovic <[email protected]> Co-authored-by: Bryan Peterson <[email protected]>
1 parent 12fce06 commit a60ff95

File tree

3 files changed

+245
-3
lines changed

3 files changed

+245
-3
lines changed

examples/README.md

Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Provides Serverless Workflow language examples
2727
- [Car vitals checks (SubFlow state Repeat)](#Car-Vitals-Checks)
2828
- [Book Lending Workflow](#Book-Lending)
2929
- [Filling a glass of water (Expression functions)](#Filling-a-glass-of-water)
30+
- [Online Food Ordering](#Online-Food-Ordering)
3031

3132
### Hello World Example
3233

@@ -3873,3 +3874,244 @@ states:
38733874
</td>
38743875
</tr>
38753876
</table>
3877+
3878+
### Online Food Ordering
3879+
3880+
#### Description
3881+
3882+
In this example we want to create an online food ordering workflow. The below image outlines the workflow
3883+
structure and the available services:
3884+
3885+
<p align="center">
3886+
<img src="../media/examples/example-foodorder-outline.png" height="450px" alt="Online Food Ordering Structure"/>
3887+
</p>
3888+
3889+
Our workflow starts with the "Place Order" [Subflow](../specification.md#SubFlow-State), which is responsible
3890+
to send the received order to the requested restaurant and the estimated order ETA.
3891+
We then wait for the ETA time when our workflow should go into the "Deliver Order" SubFlow, responsible
3892+
for dispatching a Courier and sending her/him off to pick up the order. Once the order is picked up, the Courier needs to deliver the order to the customer.
3893+
After the order has been delivered to the customer, our workflow needs to charge the customer.
3894+
3895+
Our workflow needs to communicate with three services during its execution, namely the Order, Delivery, and
3896+
the Payment services.
3897+
3898+
For the sake of the example, we assume that our workflow can communicate to the Order and Delivery services via REST and the Payment service via gRPC.
3899+
Let's start by defining an example CloudEvent which triggers an instance of our workflow.
3900+
This event can be sent by a web UI, for example, or be pushed onto a Kafka/MQTT topic to start our order workflow.
3901+
3902+
```json
3903+
{
3904+
"specversion": "1.0",
3905+
"type": "org.orders",
3906+
"source": "/orders/",
3907+
"subject": "Food Order",
3908+
"id": "A234-1234-1234",
3909+
"time": "2021-03-05T17:31:00Z",
3910+
"orderid": "ORDER-12345",
3911+
"data": {
3912+
"id": "ORDER-12345",
3913+
"customerId": "CUSTOMER-12345",
3914+
"status": [],
3915+
"order": {
3916+
"restaurantId": "RESTAURANT-54321",
3917+
"items": [
3918+
{
3919+
"itemId": "ITEM-8765",
3920+
"amount": 1,
3921+
"addons": ""
3922+
}
3923+
]
3924+
},
3925+
"delivery":{
3926+
"address": "1234 MyStreet, MyCountry",
3927+
"type": "contactless",
3928+
"requestedTime": "ASAP",
3929+
"location": "Front door",
3930+
"instructions": ""
3931+
}
3932+
}
3933+
}
3934+
```
3935+
3936+
Note the `orderid` CloudEvent context attribute, which contains the unique ID of the order specified in this event. [Event correlation](../specification.md#Correlation-Definition) is done against CE context attributes, and as such, to be able
3937+
to correlate multiple order events to the same order id, it needs to be part of the CE context attributes, and
3938+
not its data (payload).
3939+
3940+
Now let's start defining our workflow. For the sake of this example, let's define our function and event definitions
3941+
as separate YAML files (and then reference them inside our workflow definition). This is useful in cases
3942+
when you want to reuse them between multiple workflow definitions.
3943+
3944+
#### Workflow Event Definition
3945+
3946+
``` yaml
3947+
events:
3948+
- name: Food Order Event
3949+
source: "/orders/"
3950+
type: org.orders
3951+
correlation:
3952+
- contextAttributeName: orderid
3953+
- name: ETA Deadline Event
3954+
source: "/orderseta"
3955+
type: org.orders.eta
3956+
correlation:
3957+
- contextAttributeName: orderid
3958+
- name: Order Picked Up Event
3959+
source: "/orderspickup"
3960+
type: org.orders.delivery
3961+
correlation:
3962+
- contextAttributeName: orderid
3963+
- name: Order Delievered Event
3964+
source: "/orderdelivery"
3965+
type: org.orders.delivery
3966+
correlation:
3967+
- contextAttributeName: orderid
3968+
```
3969+
3970+
#### Workflow Function Definition
3971+
3972+
``` yaml
3973+
functions:
3974+
- name: Submit Order Function
3975+
operation: http://myorderservice.org/orders.json#submit
3976+
- name: Get Order ETA Function
3977+
operation: http://myorderservice.org/orders.json#orderETA
3978+
- name: Dispatch Courrier Function
3979+
operation: http://mydeliveryservice.org/deliveries.json#dispatch
3980+
- name: Deliver Order Function
3981+
operation: http://mydeliveryservice.org/deliveries.json#deliver
3982+
- name: Charge For Order Function
3983+
operation: http://mypaymentservice.org/payments.proto#PaymentService#ChargeUser
3984+
```
3985+
3986+
#### Main Workflow Definition
3987+
3988+
With the function and event definitions in place we can now start writing our main workflow definition:
3989+
3990+
``` yaml
3991+
id: foodorderworkflow
3992+
name: Food Order Workflow
3993+
version: '1.0'
3994+
start: Place Order
3995+
functions: file://orderfunctions.yml
3996+
events: file://orderevents.yml
3997+
states:
3998+
- name: Place Order
3999+
type: subflow
4000+
workflowId: placeorderworkflow
4001+
transition: Wait for ETA Deadline
4002+
- name: Wait for ETA Deadline
4003+
type: event
4004+
onEvents:
4005+
- eventRefs:
4006+
- ETA Deadline Event
4007+
eventDataFilter:
4008+
data: "${ .results.status }"
4009+
toStateData: "${ .status }"
4010+
transition: Deliver Order
4011+
- name: Deliver Order
4012+
type: subflow
4013+
workflowId: deliverorderworkflow
4014+
transition: Charge For Order
4015+
- name: Charge For Order
4016+
type: operation
4017+
actions:
4018+
- functionRef:
4019+
refName: Charge For Order Function
4020+
arguments:
4021+
order: "${ .order.id }"
4022+
actionDataFilter:
4023+
results: "${ .outcome.status }"
4024+
toStateData: "${ .status }"
4025+
stateDataFilter:
4026+
output: '${ . | {"orderid": .id, "orderstatus": .status} | .orderstatus += ["Order
4027+
Completed"] }'
4028+
end: true
4029+
```
4030+
4031+
With this in place we can start defining our sub-workflows:
4032+
4033+
#### Place Order Sub-Workflow
4034+
4035+
``` yaml
4036+
id: placeorderworkflow
4037+
name: Place Order Workflow
4038+
version: '1.0'
4039+
start: Submit Order
4040+
states:
4041+
- name: Submit Order
4042+
type: event
4043+
onEvents:
4044+
- eventRefs:
4045+
- Food Order Event
4046+
actions:
4047+
- functionRef:
4048+
refName: Submit Order Function
4049+
arguments:
4050+
order: "${ .order }"
4051+
actionDataFilter:
4052+
results: "${ .results.status }"
4053+
toStateData: "${ .status }"
4054+
- functionRef:
4055+
refName: Get Order ETA Function
4056+
arguments:
4057+
customer: "${ .customerId }"
4058+
restaurantid: "${ .order.restaurantId }"
4059+
delivery: " ${ .delivery }"
4060+
actionDataFilter:
4061+
results: "${ .results.status }"
4062+
toStateData: "${ .status }"
4063+
end: true
4064+
```
4065+
4066+
#### Deliver Order Sub-Workflow
4067+
4068+
``` yaml
4069+
id: deliverorderworkflow
4070+
name: Deliver Order Workflow
4071+
version: '1.0'
4072+
start: Dispatch Courier
4073+
states:
4074+
- name: Dispatch Courier
4075+
type: operation
4076+
actions:
4077+
- functionRef: Dispatch Courrier Function
4078+
transition: Wait for Order Pickup
4079+
- name: Wait for Order Pickup
4080+
type: event
4081+
onEvents:
4082+
- eventRefs:
4083+
- Order Picked Up Event
4084+
eventDataFilter:
4085+
data: "${ .data.status }"
4086+
toStateData: "${ .status }"
4087+
actions:
4088+
- functionRef: Deliver Order Function
4089+
transition: Wait for Delivery Confirmation
4090+
- name: Wait for Delivery Confirmation
4091+
type: event
4092+
onEvents:
4093+
- eventRefs:
4094+
- Order Delievered Event
4095+
eventDataFilter:
4096+
data: "${ .data.status }"
4097+
toStateData: "${ .status }"
4098+
end: true
4099+
```
4100+
4101+
#### Workflow Results
4102+
4103+
For the example order event, the workflow output for a successful completion would look like for example:
4104+
4105+
``` json
4106+
{
4107+
"orderid": "ORDER-12345",
4108+
"orderstatus": [
4109+
"Order Submitted",
4110+
"Order ETA Received",
4111+
"Order Picked up",
4112+
"Order Delievered",
4113+
"Order Charged",
4114+
"Order Completed"
4115+
]
4116+
}
4117+
```
557 KB
Loading

specification.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ At this point our state data should be:
658658
}
659659
```
660660

661-
**(2) CloudEvent of type "customer-arrival-type" is consumed**: Once the vent is consumed, the "eventDataFilter" is triggered.
661+
**(2) CloudEvent of type "customer-arrival-type" is consumed**: Once the event is consumed, the "eventDataFilter" is triggered.
662662
Its "data" expression selects the "customer" object from the events data. The "toStateData" expression
663663
says that we should add/merge this selected event data to the state data in its "customerInfo" property. If this property
664664
exists it should be merged, if it does not exist, one should be created.
@@ -959,7 +959,7 @@ Reference the following sections to learn more about workflow functions:
959959
### Using Functions For RESTful Service Invocations
960960

961961
[Functions](#Function-Definition) can be used to describe services and their operations that need to be invoked during
962-
workflow execution. They can be referenced by states [action definitions](#Action-Definition)] to clearly
962+
workflow execution. They can be referenced by states [action definitions](#Action-Definition) to clearly
963963
define when the service operations should be invoked during workflow execution, as well as the data parameters
964964
passed to them if needed.
965965

@@ -1085,7 +1085,7 @@ them by their logical name through workflow states where expression evaluation i
10851085

10861086
Expression functions must declare their `type` parameter to be `expression`.
10871087

1088-
Let's take at an example of such definitions:
1088+
Let's take a look at an example of such definitions:
10891089

10901090
```json
10911091
{

0 commit comments

Comments
 (0)