This is an automated email from the ASF dual-hosted git repository.
jamesnetherton pushed a commit to branch camel-quarkus-main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus-examples.git
The following commit(s) were added to refs/heads/camel-quarkus-main by this
push:
new 029f9bb6 Add Quarkus based REST Jackson example
029f9bb6 is described below
commit 029f9bb62de386e779754c041ad57c43431afe49
Author: JiriOndrusek <[email protected]>
AuthorDate: Fri Mar 20 16:30:14 2026 +0100
Add Quarkus based REST Jackson example
---
docs/modules/ROOT/attachments/examples.json | 5 +
quarkus-rest-json/README.adoc | 131 ++++++++
quarkus-rest-json/eclipse-formatter-config.xml | 276 +++++++++++++++++
quarkus-rest-json/pom.xml | 328 +++++++++++++++++++++
.../acme/rest/json/camel/OrderMessagingRoute.java | 79 +++++
.../acme/rest/json/camel/OrderProcessingRoute.java | 65 ++++
.../acme/rest/json/common/model/ErrorResponse.java | 67 +++++
.../org/acme/rest/json/common/model/Order.java | 100 +++++++
.../org/acme/rest/json/common/model/OrderItem.java | 105 +++++++
.../acme/rest/json/common/model/OrderResponse.java | 98 ++++++
.../json/common/processing/PriceCalculator.java | 81 +++++
.../common/processing/ProcessedOrdersRegistry.java | 53 ++++
.../org/acme/rest/json/quarkus/OrderResource.java | 87 ++++++
.../src/main/resources/application.properties | 101 +++++++
.../java/org/acme/rest/json/OrderResoourceIT.java | 25 ++
.../java/org/acme/rest/json/OrderResourceTest.java | 166 +++++++++++
quarkus-rest-json/test-requests.sh | 112 +++++++
17 files changed, 1879 insertions(+)
diff --git a/docs/modules/ROOT/attachments/examples.json
b/docs/modules/ROOT/attachments/examples.json
index 0969b2b8..c755be4c 100644
--- a/docs/modules/ROOT/attachments/examples.json
+++ b/docs/modules/ROOT/attachments/examples.json
@@ -109,6 +109,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": "REST with Jackson: A Quarkus based example",
+ "description": "Demonstrates how to use REST (Jackson) endpoints from a
Quarkus project and invoke Camel routes.",
+ "link":
"https://github.com/apache/camel-quarkus-examples/tree/main/quarkus-rest-json"
+ },
{
"title": "Saga and LRA",
"description": "Shows how to use saga and lra",
diff --git a/quarkus-rest-json/README.adoc b/quarkus-rest-json/README.adoc
new file mode 100644
index 00000000..c06c5696
--- /dev/null
+++ b/quarkus-rest-json/README.adoc
@@ -0,0 +1,131 @@
+= REST with Jackson: A Quarkus based example
+:cq-example-description: An example that demonstrates how to use REST
(Jackson) endpoints from a Quarkus project and invoke Camel routes.
+
+{cq-description}
+
+This example demonstrates how to invoke Camel routes from REST endpoints
defined in a Quarkus project.
+
+TIP: Check the
https://camel.apache.org/camel-quarkus/latest/first-steps.html[Camel Quarkus
User guide] for prerequisites
+and other general information.
+
+== Prerequisites
+
+The example application requires a Kafka instance.
+
+You do not need to provide a Kafka instance manually when running in
development mode (`mvn quarkus:dev` - read more
https://quarkus.io/guides/getting-started#development-mode[here]) or when
executing the supplied tests (`mvn test`).
+In these scenarios, Quarkus automatically provisions a Strimzi container via
https://quarkus.io/guides/kafka-dev-services[Quarkus Dev Services] and
configures the application accordingly, requiring no changes to
`application.properties`.
+
+== Start in the Development mode
+
+[source,shell]
+----
+$ mvn clean compile quarkus:dev
+----
+
+The above command compiles the project, starts the application, and enables
live reload via Quarkus tooling.
+Any modifications to your project will be automatically hot-reloaded into the
running application.
+
+TIP: Please refer to the Development mode section of
+https://camel.apache.org/camel-quarkus/latest/first-steps.html#_development_mode[Camel
Quarkus User guide] for more details.
+
+Then submit orders to the REST endpoint by running the `test-requests.sh`
script
+
+or
+
+send requests directly to the REST endpoint at
http://localhost:8080/api/orders.
+
+An example payload:
+```
+{
+ "customerId": "CUST001",
+ "items": [
+ {
+ "productId": "PROD001",
+ "productName": "Widget A",
+ "quantity": 1,
+ "price": 50
+ },
+ {
+ "productId": "PROD002",
+ "productName": "Widget B",
+ "quantity": 2,
+ "price": 25
+ }
+ ]
+ }
+```
+
+=== Configure Kafka client, package and run the application
+
+Once development is complete, you may want to configure the Kafka client,
package the application, and run it in production mode.
+
+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]
+
+==== Configure kafka client
+
+Uncomment the appropriate section in
`src/main/resources/application.properties` based on your authentication method:
+
+- *Kafka instance without Authentication* - if no authentication is required.
+- *Kafka instance with SASL Plain* - if using SASL Plain authentication.
+- *Kafka instance with SASL Oauth Bearer* - if using OAuth Bearer
authentication.
+
+Set the corresponding environment variables:
+- Without Authentication
+
+[source,shell]
+----
+$ export brokers=<YOUR_KAFKA_BROKERS_URL>
+----
+- SASL Plain
+[source,shell]
+----
+$ export brokers=<YOUR_KAFKA_BROKERS_URL>
+$ export id=<YOUR_KAFKA_SASL_CLIENT_ID>
+$ export secret=<YOUR_KAFKA_SASL_CLIENT_SECRET>
+----
+- SASL Oauth Bearer
+[source,shell]
+----
+$ export brokers=<YOUR_KAFKA_BROKERS_URL>
+$ export id=<YOUR_KAFKA_SASL_CLIENT_ID>
+$ export secret=<YOUR_KAFKA_SASL_CLIENT_SECRET>
+$ export token=<YOUR_KAFKA_SASL_OAUTHBEARER_TOKEN_URL>
+----
+
+To deploy on Kubernetes or OpenShift, define the above environment variables
in a secret named `camel-kafka`. Configure the required values in
`kubefiles/secret-example.yml`, then create the secret:
+
+[source,shell]
+----
+$ kubectl apply -f kubefiles/secret-example.yml
+----
+
+==== JVM mode
+
+[source,shell]
+----
+$ mvn clean package
+$ java -jar target/quarkus-app/quarkus-run.jar
+...
+[io.quarkus] (main) camel-quarkus-examples-... started in 1.163s. Listening
on: http://0.0.0.0:8080
+----
+
+==== 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 -Dnative
+$ ./target/*-runner
+...
+[io.quarkus] (main) camel-quarkus-examples-... started in 0.013s. Listening
on: http://0.0.0.0:8080
+...
+----
+
+== Feedback
+
+Please report bugs and propose improvements via
https://github.com/apache/camel-quarkus/issues[GitHub issues of Camel Quarkus]
project.
diff --git a/quarkus-rest-json/eclipse-formatter-config.xml
b/quarkus-rest-json/eclipse-formatter-config.xml
new file mode 100644
index 00000000..2248b2b8
--- /dev/null
+++ b/quarkus-rest-json/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/quarkus-rest-json/pom.xml b/quarkus-rest-json/pom.xml
new file mode 100644
index 00000000..2264cc93
--- /dev/null
+++ b/quarkus-rest-json/pom.xml
@@ -0,0 +1,328 @@
+<?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-rest-json</artifactId>
+ <groupId>org.apache.camel.quarkus.examples</groupId>
+ <version>3.33.0-SNAPSHOT</version>
+
+ <name>Camel Quarkus :: Examples :: Quarkus Rest Json</name>
+ <description>Camel Quarkus Example :: Quarkus Rest Json</description>
+
+ <properties>
+ <quarkus.platform.version>3.33.0</quarkus.platform.version>
+
<camel-quarkus.platform.version>3.33.0-SNAPSHOT</camel-quarkus.platform.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.release>17</maven.compiler.release>
+
+ <formatter-maven-plugin.version>2.29.0</formatter-maven-plugin.version>
+ <impsort-maven-plugin.version>1.13.0</impsort-maven-plugin.version>
+ <license-maven-plugin.version>5.0.0</license-maven-plugin.version>
+ <maven-compiler-plugin.version>3.15.0</maven-compiler-plugin.version>
+ <maven-jar-plugin.version>3.5.0</maven-jar-plugin.version>
+ <maven-resources-plugin.version>3.3.1</maven-resources-plugin.version>
+ <maven-surefire-plugin.version>3.5.5</maven-surefire-plugin.version>
+ </properties>
+
+ <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>
+ </dependencies>
+ </dependencyManagement>
+
+
+ <dependencies>
+ <!-- Quarkus Rest -->
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-rest</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-rest-jackson</artifactId>
+ </dependency>
+ <!-- Camel Quarkus -->
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-jackson</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-bean</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-kafka</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-hibernate-validator</artifactId>
+ </dependency>
+
+ <!-- test dependencies -->
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.rest-assured</groupId>
+ <artifactId>rest-assured</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.awaitility</groupId>
+ <artifactId>awaitility</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>
+ <extensions>true</extensions>
+ </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>
+ <exclude>**/quarkus.log*</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>
+
+ <plugin>
+ <groupId>com.mycila</groupId>
+ <artifactId>license-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>license-format</id>
+ <goals>
+ <goal>format</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.native.enabled>true</quarkus.native.enabled>
+ </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.native.enabled>${quarkus.native.enabled}</quarkus.native.enabled>
+ </systemPropertyVariables>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>skip-testcontainers-tests</id>
+ <activation>
+ <property>
+ <name>skip-testcontainers-tests</name>
+ </property>
+ </activation>
+ <properties>
+ <skipTests>true</skipTests>
+ </properties>
+ </profile>
+ </profiles>
+
+</project>
diff --git
a/quarkus-rest-json/src/main/java/org/acme/rest/json/camel/OrderMessagingRoute.java
b/quarkus-rest-json/src/main/java/org/acme/rest/json/camel/OrderMessagingRoute.java
new file mode 100644
index 00000000..e39e7678
--- /dev/null
+++
b/quarkus-rest-json/src/main/java/org/acme/rest/json/camel/OrderMessagingRoute.java
@@ -0,0 +1,79 @@
+/*
+ * 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.acme.rest.json.camel;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import org.acme.rest.json.common.model.Order;
+import org.acme.rest.json.common.processing.ProcessedOrdersRegistry;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.kafka.KafkaConstants;
+import org.apache.camel.model.dataformat.JsonLibrary;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@ApplicationScoped
+public class OrderMessagingRoute extends RouteBuilder {
+
+ private static final Logger log =
LoggerFactory.getLogger(OrderMessagingRoute.class);
+
+ @Inject
+ ProcessedOrdersRegistry processedOrdersRegistry;
+
+ @Override
+ public void configure() throws Exception {
+
+ // Producer: Send order to Kafka with error handling
+ from("direct:sendToKafka")
+ .routeId("send-to-kafka")
+ .onException(Exception.class)
+ .log("ERROR: Failed to send message to Kafka:
${exception.message}")
+ .handled(true)
+ .end()
+ .setHeader(KafkaConstants.KEY, simple("${body.orderId}"))
+ .marshal().json(JsonLibrary.Jackson)
+ .to("kafka:{{kafka.topic.orders.requests}}")
+ .log("Message sent to Kafka topic! Order ID: ${header." +
KafkaConstants.KEY + "}");
+
+ // Consumer: Process orders from Kafka with error handling
+ from("kafka:{{kafka.topic.orders.requests}}"
+ + "?groupId={{kafka.consumer.group.id}}"
+ + "&autoOffsetReset=earliest"
+ +
"&keyDeserializer=org.apache.kafka.common.serialization.StringDeserializer"
+ +
"&valueDeserializer=org.apache.kafka.common.serialization.StringDeserializer")
+ .routeId("kafka-order-consumer")
+ .onException(Exception.class)
+ .log("ERROR: Failed to process Kafka message:
${exception.message}")
+ .handled(true)
+ .end()
+ .log("Received from Kafka: \"${body}\"")
+ .unmarshal().json(JsonLibrary.Jackson, Order.class)
+ .delay(1000) // Simulate processing time
+ .process(exchange -> {
+ Order order = exchange.getIn().getBody(Order.class);
+ if (order == null) {
+ log.error("Received null order from Kafka");
+ return;
+ }
+ log.info("✓ Order {} was processed via Kafka consumer for
customer: {}",
+ order.getOrderId(), order.getCustomerId());
+
+ // Register order as processed (for testing verification)
+
processedOrdersRegistry.registerProcessed(order.getOrderId());
+ });
+ }
+}
diff --git
a/quarkus-rest-json/src/main/java/org/acme/rest/json/camel/OrderProcessingRoute.java
b/quarkus-rest-json/src/main/java/org/acme/rest/json/camel/OrderProcessingRoute.java
new file mode 100644
index 00000000..756d7bcb
--- /dev/null
+++
b/quarkus-rest-json/src/main/java/org/acme/rest/json/camel/OrderProcessingRoute.java
@@ -0,0 +1,65 @@
+/*
+ * 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.acme.rest.json.camel;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import org.acme.rest.json.common.model.Order;
+import org.acme.rest.json.common.model.OrderResponse;
+import org.acme.rest.json.common.processing.PriceCalculator;
+import org.apache.camel.builder.RouteBuilder;
+
+@ApplicationScoped
+public class OrderProcessingRoute extends RouteBuilder {
+
+ @Override
+ public void configure() throws Exception {
+
+ // Main processing route - fire and forget
+ from("direct:processOrder")
+ .routeId("order-processing-main")
+ // Validate order is not null before processing
+ .validate(body().isNotNull())
+ .validate(body().isInstanceOf(Order.class))
+ .log("Processing order: ${body.orderId} for customer:
${body.customerId}")
+
+ // Calculate pricing
+ .bean(PriceCalculator.class, "calculate")
+ .log("Price calculated: ${body.orderId}, total:
${body.totalAmount}")
+
+ // Save Order before sending to Kafka (body will be marshaled
to JSON)
+ .setProperty("originalOrder", body())
+
+ // Send to Kafka (fire-and-forget)
+ .to("direct:sendToKafka")
+
+ // Prepare immediate response (don't wait for Kafka processing)
+ .process(exchange -> {
+ Order order = exchange.getProperty("originalOrder",
Order.class);
+ // After validation, this should never be null, but
keeping check for safety
+ if (order == null) {
+ throw new IllegalStateException("Order property is
null - cannot create response");
+ }
+
+ OrderResponse response = OrderResponse.success(
+ order.getOrderId(),
+ order.getTotalAmount());
+ exchange.getMessage().setBody(response);
+ })
+ .log("Order sent to Kafka at: ${body.timestamp}");
+
+ }
+}
diff --git
a/quarkus-rest-json/src/main/java/org/acme/rest/json/common/model/ErrorResponse.java
b/quarkus-rest-json/src/main/java/org/acme/rest/json/common/model/ErrorResponse.java
new file mode 100644
index 00000000..8039642e
--- /dev/null
+++
b/quarkus-rest-json/src/main/java/org/acme/rest/json/common/model/ErrorResponse.java
@@ -0,0 +1,67 @@
+/*
+ * 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.acme.rest.json.common.model;
+
+import java.time.LocalDateTime;
+
+import io.quarkus.runtime.annotations.RegisterForReflection;
+
+@RegisterForReflection
+public class ErrorResponse {
+
+ private String error;
+ private String orderId;
+ private LocalDateTime timestamp;
+
+ public ErrorResponse() {
+ this.timestamp = LocalDateTime.now();
+ }
+
+ public ErrorResponse(String error, String orderId) {
+ this.error = error;
+ this.orderId = orderId;
+ this.timestamp = LocalDateTime.now();
+ }
+
+ public static ErrorResponse of(String error, String orderId) {
+ return new ErrorResponse(error, orderId);
+ }
+
+ public String getError() {
+ return error;
+ }
+
+ public void setError(String error) {
+ this.error = error;
+ }
+
+ public String getOrderId() {
+ return orderId;
+ }
+
+ public void setOrderId(String orderId) {
+ this.orderId = orderId;
+ }
+
+ public LocalDateTime getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(LocalDateTime timestamp) {
+ this.timestamp = timestamp;
+ }
+}
diff --git
a/quarkus-rest-json/src/main/java/org/acme/rest/json/common/model/Order.java
b/quarkus-rest-json/src/main/java/org/acme/rest/json/common/model/Order.java
new file mode 100644
index 00000000..dbb23e31
--- /dev/null
+++ b/quarkus-rest-json/src/main/java/org/acme/rest/json/common/model/Order.java
@@ -0,0 +1,100 @@
+/*
+ * 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.acme.rest.json.common.model;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.UUID;
+
+import io.quarkus.runtime.annotations.RegisterForReflection;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotEmpty;
+
+@RegisterForReflection
+public class Order {
+
+ private String orderId;
+
+ @NotBlank(message = "Customer ID is required")
+ private String customerId;
+
+ @NotEmpty(message = "Order must contain at least one item")
+ private List<OrderItem> items = new ArrayList<>();
+
+ private BigDecimal totalAmount;
+
+ public Order() {
+ // UUID will be set in getter if not provided
+ }
+
+ public String getOrderId() {
+ if (orderId == null) {
+ orderId = UUID.randomUUID().toString();
+ }
+ return orderId;
+ }
+
+ public void setOrderId(String orderId) {
+ this.orderId = orderId;
+ }
+
+ public String getCustomerId() {
+ return customerId;
+ }
+
+ public void setCustomerId(String customerId) {
+ this.customerId = customerId;
+ }
+
+ public BigDecimal getTotalAmount() {
+ return totalAmount;
+ }
+
+ public void setTotalAmount(BigDecimal totalAmount) {
+ this.totalAmount = totalAmount;
+ }
+
+ public List<OrderItem> getItems() {
+ return items;
+ }
+
+ public void setItems(List<OrderItem> items) {
+ this.items = items;
+ }
+
+ public BigDecimal calculateTotal() {
+ if (items == null || items.isEmpty()) {
+ return BigDecimal.ZERO;
+ }
+ return items.stream()
+ .filter(Objects::nonNull)
+ .map(OrderItem::getSubtotal)
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+ }
+
+ @Override
+ public String toString() {
+ return "Order{" +
+ "orderId='" + orderId + '\'' +
+ ", customerId='" + customerId + '\'' +
+ ", items=" + items +
+ ", totalAmount=" + totalAmount +
+ '}';
+ }
+}
diff --git
a/quarkus-rest-json/src/main/java/org/acme/rest/json/common/model/OrderItem.java
b/quarkus-rest-json/src/main/java/org/acme/rest/json/common/model/OrderItem.java
new file mode 100644
index 00000000..76670989
--- /dev/null
+++
b/quarkus-rest-json/src/main/java/org/acme/rest/json/common/model/OrderItem.java
@@ -0,0 +1,105 @@
+/*
+ * 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.acme.rest.json.common.model;
+
+import java.math.BigDecimal;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.quarkus.runtime.annotations.RegisterForReflection;
+import jakarta.validation.constraints.DecimalMin;
+import jakarta.validation.constraints.Min;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+
+@RegisterForReflection
+public class OrderItem {
+
+ @NotBlank(message = "Product ID is required")
+ private String productId;
+
+ @NotBlank(message = "Product name is required")
+ private String productName;
+
+ @NotNull(message = "Quantity is required")
+ @Min(value = 1, message = "Quantity must be at least 1")
+ private Integer quantity;
+
+ @NotNull(message = "Price is required")
+ @DecimalMin(value = "0.01", message = "Price must be greater than 0")
+ private BigDecimal price;
+
+ public OrderItem() {
+ // No-arg constructor for Jackson deserialization
+ }
+
+ public OrderItem(String productId, String productName, Integer quantity,
BigDecimal price) {
+ this.productId = productId;
+ this.productName = productName;
+ this.quantity = quantity;
+ this.price = price;
+ }
+
+ public String getProductId() {
+ return productId;
+ }
+
+ public void setProductId(String productId) {
+ this.productId = productId;
+ }
+
+ public String getProductName() {
+ return productName;
+ }
+
+ public void setProductName(String productName) {
+ this.productName = productName;
+ }
+
+ public Integer getQuantity() {
+ return quantity;
+ }
+
+ public void setQuantity(Integer quantity) {
+ this.quantity = quantity;
+ }
+
+ public BigDecimal getPrice() {
+ return price;
+ }
+
+ public void setPrice(BigDecimal price) {
+ this.price = price;
+ }
+
+ @JsonIgnore
+ public BigDecimal getSubtotal() {
+ if (price != null && quantity != null) {
+ return price.multiply(BigDecimal.valueOf(quantity));
+ }
+ return BigDecimal.ZERO;
+ }
+
+ @Override
+ public String toString() {
+ return "OrderItem{" +
+ "productId='" + productId + '\'' +
+ ", productName='" + productName + '\'' +
+ ", quantity=" + quantity +
+ ", price=" + price +
+ '}';
+ }
+}
diff --git
a/quarkus-rest-json/src/main/java/org/acme/rest/json/common/model/OrderResponse.java
b/quarkus-rest-json/src/main/java/org/acme/rest/json/common/model/OrderResponse.java
new file mode 100644
index 00000000..32fdd72f
--- /dev/null
+++
b/quarkus-rest-json/src/main/java/org/acme/rest/json/common/model/OrderResponse.java
@@ -0,0 +1,98 @@
+/*
+ * 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.acme.rest.json.common.model;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+import io.quarkus.runtime.annotations.RegisterForReflection;
+
+@RegisterForReflection
+public class OrderResponse {
+
+ private String orderId;
+ private boolean confirmed;
+ private BigDecimal totalAmount;
+ private LocalDateTime timestamp;
+
+ public OrderResponse() {
+ this.timestamp = LocalDateTime.now();
+ }
+
+ public OrderResponse(String orderId, boolean confirmed) {
+ this.orderId = orderId;
+ this.confirmed = confirmed;
+ this.timestamp = LocalDateTime.now();
+ }
+
+ public static OrderResponse success(String orderId, BigDecimal
totalAmount) {
+ OrderResponse response = new OrderResponse();
+ response.setOrderId(orderId);
+ response.setConfirmed(true);
+ response.setTotalAmount(totalAmount);
+ return response;
+ }
+
+ public static OrderResponse error(String orderId) {
+ OrderResponse response = new OrderResponse();
+ response.setOrderId(orderId);
+ response.setConfirmed(false);
+ return response;
+ }
+
+ public String getOrderId() {
+ return orderId;
+ }
+
+ public void setOrderId(String orderId) {
+ this.orderId = orderId;
+ }
+
+ public boolean isConfirmed() {
+ return confirmed;
+ }
+
+ public void setConfirmed(boolean confirmed) {
+ this.confirmed = confirmed;
+ }
+
+ public BigDecimal getTotalAmount() {
+ return totalAmount;
+ }
+
+ public void setTotalAmount(BigDecimal totalAmount) {
+ this.totalAmount = totalAmount;
+ }
+
+ public LocalDateTime getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(LocalDateTime timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ @Override
+ public String toString() {
+ return "OrderResponse{" +
+ "orderId='" + orderId + '\'' +
+ ", confirmed=" + confirmed +
+ ", totalAmount=" + totalAmount +
+ ", timestamp=" + timestamp +
+ '}';
+ }
+}
diff --git
a/quarkus-rest-json/src/main/java/org/acme/rest/json/common/processing/PriceCalculator.java
b/quarkus-rest-json/src/main/java/org/acme/rest/json/common/processing/PriceCalculator.java
new file mode 100644
index 00000000..c361dd43
--- /dev/null
+++
b/quarkus-rest-json/src/main/java/org/acme/rest/json/common/processing/PriceCalculator.java
@@ -0,0 +1,81 @@
+/*
+ * 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.acme.rest.json.common.processing;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+import io.quarkus.runtime.annotations.RegisterForReflection;
+import jakarta.enterprise.context.ApplicationScoped;
+import org.acme.rest.json.common.model.Order;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Calculates order pricing based on customer ID.
+ *
+ * Customer tiers:
+ * - CUST001: GOLD (10% discount)
+ * - CUST004: PLATINUM (15% discount)
+ * - Others: STANDARD (no discount)
+ */
+@RegisterForReflection
+@ApplicationScoped
+public class PriceCalculator {
+
+ private static final Logger log =
LoggerFactory.getLogger(PriceCalculator.class);
+ private static final BigDecimal GOLD_DISCOUNT = new BigDecimal("0.10"); //
10%
+ private static final BigDecimal PLATINUM_DISCOUNT = new
BigDecimal("0.15"); // 15%
+
+ public void calculate(Order order) {
+ if (order == null) {
+ throw new IllegalArgumentException("Order cannot be null");
+ }
+
+ log.info("Calculating price for order: {}", order.getOrderId());
+
+ // Calculate subtotal from items
+ BigDecimal subtotal = order.calculateTotal();
+
+ // Apply customer discount based on customer ID
+ BigDecimal discount = getDiscountForCustomer(order.getCustomerId());
+ BigDecimal discountAmount = subtotal.multiply(discount).setScale(2,
RoundingMode.HALF_UP);
+ BigDecimal total = subtotal.subtract(discountAmount);
+
+ if (discount.compareTo(BigDecimal.ZERO) > 0) {
+ log.info("Applied {}% discount: {}", discount.multiply(new
BigDecimal("100")), discountAmount);
+ }
+
+ order.setTotalAmount(total.setScale(2, RoundingMode.HALF_UP));
+
+ log.info("Final total for order {}: {}", order.getOrderId(),
order.getTotalAmount());
+ }
+
+ private BigDecimal getDiscountForCustomer(String customerId) {
+ if (customerId == null) {
+ return BigDecimal.ZERO;
+ }
+ switch (customerId) {
+ case "CUST004":
+ return PLATINUM_DISCOUNT;
+ case "CUST001":
+ return GOLD_DISCOUNT;
+ default:
+ return BigDecimal.ZERO;
+ }
+ }
+}
diff --git
a/quarkus-rest-json/src/main/java/org/acme/rest/json/common/processing/ProcessedOrdersRegistry.java
b/quarkus-rest-json/src/main/java/org/acme/rest/json/common/processing/ProcessedOrdersRegistry.java
new file mode 100644
index 00000000..d67385c0
--- /dev/null
+++
b/quarkus-rest-json/src/main/java/org/acme/rest/json/common/processing/ProcessedOrdersRegistry.java
@@ -0,0 +1,53 @@
+/*
+ * 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.acme.rest.json.common.processing;
+
+import java.util.concurrent.CopyOnWriteArraySet;
+
+import io.quarkus.runtime.annotations.RegisterForReflection;
+import jakarta.enterprise.context.ApplicationScoped;
+
+/**
+ * Thread-safe registry of processed order IDs.
+ * Used for testing to verify that orders are processed via Kafka.
+ */
+@ApplicationScoped
+@RegisterForReflection
+public class ProcessedOrdersRegistry {
+
+ private final CopyOnWriteArraySet<String> processedOrderIds = new
CopyOnWriteArraySet<>();
+
+ /**
+ * Registers an order as processed.
+ *
+ * @param orderId the order ID
+ */
+ public void registerProcessed(String orderId) {
+ processedOrderIds.add(orderId);
+ }
+
+ /**
+ * Checks if an order has been processed.
+ *
+ * @param orderId the order ID
+ * @return true if the order has been processed
+ */
+ public boolean isProcessed(String orderId) {
+ return processedOrderIds.contains(orderId);
+ }
+
+}
diff --git
a/quarkus-rest-json/src/main/java/org/acme/rest/json/quarkus/OrderResource.java
b/quarkus-rest-json/src/main/java/org/acme/rest/json/quarkus/OrderResource.java
new file mode 100644
index 00000000..40015790
--- /dev/null
+++
b/quarkus-rest-json/src/main/java/org/acme/rest/json/quarkus/OrderResource.java
@@ -0,0 +1,87 @@
+/*
+ * 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.acme.rest.json.quarkus;
+
+import jakarta.inject.Inject;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotNull;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import org.acme.rest.json.common.model.ErrorResponse;
+import org.acme.rest.json.common.model.Order;
+import org.acme.rest.json.common.model.OrderResponse;
+import org.acme.rest.json.common.processing.ProcessedOrdersRegistry;
+import org.apache.camel.ProducerTemplate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Path("/api/orders")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class OrderResource {
+
+ private static final Logger log =
LoggerFactory.getLogger(OrderResource.class);
+
+ @Inject
+ ProducerTemplate producerTemplate;
+
+ @Inject
+ ProcessedOrdersRegistry registry;
+
+ @POST
+ public Response createOrder(@Valid @NotNull Order order) {
+ // @NotNull and @Valid ensure order and its fields are validated
before reaching here
+ log.info("Received order request for customer: {}",
order.getCustomerId());
+
+ try {
+ // Delegate to Camel route for processing
+ OrderResponse response = producerTemplate.requestBody(
+ "direct:processOrder",
+ order,
+ OrderResponse.class);
+
+ if (response == null) {
+ log.error("Order processing returned null response for order:
{}", order.getOrderId());
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
+ .entity(ErrorResponse.of("Order processing failed",
order.getOrderId()))
+ .build();
+ }
+
+ log.info("Order processing completed: {}", response.getOrderId());
+ return
Response.status(Response.Status.CREATED).entity(response).build();
+
+ } catch (Exception e) {
+ log.error("Failed to process order: {}", order.getOrderId(), e);
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
+ .entity(ErrorResponse.of("An error occurred while
processing your order", order.getOrderId()))
+ .build();
+ }
+ }
+
+ /**
+ * Check if a specific order has been processed.
+ *
+ * @param orderId the order ID to check
+ * @return true if the order has been processed
+ */
+ @GET
+ @Path("isProcessed/{orderId}")
+ public boolean isProcessed(@PathParam("orderId") String orderId) {
+ return registry.isProcessed(orderId);
+ }
+}
diff --git a/quarkus-rest-json/src/main/resources/application.properties
b/quarkus-rest-json/src/main/resources/application.properties
new file mode 100644
index 00000000..27fab82c
--- /dev/null
+++ b/quarkus-rest-json/src/main/resources/application.properties
@@ -0,0 +1,101 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+# Use Strimzi as it's power architecture compatible
+quarkus.kafka.devservices.provider = strimzi
+quarkus.kafka.devservices.image-name =
quay.io/strimzi-test-container/test-container:0.114.0-kafka-4.1.0
+quarkus.kafka.devservices.topic-partitions.orders-requests=3
+
+# Kafka topic names
+kafka.topic.orders.requests=orders-requests
+
+# Consumer group
+kafka.consumer.group.id=order-processor-group
+
+# Kafka producer configuration - disable idempotent producer to avoid null key
errors
+camel.component.kafka.additional-properties[enable.idempotence]=false
+
+# Kafka brokers in native test and production
+%test,prod.camel.component.kafka.brokers=${kafka.bootstrap.servers}
+
+# Kafka instance without Authentication
+#camel.component.kafka.brokers=${brokers}
+
+# uncomment to set Kafka instance with SASL Plain
+#camel.component.kafka.brokers=${brokers}
+#camel.component.kafka.security-protocol=SASL_SSL
+#camel.component.kafka.sasl-mechanism=PLAIN
+#camel.component.kafka.sasl-jaas-config=org.apache.kafka.common.security.plain.PlainLoginModule
required username="${id}" password="${secret}";
+
+# uncomment to set Kafka instance with SASL Oauth Bearer
+#camel.component.kafka.brokers = ${brokers}
+#camel.component.kafka.security-protocol = SASL_SSL
+#camel.component.kafka.sasl-mechanism = OAUTHBEARER
+#camel.component.kafka.sasl-jaas-config =
org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
+# oauth.client.id="${id}" \
+# oauth.client.secret="${secret}" \
+# oauth.token.endpoint.uri="${token}" ;
+#camel.component.kafka.additional-properties[sasl.login.callback.handler.class]
= io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler
+
+
+###################################
+# Kubernetes specific
+###################################
+# secrets
+#quarkus.kubernetes-config.enabled=true
+#getting secrets while deploying to kubernetes
+#quarkus.kubernetes-config.namespace=test
+#quarkus.kubernetes-config.secrets.enabled=true
+#quarkus.kubernetes-config.secrets=camel-kafka
+
+# creating container with jib
+#quarkus.container-image.build=true
+#quarkus.kubernetes.deployment-target=kubernetes
+#quarkus.container-image.group=<YOUR_IMAGE_GROUP>
+#quarkus.container-image.registry=<YOUR_REGISTRY_URL>
+
+# Uncomment to trust self signed certificates if they are presented by the
Kubernetes API server
+#quarkus.kubernetes-client.trust-certs=true
+
+# Uncomment to set resource limits
+#quarkus.kubernetes.resources.requests.memory=64Mi
+#quarkus.kubernetes.resources.requests.cpu=250m
+#quarkus.kubernetes.resources.limits.memory=512Mi
+#quarkus.kubernetes.resources.limits.cpu=1000m
+
+###################################
+# OpenShift specific
+###################################
+# secrets
+#quarkus.kubernetes-config.enabled=true
+#getting secrets while deploying to kubernetes
+#quarkus.kubernetes-config.namespace=test
+#quarkus.kubernetes-config.secrets.enabled=true
+#quarkus.kubernetes-config.secrets=camel-kafka
+
+# creating container for openshift
+#quarkus.container-image.build=true
+#quarkus.kubernetes.deployment-target=openshift
+
+# OpenShift
+#quarkus.openshift.image-pull-policy=IfNotPresent
+
+# Uncomment to set resource limits
+#quarkus.openshift.resources.requests.memory=64Mi
+#quarkus.openshift.resources.requests.cpu=250m
+#quarkus.openshift.resources.limits.memory=512Mi
+#quarkus.openshift.resources.limits.cpu=1000m
diff --git
a/quarkus-rest-json/src/test/java/org/acme/rest/json/OrderResoourceIT.java
b/quarkus-rest-json/src/test/java/org/acme/rest/json/OrderResoourceIT.java
new file mode 100644
index 00000000..aa6b100e
--- /dev/null
+++ b/quarkus-rest-json/src/test/java/org/acme/rest/json/OrderResoourceIT.java
@@ -0,0 +1,25 @@
+/*
+ * 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.acme.rest.json;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+import org.junit.jupiter.api.TestInstance;
+
+@QuarkusIntegrationTest
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+class OrderResourceIT extends OrderResourceTest {
+}
diff --git
a/quarkus-rest-json/src/test/java/org/acme/rest/json/OrderResourceTest.java
b/quarkus-rest-json/src/test/java/org/acme/rest/json/OrderResourceTest.java
new file mode 100644
index 00000000..b2f8ff05
--- /dev/null
+++ b/quarkus-rest-json/src/test/java/org/acme/rest/json/OrderResourceTest.java
@@ -0,0 +1,166 @@
+/*
+ * 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.acme.rest.json;
+
+import java.util.concurrent.TimeUnit;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.restassured.http.ContentType;
+import io.restassured.response.Response;
+import org.junit.jupiter.api.Test;
+
+import static io.restassured.RestAssured.get;
+import static io.restassured.RestAssured.given;
+import static org.awaitility.Awaitility.await;
+import static org.hamcrest.CoreMatchers.*;
+
+@QuarkusTest
+public class OrderResourceTest {
+
+ private static final String ORDER_ENDPOINT = "/api/orders";
+
+ /**
+ * Checks if an order has been processed by querying the test endpoint.
+ * Works in both JVM and native modes.
+ *
+ * @param orderId the order ID to check
+ * @return true if the order has been processed
+ */
+ protected boolean isOrderProcessed(String orderId) {
+ return given()
+ .log().ifValidationFails() // Only log on failure
+ .when()
+ .get(ORDER_ENDPOINT + "/isProcessed/" + orderId)
+ .then()
+ .statusCode(200)
+ .extract()
+ .as(Boolean.class);
+ }
+
+ private static String createOrderJson(String customerId) {
+ return "{" +
+ "\"customerId\": \"" + customerId + "\"," +
+ "\"items\": [" +
+ "{" +
+ "\"productId\": \"PROD001\"," +
+ "\"productName\": \"Widget A\"," +
+ "\"quantity\": 1," +
+ "\"price\": 50.00" +
+ "}," +
+ "{" +
+ "\"productId\": \"PROD002\"," +
+ "\"productName\": \"Widget B\"," +
+ "\"quantity\": 2," +
+ "\"price\": 25.00" +
+ "}" +
+ "]" +
+ "}";
+ }
+
+ /**
+ * Test order creation with GOLD customer (10% discount).
+ * Subtotal: $100.00
+ * Discount: 10% = $10.00
+ * Expected Total: $90.00
+ */
+ @Test
+ public void testGoldCustomerDiscount() {
+ String orderJson = createOrderJson("CUST001");
+
+ Response response = given()
+ .contentType(ContentType.JSON)
+ .body(orderJson)
+ .when()
+ .post(ORDER_ENDPOINT)
+ .then()
+ .statusCode(201)
+ .body("confirmed", equalTo(true))
+ .body("orderId", notNullValue())
+ .body("totalAmount", equalTo(90.00f))
+ .extract()
+ .response();
+
+ String orderId = response.jsonPath().getString("orderId");
+
+ // Verify order was processed via Kafka (works in both JVM and native
modes)
+ await()
+ .atMost(30, TimeUnit.SECONDS)
+ .untilAsserted(() -> isOrderProcessed(orderId));
+ }
+
+ /**
+ * Test order creation with PLATINUM customer (15% discount).
+ * Subtotal: $100.00
+ * Discount: 15% = $15.00
+ * Expected Total: $85.00
+ */
+ @Test
+ public void testPlatinumCustomerDiscount() {
+ String orderJson = createOrderJson("CUST004");
+
+ Response response = given()
+ .contentType(ContentType.JSON)
+ .body(orderJson)
+ .when()
+ .post(ORDER_ENDPOINT)
+ .then()
+ .statusCode(201)
+ .body("confirmed", equalTo(true))
+ .body("orderId", notNullValue())
+ .body("totalAmount", equalTo(85.00f))
+ .extract()
+ .response();
+
+ String orderId = response.jsonPath().getString("orderId");
+
+ // Verify order was processed via Kafka (works in both JVM and native
modes)
+ await()
+ .atMost(10, TimeUnit.SECONDS)
+ .untilAsserted(() -> isOrderProcessed(orderId));
+ }
+
+ /**
+ * Test order creation with STANDARD customer (no discount).
+ * Subtotal: $100.00
+ * Discount: 0%
+ * Expected Total: $100.00
+ */
+ @Test
+ public void testStandardCustomerNoDiscount() {
+ String orderJson = createOrderJson("CUST999");
+
+ Response response = given()
+ .contentType(ContentType.JSON)
+ .body(orderJson)
+ .when()
+ .post(ORDER_ENDPOINT)
+ .then()
+ .statusCode(201)
+ .body("confirmed", equalTo(true))
+ .body("orderId", notNullValue())
+ .body("totalAmount", equalTo(100.00f))
+ .extract()
+ .response();
+
+ String orderId = response.jsonPath().getString("orderId");
+
+ // Verify order was processed via Kafka (works in both JVM and native
modes)
+ await()
+ .atMost(10, TimeUnit.SECONDS)
+ .untilAsserted(() -> isOrderProcessed(orderId));
+ }
+}
diff --git a/quarkus-rest-json/test-requests.sh
b/quarkus-rest-json/test-requests.sh
new file mode 100755
index 00000000..79d639de
--- /dev/null
+++ b/quarkus-rest-json/test-requests.sh
@@ -0,0 +1,112 @@
+#!/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.
+#
+
+
+# Test script for the Camel-Quarkus REST Integration Example
+
+
+if ! jq --version &> /dev/null; then
+ echo "Error: jq is not installed. Please install it first." >&2
+ exit 1
+fi
+
+# rest of your script...
+BASE_URL="http://localhost:8080"
+
+echo "========================================="
+echo "Camel-Quarkus REST Integration Tests"
+echo "========================================="
+echo ""
+
+# Colors for output
+GREEN='\033[0;32m'
+BLUE='\033[0;34m'
+NC='\033[0m' # No Color
+
+# Test 1: Create order with GOLD customer (10% discount)
+echo -e "${BLUE}2. Creating order for GOLD customer (CUST001)...${NC}"
+curl -s -X POST "${BASE_URL}/api/orders" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "customerId": "CUST001",
+ "items": [
+ {
+ "productId": "PROD001",
+ "productName": "Widget A",
+ "quantity": 1,
+ "price": 50
+ },
+ {
+ "productId": "PROD002",
+ "productName": "Widget B",
+ "quantity": 2,
+ "price": 25
+ }
+ ]
+ }' | jq .
+echo -e "\n"
+
+# Test 2: PLATINUM customer (15% discount)
+echo -e "${BLUE}3. Creating order for PLATINUM customer (CUST004)...${NC}"
+curl -s -X POST "${BASE_URL}/api/orders" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "customerId": "CUST004",
+ "items": [
+ {
+ "productId": "PROD001",
+ "productName": "Widget A",
+ "quantity": 1,
+ "price": 50
+ },
+ {
+ "productId": "PROD002",
+ "productName": "Widget B",
+ "quantity": 2,
+ "price": 25
+ }
+ ]
+ }' | jq .
+echo -e "\n"
+
+# Test 3: STANDARD customer (no discount)
+echo -e "${BLUE}4. Creating order for STANDARD customer (CUST999)...${NC}"
+curl -s -X POST "${BASE_URL}/api/orders" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "customerId": "CUST999",
+ "items": [
+ {
+ "productId": "PROD001",
+ "productName": "Widget A",
+ "quantity": 1,
+ "price": 50
+ },
+ {
+ "productId": "PROD002",
+ "productName": "Widget B",
+ "quantity": 2,
+ "price": 25
+ }
+ ]
+ }' | jq .
+echo -e "\n"
+
+echo -e "${GREEN}=========================================${NC}"
+echo -e "${GREEN}All tests completed!${NC}"
+echo -e "${GREEN}=========================================${NC}"