This is an automated email from the ASF dual-hosted git repository. zhfeng pushed a commit to branch camel-quarkus-main in repository https://gitbox.apache.org/repos/asf/camel-quarkus-examples.git
commit 709a81f9d0ff5d19260e99c2594e3887ba088bd5 Author: Zheng Feng <[email protected]> AuthorDate: Thu Jun 6 06:53:57 2024 +0800 Add saga example --- .github/dependabot.yml | 1 + .github/generate-test-groups.groovy | 2 +- .gitignore | 7 + docs/modules/ROOT/attachments/examples.json | 5 + saga/README.adoc | 170 ++++++++++++ saga/doc-resources/compesate-diagram.png | Bin 0 -> 37193 bytes saga/doc-resources/logic-diagram.png | Bin 0 -> 27916 bytes saga/doc-resources/tech-diagram.png | Bin 0 -> 33322 bytes saga/eclipse-formatter-config.xml | 276 +++++++++++++++++++ saga/pom.xml | 302 +++++++++++++++++++++ saga/run.sh | 34 +++ saga/saga-app/pom.xml | 34 +++ .../org/apache/camel/example/saga/SagaRoute.java | 51 ++++ saga/saga-app/src/main/resources/application.yml | 45 +++ saga/saga-flight-service/pom.xml | 34 +++ .../org/apache/camel/example/saga/FlightRoute.java | 41 +++ .../src/main/resources/application.yml | 45 +++ saga/saga-payment-service/pom.xml | 34 +++ .../apache/camel/example/saga/PaymentRoute.java | 48 ++++ .../src/main/resources/application.yml | 44 +++ saga/saga-train-service/pom.xml | 34 +++ .../org/apache/camel/example/saga/TrainRoute.java | 41 +++ .../src/main/resources/application.yml | 45 +++ saga/stop.sh | 30 ++ 24 files changed, 1322 insertions(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 6721016..e85370b 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -49,6 +49,7 @@ updates: - "/openapi-contract-first" - "/platform-http-security-keycloak" - "/rest-json" + - "/saga" - "/timer-log-kotlin" - "/timer-log-main" - "/timer-log" diff --git a/.github/generate-test-groups.groovy b/.github/generate-test-groups.groovy index 8190abf..3c481d1 100644 --- a/.github/generate-test-groups.groovy +++ b/.github/generate-test-groups.groovy @@ -22,7 +22,7 @@ int groupId = 0 // Distribute example projects across a bounded set of test groups and output as JSON new File(".").eachFileRecurse { file -> - if (file.getName() == "pom.xml") { + if (file.getName() == "pom.xml" && file.getParentFile().getParentFile().getName() == ".") { if (GROUPS[groupId] == null) { GROUPS[groupId] = [:] GROUPS[groupId].name = "group-${String.format("%02d", groupId + 1)}" diff --git a/.gitignore b/.gitignore index daf7212..52998f3 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,10 @@ nb-configuration.xml # Quarkus quarkus.log* + +# Saga +payment.* +flight.* +train.* +app.* + diff --git a/docs/modules/ROOT/attachments/examples.json b/docs/modules/ROOT/attachments/examples.json index 1db0eb9..5160626 100644 --- a/docs/modules/ROOT/attachments/examples.json +++ b/docs/modules/ROOT/attachments/examples.json @@ -94,6 +94,11 @@ "description": "Demonstrates how to create a REST service using the Camel REST DSL and Jackson.", "link": "https://github.com/apache/camel-quarkus-examples/tree/main/rest-json" }, + { + "title": "Saga and LRA", + "description": "Shows how to use saga and lra", + "link": "https://github.com/apache/camel-quarkus-examples/tree/main/saga" + }, { "title": "Timer Hello World", "description": "Uses the Camel timer component to output a Hello world message to the console", diff --git a/saga/README.adoc b/saga/README.adoc new file mode 100644 index 0000000..baf87cf --- /dev/null +++ b/saga/README.adoc @@ -0,0 +1,170 @@ += Saga and LRA: A Camel Quarkus example +:cq-example-description: An example that shows how to use saga and lra + +{cq-description} + +TIP: Check the https://camel.apache.org/camel-quarkus/latest/first-steps.html[Camel Quarkus User guide] for prerequisites +and other general information. + +=== How it works + +There are 4 services as participants of the Saga: + +- payment-service: it emulates a real payment transaction and it will be used by both flight-service and train-service +- flight-service: it emulates the booking of a flight ticket and it uses the payment-service to execute a payment transaction +- train-service: it emulates the reservation of a train seat and it uses the payment-service to execute a payment transaction +- app: is the starting point and it emulates a user that starts the transaction to buy both flight and train tickets + +The starting point is a REST endpoint that creates a request for a new reservation +and there is 15% probability that the payment service fails. + +==== Logical view + +image::doc-resources/logic-diagram.png[] + +==== Compensating a failure + +image::doc-resources/compesate-diagram.png[] + +==== Technical view + +image::doc-resources/tech-diagram.png[] + +The communication between services and LRA coordinator (blue connectors) is via HTTP protocol, +so every service expose REST endpoints called by the LRA, moreover it calls LRA via REST endpoint + +The communication between services (red connectors) is via AMQ broker (using OPENWIRE protocol), +implemented using Camel JMS component and RequestReply EIP +obtaining a synchronous behavior using asynchronous protocol + +==== Analyzing logs + +In the logs there will be all the messages about the execution of the service. + +First the app starts the saga LRA, passing the id to the entry point REST + +[source,shell] +---- +curl -X POST http://localhost:8084/api/saga?id=1 +---- + +in the log + +[source] +---- +Executing saga #1 with LRA http://localhost:8080/lra-coordinator/0_ffff7f000001_8aad_62d16f11_2 +---- + +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 + +We're expecting that if the payment is ok, the message in the payment service will be: + +[source] +---- +Paying train for order #1 + +Payment train done for order #1 with payment transaction xxxxx + +Payment flight done for order #1 with payment transaction xxxxx +---- + +the value of the payment transaction is the `JMSCorrelationID` used in the RequestReply EIP in the payment service + +If the random failure occurs, the log in the payment service will be + +[source] +---- +Payment flight for saga #65 fails! + +Payment for order #65 has been cancelled +---- + +It means that the compensation for the payment has been called, so we expect that in the flight service there will be a log + +[source] +---- +Flight purchase #65 has been cancelled due to payment failure +---- + +in the train service + +[source] +---- +Train purchase #65 has been cancelled due to payment failure +---- + +in the app + +[source] +---- +Transaction http://localhost:8080/lra-coordinator/0_ffff7f000001_8aad_62d16f11_74 has been cancelled due to flight or train failure +---- + + +=== Package and run the application + +Once you are done with developing you may want to package and run the application. + +TIP: Find more details about the JVM mode and Native mode in the Package and run section of +https://camel.apache.org/camel-quarkus/latest/first-steps.html#_package_and_run_the_application[Camel Quarkus User guide] + +==== External systems + +Start Artemis: + +[source, shell] +---- +docker run --name artemis \ + -e AMQ_USER=admin -e AMQ_PASSWORD=admin \ + -d -p 61616:61616 \ + quay.io/artemiscloud/activemq-artemis-broker +---- + +Start Narayana LRA Coordinator Server: + +[source, shell] +---- +docker run --network host -e QUARKUS_HTTP_PORT=8080 quay.io/jbosstm/lra-coordinator:latest +---- + +==== JVM mode + +[source,shell] +---- +$ mvn clean package +---- + +==== Native mode + +IMPORTANT: Native mode requires having GraalVM and other tools installed. Please check the Prerequisites section +of https://camel.apache.org/camel-quarkus/latest/first-steps.html#_prerequisites[Camel Quarkus User guide]. + +To prepare a native executable using GraalVM, run the following command: + +[source,shell] +---- +$ mvn clean package -Pnative +---- + +==== Run script to execute services locally + +[source,shell] +---- +./run.sh +---- + +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 + +==== Run script to stop services locally + +[source,shell] +---- +./stop.sh +---- + +This command will kill the running processes, remove the PID files; the log files will be left + + +== Feedback + +Please report bugs and propose improvements via https://github.com/apache/camel-quarkus/issues[GitHub issues of Camel Quarkus] project. diff --git a/saga/doc-resources/compesate-diagram.png b/saga/doc-resources/compesate-diagram.png new file mode 100644 index 0000000..6ea7633 Binary files /dev/null and b/saga/doc-resources/compesate-diagram.png differ diff --git a/saga/doc-resources/logic-diagram.png b/saga/doc-resources/logic-diagram.png new file mode 100644 index 0000000..30996ec Binary files /dev/null and b/saga/doc-resources/logic-diagram.png differ diff --git a/saga/doc-resources/tech-diagram.png b/saga/doc-resources/tech-diagram.png new file mode 100644 index 0000000..1ae6c06 Binary files /dev/null and b/saga/doc-resources/tech-diagram.png differ diff --git a/saga/eclipse-formatter-config.xml b/saga/eclipse-formatter-config.xml new file mode 100644 index 0000000..2248b2b --- /dev/null +++ b/saga/eclipse-formatter-config.xml @@ -0,0 +1,276 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +<profiles version="8"> + <profile name="Camel Java Conventions" version="8" kind="CodeFormatterProfile"> + <setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/> + <setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/> + <setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/> + <setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/> + <setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/> + <setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/> + <setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/> + <setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/> + <setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="16"/> + <setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="16"/> + <setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/> + <setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/> + <setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/> + <setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/> + <setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/> + <setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/> + <setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/> + <setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/> + <setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/> + <setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/> + <setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/> + <setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/> + <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/> + <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/> + <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/> + <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/> + <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/> + <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/> + <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/> + <setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/> + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/> + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/> + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/> + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/> + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/> + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/> + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/> + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/> + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/> + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/> + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/> + <setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="true"/> + <setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="false"/> + <setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines" value="false"/> + <setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="false"/> + <setting id="org.eclipse.jdt.core.formatter.comment.format_comments" value="true"/> + <setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/> + <setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/> + <setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/> + <setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="false"/> + <setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/> + <setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/> + <setting id="org.eclipse.jdt.core.formatter.comment.indent_return_description" value="false"/> + <setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="false"/> + <setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="120"/> + <setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/> + <setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/> + <setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/> + <setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/> + <setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/> + <setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/> + <setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/> + <setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/> + <setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/> + <setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/> + <setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/> + <setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/> + <setting id="org.eclipse.jdt.core.formatter.indentation.size" value="8"/> + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/> + <setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="false"/> + <setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="false"/> + <setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/> + <setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/> + <setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/> + <setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/> + <setting id="org.eclipse.jdt.core.formatter.lineSplit" value="128"/> + <setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/> + <setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/> + <setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/> + <setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/> + <setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/> + <setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/> + <setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/> + <setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="CHECKSTYLE:OFF"/> + <setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="CHECKSTYLE:ON"/> + </profile> +</profiles> diff --git a/saga/pom.xml b/saga/pom.xml new file mode 100644 index 0000000..c8e1908 --- /dev/null +++ b/saga/pom.xml @@ -0,0 +1,302 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <artifactId>camel-quarkus-examples-saga</artifactId> + <groupId>org.apache.camel.quarkus.examples</groupId> + <version>3.12.0-SNAPSHOT</version> + + <name>Camel Quarkus :: Examples :: Saga</name> + <description>Camel Quarkus Example :: Saga</description> + <packaging>pom</packaging> + + <properties> + <quarkus.platform.version>3.11.0</quarkus.platform.version> + <camel-quarkus.platform.version>3.12.0-SNAPSHOT</camel-quarkus.platform.version> + <quarkiverse-artemis.version>3.3.0</quarkiverse-artemis.version> + + <quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id> + <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id> + <camel-quarkus.platform.group-id>org.apache.camel.quarkus</camel-quarkus.platform.group-id> + <camel-quarkus.platform.artifact-id>camel-quarkus-bom</camel-quarkus.platform.artifact-id> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> + <maven.compiler.target>17</maven.compiler.target> + <maven.compiler.source>17</maven.compiler.source> + <maven.compiler.testTarget>${maven.compiler.target}</maven.compiler.testTarget> + <maven.compiler.testSource>${maven.compiler.source}</maven.compiler.testSource> + + <formatter-maven-plugin.version>2.24.1</formatter-maven-plugin.version> + <impsort-maven-plugin.version>1.10.0</impsort-maven-plugin.version> + <license-maven-plugin.version>4.5</license-maven-plugin.version> + <maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version> + <maven-jar-plugin.version>3.4.1</maven-jar-plugin.version> + <maven-resources-plugin.version>3.3.1</maven-resources-plugin.version> + <maven-surefire-plugin.version>3.2.5</maven-surefire-plugin.version> + </properties> + + <modules> + <module>saga-app</module> + <module>saga-flight-service</module> + <module>saga-payment-service</module> + <module>saga-train-service</module> + </modules> + + <dependencyManagement> + <dependencies> + <!-- Import BOM --> + <dependency> + <groupId>${quarkus.platform.group-id}</groupId> + <artifactId>${quarkus.platform.artifact-id}</artifactId> + <version>${quarkus.platform.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + <dependency> + <groupId>${camel-quarkus.platform.group-id}</groupId> + <artifactId>${camel-quarkus.platform.artifact-id}</artifactId> + <version>${camel-quarkus.platform.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + <dependency> + <groupId>io.quarkiverse.artemis</groupId> + <artifactId>quarkus-artemis-bom</artifactId> + <version>${quarkiverse-artemis.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + + <dependencies> + <dependency> + <groupId>io.quarkus</groupId> + <artifactId>quarkus-config-yaml</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-core</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-direct</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-jms</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-lra</artifactId> + </dependency> + <dependency> + <groupId>io.quarkiverse.artemis</groupId> + <artifactId>quarkus-artemis-jms</artifactId> + </dependency> + + <!-- Test --> + <dependency> + <groupId>io.quarkus</groupId> + <artifactId>quarkus-junit5</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <pluginManagement> + <plugins> + <plugin> + <groupId>net.revelc.code.formatter</groupId> + <artifactId>formatter-maven-plugin</artifactId> + <version>${formatter-maven-plugin.version}</version> + <configuration> + <configFile>${maven.multiModuleProjectDirectory}/eclipse-formatter-config.xml</configFile> + <lineEnding>LF</lineEnding> + </configuration> + </plugin> + + <plugin> + <groupId>net.revelc.code</groupId> + <artifactId>impsort-maven-plugin</artifactId> + <version>${impsort-maven-plugin.version}</version> + <configuration> + <groups>java.,javax.,org.w3c.,org.xml.,junit.</groups> + <removeUnused>true</removeUnused> + <staticAfter>true</staticAfter> + <staticGroups>java.,javax.,org.w3c.,org.xml.,junit.</staticGroups> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${maven-compiler-plugin.version}</version> + <configuration> + <showDeprecation>true</showDeprecation> + <showWarnings>true</showWarnings> + <compilerArgs> + <arg>-Xlint:unchecked</arg> + </compilerArgs> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${maven-surefire-plugin.version}</version> + <configuration> + <failIfNoTests>false</failIfNoTests> + <systemPropertyVariables> + <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager> + </systemPropertyVariables> + </configuration> + </plugin> + + <plugin> + <groupId>${quarkus.platform.group-id}</groupId> + <artifactId>quarkus-maven-plugin</artifactId> + <version>${quarkus.platform.version}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-failsafe-plugin</artifactId> + <version>${maven-surefire-plugin.version}</version> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <version>${maven-jar-plugin.version}</version> + </plugin> + + <plugin> + <groupId>com.mycila</groupId> + <artifactId>license-maven-plugin</artifactId> + <version>${license-maven-plugin.version}</version> + <configuration> + <failIfUnknown>true</failIfUnknown> + <header>${maven.multiModuleProjectDirectory}/header.txt</header> + <excludes> + <exclude>**/*.adoc</exclude> + <exclude>**/*.txt</exclude> + <exclude>**/LICENSE.txt</exclude> + <exclude>**/LICENSE</exclude> + <exclude>**/NOTICE.txt</exclude> + <exclude>**/NOTICE</exclude> + <exclude>**/README</exclude> + <exclude>**/pom.xml.versionsBackup</exclude> + </excludes> + <mapping> + <java>SLASHSTAR_STYLE</java> + <properties>CAMEL_PROPERTIES_STYLE</properties> + <kt>SLASHSTAR_STYLE</kt> + </mapping> + <headerDefinitions> + <headerDefinition>${maven.multiModuleProjectDirectory}/license-properties-headerdefinition.xml</headerDefinition> + </headerDefinitions> + </configuration> + </plugin> + </plugins> + </pluginManagement> + + <plugins> + <plugin> + <groupId>${quarkus.platform.group-id}</groupId> + <artifactId>quarkus-maven-plugin</artifactId> + <executions> + <execution> + <id>build</id> + <goals> + <goal>build</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>net.revelc.code.formatter</groupId> + <artifactId>formatter-maven-plugin</artifactId> + <executions> + <execution> + <id>format</id> + <goals> + <goal>format</goal> + </goals> + <phase>process-sources</phase> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>net.revelc.code</groupId> + <artifactId>impsort-maven-plugin</artifactId> + <executions> + <execution> + <id>sort-imports</id> + <goals> + <goal>sort</goal> + </goals> + <phase>process-sources</phase> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <profiles> + <profile> + <id>native</id> + <activation> + <property> + <name>native</name> + </property> + </activation> + <properties> + <quarkus.package.type>native</quarkus.package.type> + </properties> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-failsafe-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>integration-test</goal> + <goal>verify</goal> + </goals> + <configuration> + <systemPropertyVariables> + <quarkus.package.type>${quarkus.package.type}</quarkus.package.type> + </systemPropertyVariables> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + </profiles> + +</project> diff --git a/saga/run.sh b/saga/run.sh new file mode 100755 index 0000000..bea2e56 --- /dev/null +++ b/saga/run.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +echo running payment service +mvn -f saga-payment-service/pom.xml clean quarkus:dev -Dquarkus.http.port=8081 > payment.log 2>&1 & +echo "$!" > payment.pid + +echo running flight service +mvn -f saga-flight-service/pom.xml clean quarkus:dev -Dquarkus.http.port=8082 > flight.log 2>&1 & +echo "$!" > flight.pid + +echo running train service +mvn -f saga-train-service/pom.xml clean quarkus:dev -Dquarkus.http.port=8083 > train.log 2>&1 & +echo "$!" > train.pid + +echo running saga application +mvn -f saga-app/pom.xml clean quarkus:dev -Dquarkus.http.port=8084 > app.log 2>&1 & +echo "$!" > app.pid diff --git a/saga/saga-app/pom.xml b/saga/saga-app/pom.xml new file mode 100644 index 0000000..eb49548 --- /dev/null +++ b/saga/saga-app/pom.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <artifactId>camel-quarkus-examples-saga</artifactId> + <groupId>org.apache.camel.quarkus.examples</groupId> + <version>3.12.0-SNAPSHOT</version> + </parent> + + <artifactId>camel-quarkus-example-saga-app</artifactId> + <name>Camel Quarkus :: Examples :: Saga :: App</name> + <description>Main application starting SAGA</description> + +</project> diff --git a/saga/saga-app/src/main/java/org/apache/camel/example/saga/SagaRoute.java b/saga/saga-app/src/main/java/org/apache/camel/example/saga/SagaRoute.java new file mode 100644 index 0000000..d198532 --- /dev/null +++ b/saga/saga-app/src/main/java/org/apache/camel/example/saga/SagaRoute.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.example.saga; + +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.model.rest.RestParamType; + +public class SagaRoute extends RouteBuilder { + + @Override + public void configure() throws Exception { + + rest().post("/saga") + .param().type(RestParamType.query).name("id").dataType("int").required(true).endParam() + .to("direct:saga"); + + from("direct:saga") + .saga() + .compensation("direct:cancelOrder") + .log("Executing saga #${header.id} with LRA ${header.Long-Running-Action}") + .setHeader("payFor", constant("train")) + .to("jms:queue:{{example.services.train}}?exchangePattern=InOut" + + "&replyTo={{example.services.train}}.reply") + .log("train seat reserved for saga #${header.id} with payment transaction: ${body}") + .setHeader("payFor", constant("flight")) + .to("jms:queue:{{example.services.flight}}?exchangePattern=InOut" + + "&replyTo={{example.services.flight}}.reply") + .log("flight booked for saga #${header.id} with payment transaction: ${body}") + .setBody(header("Long-Running-Action")) + .end(); + + from("direct:cancelOrder") + .log("Transaction ${header.Long-Running-Action} has been cancelled due to flight or train failure"); + + } + +} diff --git a/saga/saga-app/src/main/resources/application.yml b/saga/saga-app/src/main/resources/application.yml new file mode 100644 index 0000000..fdd42f9 --- /dev/null +++ b/saga/saga-app/src/main/resources/application.yml @@ -0,0 +1,45 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +quarkus: + artemis: + url: tcp://localhost:61616 + username: admin + password: admin +camel: + rest: + context-path: /api + component: + jms: + test-connection-on-startup: true + concurrent-consumers: 5 + lra: + enabled: true + coordinator-url: http://localhost:8080 + local-participant-url: http://localhost:${quarkus.http.port}/api +example: + services: + train: saga-train-service + flight: saga-flight-service +logging: + level: + root: INFO + org.apache.camel: INFO + org.apache.camel.processor.errorhandler.DefaultErrorHandler: OFF + org.apache.camel.component.jms.EndpointMessageListener: OFF + org.apache.camel.component.jms.reply.QueueReplyManager: OFF + diff --git a/saga/saga-flight-service/pom.xml b/saga/saga-flight-service/pom.xml new file mode 100644 index 0000000..83b074e --- /dev/null +++ b/saga/saga-flight-service/pom.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <artifactId>camel-quarkus-examples-saga</artifactId> + <groupId>org.apache.camel.quarkus.examples</groupId> + <version>3.12.0-SNAPSHOT</version> + </parent> + + <artifactId>camel-quarkus-example-saga-flight</artifactId> + <name>Camel Quarkus :: Examples :: Saga :: Flight Service</name> + <description>Flight Service</description> + +</project> diff --git a/saga/saga-flight-service/src/main/java/org/apache/camel/example/saga/FlightRoute.java b/saga/saga-flight-service/src/main/java/org/apache/camel/example/saga/FlightRoute.java new file mode 100644 index 0000000..8e0bd7e --- /dev/null +++ b/saga/saga-flight-service/src/main/java/org/apache/camel/example/saga/FlightRoute.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.example.saga; + +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.model.SagaPropagation; + +public class FlightRoute extends RouteBuilder { + + @Override + public void configure() throws Exception { + from("jms:queue:{{example.services.flight}}") + .saga() + .propagation(SagaPropagation.MANDATORY) + .option("id", header("id")) + .compensation("direct:cancelPurchase") + .log("Buying flight #${header.id}") + .to("jms:queue:{{example.services.payment}}?exchangePattern=InOut" + + "&replyTo={{example.services.payment}}.flight.reply") + .log("Payment for flight #${header.id} done with transaction ${body}") + .end(); + + from("direct:cancelPurchase") + .log("Flight purchase #${header.id} has been cancelled due to payment failure"); + } + +} diff --git a/saga/saga-flight-service/src/main/resources/application.yml b/saga/saga-flight-service/src/main/resources/application.yml new file mode 100644 index 0000000..91ae197 --- /dev/null +++ b/saga/saga-flight-service/src/main/resources/application.yml @@ -0,0 +1,45 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +quarkus: + artemis: + url: tcp://localhost:61616 + username: admin + password: admin +camel: + rest: + context-path: /api + component: + jms: + test-connection-on-startup: true + concurrent-consumers: 5 + lra: + enabled: true + coordinator-url: http://localhost:8080 + local-participant-url: http://localhost:${quarkus.http.port}/api +example: + services: + flight: saga-flight-service + payment: saga-payment-service +logging: + level: + root: INFO + org.apache.camel: INFO + org.apache.camel.processor.errorhandler.DefaultErrorHandler: OFF + org.apache.camel.component.jms.EndpointMessageListener: OFF + org.apache.camel.component.jms.reply.QueueReplyManager: OFF + diff --git a/saga/saga-payment-service/pom.xml b/saga/saga-payment-service/pom.xml new file mode 100644 index 0000000..fad637f --- /dev/null +++ b/saga/saga-payment-service/pom.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <artifactId>camel-quarkus-examples-saga</artifactId> + <groupId>org.apache.camel.quarkus.examples</groupId> + <version>3.12.0-SNAPSHOT</version> + </parent> + + <artifactId>camel-quarkus-example-saga-payment</artifactId> + <name>Camel Quarkus :: Examples :: Saga :: Payment Service</name> + <description>Payment Service</description> + +</project> diff --git a/saga/saga-payment-service/src/main/java/org/apache/camel/example/saga/PaymentRoute.java b/saga/saga-payment-service/src/main/java/org/apache/camel/example/saga/PaymentRoute.java new file mode 100644 index 0000000..342a3d8 --- /dev/null +++ b/saga/saga-payment-service/src/main/java/org/apache/camel/example/saga/PaymentRoute.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.example.saga; + +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.model.SagaPropagation; + +public class PaymentRoute extends RouteBuilder { + + @Override + public void configure() throws Exception { + + from("jms:queue:{{example.services.payment}}") + .routeId("payment-service") + .saga() + .propagation(SagaPropagation.MANDATORY) + .option("id", header("id")) + .compensation("direct:cancelPayment") + .log("Paying ${header.payFor} for order #${header.id}") + .setBody(header("JMSCorrelationID")) + .choice() + .when(x -> Math.random() >= 0.85) + .log("Payment ${header.payFor} for saga #${header.id} fails!") + .throwException(new RuntimeException("Random failure during payment")) + .endChoice() + .end() + .log("Payment ${header.payFor} done for order #${header.id} with payment transaction ${body}") + .end(); + + from("direct:cancelPayment") + .routeId("payment-cancel") + .log("Payment for order #${header.id} has been cancelled"); + } +} diff --git a/saga/saga-payment-service/src/main/resources/application.yml b/saga/saga-payment-service/src/main/resources/application.yml new file mode 100644 index 0000000..95965ff --- /dev/null +++ b/saga/saga-payment-service/src/main/resources/application.yml @@ -0,0 +1,44 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +quarkus: + artemis: + url: tcp://localhost:61616 + username: admin + password: admin +camel: + rest: + context-path: /api + component: + jms: + test-connection-on-startup: true + concurrent-consumers: 5 + lra: + enabled: true + coordinator-url: http://localhost:8080 + local-participant-url: http://localhost:${quarkus.http.port}/api +example: + services: + payment: saga-payment-service +logging: + level: + root: INFO + org.apache.camel: INFO + org.apache.camel.processor.errorhandler.DefaultErrorHandler: OFF + org.apache.camel.component.jms.EndpointMessageListener: OFF + org.apache.camel.component.jms.reply.QueueReplyManager: OFF + diff --git a/saga/saga-train-service/pom.xml b/saga/saga-train-service/pom.xml new file mode 100644 index 0000000..3ebc1b6 --- /dev/null +++ b/saga/saga-train-service/pom.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <artifactId>camel-quarkus-examples-saga</artifactId> + <groupId>org.apache.camel.quarkus.examples</groupId> + <version>3.12.0-SNAPSHOT</version> + </parent> + + <artifactId>camel-quarkus-example-saga-train</artifactId> + <name>Camel Quarkus :: Examples :: Saga :: Train Service</name> + <description>Train Service</description> + +</project> diff --git a/saga/saga-train-service/src/main/java/org/apache/camel/example/saga/TrainRoute.java b/saga/saga-train-service/src/main/java/org/apache/camel/example/saga/TrainRoute.java new file mode 100644 index 0000000..bf5b05a --- /dev/null +++ b/saga/saga-train-service/src/main/java/org/apache/camel/example/saga/TrainRoute.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.example.saga; + +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.model.SagaPropagation; + +public class TrainRoute extends RouteBuilder { + + @Override + public void configure() throws Exception { + from("jms:queue:{{example.services.train}}") + .saga() + .propagation(SagaPropagation.MANDATORY) + .option("id", header("id")) + .compensation("direct:cancelPurchase") + .log("Buying train #${header.id}") + .to("jms:queue:{{example.services.payment}}?exchangePattern=InOut" + + "&replyTo={{example.services.payment}}.train.reply") + .log("Payment for train #${header.id} done with transaction ${body}") + .end(); + + from("direct:cancelPurchase") + .log("Train purchase #${header.id} has been cancelled due to payment failure"); + } + +} diff --git a/saga/saga-train-service/src/main/resources/application.yml b/saga/saga-train-service/src/main/resources/application.yml new file mode 100644 index 0000000..9dd3a7b --- /dev/null +++ b/saga/saga-train-service/src/main/resources/application.yml @@ -0,0 +1,45 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +quarkus: + artemis: + url: tcp://localhost:61616 + username: admin + password: admin +camel: + rest: + context-path: /api + component: + jms: + test-connection-on-startup: true + concurrent-consumers: 5 + lra: + enabled: true + coordinator-url: http://localhost:8080 + local-participant-url: http://localhost:${quarkus.http.port}/api +example: + services: + train: saga-train-service + payment: saga-payment-service +logging: + level: + root: INFO + org.apache.camel: INFO + org.apache.camel.processor.errorhandler.DefaultErrorHandler: OFF + org.apache.camel.component.jms.EndpointMessageListener: OFF + org.apache.camel.component.jms.reply.QueueReplyManager: OFF + diff --git a/saga/stop.sh b/saga/stop.sh new file mode 100755 index 0000000..edc1f7a --- /dev/null +++ b/saga/stop.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +echo stopping saga application +kill $(cat app.pid) && rm app.pid + +echo stopping flight service +kill $(cat flight.pid) && rm flight.pid + +echo stopping train service +kill $(cat train.pid) && rm train.pid + +echo stopping payment service +kill $(cat payment.pid) && rm payment.pid
