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 a2969aa Create an example project for vertx-websocket
a2969aa is described below
commit a2969aae53b303495e3f938ed11ac4094e42d65b
Author: shravani <[email protected]>
AuthorDate: Mon Apr 8 17:25:57 2024 +0530
Create an example project for vertx-websocket
---
docs/modules/ROOT/attachments/examples.json | 5 +
vertx-websocket-chat/README.adoc | 56 ++++
vertx-websocket-chat/eclipse-formatter-config.xml | 276 ++++++++++++++++++++
vertx-websocket-chat/pom.xml | 287 +++++++++++++++++++++
.../main/java/org/acme/websocket/ChatMessage.java | 41 +++
.../java/org/acme/websocket/SessionManager.java | 54 ++++
.../java/org/acme/websocket/WebSocketRoutes.java | 115 +++++++++
.../main/resources/META-INF/resources/index.html | 201 +++++++++++++++
.../src/main/resources/application.properties | 20 ++
.../java/org/acme/websocket/WebSocketRoutesIT.java | 23 ++
.../org/acme/websocket/WebSocketRoutesTest.java | 90 +++++++
11 files changed, 1168 insertions(+)
diff --git a/docs/modules/ROOT/attachments/examples.json
b/docs/modules/ROOT/attachments/examples.json
index d2e7c04..436a87d 100644
--- a/docs/modules/ROOT/attachments/examples.json
+++ b/docs/modules/ROOT/attachments/examples.json
@@ -98,5 +98,10 @@
"title": "Tokenize a CSV file",
"description": "Shows how to define a Camel route in XML for tokenizing a
CSV a file.",
"link":
"https://github.com/apache/camel-quarkus-examples/tree/main/file-split-log-xml"
+ },
+ {
+ "title": "Vertx-Websocket Chat",
+ "description": "Shows how to configure a WebSocket server and interact
with connected peers.",
+ "link":
"https://github.com/apache/camel-quarkus-examples/tree/main/vertx-websocket-chat"
}
]
\ No newline at end of file
diff --git a/vertx-websocket-chat/README.adoc b/vertx-websocket-chat/README.adoc
new file mode 100644
index 0000000..34ce8de
--- /dev/null
+++ b/vertx-websocket-chat/README.adoc
@@ -0,0 +1,56 @@
+= Vertx-Websocket Chat: A Camel Quarkus example
+:cq-example-description: An example that shows how to configure a WebSocket
server and interact with connected peers.
+
+{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.
+
+== Start in the Development mode
+
+You can run your application in dev mode that enables live coding using:
+
+[source,shell]
+----
+$ mvn compile quarkus:dev
+----
+
+The above command compiles the project, starts the application and lets the
Quarkus tooling watch for changes in your workspace. Any modifications in your
project will automatically take effect in the running application.You can find
the application running http://localhost:8080
+
+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.
+
+As we run the example in Quarkus Dev Mode, you can connect to the websocket by
providing a username.Once you connect, you can see a chat room where you can
send/receive messages.
+You can write your message in the message section and you will be able to send
the message either to a specific peer or to all of the users conncected by
clicking the dropdown of the send button.You can click on the peer of your
choice from the list to send the message only to that speicific peer.On
clicking Send All,you can send your message to all of the users connected
locally.You'll also be able to see the conversation on your window.
+
+=== 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]
+
+==== JVM mode
+
+[source,shell]
+----
+$ mvn clean package
+$ java -jar target/quarkus-app/quarkus-run.jar
+----
+
+==== 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
+$ ./target/*-runner
+----
+
+== Feedback
+
+Please report bugs and propose improvements via
https://github.com/apache/camel-quarkus/issues[GitHub issues of Camel Quarkus]
project.
\ No newline at end of file
diff --git a/vertx-websocket-chat/eclipse-formatter-config.xml
b/vertx-websocket-chat/eclipse-formatter-config.xml
new file mode 100644
index 0000000..2248b2b
--- /dev/null
+++ b/vertx-websocket-chat/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/vertx-websocket-chat/pom.xml b/vertx-websocket-chat/pom.xml
new file mode 100644
index 0000000..320da7d
--- /dev/null
+++ b/vertx-websocket-chat/pom.xml
@@ -0,0 +1,287 @@
+<?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-vertx-websocket-chat</artifactId>
+ <groupId>org.apache.camel.quarkus.examples</groupId>
+ <version>3.10.0-SNAPSHOT</version>
+
+ <name>Camel Quarkus :: Examples :: Vertx-Websocket chat</name>
+ <description>Camel Quarkus Example :: Implementing Websocket</description>
+
+ <properties>
+ <quarkus.platform.version>3.9.0</quarkus.platform.version>
+
<camel-quarkus.platform.version>3.10.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.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.23.0</formatter-maven-plugin.version>
+ <impsort-maven-plugin.version>1.9.0</impsort-maven-plugin.version>
+ <license-maven-plugin.version>4.2</license-maven-plugin.version>
+ <maven-compiler-plugin.version>3.11.0</maven-compiler-plugin.version>
+ <maven-jar-plugin.version>3.3.0</maven-jar-plugin.version>
+ <maven-resources-plugin.version>3.3.1</maven-resources-plugin.version>
+ <maven-surefire-plugin.version>3.1.2</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>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-bean</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-jackson</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-vertx-websocket</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-rest</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-arc</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>
\ No newline at end of file
diff --git
a/vertx-websocket-chat/src/main/java/org/acme/websocket/ChatMessage.java
b/vertx-websocket-chat/src/main/java/org/acme/websocket/ChatMessage.java
new file mode 100644
index 0000000..58d264d
--- /dev/null
+++ b/vertx-websocket-chat/src/main/java/org/acme/websocket/ChatMessage.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.acme.websocket;
+
+import io.quarkus.runtime.annotations.RegisterForReflection;
+
+@RegisterForReflection(fields = false)
+public class ChatMessage {
+ private String messageContent;
+ private String recipientName;
+
+ public String getMessageContent() {
+ return messageContent;
+ }
+
+ public void setMessageContent(String messageContent) {
+ this.messageContent = messageContent;
+ }
+
+ public String getRecipientName() {
+ return recipientName;
+ }
+
+ public void setRecipientName(String recipientName) {
+ this.recipientName = recipientName;
+ }
+}
diff --git
a/vertx-websocket-chat/src/main/java/org/acme/websocket/SessionManager.java
b/vertx-websocket-chat/src/main/java/org/acme/websocket/SessionManager.java
new file mode 100644
index 0000000..85f0376
--- /dev/null
+++ b/vertx-websocket-chat/src/main/java/org/acme/websocket/SessionManager.java
@@ -0,0 +1,54 @@
+/*
+ * 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.websocket;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import io.quarkus.runtime.annotations.RegisterForReflection;
+import jakarta.inject.Singleton;
+
+@Singleton
+@RegisterForReflection
+public class SessionManager {
+ private final Map<String, String> SESSIONS = new ConcurrentHashMap<>();
+
+ public void startSession(String userName, String connectionKey) {
+ SESSIONS.put(userName.toLowerCase(), connectionKey);
+ }
+
+ public void endSession(String userName) {
+ SESSIONS.remove(userName.toLowerCase());
+ }
+
+ public String getConnectionKey(String userName) {
+ return SESSIONS.get(userName.toLowerCase());
+ }
+
+ public boolean isSessionExists(String userName) {
+ return SESSIONS.containsKey(userName.toLowerCase());
+ }
+
+ public String[] getAllConnectedUsers() {
+ String[] connectedUsers = new String[SESSIONS.size()];
+ int index = 0;
+ for (String userName : SESSIONS.keySet()) {
+ connectedUsers[index++] = userName;
+ }
+ return connectedUsers;
+ }
+}
diff --git
a/vertx-websocket-chat/src/main/java/org/acme/websocket/WebSocketRoutes.java
b/vertx-websocket-chat/src/main/java/org/acme/websocket/WebSocketRoutes.java
new file mode 100644
index 0000000..b9bb127
--- /dev/null
+++ b/vertx-websocket-chat/src/main/java/org/acme/websocket/WebSocketRoutes.java
@@ -0,0 +1,115 @@
+/*
+ * 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.websocket;
+
+import io.vertx.core.http.ServerWebSocket;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import org.apache.camel.Message;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.vertx.websocket.VertxWebsocketConstants;
+import org.apache.camel.model.rest.RestBindingMode;
+import org.jboss.logging.Logger;
+
+@ApplicationScoped
+public class WebSocketRoutes extends RouteBuilder {
+ static final Logger LOG = Logger.getLogger(WebSocketRoutes.class);
+
+ @Inject
+ SessionManager sessionManager;
+
+ @Override
+ public void configure() throws Exception {
+
from("vertx-websocket:/chat/{userName}?fireWebSocketConnectionEvents=true")
+ .choice()
+
+ // Capture OPEN events to track newly connected peers
+ .when(simple("${header.CamelVertxWebsocket.event} == 'OPEN'"))
+ .process(exchange -> {
+ Message message = exchange.getMessage();
+ String userName = message.getHeader("userName",
String.class);
+ if (!sessionManager.isSessionExists(userName)) {
+ String connectionKey =
message.getHeader(VertxWebsocketConstants.CONNECTION_KEY, String.class);
+ sessionManager.startSession(userName, connectionKey);
+ LOG.infof("Session started for user: %s", userName);
+ message.setBody("<<<<< " + userName + ": joined the
chat");
+ } else {
+ // Reject connections for a user name that is already
taken
+ ServerWebSocket webSocket =
message.getBody(ServerWebSocket.class);
+ // RFC 6455 status codes:
https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1
+ webSocket.close((short) 1000,
"SESSION_ALREADY_EXISTS");
+ LOG.warnf("Rejected connection for user: %s. User
session already exists", userName);
+ }
+ })
+ .to("vertx-websocket:/chat/{userName}?sendToAll=true")
+ .endChoice()
+
+ // Capture MESSAGE events and broadcast them to all connected
peers or specified peer
+ .when(simple("${header.CamelVertxWebsocket.event} ==
'MESSAGE'"))
+ .choice()
+ .when(body().contains("recipientName"))
+ .unmarshal().json(ChatMessage.class)
+ .process(exchange -> {
+ Message message = exchange.getMessage();
+ ChatMessage chatMessage =
message.getBody(ChatMessage.class);
+
+ String recipientConnectionKey =
sessionManager.getConnectionKey(chatMessage.getRecipientName());
+
exchange.getMessage().setHeader(VertxWebsocketConstants.CONNECTION_KEY,
recipientConnectionKey);
+ exchange.getMessage().setBody(chatMessage);
+ })
+ .setBody().simple("<<<<< ${header.userName}:
${body.messageContent}")
+ .to("vertx-websocket:/chat/{userName}")
+ .otherwise()
+ .log("New message from user ${header.userName}: ${body}")
+ .setBody().simple("<<<<< ${header.userName}: ${body}")
+ .to("vertx-websocket:/chat/{userName}?sendToAll=true")
+ .endChoice()
+
+ // Capture CLOSE events to track peers disconnecting
+ .when(simple("${header.CamelVertxWebsocket.event} == 'CLOSE'"))
+ .process(exchange -> {
+ Message message = exchange.getMessage();
+ String userName = message.getHeader("userName",
String.class);
+ String connectionKey =
message.getHeader(VertxWebsocketConstants.CONNECTION_KEY, String.class);
+ String userConnectionKey =
sessionManager.getConnectionKey(userName);
+ if (!connectionKey.equals(userConnectionKey)) {
+ // WebSocket was closed due to a username that is
already active. No need for further processing
+ message.setBody(null);
+ return;
+ }
+
+ if (sessionManager.isSessionExists(userName)) {
+ LOG.infof("Session ended for user: %s", userName);
+ sessionManager.endSession(userName);
+ }
+ })
+ .setBody().simple("<<<<< ${header.userName} left the chat")
+ .to("vertx-websocket:/chat/{userName}?sendToAll=true")
+ .endChoice();
+
+ //Displays list of connected users in the UI
+ restConfiguration().bindingMode(RestBindingMode.json);
+
+ rest("/peers")
+ .get()
+ .to("direct:getConnectedUsers");
+
+ from("direct:getConnectedUsers")
+ .setBody(method(sessionManager, "getAllConnectedUsers"));
+
+ }
+}
diff --git
a/vertx-websocket-chat/src/main/resources/META-INF/resources/index.html
b/vertx-websocket-chat/src/main/resources/META-INF/resources/index.html
new file mode 100644
index 0000000..549b359
--- /dev/null
+++ b/vertx-websocket-chat/src/main/resources/META-INF/resources/index.html
@@ -0,0 +1,201 @@
+<!--
+
+ 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.
+
+-->
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>Vert.x WebSocket Chat Demo</title>
+ <link
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM"
crossorigin="anonymous">
+ <script src="https://code.jquery.com/jquery-3.7.1.slim.min.js"
integrity="sha256-kmHvs0B+OpCW5GVHUNjv9rOmY0IvSIRcf7zGUDTDQM8="
crossorigin="anonymous"></script>
+</head>
+<body>
+ <div class="toast-container position-fixed bottom-0 end-0 p-3">
+ <div id="liveToast" class="toast" role="alert" aria-live="assertive"
aria-atomic="true">
+ <div class="toast-header">
+ <strong class="me-auto">Error</strong>
+ <button type="button" class="btn-close"
data-bs-dismiss="toast" aria-label="Close"></button>
+ </div>
+ <div id="toast-body" class="toast-body">
+ Chat session already exists for this user!
+ </div>
+ </div>
+ </div>
+
+ <div class="container" style="margin-top: 30px">
+ <div class="container">
+ <h4>Camel Quarkus Vert.x WebSocket Chat</h4>
+ </div>
+
+ <div class="container" id="connect-dialog">
+ <div class="mb-3">
+ <div class="mb-3">
+ <label for="userName" class="col-form-label">Enter your
chat user name</label>
+ <input type="text" class="form-control" id="userName"
maxlength="50" style="width:25%"/>
+ </div>
+ <div class="mb-3">
+ <button type="button" class="btn btn-primary" id="connect"
onclick="startSession()">Connect</button>
+ </div>
+ </div>
+ </div>
+
+ <div id="chat-dialog" class="container d-none">
+ <div class="mb-3">
+ <div class="col-auto">
+ <textarea class="form-control" rows="10" cols="100"
readonly id="chat"></textarea>
+ </div>
+ </div>
+ <div class="mb-3">
+ <div class="mb-3">
+ <label for="message" class="col-form-label">Message</label>
+ <input type="text" class="form-control" id="message"
style="width:50%"/>
+ </div>
+ <div class="dropdown">
+ <button type="button" class="btn btn-secondary
dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false" id="sending"
onclick="listUsers()">Send</button>
+ <ul class="dropdown-menu"
aria-labelledby="dropdownMenuButton1" id="userList">
+
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+ <script
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz"
crossorigin="anonymous"></script>
+ <script>
+ const userName = $("#userName");
+ const chat = $("#chat");
+ const message = $("#message");
+ const connectDialog = $("#connect-dialog");
+ const chatDialog = $("#chat-dialog");
+
+ userName.val("");
+ chat.val("");
+ message.val("");
+
+ $(userName).keypress(function(event){
+ if(event.keyCode == 13 || event.which == 13) {
+ startSession();
+ }
+ });
+
+ $(message).keypress(function(event){
+ if(event.keyCode == 13 || event.which == 13) {
+ sendMessage();
+ }
+ });
+
+ function startSession() {
+ const userNameValue = userName.val().trim();
+ if (userNameValue.length) {
+ socket = new WebSocket("ws://" + location.host + "/chat/" +
userNameValue);
+ socket.addEventListener("message", (event) => {
+ if (!event.data.toString().startsWith("<<<<< " +
userName.val() + ":")) {
+ chat.val(chat.val() + event.data + "\n");
+ scrollChat();
+ }
+ });
+
+ socket.addEventListener("error", (event) => {
+ console.log("WebSocket error: ", event);
+ });
+
+ socket.addEventListener("open", (event) => {
+ connectDialog.addClass('d-none');
+ chatDialog.removeClass('d-none');
+ });
+
+ socket.addEventListener("close", (event) => {
+ if (event.reason === 'SESSION_ALREADY_EXISTS') {
+ connectDialog.removeClass('d-none');
+ chatDialog.addClass('d-none');
+
bootstrap.Toast.getOrCreateInstance($('#liveToast')).show();
+ }
+ });
+ }
+ }
+
+ function sendMessage() {
+ if (message.val().length) {
+ socket.send(message.val());
+ chat.val(chat.val() + ">>>>> " + userName.val() + ": " +
message.val() + "\n");
+ message.val("");
+ scrollChat();
+ }
+ }
+
+ function sendDM(user){
+ let recipient = user;
+
+ let data = {
+ recipientName: recipient,
+ messageContent: message.val()
+ };
+
+ if (recipient.length && message.length) {
+ socket.send(JSON.stringify(data));
+ chat.val(chat.val() + ">>>>> " + userName.val() + ": " +
message.val() + "\n");
+ message.val("");
+ scrollChat();
+ }
+ }
+
+ async function getConnectedUsers() {
+ try{
+ const response = await fetch('/peers');
+ const peers = await response.json();
+ return peers;
+ }catch(error){
+ console.log('Error',error);
+ throw error;
+ }
+ }
+
+ async function listUsers() {
+ const currentUser = userName.val().trim();
+ let userList = document.getElementById("userList");
+ userList.innerHTML = "";
+ try {
+ let connectedUsers = await getConnectedUsers();
+ connectedUsers.forEach(function(user) {
+ if (user !== currentUser){
+ let listItem = document.createElement("button");
+ listItem.classList.add("dropdown-item");
+ listItem.innerText = user;
+ listItem.addEventListener("click", function() {
+ sendDM(user);
+ });
+ userList.appendChild(listItem);
+ }
+ });
+
+ let sendAll = document.createElement("button");
+ sendAll.classList.add("dropdown-item");
+ sendAll.innerText = "Send All";
+ sendAll.addEventListener("click", sendMessage);
+ userList.appendChild(sendAll);
+ } catch(error) {
+ console.error('Error populating user list:', error);
+ }
+ }
+
+ function scrollChat() {
+ chat.scrollTop($(chat)[0].scrollHeight);
+ }
+ </script>
+</body>
+</html>
diff --git a/vertx-websocket-chat/src/main/resources/application.properties
b/vertx-websocket-chat/src/main/resources/application.properties
new file mode 100644
index 0000000..0a48b4f
--- /dev/null
+++ b/vertx-websocket-chat/src/main/resources/application.properties
@@ -0,0 +1,20 @@
+## ---------------------------------------------------------------------------
+## 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
+#
+quarkus.banner.enabled = false
diff --git
a/vertx-websocket-chat/src/test/java/org/acme/websocket/WebSocketRoutesIT.java
b/vertx-websocket-chat/src/test/java/org/acme/websocket/WebSocketRoutesIT.java
new file mode 100644
index 0000000..84a61b1
--- /dev/null
+++
b/vertx-websocket-chat/src/test/java/org/acme/websocket/WebSocketRoutesIT.java
@@ -0,0 +1,23 @@
+/*
+ * 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.websocket;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+public class WebSocketRoutesIT extends WebSocketRoutesTest {
+}
diff --git
a/vertx-websocket-chat/src/test/java/org/acme/websocket/WebSocketRoutesTest.java
b/vertx-websocket-chat/src/test/java/org/acme/websocket/WebSocketRoutesTest.java
new file mode 100644
index 0000000..efd630d
--- /dev/null
+++
b/vertx-websocket-chat/src/test/java/org/acme/websocket/WebSocketRoutesTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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.websocket;
+
+import java.net.URI;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import io.quarkus.test.common.http.TestHTTPResource;
+import io.quarkus.test.junit.QuarkusTest;
+import io.vertx.core.Vertx;
+import io.vertx.core.buffer.Buffer;
+import io.vertx.core.http.HttpClient;
+import io.vertx.core.http.WebSocket;
+import org.junit.jupiter.api.Test;
+
+@QuarkusTest
+public class WebSocketRoutesTest {
+ @TestHTTPResource("/chat/bob")
+ URI userBob;
+
+ @TestHTTPResource("/chat/amy")
+ URI userAmy;
+
+ @Test
+ void chatTest() throws InterruptedException {
+ CountDownLatch connectLatch = new CountDownLatch(2);
+ CountDownLatch messageLatch = new CountDownLatch(2);
+
+ Vertx vertx = Vertx.vertx();
+ HttpClient client = vertx.createHttpClient();
+ try {
+ AtomicReference<WebSocket> bobWebSocketAtomicReference = new
AtomicReference<>();
+ client.webSocket(userBob.getPort(), userBob.getHost(),
userBob.getPath()).onSuccess(webSocket -> {
+ bobWebSocketAtomicReference.set(webSocket);
+ connectLatch.countDown();
+ });
+
+ AtomicReference<WebSocket> amyWebSocketAtomicReference = new
AtomicReference<>();
+ client.webSocket(userAmy.getPort(), userAmy.getHost(),
userAmy.getPath()).onSuccess(webSocket -> {
+ amyWebSocketAtomicReference.set(webSocket);
+ connectLatch.countDown();
+ });
+
+ connectLatch.await(5, TimeUnit.SECONDS);
+
+ WebSocket bobWebSocket = bobWebSocketAtomicReference.get();
+ bobWebSocket.handler(message -> {
+ if (message.toString().toLowerCase().contains("hi bob")) {
+ messageLatch.countDown();
+ }
+ });
+
+ WebSocket amyWebSocket = amyWebSocketAtomicReference.get();
+ amyWebSocket.handler(message -> {
+ if (message.toString().toLowerCase().contains("hi amy")) {
+ messageLatch.countDown();
+ }
+ });
+
+ bobWebSocket.write(Buffer.buffer("Hi Amy"));
+ amyWebSocket.write(Buffer.buffer("Hi Bob"));
+
+ messageLatch.await(5, TimeUnit.SECONDS);
+ } finally {
+ if (client != null) {
+ client.close();
+ }
+
+ if (vertx != null) {
+ vertx.close();
+ }
+ }
+ }
+}