Skip to content

Commit c12f7c3

Browse files
zhfengaldettinger
authored andcommitted
Add saga example
1 parent e1a19d0 commit c12f7c3

File tree

24 files changed

+1322
-1
lines changed

24 files changed

+1322
-1
lines changed

.github/dependabot.yml

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ updates:
4949
- "/openapi-contract-first"
5050
- "/platform-http-security-keycloak"
5151
- "/rest-json"
52+
- "/saga"
5253
- "/timer-log-kotlin"
5354
- "/timer-log-main"
5455
- "/timer-log"

.github/generate-test-groups.groovy

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ int groupId = 0
2222

2323
// Distribute example projects across a bounded set of test groups and output as JSON
2424
new File(".").eachFileRecurse { file ->
25-
if (file.getName() == "pom.xml") {
25+
if (file.getName() == "pom.xml" && file.getParentFile().getParentFile().getName() == ".") {
2626
if (GROUPS[groupId] == null) {
2727
GROUPS[groupId] = [:]
2828
GROUPS[groupId].name = "group-${String.format("%02d", groupId + 1)}"

.gitignore

+7
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,10 @@ nb-configuration.xml
4141

4242
# Quarkus
4343
quarkus.log*
44+
45+
# Saga
46+
payment.*
47+
flight.*
48+
train.*
49+
app.*
50+

docs/modules/ROOT/attachments/examples.json

+5
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@
9494
"description": "Demonstrates how to create a REST service using the Camel REST DSL and Jackson.",
9595
"link": "https://github.com/apache/camel-quarkus-examples/tree/main/rest-json"
9696
},
97+
{
98+
"title": "Saga and LRA",
99+
"description": "Shows how to use saga and lra",
100+
"link": "https://github.com/apache/camel-quarkus-examples/tree/main/saga"
101+
},
97102
{
98103
"title": "Timer Hello World",
99104
"description": "Uses the Camel timer component to output a Hello world message to the console",

saga/README.adoc

+170
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
= Saga and LRA: A Camel Quarkus example
2+
:cq-example-description: An example that shows how to use saga and lra
3+
4+
{cq-description}
5+
6+
TIP: Check the https://camel.apache.org/camel-quarkus/latest/first-steps.html[Camel Quarkus User guide] for prerequisites
7+
and other general information.
8+
9+
=== How it works
10+
11+
There are 4 services as participants of the Saga:
12+
13+
- payment-service: it emulates a real payment transaction and it will be used by both flight-service and train-service
14+
- flight-service: it emulates the booking of a flight ticket and it uses the payment-service to execute a payment transaction
15+
- train-service: it emulates the reservation of a train seat and it uses the payment-service to execute a payment transaction
16+
- app: is the starting point and it emulates a user that starts the transaction to buy both flight and train tickets
17+
18+
The starting point is a REST endpoint that creates a request for a new reservation
19+
and there is 15% probability that the payment service fails.
20+
21+
==== Logical view
22+
23+
image::doc-resources/logic-diagram.png[]
24+
25+
==== Compensating a failure
26+
27+
image::doc-resources/compesate-diagram.png[]
28+
29+
==== Technical view
30+
31+
image::doc-resources/tech-diagram.png[]
32+
33+
The communication between services and LRA coordinator (blue connectors) is via HTTP protocol,
34+
so every service expose REST endpoints called by the LRA, moreover it calls LRA via REST endpoint
35+
36+
The communication between services (red connectors) is via AMQ broker (using OPENWIRE protocol),
37+
implemented using Camel JMS component and RequestReply EIP
38+
obtaining a synchronous behavior using asynchronous protocol
39+
40+
==== Analyzing logs
41+
42+
In the logs there will be all the messages about the execution of the service.
43+
44+
First the app starts the saga LRA, passing the id to the entry point REST
45+
46+
[source,shell]
47+
----
48+
curl -X POST http://localhost:8084/api/saga?id=1
49+
----
50+
51+
in the log
52+
53+
[source]
54+
----
55+
Executing saga #1 with LRA http://localhost:8080/lra-coordinator/0_ffff7f000001_8aad_62d16f11_2
56+
----
57+
58+
where the URL contains the id of the LRA and the number of the saga is the value of the parameter passed to the rest in the starting point
59+
60+
We're expecting that if the payment is ok, the message in the payment service will be:
61+
62+
[source]
63+
----
64+
Paying train for order #1
65+
66+
Payment train done for order #1 with payment transaction xxxxx
67+
68+
Payment flight done for order #1 with payment transaction xxxxx
69+
----
70+
71+
the value of the payment transaction is the `JMSCorrelationID` used in the RequestReply EIP in the payment service
72+
73+
If the random failure occurs, the log in the payment service will be
74+
75+
[source]
76+
----
77+
Payment flight for saga #65 fails!
78+
79+
Payment for order #65 has been cancelled
80+
----
81+
82+
It means that the compensation for the payment has been called, so we expect that in the flight service there will be a log
83+
84+
[source]
85+
----
86+
Flight purchase #65 has been cancelled due to payment failure
87+
----
88+
89+
in the train service
90+
91+
[source]
92+
----
93+
Train purchase #65 has been cancelled due to payment failure
94+
----
95+
96+
in the app
97+
98+
[source]
99+
----
100+
Transaction http://localhost:8080/lra-coordinator/0_ffff7f000001_8aad_62d16f11_74 has been cancelled due to flight or train failure
101+
----
102+
103+
104+
=== Package and run the application
105+
106+
Once you are done with developing you may want to package and run the application.
107+
108+
TIP: Find more details about the JVM mode and Native mode in the Package and run section of
109+
https://camel.apache.org/camel-quarkus/latest/first-steps.html#_package_and_run_the_application[Camel Quarkus User guide]
110+
111+
==== External systems
112+
113+
Start Artemis:
114+
115+
[source, shell]
116+
----
117+
docker run --name artemis \
118+
-e AMQ_USER=admin -e AMQ_PASSWORD=admin \
119+
-d -p 61616:61616 \
120+
quay.io/artemiscloud/activemq-artemis-broker
121+
----
122+
123+
Start Narayana LRA Coordinator Server:
124+
125+
[source, shell]
126+
----
127+
docker run --network host -e QUARKUS_HTTP_PORT=8080 quay.io/jbosstm/lra-coordinator:latest
128+
----
129+
130+
==== JVM mode
131+
132+
[source,shell]
133+
----
134+
$ mvn clean package
135+
----
136+
137+
==== Native mode
138+
139+
IMPORTANT: Native mode requires having GraalVM and other tools installed. Please check the Prerequisites section
140+
of https://camel.apache.org/camel-quarkus/latest/first-steps.html#_prerequisites[Camel Quarkus User guide].
141+
142+
To prepare a native executable using GraalVM, run the following command:
143+
144+
[source,shell]
145+
----
146+
$ mvn clean package -Pnative
147+
----
148+
149+
==== Run script to execute services locally
150+
151+
[source,shell]
152+
----
153+
./run.sh
154+
----
155+
156+
It will generate all the java processes and start in dev mode, logs are stored in the `.log` files, and process id in the `.pid` files
157+
158+
==== Run script to stop services locally
159+
160+
[source,shell]
161+
----
162+
./stop.sh
163+
----
164+
165+
This command will kill the running processes, remove the PID files; the log files will be left
166+
167+
168+
== Feedback
169+
170+
Please report bugs and propose improvements via https://github.com/apache/camel-quarkus/issues[GitHub issues of Camel Quarkus] project.
36.3 KB
Loading

saga/doc-resources/logic-diagram.png

27.3 KB
Loading

saga/doc-resources/tech-diagram.png

32.5 KB
Loading

0 commit comments

Comments
 (0)