红帽构建的 Apache Camel for Quarkus 入门
红帽构建的 Apache Camel for Quarkus 入门
摘要
前言
向红帽构建的 Apache Camel 文档提供反馈
要报告错误或改进文档,请登录您的红帽 JIRA 帐户并提交问题。如果您没有红帽 JIRA 帐户,系统会提示您创建一个帐户。
流程
- 要创建 ticket,请点击此链接: 创建 ticket
- 在 Summary 中输入问题的简短描述。
- 提供有关描述中问题或功能增强的详细描述。包括一个 URL,以在文档中发生问题。
- 点 Submit 创建问题并将其路由到适当的文档团队。
第 1 章 Red Hat build of Apache Camel for Quarkus 概述
红帽构建的 Apache Camel for Quarkus 将 Apache Camel 的集成功能及其大量组件库引入 Quarkus 运行时。
使用红帽构建的 Apache Camel for Quarkus 的好处包括:
- 让用户能够利用性能优势、developer joy 和容器第一个由 Quarkus 提供的 ethos。
- 为许多 Apache Camel 组件提供 Quarkus 扩展。
- 利用 Camel 中所做的很多性能改进,从而提高了内存占用率,更不依赖于反应速度和更快的启动时间。
第 2 章 访问集成的开源功能
红帽构建的 Apache Camel 在各种环境中经过认证并提供支持,将最佳开源集成项目合并到一个强大的企业级工具包中,旨在简化和加速现代业务云原生集成。
这些集成包括:
- Apache Camel 集成框架,实施企业集成模式并提供数百个预构建组件和连接器。
- 适用于 Apache Camel 的 Kaoto 视觉设计器.
- HawtIO 模块化 Web 控制台,用于故障排除和远程集成管理。
- 用于开发和使用简单对象访问协议(SOAP) Web 服务的 Apache CXF。
- Camel CLI 用于迭代集成原型.
- VS Code 开发工具,用于代码协助和调试。
- 需要许可库的额外 Camel 组件。
- 用于 Backstage 的 Camel 金级路径模板。
- 通过 Prometheus 和 OpenTelemetry 监控 和追踪。
- Narayana 事务管理器.
- Quarkus 和 Spring Boot 运行时。
- 带有同步安全更新 的 Quarkus 平台 成员。
第 3 章 工具
3.1. 语言
在 Red Hat build of Apache Camel for Quarkus 中,您可以使用以下语言定义 Camel 路由:
- Java DSL
- YAML
- XML IO
3.2. HawtIO diagnostics Console
HawtIO diagnostics 控制台是一个可插拔的 Web 诊断控制台,用于构建使用现代 Web 技术(如 React 和 PatternFly)构建的 Apache Camel。HawtIO 提供了一个中央接口,用于根据您启用的插件,检查和管理一个或多个启用了 HawtIO 的容器的详细信息。您可以监控 HawtIO 和系统资源,执行更新,以及启动或停止服务。
如需更多信息,请参阅 HawtIO diagnose Console 文档中的使用 Jolokia 为 HawtIO Online 设置 Quarkus 应用程序 部分
3.3. Kaoto
Kaoto (Kamel Orchestration Tool)是一个低的,没有基于 Apache Camel 的代码集成设计程序,可让您创建和编辑集成。Kaoto 可扩展、灵活,适应不同的用例。
如需更多信息,请参阅 Kaoto 文档中的 创建 Camel 路由 部分。
3.4. Camel CLI
Camel CLI 是一个基于 JBang 的 Camel 应用程序,您可以使用它来创建和运行 Camel 路由。
如需更多信息,请参阅 Red Hat build of Apache Camel for Quarkus Tooling Guide 文档中的 创建并运行 Camel 路由 部分。
3.5. IDE 插件
您可以使用语言支持、代码/配置完成、项目创建向导等安装插件。该插件在每个各自 IDE 市场中可用。
并非所有插件都由红帽提供的,其中一些插件目前不被支持,但此处提供了作为考虑的选项。
VS Code:
eclipse:
- Eclipse 插件 (当前不支持)
Jetbrains:
- IntelliJ 插件 (目前不支持)
检查插件文档,以了解如何为您的首选 IDE 创建项目。
3.6. Camel 内容辅助
以下插件在编辑 Camel 路由和 application.properties
时提供对内容协助的支持:
eclipse:
JetBrains:
- Apache Camel IDEA 插件 (并不总是最新)
VS Code:
- 用于 Camel 的 VS Code 语言支持
- Apache Camel 的调试适配器,以调试以 Java、YAML 或 XML 本地编写的 Camel 集成。
- YAML
- XML
其他:
- 如果您使用支持 语言服务器协议 的任何其他 IDE,您可以手动安装和配置 Camel Language Server
有关 Apache Camel 中工具的更多信息,请参阅 工具指南。
有关 开发支持范围的更多信息,请参阅 红帽支持 门户(需要登录)中的开发支持覆盖范围。
第 4 章 红帽构建的 Apache Camel for Quarkus 入门
本指南介绍了红帽构建的 Apache Camel for Quarkus,这是创建项目的各种方法,以及如何使用红帽构建的 Apache Camel for Quarkus 构建应用程序:
4.1. Red Hat build of Apache Camel for Quarkus 概述
红帽构建的 Apache Camel for Quarkus 将 Apache Camel 的集成功能及其大量组件库引入 Quarkus 运行时。
使用红帽构建的 Apache Camel for Quarkus 的好处包括:
- 让用户能够利用性能优势、developer joy 和容器第一个由 Quarkus 提供的 ethos。
- 为许多 Apache Camel 组件提供 Quarkus 扩展。
- 利用 Camel 中所做的很多性能改进,从而提高了内存占用率,更不依赖于反应速度和更快的启动时间。
4.2. 使用红帽构建的 Apache Camel for Quarkus 构建第一个项目
4.2.1. 概述
您可以使用 code.quarkus.redhat.com 生成 Quarkus Maven 项目,该项目会自动添加并配置要在应用程序中使用的扩展。
本节介绍了使用红帽构建的 Apache Camel for Quarkus 创建 Quarkus Maven 项目的过程,包括:
- 使用 code.quarkus.redhat.com创建框架应用程序
- 添加简单的 Camel 路由
- 探索应用程序代码
- 在开发模式中编译应用程序
- 测试应用程序
4.2.2. 使用 code.quarkus.redhat.com 生成框架应用程序
您可以在 code.quarkus.redhat.com 上引导和生成项目。
红帽构建的 Apache Camel for Quarkus 扩展位于"集成"标题下。
如果您需要额外的扩展,请使用 'search' 字段查找它们。
选择您要处理的组件扩展,然后点 'Generate your application' 下载基本框架项目。
您还可以将项目直接推送到 GitHub。
有关使用 code.quarkus.redhat.com
生成 Quarkus Maven 项目的更多信息,请参阅 Getting started with Red Hat build of Quarkus 指南中的使用 code.quarkus.redhat.com 创建 Quarkus Maven 项目。
流程
在 code.quarkus.redhat.com 网站中,选择以下扩展:
-
camel-quarkus-rest
-
camel-quarkus-jackson
camel-quarkus-direct
注意不要在 code.quarkus.redhat.com 上编译应用程序(在流程的最后一步中)。反之,使用下面 第 4.2.5 节 “开发模式” 部分描述的 compile 命令。
-
进入从上一步中提取生成的项目文件的目录:
cd <directory_name>
$ cd <directory_name>
Copy to Clipboard Copied!
4.2.3. 探索应用程序代码
应用程序有两个编译依赖关系,它们在 com.redhat.quarkus.platform:quarkus-camel-bom
中导入,它们是在 < dependencyManagement&
gt; 中导入的:
pom.xml
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id> <quarkus.platform.group-id>com.redhat.quarkus.platform</quarkus.platform.group-id> <quarkus.platform.version> <!-- The latest 3.20.x version from https://maven.repository.redhat.com/ga/com/redhat/quarkus/platform/quarkus-bom --> </quarkus.platform.version> ... <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>${quarkus.platform.group-id}</groupId> <artifactId>quarkus-camel-bom</artifactId> <version>${quarkus.platform.version}</version> <type>pom</type> <scope>import</scope> </dependency>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>com.redhat.quarkus.platform</quarkus.platform.group-id>
<quarkus.platform.version>
<!-- The latest 3.20.x version from https://maven.repository.redhat.com/ga/com/redhat/quarkus/platform/quarkus-bom -->
</quarkus.platform.version>
...
<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>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-camel-bom</artifactId>
<version>${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
如需有关 BOM 依赖项管理的更多信息,请参阅使用红帽构建的 Apache Camel for Quarkus 开发应用程序
应用程序由 src/main/resources/application.properties
中定义的属性配置,例如: camel.context.name
可以在其中设置。
4.2.4. 添加简单的 Camel 路由
在本例中,我们使用 camel-quarkus-examples 存储库中的简单示例。它由两个简单的类 Fruit.java
,Legume.java
和路由定义 Routes.java
组成。
流程
-
在
src/main/java/org/acme/
子文件夹中创建名为Fruit.java
的文件。 添加类,如以下代码片段所示:
Fruit.java
package org.acme.rest.json; import java.util.Objects; import io.quarkus.runtime.annotations.RegisterForReflection; /** * A REST entity representing a fruit. */ @RegisterForReflection // Lets Quarkus register this class for reflection during the native build public class Fruit { private String name; private String description; public Fruit() { } public Fruit(String name, String description) { this.name = name; this.description = description; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } @Override public boolean equals(Object obj) { if (!(obj instanceof Fruit)) { return false; } Fruit other = (Fruit) obj; return Objects.equals(other.name, this.name); } @Override public int hashCode() { return Objects.hash(this.name); } }
package org.acme.rest.json; import java.util.Objects; import io.quarkus.runtime.annotations.RegisterForReflection; /** * A REST entity representing a fruit. */ @RegisterForReflection // Lets Quarkus register this class for reflection during the native build public class Fruit { private String name; private String description; public Fruit() { } public Fruit(String name, String description) { this.name = name; this.description = description; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } @Override public boolean equals(Object obj) { if (!(obj instanceof Fruit)) { return false; } Fruit other = (Fruit) obj; return Objects.equals(other.name, this.name); } @Override public int hashCode() { return Objects.hash(this.name); } }
Copy to Clipboard Copied! -
在
src/main/java/org/acme/
子文件夹中创建名为Legume.java
的文件。 添加类,如以下代码片段所示:
Legume.java
package org.acme.rest.json; import java.util.Objects; import io.quarkus.runtime.annotations.RegisterForReflection; /** * A REST entity representing a legume. */ @RegisterForReflection // Lets Quarkus register this class for reflection during the native build public class Legume { private String name; private String description; public Legume() { } public Legume(String name, String description) { this.name = name; this.description = description; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } @Override public boolean equals(Object obj) { if (!(obj instanceof Legume)) { return false; } Legume other = (Legume) obj; return Objects.equals(other.name, this.name); } @Override public int hashCode() { return Objects.hash(this.name); } }
package org.acme.rest.json; import java.util.Objects; import io.quarkus.runtime.annotations.RegisterForReflection; /** * A REST entity representing a legume. */ @RegisterForReflection // Lets Quarkus register this class for reflection during the native build public class Legume { private String name; private String description; public Legume() { } public Legume(String name, String description) { this.name = name; this.description = description; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } @Override public boolean equals(Object obj) { if (!(obj instanceof Legume)) { return false; } Legume other = (Legume) obj; return Objects.equals(other.name, this.name); } @Override public int hashCode() { return Objects.hash(this.name); } }
Copy to Clipboard Copied! -
在
src/main/java/org/acme/
子文件夹中创建名为Routes.java
的文件。 添加 Camel Rest 路由,如以下代码片段所示:
Routes.java
package org.acme.rest.json; import java.util.Collections; import java.util.LinkedHashSet; import java.util.Set; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.model.rest.RestBindingMode; /** * Camel route definitions. */ public class Routes extends RouteBuilder { private final Set<Fruit> fruits = Collections.synchronizedSet(new LinkedHashSet<>()); private final Set<Legume> legumes = Collections.synchronizedSet(new LinkedHashSet<>()); public Routes() { /* Let's add some initial fruits */ this.fruits.add(new Fruit("Apple", "Winter fruit")); this.fruits.add(new Fruit("Pineapple", "Tropical fruit")); /* Let's add some initial legumes */ this.legumes.add(new Legume("Carrot", "Root vegetable, usually orange")); this.legumes.add(new Legume("Zucchini", "Summer squash")); } @Override public void configure() throws Exception { restConfiguration().bindingMode(RestBindingMode.json); rest("/fruits") .get() .to("direct:getFruits") .post() .type(Fruit.class) .to("direct:addFruit"); rest("/legumes") .get() .to("direct:getLegumes"); from("direct:getFruits") .setBody().constant(fruits); from("direct:addFruit") .process().body(Fruit.class, fruits::add) .setBody().constant(fruits); from("direct:getLegumes") .setBody().constant(legumes); } }
package org.acme.rest.json; import java.util.Collections; import java.util.LinkedHashSet; import java.util.Set; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.model.rest.RestBindingMode; /** * Camel route definitions. */ public class Routes extends RouteBuilder { private final Set<Fruit> fruits = Collections.synchronizedSet(new LinkedHashSet<>()); private final Set<Legume> legumes = Collections.synchronizedSet(new LinkedHashSet<>()); public Routes() { /* Let's add some initial fruits */ this.fruits.add(new Fruit("Apple", "Winter fruit")); this.fruits.add(new Fruit("Pineapple", "Tropical fruit")); /* Let's add some initial legumes */ this.legumes.add(new Legume("Carrot", "Root vegetable, usually orange")); this.legumes.add(new Legume("Zucchini", "Summer squash")); } @Override public void configure() throws Exception { restConfiguration().bindingMode(RestBindingMode.json); rest("/fruits") .get() .to("direct:getFruits") .post() .type(Fruit.class) .to("direct:addFruit"); rest("/legumes") .get() .to("direct:getLegumes"); from("direct:getFruits") .setBody().constant(fruits); from("direct:addFruit") .process().body(Fruit.class, fruits::add) .setBody().constant(fruits); from("direct:getLegumes") .setBody().constant(legumes); } }
Copy to Clipboard Copied! 有关此示例的更多信息,请参阅 camel-quarkus-examples 存储库。
4.2.5. 开发模式
mvn clean compile quarkus:dev
$ mvn clean compile quarkus:dev
此命令编译项目、启动应用程序,并允许 Quarkus 工具监视工作区中的更改。对项目所做的任何修改都会在运行的应用程序中自动生效。
您可以在浏览器中检查应用程序。(例如,对于 rest-json
示例应用程序,请访问 http://localhost:8080/fruits
。)
如果更改了应用程序代码,例如,将 'Apple' 更改为 'Orange',则应用程序会自动更新。要查看应用的更改,请刷新浏览器。
如需有关 开发模式的更多详细信息, 请参阅 Quarkus 文档开发模式 部分。
../camel-extensions-development/proc-testing-your-first-camel-extensions-for-quarkus-project.adoc
4.2.6. 打包并运行应用程序
4.2.6.1. JVM 模式
流程
运行
mvn package
,以准备在库存 JVM 上运行的精简jar
:mvn clean package ls -lh target/quarkus-app
$ mvn clean package $ ls -lh target/quarkus-app ... -rw-r--r--. 1 user user 238K Oct 11 18:55 quarkus-run.jar ...
Copy to Clipboard Copied! 注意瘦
jar
仅包含应用程序代码。您还需要target/quarkus-app/lib
中的依赖项来运行它。运行 jar,如下所示:
java -jar target/quarkus-app/quarkus-run.jar
$ java -jar target/quarkus-app/quarkus-run.jar ... [io.quarkus] (main) Quarkus started in 1.163s. Listening on: http://[::]:8080
Copy to Clipboard Copied!
引导时间应该大约是一秒。
4.2.6.2. 原生模式
流程
要准备原生可执行文件,请执行以下操作:
运行命令
mvn clean package -Pnative
:mvn clean package -Pnative ls -lh target
$ mvn clean package -Pnative $ ls -lh target ... -rwxr-xr-x. 1 user user 46M Oct 11 18:57 code-with-quarkus-1.0.0-SNAPSHOT-runner ...
Copy to Clipboard Copied! 注意运行程序
没有.jar
扩展,并且设置了x
(executable)权限。您可以直接运行它:./target/*-runner
$ ./target/*-runner ... [io.quarkus] (main) Quarkus started in 0.013s. Listening on: http://[::]:8080 ...
Copy to Clipboard Copied! 应用程序以 13 毫秒启动。
使用
ps -o rss,command -p $(pgrep code-with)
命令来查看内存用量:ps -o rss,command -p $(pgrep code-with)
$ ps -o rss,command -p $(pgrep code-with) RSS COMMAND 65852 ./target/code-with-quarkus-1.0.0-SNAPSHOT-runner
Copy to Clipboard Copied! 应用程序使用 65 MB 内存。
有关准备原生可执行文件的更多信息,请参阅 Compiling your Quarkus applications to native executables 指南中的 Producing a native executable。
Quarkus 原生可执行文件 包含更多详细信息,包括 创建容器镜像的步骤。
第 5 章 部署 Quarkus 应用程序
您可以使用以下构建策略在 OpenShift 上部署 Quarkus 应用程序:
- Docker 构建
- S2I Binary
- 源 S2I
有关每个构建策略的详情,请参阅 OpenShift Container Platform 构建策略和红帽构建 Quarkus 应用程序到 OpenShift Container Platform 指南。
OpenShift Docker 构建策略是支持面向 JVM 的 Quarkus 应用,以及编译到原生可执行文件的 Quarkus 应用的首选构建策略。您可以使用 quarkus.openshift.build-strategy
属性配置部署策略。
第 6 章 测试
6.1. 测试 Camel Quarkus 扩展
测试提供了确保 Camel 路由在一段时间内的行为良好的方法。如果您还没有这样做,请阅读 Camel Quarkus 用户指南第一步和 Quarkus 文档 测试应用程序 部分。https://camel.apache.org/camel-quarkus/3.20.x/user-guide/first-steps.html
在 Quarkus 上下文中测试路由时,建议的做法是编写本地集成测试。这具有涵盖 JVM 和原生模式的优点。
在 JVM 模式中,您可以使用 CamelTestSupport
风格测试。
6.1.1. 在 JVM 模式下运行
在 JVM 模式中,使用 @QuarkusTest
注释来引导 Quarkus,并在 @Test
逻辑执行前启动 Camel 路由。
例如:
import io.quarkus.test.junit.QuarkusTest; import org.junit.jupiter.api.Test; @QuarkusTest class MyTest { @Test public void test() { // Use any suitable code that sends test data to the route and then assert outcomes ... } }
import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;
@QuarkusTest
class MyTest {
@Test
public void test() {
// Use any suitable code that sends test data to the route and then assert outcomes
...
}
}
您可以在 Camel Quarkus 源中找到示例实现:
6.1.2. 在原生模式下运行
始终测试您的应用程序是否在原生模式中适用于所有支持的扩展。
您可以通过从相应的 JVM 模式类继承逻辑来重复利用为 JVM 模式定义的测试逻辑。
添加 @QuarkusIntegrationTest
注释,以指示 Quarkus JUnit 扩展编译应用程序到原生镜像,并在运行测试前启动它。
import io.quarkus.test.junit.QuarkusIntegrationTest; @QuarkusIntegrationTest class MyIT extends MyTest { ... }
import io.quarkus.test.junit.QuarkusIntegrationTest;
@QuarkusIntegrationTest
class MyIT extends MyTest {
...
}
您可以在 Camel Quarkus 源中找到示例实现:
6.1.3. @QuarkusTest
和 @QuarkusIntegrationTest
之间的区别
原生可执行文件不需要 JVM 来运行,且不能在 JVM 中运行,因为它是原生代码,而不是字节代码。
对原生代码进行编译测试没有点,以便它们使用传统的 JVM 运行。
这意味着测试和应用程序之间的通信必须通过网络(HTTP/REST 或其他协议)通过监视文件系统(例如,日志文件)或其他进程间通信。
6.1.3.1. JVM 模式的 @QuarkusTest
在 JVM 模式中,使用 @QuarkusTest
标注的测试在与测试中的应用相同的 JVM 中执行。
这意味着,您可以使用 @Inject
将来自应用的 Bean 添加到测试代码中。
您还可以使用 @jakarta. enterprise.inject.Alternative 和
来定义新的 Bean,甚至覆盖来自应用程序的 Bean。
@jakarta
.annotation.Priority
6.1.3.2. 在原生模式中 @QuarkusIntegrationTest
在原生模式中,在独立于正在运行的原生应用程序的 JVM 中,使用 @QuarkusIntegrationTest
标注的测试。
这一点非常重要,即测试与原生应用程序之间的所有通信都必须采用以下一个或多个形式:
- 网络调用。通常,应用程序支持的 HTTP 或任何其他网络协议。
-
监视文件系统的更改。(例如,通过 Camel
文件
端点。) - 任何其他类型的进程间通信。
QuarkusIntegrationTest
提供了通过 @QuarkusTest
不提供的额外功能:
- 在 JVM 模式中,您可以启动并测试 Quarkus 构建生成的可运行应用程序 JAR。
- 在原生模式中,您可以启动并测试 Quarkus 构建生成的原生应用程序。
- 如果您在构建中添加容器镜像,则容器将启动并测试。
有关 QuarkusIntegrationTest
的更多信息,请参阅 Quarkus 测试指南。
6.1.4. 使用外部服务进行测试
6.1.4.1. Testcontainers
有时,应用程序需要访问一些外部资源,如消息传递代理、数据库或其他服务。
如果容器镜像可用于感兴趣的服务,您可以使用 Testcontainers 在测试过程中启动并配置服务。
6.1.4.1.1. 使用 QuarkusTestResourceLifecycleManager
传递配置数据
要使应用正常工作,在启动前,通常要将连接配置数据(主机、端口、用户、远程服务密码)传递给应用程序。
在 Quarkus 生态系统中,QuarkusTestResourceLifecycleManager
提供此目的。
您可以使用 start ()
方法启动一个或多个 Testcontainers,并以 Map
的形式从方法返回连接配置。
然后,这个映射的条目会根据模式以不同的方式传递给应用程序:
-
原生模式:命令行(
-Dkey=value
) - JVM 模式:特殊的 MicroProfile 配置提供程序
命令行和 MicroProfile 设置的优先级高于 application.properties
文件中的设置。
import java.util.Map; import java.util.HashMap; import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.Wait; public class MyTestResource implements QuarkusTestResourceLifecycleManager { private GenericContainer<?> myContainer; @Override public Map<String, String> start() { // Start the needed container(s) myContainer = new GenericContainer(DockerImageName.parse("my/image:1.0.0")) .withExposedPorts(1234) .waitingFor(Wait.forListeningPort()); myContainer.start(); // Pass the configuration to the application under test // You can also pass camel component property names / values to automatically configure Camel components return new HashMap<>() {{ put("my-container.host", container.getHost()); put("my-container.port", "" + container.getMappedPort(1234)); }}; } @Override public void stop() { // Stop the needed container(s) myContainer.stop(); ... } }
import java.util.Map;
import java.util.HashMap;
import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;
public class MyTestResource implements QuarkusTestResourceLifecycleManager {
private GenericContainer<?> myContainer;
@Override
public Map<String, String> start() {
// Start the needed container(s)
myContainer = new GenericContainer(DockerImageName.parse("my/image:1.0.0"))
.withExposedPorts(1234)
.waitingFor(Wait.forListeningPort());
myContainer.start();
// Pass the configuration to the application under test
// You can also pass camel component property names / values to automatically configure Camel components
return new HashMap<>() {{
put("my-container.host", container.getHost());
put("my-container.port", "" + container.getMappedPort(1234));
}};
}
@Override
public void stop() {
// Stop the needed container(s)
myContainer.stop();
...
}
}
使用 @QuarkusTestResource
从测试类引用定义的测试资源:
import io.quarkus.test.common.QuarkusTestResource; import io.quarkus.test.junit.QuarkusTest; @QuarkusTest @QuarkusTestResource(MyTestResource.class) class MyTest { ... }
import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusTest;
@QuarkusTest
@QuarkusTestResource(MyTestResource.class)
class MyTest {
...
}
您可以在 Camel Quarkus 源中找到示例实现:
6.1.4.2. WireMock
例如,如果测试不可用、不可靠或昂贵的,您可以 stub 与第三方服务和 API 交互,而不是将测试连接到实时端点。
您可以使用 WireMock 进行模拟和记录 HTTP 交互。它在整个 Camel Quarkus 测试套件中广泛使用,用于各种组件扩展。
6.1.4.2.1. 设置 WireMock
流程
设置 WireMock 服务器。
注意始终在 test 下配置 Camel 组件,以通过 WireMock 代理传递任何 HTTP 交互。您可以通过配置决定 API 端点 URL 的组件属性来实现此目的。
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.get; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; import java.util.HashMap; import java.util.Map; import com.github.tomakehurst.wiremock.WireMockServer; import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; public class WireMockTestResource implements QuarkusTestResourceLifecycleManager { private WireMockServer server; @Override public Map<String, String> start() { // Setup & start the server server = new WireMockServer( wireMockConfig().dynamicPort() ); server.start(); // Stub an HTTP endpoint. WireMock also supports a record and playback mode // https://wiremock.org/docs/record-playback/ server.stubFor( get(urlEqualTo("/api/greeting")) .willReturn(aResponse() .withHeader("Content-Type", "application/json") .withBody("{\"message\": \"Hello World\"}"))); // Ensure the camel component API client passes requests through the WireMock proxy Map<String, String> conf = new HashMap<>(); conf.put("camel.component.foo.server-url", server.baseUrl()); return conf; } @Override public void stop() { if (server != null) { server.stop(); } } }
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.get; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; import java.util.HashMap; import java.util.Map; import com.github.tomakehurst.wiremock.WireMockServer; import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; public class WireMockTestResource implements QuarkusTestResourceLifecycleManager { private WireMockServer server; @Override public Map<String, String> start() { // Setup & start the server server = new WireMockServer( wireMockConfig().dynamicPort() ); server.start(); // Stub an HTTP endpoint. WireMock also supports a record and playback mode // https://wiremock.org/docs/record-playback/ server.stubFor( get(urlEqualTo("/api/greeting")) .willReturn(aResponse() .withHeader("Content-Type", "application/json") .withBody("{\"message\": \"Hello World\"}"))); // Ensure the camel component API client passes requests through the WireMock proxy Map<String, String> conf = new HashMap<>(); conf.put("camel.component.foo.server-url", server.baseUrl()); return conf; } @Override public void stop() { if (server != null) { server.stop(); } } }
Copy to Clipboard Copied! -
确保您的测试类具有
@QuarkusTestResource
注释,并将适当的 test 资源类指定为值。WireMock 服务器将在执行所有测试之前启动,并在所有测试完成后关闭。
import io.quarkus.test.common.QuarkusTestResource; import io.quarkus.test.junit.QuarkusTest; @QuarkusTest @QuarkusTestResource(WireMockTestResource.class) class MyTest { ... }
import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusTest;
@QuarkusTest
@QuarkusTestResource(WireMockTestResource.class)
class MyTest {
...
}
WireMock 服务器在所有测试执行前启动,并在所有测试完成后关闭。
您可以在 Camel Quarkus 集成测试源树中找到示例实现:
6.1.5. CamelTestSupport
style of testing with CamelQuarkusTestSupport
从 Camel Quarkus 2.13.0 开始,您可以使用 CamelQuarkusTestSupport
进行测试。它是 CamelTestSupport
的替代品,其不适用于 Quarkus。
CamelQuarkusTestSupport
仅适用于 JVM 模式。如果您需要以原生模式进行测试,请使用上述其中一个替代测试策略。
6.1.5.1. 在 JVM 模式下使用 CamelQuarkusTestSupport
测试
将以下依赖项添加到模块中(最好在 测试
范围内):
<dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-junit5</artifactId> <scope>test</scope> </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
您可以在测试中使用 CamelQuarkusTestSupport
,如下所示:
@QuarkusTest @TestProfile(SimpleTest.class) //necessary only if "newly created" context is required for the test (worse performance) public class SimpleTest extends CamelQuarkusTestSupport { ... }
@QuarkusTest
@TestProfile(SimpleTest.class) //necessary only if "newly created" context is required for the test (worse performance)
public class SimpleTest extends CamelQuarkusTestSupport {
...
}
6.1.5.2. 自定义 CamelContext
进行测试
您可以使用 配置文件、CDI Bean、观察程序、模拟 等自定义 CamelContext
进行测试。您还可以覆盖 createCamelContext
方法,并直接与 CamelContext
交互。
使用 createCamelContext
时,您必须实例化并返回新的 CamelContext
。相反,调用 super.createCamelContext ()
,并根据需要修改返回的 CamelContext
。无法遵循此规则将导致抛出异常。
@QuarkusTest class SimpleTest extends CamelQuarkusTestSupport { @Override protected CamelContext createCamelContext() throws Exception { // Must call super to get a handle on the application scoped CamelContext CamelContext context = super.createCamelContext(); // Apply customizations context.setTracing(true); // Return the modified CamelContext return context; } }
@QuarkusTest
class SimpleTest extends CamelQuarkusTestSupport {
@Override
protected CamelContext createCamelContext() throws Exception {
// Must call super to get a handle on the application scoped CamelContext
CamelContext context = super.createCamelContext();
// Apply customizations
context.setTracing(true);
// Return the modified CamelContext
return context;
}
}
6.1.5.3. 配置路由用于测试
在您的应用程序中扩展 RouteBuilder
的任何类都会将其路由自动添加到 CamelContext
中。同样,从 camel.main.routes-include-pattern
配置的任何 XML 或 YAML 路由也会被加载。
这可能并不适用于您的测试。您可以使用配置属性控制在测试时载入哪些路由:
-
quarkus.camel.routes-discovery.include-patterns
-
quarkus.camel.routes-discovery.exclude-patterns
, -
camel.main.routes-include-pattern
-
camel.main.routes-exclude-pattern
.
您还可以通过覆盖 createRouteBuilder
来定义每个测试类的测试特定路由:
@QuarkusTest class SimpleTest extends CamelQuarkusTestSupport { @Test void testGreeting() { MockEndpoint mockEndpoint = getMockEndpoint("mock:result"); mockEndpoint.expectedBodiesReceived("Hello World"); template.sendBody("direct:start", "World"); mockEndpoint.assertIsSatisified(); } @Override protected RoutesBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { from("direct:start") .transform().simple("Hello ${body}") .to("mock:result"); } }; } }
@QuarkusTest
class SimpleTest extends CamelQuarkusTestSupport {
@Test
void testGreeting() {
MockEndpoint mockEndpoint = getMockEndpoint("mock:result");
mockEndpoint.expectedBodiesReceived("Hello World");
template.sendBody("direct:start", "World");
mockEndpoint.assertIsSatisified();
}
@Override
protected RoutesBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:start")
.transform().simple("Hello ${body}")
.to("mock:result");
}
};
}
}
6.1.5.4. CamelContext 测试生命周期
与 CamelTestSupport
相比,CamelQuarkusTestSupport
的主要区别之一是如何管理 CamelContext
生命周期。
在 Camel Quarkus 上,运行时会自动为您创建一个 CamelContext
。默认情况下,此 CamelContext
在所有测试之间共享,并在整个测试套件执行期间保持启动。
这可能会对您的测试造成一些意外的副作用。如果您需要在测试之间重新启动 CamelContext
,则可以创建自定义 测试配置文件,这将强制应用程序在测试后重新启动。
例如,定义测试配置集:
@QuarkusTest class MyTestProfile implements QuarkusTestProfile { ... }
@QuarkusTest
class MyTestProfile implements QuarkusTestProfile {
...
}
然后,使用 @TestProfile
在测试类中引用它:
// @TestProfile will trigger the application to be restarted @TestProfile(MyTestProfile.class) @QuarkusTest class SimpleTest extends CamelQuarkusTestSupport { ... }
// @TestProfile will trigger the application to be restarted
@TestProfile(MyTestProfile.class)
@QuarkusTest
class SimpleTest extends CamelQuarkusTestSupport {
...
}
您无法通过调用其 stop ()
和 start ()
方法来手动重启 CamelContext
。这将会产生一个例外。
6.1.5.5. 例子
6.1.5.5.1. 简单 RouteBuilder
和 test 类
simple RouteBuilder
:
public class MyRoutes extends RouteBuilder { @Override public void configure() { from("direct:start") .transform().simple("Hello ${body}") .to("mock:result"); } }
public class MyRoutes extends RouteBuilder {
@Override
public void configure() {
from("direct:start")
.transform().simple("Hello ${body}")
.to("mock:result");
}
}
测试向 direct:start
端点发送消息有效负载:
@QuarkusTest class SimpleTest extends CamelQuarkusTestSupport { @Test void testGreeting() { MockEndpoint mockEndpoint = getMockEndpoint("mock:result"); mockEndpoint.expectedBodiesReceived("Hello World"); template.sendBody("direct:start", "World"); mockEndpoint.assertIsSatisified(); } }
@QuarkusTest
class SimpleTest extends CamelQuarkusTestSupport {
@Test
void testGreeting() {
MockEndpoint mockEndpoint = getMockEndpoint("mock:result");
mockEndpoint.expectedBodiesReceived("Hello World");
template.sendBody("direct:start", "World");
mockEndpoint.assertIsSatisified();
}
}
6.1.5.5.2. 使用 AdviceWith
@QuarkusTest class SimpleTest extends CamelQuarkusTestSupport { @BeforeEach public void beforeEach() throws Exception { AdviceWith.adviceWith(this.context, "advisedRoute", route -> { route.replaceFromWith("direct:replaced"); }); } @Override protected RoutesBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { from("direct:start").routeId("advisedRoute") .transform().simple("Hello ${body}") .to("mock:result"); } }; } @Test void testAdvisedRoute() throws Exception { MockEndpoint mockEndpoint = getMockEndpoint("mock:result"); mockEndpoint.expectedBodiesReceived("Hello World"); template.sendBody("direct:replaced", "World"); mockEndpoint.assertIsSatisfied(); } }
@QuarkusTest
class SimpleTest extends CamelQuarkusTestSupport {
@BeforeEach
public void beforeEach() throws Exception {
AdviceWith.adviceWith(this.context, "advisedRoute", route -> {
route.replaceFromWith("direct:replaced");
});
}
@Override
protected RoutesBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:start").routeId("advisedRoute")
.transform().simple("Hello ${body}")
.to("mock:result");
}
};
}
@Test
void testAdvisedRoute() throws Exception {
MockEndpoint mockEndpoint = getMockEndpoint("mock:result");
mockEndpoint.expectedBodiesReceived("Hello World");
template.sendBody("direct:replaced", "World");
mockEndpoint.assertIsSatisfied();
}
}
6.1.5.5.3. 显式启用建议
当显式启用 建议 时,您必须在完成 AdviceWith
设置时调用 startRouteDefinitions
。
只有在您配置了未建议的路由时,才需要调用 startRouteDefinitions
。
6.1.5.6. 限制:
6.1.5.6.1. 测试继承自 CamelTestSupport
的生命周期方法
CamelQuarkusTestSupport
继承 CamelTestSupport
的一些测试生命周期方法。但是,不应使用它们,而是替换为 CamelQuarkusTestSupport
中的等效方法。
CamelTestSupport 生命周期方法 | CamelQuarkusTestSupport 等 |
---|---|
|
|
|
|
|
|
|
|
6.1.5.6.2. 不支持创建自定义 Camel registry
CamelQuarkusTestSupport
的 createCamelRegistry
实施会抛出 UnsupportedOperationException
。
如果需要将对象绑定到 Camel registry,则您可以使用以下方法之一完成此操作。
生成命名的 CDI Bean
public class MyBeanProducers { @Produces @Named("myBean") public MyBean createMyBean() { return new MyBean(); } }
public class MyBeanProducers { @Produces @Named("myBean") public MyBean createMyBean() { return new MyBean(); } }
Copy to Clipboard Copied! -
override
createCamelContext
(请参阅上面的示例)并调用camelContext.getRegistry ().bind ("foo", fooBean)
使用
@BindToRegistry
注释@QuarkusTest class SimpleTest extends CamelQuarkusTestSupport { @BindToRegistry("myBean") MyBean myBean = new MyBean(); }
@QuarkusTest class SimpleTest extends CamelQuarkusTestSupport { @BindToRegistry("myBean") MyBean myBean = new MyBean(); }
Copy to Clipboard Copied! 注意Bean 从单个测试类绑定到 Camel registry,将在测试套件执行期间保留。根据您的测试预期,这可能会产生意外的后果。您可以使用测试配置集重启
CamelContext
以避免这种情况。
第 7 章 本地设置 Maven
典型的红帽构建的 Apache Camel 应用程序开发使用 Maven 来构建和管理项目。
7.1. 准备设置 Maven
Maven 是一个来自 Apache 的免费开源、构建工具。通常,您可以使用 Maven 来构建 Fuse 应用程序。
流程
从 Maven 下载页面 下载 Maven 3.8.6 或更高版本。
提示要验证您是否安装了正确的 Maven 和 JDK 版本,请打开终端并输入以下命令:
mvn --version
mvn --version
Copy to Clipboard Copied! 检查输出,以验证 Maven 是 3.8.6 或更新版本,并使用 OpenJDK 17。
确定您的系统已连接到互联网。
在构建项目时,Maven 会搜索外部存储库并下载所需的工件。Maven 查找可通过互联网访问的存储库。
您可以更改此行为,以便 Maven 仅搜索本地网络上的存储库。也就是说,Maven 可以在离线模式下运行。在离线模式中,Maven 会在其本地存储库中查找工件。请参阅 第 7.3 节 “使用本地 Maven 存储库”。
7.2. 在 Maven 中添加红帽软件仓库
要访问 Red Hat Maven 存储库中的工件,您需要将这些存储库添加到 Maven 的 settings.xml
文件中。
Maven 在用户主目录的 .m2
目录中查找 settings.xml
文件。如果没有用户指定的 settings.xml
文件,Maven 将使用 M2_HOME/conf/
文件中的系统级 settings.xml 文件。
settings.xml
前提条件
您知道要在其中添加红帽存储库的 settings.xml
文件的位置。
流程
在 settings.xml
文件中,为红帽软件仓库添加 存储库
元素,如下例所示:
如果您使用 camel-jira
组件,还要添加 atlassian 存储库。
<?xml version="1.0"?> <settings> <profiles> <profile> <id>extra-repos</id> <activation> <activeByDefault>true</activeByDefault> </activation> <repositories> <repository> <id>redhat-ga-repository</id> <url>https://maven.repository.redhat.com/ga</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> <repository> <id>atlassian</id> <url>https://packages.atlassian.com/maven-external/</url> <name>atlassian external repo</name> <snapshots> <enabled>false</enabled> </snapshots> <releases> <enabled>true</enabled> </releases> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>redhat-ga-repository</id> <url>https://maven.repository.redhat.com/ga</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> </profile> </profiles> <activeProfiles> <activeProfile>extra-repos</activeProfile> </activeProfiles> </settings>
<?xml version="1.0"?>
<settings>
<profiles>
<profile>
<id>extra-repos</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>redhat-ga-repository</id>
<url>https://maven.repository.redhat.com/ga</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>atlassian</id>
<url>https://packages.atlassian.com/maven-external/</url>
<name>atlassian external repo</name>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>redhat-ga-repository</id>
<url>https://maven.repository.redhat.com/ga</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>extra-repos</activeProfile>
</activeProfiles>
</settings>
7.3. 使用本地 Maven 存储库
如果您在没有互联网连接的情况下运行容器,并且需要部署具有不可用依赖项的应用程序,您可以使用 Maven 依赖项插件将应用的依赖项下载到 Maven 离线存储库中。然后,您可以将这个自定义的 Maven 离线存储库分发到没有互联网连接的机器。
流程
在包含
pom.xml
文件的项目目录中,运行以下命令来下载 Maven 项目的存储库,如下所示:mvn org.apache.maven.plugins:maven-dependency-plugin:3.1.0:go-offline -Dmaven.repo.local=/tmp/my-project
mvn org.apache.maven.plugins:maven-dependency-plugin:3.1.0:go-offline -Dmaven.repo.local=/tmp/my-project
Copy to Clipboard Copied! 在本例中,构建项目所需的 Maven 依赖项和插件会下载到
/tmp/my-project
目录中。- 在内部将这个自定义 Maven 离线存储库分发到没有互联网连接的任何机器。
7.4. 使用环境变量或系统属性设置 Maven 镜像
在运行应用程序时,您需要访问 Red Hat Maven 存储库中的工件。这些软件仓库被添加到 Maven 的 settings.xml
文件中。Maven 检查 settings.xml
文件的以下位置:
- 查找指定的 url
-
如果没有找到查找
${user.home}/.m2/settings.xml
-
如果没有找到查找
${maven.home}/conf/settings.xml
-
如果没有找到查找
${M2_HOME}/conf/settings.xml
-
如果没有找到位置,则创建空的
org.apache.maven.settings.Settings
实例。
7.4.1. 关于 Maven 镜像
Maven 使用一组远程存储库来访问工件,这些工件目前在本地存储库中不可用。存储库列表几乎始终包含 Maven Central 存储库,但对于 Red Hat Fuse,它还包含 Maven 红帽存储库。在某些情况下,如果无法或允许访问不同的远程存储库,您可以使用 Maven 镜像机制。镜像会将特定存储库 URL 替换为不同的存储库 URL,因此搜索远程工件时的所有 HTTP 流量都可以定向到单个 URL。
7.4.2. 将 Maven mirror 添加到 settings.xml
要设置 Maven 镜像,请在 Maven 的 settings.xml
中添加以下部分:
<mirror> <id>all</id> <mirrorOf>*</mirrorOf> <url>http://host:port/path</url> </mirror>
<mirror>
<id>all</id>
<mirrorOf>*</mirrorOf>
<url>http://host:port/path</url>
</mirror>
如果在 settings.xml
文件中找不到上述部分,则无法使用镜像。要指定全局镜像但不提供 XML 配置,您可以使用系统属性或环境变量。
7.4.3. 使用环境变量或系统属性设置 Maven 镜像
要使用环境变量或系统属性设置 Maven 镜像,您可以添加:
-
名为 MAVEN_MIRROR_URL 的环境变量到
bin/setenv
文件 -
名为 mavenMirrorUrl 的系统属性到
etc/system.properties
文件
7.4.4. 使用 Maven 选项指定 Maven 镜像 url
要使用替代的 Maven 镜像 url (环境变量或系统属性指定),在运行应用程序时使用以下 maven 选项:
-DmavenMirrorUrl=mirrorId::mirrorUrl
for example,
-DmavenMirrorUrl=my-mirror::http://mirror.net/repository
-DmavenMirrorUrl=mirrorUrl
for example,
-DmavenMirrorUrl=http://mirror.net/repository
.在本例中,<mirror> 的 <id> 只是一个镜像。
7.5. 关于 Maven 工件和协调
在 Maven 构建系统中,基本构建块是一个 构件。构建后,工件的输出通常是一个存档,如 JAR 或 WAR 文件。
Maven 的一个重要方面是能够定位工件并管理它们之间的依赖关系。Maven 协调 是一组用于标识特定工件位置的值。基本协调以以下格式有三个值:
groupId:artifactId:version
有时,Maven 使用 打包值或打包 值和类器值增强基本协调。 Maven 协调可以具有以下格式之一:
groupId:artifactId:version groupId:artifactId:packaging:version groupId:artifactId:packaging:classifier:version
groupId:artifactId:version
groupId:artifactId:packaging:version
groupId:artifactId:packaging:classifier:version
以下是值的描述:
- groupdId
-
定义工件名称的范围。您通常使用所有或包名的一部分作为组 ID。例如,
org.fusesource.example
。 - artifactId
- 定义相对于组 ID 的工件名称。
- version
-
指定工件的版本。版本号最多可有四个部分:
n.n.n.n
.n,其中版本号的最后一部分可以包含非数字字符。例如,1.0-SNAPSHOT 的最后一部分是字母
子字符串,即0-SNAPSHOT
。 - 打包
-
定义构建项目时生成的打包实体。对于 OSGi 项目,打包是
捆绑的
。默认值为jar
。 - 分类器
- 可让您区分从同一 POM 构建的工件,但具有不同的内容。
工件的 POM 文件中的元素定义了工件的组 ID、工件 ID、打包和版本,如下所示:
<project ... > ... <groupId>org.fusesource.example</groupId> <artifactId>bundle-demo</artifactId> <packaging>bundle</packaging> <version>1.0-SNAPSHOT</version> ... </project>
<project ... >
...
<groupId>org.fusesource.example</groupId>
<artifactId>bundle-demo</artifactId>
<packaging>bundle</packaging>
<version>1.0-SNAPSHOT</version>
...
</project>
要定义对上述工件的依赖项,您要将以下 dependency
元素添加到 POM 文件中:
<project ... > ... <dependencies> <dependency> <groupId>org.fusesource.example</groupId> <artifactId>bundle-demo</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> ... </project>
<project ... >
...
<dependencies>
<dependency>
<groupId>org.fusesource.example</groupId>
<artifactId>bundle-demo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
...
</project>
不需要在上述依赖项中指定 bundle
软件包类型,因为捆绑包只是特定类型的 JAR 文件,jar
是默认的 Maven 软件包类型。如果您需要在依赖项中明确指定打包类型,您可以使用 type
元素。
第 8 章 示例应用程序
8.1. 红帽构建的 Quarkus 示例
红帽构建的 Quarkus 示例 存储库包含许多有关如何与 Camel 集成用于各种用例的示例。它们提供最佳实践建议,并描述了我们在集成和消息传递问题中发现的通用模式。
这些示例可以使用 Maven 运行。使用 mvn
命令时,Maven 将尝试从中央存储库下载所需的依赖项到您的本地存储库。
8.2. 仓库示例
Example | 描述 |
---|---|
演示了如何使用 MQTT 协议从 Apache Artemis 代理使用消息,转换为 ElasticSearch。 | |
演示了如何将 Camel 的 master 组件用于 Kubernetes 领导选举机制。 | |
显示如何从自定义 | |
演示了如何使用 Camel CXF SOAP 组件。 | |
演示了如何提取、转换和负载在两个数据库之间。 | |
演示了如何使用 CSV 文件、marshal 和 unmarshal 数据并通过 FTP 发送。 | |
演示了如何将 Camel health-checks 与 Quarkus 搭配使用。 | |
演示了如何使用 platform-http 或 RESTEasy 创建 HTTP 端点。 | |
演示一个 Camel Quarkus 应用程序,支持跨多个事务资源的 JTA 事务。 | |
显示如何只消耗一次消息,即使多次发送了。 | |
演示 MySQL 和模拟 XAResource 之间的 JTA 事务。 | |
显示如何使用 Strimzi Operator 在 Kafka 主题中生成和使用信息。 | |
演示了如何构建用于 Camel 应用程序的简单 Kamelet。 | |
演示带有连接池和 XA 事务的 AMQ 和 IBM MQ 客户端。 | |
演示添加指标、健康检查和分布式追踪支持。 | |
演示了如何使用 Contract First OpenAPI 运行。 | |
演示了如何使用 Keycloak 保护平台 HTTP。 | |
演示使用 Camel REST DSL 和 Jackson 创建 REST 服务。 | |
展示如何使用 saga 和 LRA 模式。 | |
使用 Camel 计时器组件将 Hello world 消息输出到控制台。 | |
演示了如何在 XML 中定义用于令牌 CSV 文件的 Camel 路由。 | |
演示了如何配置 WebSocket 服务器并与连接的对等点交互。 |