Update README.md
This commit is contained in:
parent
5d5cb10315
commit
af3e6ea20e
@ -1,200 +1,13 @@
|
|||||||
# Food Delivery Service implemented using Conductor
|
# Saga Pattern Using Orkes Conductor
|
||||||
Sample Java Application demonstrating Saga microservice architecture pattern for a food delivery app.
|
|
||||||
|
|
||||||
## Running this Example
|
This is an example project showing how to build event driven applications using [Conductor](https://github.com/conductor-oss/conductor)
|
||||||
|
|
||||||
### Environment setup
|
# Pre-requisites
|
||||||
1. Install JAVA 17 - https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html
|
1. Docker
|
||||||
2. Install Gradle - https://gradle.org/install/
|
2. Running conductor server
|
||||||
3. Generate Gradle Wrapper - https://www.baeldung.com/gradle-wrapper
|
|
||||||
4. Install sqlite (Only if necessary, i.e if SQLite JDBC Driver is not installed. If you are on Mac OS X or Linux, then SQLite is normally pre-installed) - https://www.tutorialspoint.com/sqlite/sqlite_installation.htm.
|
|
||||||
|
|
||||||
### Workflow Setup on Orkes Playground
|
**Start the conductor server**
|
||||||
|
|
||||||
#### Use existing out-of-the-box workflows
|
```shell
|
||||||
We have already setup these workflows with all the necessary permissions. These can be used directly, if you don't need to modify these workflows.
|
docker run --init -p 8080:8080 -p 1234:5000 conductoross/conductor-standalone:3.15.0
|
||||||
1. Food Delivery Workflow - https://play.orkes.io/workflowDef/FoodDeliveryWorkflow
|
```
|
||||||
2. Cancellation workflow - https://play.orkes.io/workflowDef/FoodDeliveryFailureWorkflow
|
|
||||||
|
|
||||||
### Running the application and workers locally
|
|
||||||
|
|
||||||
1. Clone the project to your local
|
|
||||||
2. Update following properties in [application.properties](src/main/resources/application.properties)
|
|
||||||
1. `conductor.security.client.key-id` and `conductor.security.client.secret` are **NOT** set, please set them
|
|
||||||
* When connecting to playground - refer to this [article](https://orkes.io/content/how-to-videos/access-key-and-secret) to get a key and secret
|
|
||||||
* When connecting locally - follow the instructions [here (Install and Run Locally)](https://orkes.io/content/get-orkes-conductor)
|
|
||||||
2. `conductor.worker.all.domain` is set to 'saga' by default, please change it to <yourname> or something else to avoid conflicts with workflows and workers spun up by others
|
|
||||||
3. From the root project folder, run `gradlew bootRun`
|
|
||||||
|
|
||||||
### Order Creation
|
|
||||||
|
|
||||||
We can use two approaches:
|
|
||||||
1. Call the triggerRideBookingFlow API from within the Application
|
|
||||||
```
|
|
||||||
curl --location 'http://localhost:8081/triggerFoodDeliveryFlow' \
|
|
||||||
--header 'Content-Type: application/json' \
|
|
||||||
--data '{
|
|
||||||
"customerEmail": "tester.qa@example.com",
|
|
||||||
"customerName": "Tester QA",
|
|
||||||
"customerContact": "+1(605)123-5674",
|
|
||||||
"address": "350 East 62nd Street, NY 10065",
|
|
||||||
"restaurantId": 2,
|
|
||||||
"foodItems": [
|
|
||||||
{
|
|
||||||
"item": "Chicken with Broccoli",
|
|
||||||
"quantity": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"item": "Veggie Fried Rice",
|
|
||||||
"quantity": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"item": "Egg Drop Soup",
|
|
||||||
"quantity": 2
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"additionalNotes": [
|
|
||||||
"Do not put spice.",
|
|
||||||
"Send cutlery."
|
|
||||||
],
|
|
||||||
"paymentMethod" : {
|
|
||||||
"type": "Credit Card",
|
|
||||||
"details": {
|
|
||||||
"number": "1234 4567 3325 1345",
|
|
||||||
"cvv": "123",
|
|
||||||
"expiry": "05/2022"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"paymentAmount": 45.34,
|
|
||||||
"deliveryInstructions": "Leave at the door!"
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
2. Directly call the Orkes API for creating a workflow
|
|
||||||
1. Generate a JWT token by following steps mentioned [here](https://orkes.io/content/access-control-and-security/applications#generating-token)
|
|
||||||
2. Make an HTTPS request from postman/curl similar to below after replacing \<JWT Token\>:
|
|
||||||
```
|
|
||||||
curl --location 'https://play.orkes.io/api/workflow' \
|
|
||||||
--header "Content-Type: application/json" \
|
|
||||||
--header 'X-Authorization: <JWT Token>' \
|
|
||||||
--request POST \
|
|
||||||
--data \
|
|
||||||
'
|
|
||||||
{
|
|
||||||
"name": "FoodDeliveryWorkflow",
|
|
||||||
"version": 1,
|
|
||||||
"input": {
|
|
||||||
"customerEmail": "tester.qa@example.com",
|
|
||||||
"customerName": "Tester QA",
|
|
||||||
"customerContact": "+1(605)123-5674",
|
|
||||||
"address": "350 East 62nd Street, NY 10065",
|
|
||||||
"restaurantId": 2,
|
|
||||||
"foodItems": [
|
|
||||||
{
|
|
||||||
"item": "Chicken with Broccoli",
|
|
||||||
"quantity": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"item": "Veggie Fried Rice",
|
|
||||||
"quantity": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"item": "Egg Drop Soup",
|
|
||||||
"quantity": 2
|
|
||||||
}],
|
|
||||||
"additionalNotes": [
|
|
||||||
"Do not put spice.",
|
|
||||||
"Send cutlery."
|
|
||||||
],
|
|
||||||
"deliveryInstructions": "Leave at the door!",
|
|
||||||
"paymentAmount": 45.34,
|
|
||||||
"paymentMethod": {
|
|
||||||
"type" : "Credit Card",
|
|
||||||
"details" : {
|
|
||||||
"number": "1234 4567 3325 1345",
|
|
||||||
"expiry": "05/2025",
|
|
||||||
"cvv": "123"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"taskToDomain": {
|
|
||||||
"*": "saga"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
'
|
|
||||||
```
|
|
||||||
|
|
||||||
A successful order creation workflow run will look like this:
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
#### Triggering the cancellation workflow to simulate rollback of distributed transactions
|
|
||||||
|
|
||||||
* Create an order with invalid payment expiry
|
|
||||||
```
|
|
||||||
curl --location 'https://play.orkes.io/api/workflow' \
|
|
||||||
--header "Content-Type: application/json" \
|
|
||||||
--header 'X-Authorization: <JWT Token>' \
|
|
||||||
--request POST \
|
|
||||||
--data \
|
|
||||||
'
|
|
||||||
{
|
|
||||||
"name": "FoodDeliveryWorkflow",
|
|
||||||
"version": 1,
|
|
||||||
"input": {
|
|
||||||
"customerEmail": "tester.qa@example.com",
|
|
||||||
"customerName": "Tester QA",
|
|
||||||
"customerContact": "+1(605)123-5674",
|
|
||||||
"address": "350 East 62nd Street, NY 10065",
|
|
||||||
"restaurantId": 2,
|
|
||||||
"foodItems": [
|
|
||||||
{
|
|
||||||
"item": "Chicken with Broccoli",
|
|
||||||
"quantity": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"item": "Veggie Fried Rice",
|
|
||||||
"quantity": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"item": "Egg Drop Soup",
|
|
||||||
"quantity": 2
|
|
||||||
}],
|
|
||||||
"additionalNotes": [
|
|
||||||
"Do not put spice.",
|
|
||||||
"Send cutlery."
|
|
||||||
],
|
|
||||||
"deliveryInstructions": "Leave at the door!",
|
|
||||||
"paymentAmount": 45.34,
|
|
||||||
"paymentMethod": {
|
|
||||||
"type" : "Credit Card",
|
|
||||||
"details" : {
|
|
||||||
"number": "1234 4567 3325 1345",
|
|
||||||
"expiry": "05/2022",
|
|
||||||
"cvv": "123"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"taskToDomain": {
|
|
||||||
"*": "saga"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
'
|
|
||||||
```
|
|
||||||
|
|
||||||
* This will cause the workflow to fail and trigger the cancellation workflow.
|
|
||||||
* Failed workflow run will look like this:
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
* A cancellation workflow run will look like this:
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
* In the above workflow diagram, the simulated distributed rollback can be seen. The rollback sequence in case of failure occurring while payment processing is as follows:
|
|
||||||
1. Shipment is cancelled in the Shipment Service
|
|
||||||
2. Payment is cancelled in the Payment Service
|
|
||||||
3. Order is cancelled in the Order Service
|
|
Loading…
x
Reference in New Issue
Block a user