JBoss Fuse - 快速指南e
JBoss Fuse - ESB 简介
在本章中,我们将从企业服务总线的基本知识开始。下面详细介绍了 ESB 及其优点、缺点,并附上几张便于理解的图表。
什么是 ESB?
ESB 代表企业服务总线。ESB 最简单的形式是一种中间件,充当信息高速公路,帮助多个应用程序进行通信。
在企业界,我们为许多事情开发解决方案。这些解决方案可能使用不同的技术和不同的数据格式。由于这些技术中通信或数据格式的兼容性差异,将这些解决方案一起使用变得很麻烦。因此,我们需要一种允许这些不同解决方案之间松散耦合集成的技术。
ESB 旨在通过成为位于所有应用程序中间的"HUB"并促进它们之间的消息路由来简化集成问题。 ESB 充当中介,充当信息高速公路,负责数据转换路由,让编码人员或开发人员专注于自己的应用程序逻辑。
当我们理解了 ESB 专门设计用于解决的问题,解决方案也变得简单时,理解 ESB 就变得非常简单。我们应该清楚地了解如何使许多不同的系统(使用不同的语言编写,在不同机器上运行,使用不同的数据格式)共享信息并形成一个集成的业务平台。
集成问题
在企业平台中,多个应用程序协作并提供整体业务功能是很常见的,但这些应用程序的集成是最常见的问题。随着应用程序的增长,随着时间的推移,它变得更加困难。
每个应用程序都可以以自己的格式输入和输出数据。如果应用程序数量较少,这种方法效果很好,但随着应用程序数量的增长,集成也需要采用更好的方法。例如,如果需要更改某个业务的特定应用程序,则依赖于该主应用程序的所有应用程序的输出或输入数据格式都会受到影响。
这种方法是集成的最大障碍,因为集成需要紧密耦合的架构。这就是 ESB 发挥作用的地方。每个应用程序不需要直接与其他应用程序通信;相反,所有应用程序都与 ESB 通信,ESB 处理信息路由和内部数据格式转换。

为什么是 ESB?
以下几点解释了企业服务总线为何必不可少。
ESB 旨在简化与各种兼容应用程序的集成问题。
它充当中间件,充当所有应用程序的中介,并促进它们之间的消息路由。
现在,每个应用程序都只有一个 ESB 接口,而不是每个应用程序都直接与其他应用程序交互。
ESB 负责将消息转换为通用格式或从通用格式转换为通用格式,并将其路由到其目的地。
如果您必须替换任何现有应用程序,这种方法的主要节省将是一个福音。您现在只需关注一个接口(应用程序和 ESB 之间),而不必编写一大堆新接口。

SOA 和 ESB?
SOA 和 ESB 通常可互换使用,但它们完全不同。
SOA 是一种设计模式,允许应用程序通过通信协议通过网络将其功能作为服务公开,而 ESB 是一种促进不同系统之间通信的模型,但 ESB 可在实施 SOA 时用作主干。
什么是 Fuse?
JBoss Fuse 是 Redhat 推出的一款开源 ESB 解决方案。它是基于社区项目 Apache Servicemix 的企业解决方案。
集成到 Fuse
JBoss Fuse 是一个轻量级且灵活的集成平台,允许快速集成企业应用程序。
Fuse 最初由 Progressive software Inc. 开发,该公司于 2012 年被 Redhat 收购。JBoss Fuse 6.1.0.redhat-379 GA 是 Fuse 的稳定版本,可从其官方网站下载。
架构
Fuse 将各种技术组合在一起作为单个产品。

组件
Apache CXF
Apache CXF 是一个开源 Web 服务开发框架,它还支持 SOAP 和Rest Web 服务。
Apache Camel
Apache Camel 是一个基于 EIP 的集成框架。EIP 或企业集成模式是针对企业集成中反复出现的问题而确定的解决方案。通过组合这些预定义的开箱即用模式,可以迅速实现完整的集成解决方案。
它允许使用多种领域特定语言(如 Java、Spring DSL 和 Scala 等)编写路由逻辑。
Apache AMQ
Apache AMQ 是一种 JMS,它根据 JMS 标准提供可靠的消息传递系统。它不仅支持 JMS 规范,还提供了一些 JMS 规范中未包含的令人兴奋且有用的功能。
Apache Karaf
Apache Karaf 是轻量级 OSGi 容器,可充当工件的运行时。与 JVM 相比,Apache Karaf 本质上更具动态性。它允许在运行时安装或卸载模块。 Fuse 中的所有工件都部署在 Karaf 中。
Fabric
Fabric 提供了一种在大型分布式环境中管理工件部署的简便方法。它为所有多个 fuse 实例提供集中管理。
安装 Fuse
安装 Fuse 非常简单。与其他 JBoss 产品一样,Fuse 以 zip 文件的形式提供,可以解压,经过一些小的配置更改后即可直接启动。
安装 Fuse 分为四个步骤 −
下载
从以下链接下载 Fuse 6.1.0 GA。 https://www.jboss.org/
解压
与所有其他 JBoss 产品一样,Fuse 也是一个独立于平台的 zip 文件。
将下载的文件解压到您想要作为 Fuse 安装目录的目标目录中。请明智地选择此目录,因为该目录应在 Fuse 实例的整个生命周期内保持不变。
注意 −尽管 Fuse 像其他 JBoss 产品一样解压并启动,但不建议在安装完成后将 Fuse 安装从一个位置移动到另一个位置。
配置
解压 Fuse 后,您将在解压的目录 − 中找到以下目录
- bin
- etc
- deploy
- lib
- licenses
- extras
- quickstarts
其中我们只使用两个目录 bin 和 etc。
实际上,在解压 Fuse 后,我们应该能够直接启动 fuse,但这将使用所有默认配置启动 Fuse,这对于生产环境来说是不可取的。强烈建议在启动 Fuse 之前进行以下更改。
设置环境变量
设置以下环境变量 − JAVA_HOME
变量应指向 java 安装目录 − M2_HOME
变量应指向 Maven 安装目录 − PATH
设置路径变量以包含 Java 和 Maven 可执行文件。
Windows
在 Windows 上,可以按照以下给出的说明进行设置 −
开始 → 我的电脑 → 右键单击 → 属性 → 高级系统设置 → 环境变量。
UNIX &克隆
对于每个用户,在 *nix 操作系统中都有一个 bash 配置文件。我们可以通过更改此文件来添加或编辑现有系统变量。
$ vi ~/.bash_proflle
注意 − 此文件中的任何更改都是永久性的。强烈建议在更改原始文件之前备份现有文件。
基本配置
我们将讨论 JBoss Fuse 的基本配置,为此我们必须从以下命令开始编辑 $FUSE_INSTALLATION_DIR/etc/
在 user.properties
#admin=admin,admin
这需要根据我们想要的第一个管理员的用户名进行更改,第二个管理员的密码进行更改,第三个管理员可以保留原样,因为它表示一个角色,不要忘记删除#
例如 - FuseAdmin = FusePAss,admin

在 System.properties
karafName = root
这表示您要赋予 Karaf 的名称实例。
我们可以将其命名为任何我们想要的名称,例如 Cont1。
确保您给出的名称是唯一的,并且未被 Fuse 的其他实例使用。
在 org.ops4j.pax.web.cfg
Org.osgi.service.http.port = 8181
此属性表示用于访问由 Fuse 提供的基于浏览器的界面 HAWTIO 的端口
HAWTIO 是 Fuse 的内置浏览器界面,从 6.0 开始可用
在org.ops4j.pax.url.mvn.cfg
org.ops4j.pax.url.mvn.localRepository = D:/repository
此属性指示我们的 Maven 的 localRepository 路径,Fuse 将从该路径安装其工件。
org.ops4j.pax.url.mvn.settings = D:/Maven/conf/settings.xml
此属性指示 Fuse 应使用 settings.xml 从 Maven 获取工件。
配置 Maven
Maven 是安装 Fuse 的先决条件。如果您不知道 maven 是什么,请参阅 https://www.tutorialspoint.com/maven/
Maven 是一个用于构建 Fuse 工件的构建工具。当我们发出安装工件的命令时,Fuse 首先在 Maven 本地存储库中搜索工件。所以我们必须让 Fuse 知道 Maven 的安装位置以及 Maven 本地存储库的路径。
编辑 $FUSE_INSTALLATION_DIR/etc/org.ops4j.paxurl.mvn.cfg
更新以下两个属性 −
- org.ops4j.pax.url.mvn.settings = $M2_HOME/conf /settings.xml
- org.ops4j.pax.url.mvn.localRepository = $local_repo
注意 − 请将 $local_repo 更改为 Mavens settings.xml 中提到的本地存储库的实际路径。
运行
完成基本配置更改后,我们现在可以启动 Fuse。所有与 Fuse 一起使用的二进制文件都位于 $FUSE_INSTALLATION_DIR 中。
有两种方法可以启动 Fuse −
使用 ./fuse
这将允许您在启动 Fuse 的同一窗口中查看所有进度和日志。
它将在同一个终端中为您提供 Karaf 控制台,如下所示。
注意 − 这将在控制台模式下启动 fuse,这意味着当用户从会话中注销或关闭终端时,Fuse 进程也将停止,这在生产或开发场景中是不可取的。此脚本仅用于调试 Fuse。
使用 ./start
这不会在屏幕上显示任何日志,甚至不会显示进度,但这会在后台启动 Fuse,并且当用户退出会话或关闭终端时,Fuse 服务不会停止。
在现实世界的应用程序中,需要这种类型的行为。即使我们关闭终端,Fuse 也应该在后台运行。
如果您想连接到在后台运行的 Fuse,您可以使用位于同一文件夹中的 客户端 脚本。
您应该获得如以下屏幕截图所示的显示。
退出客户端脚本不会停止 Fuse 服务。它只会关闭 Fuse 控制台。

HAWTIO
Fuse 还使用 FMC(Fuse 管理控制台)提供完整的 GUI 访问。您可以在以下 URL http://localhost:8181 上找到 GUI。

我们通过执行命令所做的一切也可以通过访问这个基于浏览器的 GUI 来完成。当我们有多个容器并且在 Fabric 环境中运行时,它会变得非常有用。
JBoss Fuse - Apache Karaf
在本章中,我们将讨论 Apache Karaf 以及它被称为轻量级 OSGi 容器的原因,以及它的优点和其他重要功能。
JVM 问题
JVM 或 Java 虚拟机不充当实际的虚拟机。它允许您随时停止、启动或重新启动在其中运行的组件。它有时可能允许在类级别进行热部署,但您无法在不重新启动虚拟机的情况下部署或取消部署应用程序的组件。
为了解决这个问题并允许 Java 应用程序中的模块化,Fuse 使用基于 OSGi 的运行时,称为 Apache Karaf。
OSGi
OSGi 技术是一组定义 Java 动态组件系统的规范。这些规范允许一种开发模型,其中应用程序(动态地)由许多不同的(可重用)组件组成。
OSGi 的好处
降低复杂性 − 应用程序构建为协作组件,彼此隐藏其实现细节,从而降低复杂性。
可重用性 − 许多组件可以利用部署在容器中的相同组件。
部署 − OSGi 通过其生命周期管理 API 提供对动态启动、停止和更新组件的支持,无需重新启动容器。
Bundles 与 Features
以下是 Bundles 与 Features 之间的比较。
Bundles
Bundles 与 OSGi 的关系相当于 jar 与 JVM 的关系。Bundles 是可在 OSGi 容器中部署的工件。Bundles 是可以协同或独立工作以形成应用程序的组件。
这些 Bundles 可以在运行时安装、卸载、更新、启动或停止,而无需重新启动容器。
Features
Features 是一种将多个 Bundles 一起部署的方式。有时成组部署 Bundles 更有意义。这些功能允许我们仅使用一个命令即可部署一组包。
为什么要使用另一个容器?
Apache Karaf 是一个基于 OSGi 的运行时,我们的应用程序包就是在这里运行的。Fuse 使用 Apache Karaf 作为其运行时,包在其中运行并协作以提供业务功能。
Karaf 建立在 Felix 和 equinox 上,它们是 OSGi 框架。
Karaf 架构

Apache Karaf 为基本 OSGi 运行时添加了以下附加功能。
热部署
Karaf 支持热部署。它包含一个热部署目录。放置在此目录中的所有内容都会自动部署并作为包安装在 Karaf 中。
日志记录
Karaf 通过在 $Fuse_home/data/log 中为所有包生成日志来提供集中日志记录。我们可以在 $Fuse_home/etc 目录 中的 org.ops4j.pax.logging.cfg 中编辑记录器配置。
管理控制台
Karaf 提供了一个复杂而清晰的管理控制台来与正在运行的 fuse 实例进行交互。它还提供了一组预安装的命令,可用于在运行时管理和监控组件(包)。此控制台是可扩展的,因此我们可以通过向控制台添加新包来向控制台添加新命令。

SSH 访问
Karaf 允许使用 SSH 远程访问此管理控制台。任何拥有有效凭据的人都可以通过 SSH 终端连接到 karaf 管理控制台。
JBoss Fuse - Apache Camel
在本章中,我们将讨论什么是 Apache Camel 以及它如何有效地在端点之间路由数据,并提供一些示例。
什么是 Apache Camel?
Apache Camel 是一个开源集成框架,于 2007 年初启动。
它是一种基于 EIP(企业集成模式)的方法,提供了几种可用于解决企业集成问题的开箱即用模式实现。 EIP 只不过是针对企业集成中记录良好且反复出现的问题的经过验证的解决方案。
Camel 也称为路由和中介引擎,因为它可以有效地在端点之间路由数据,同时承担数据格式转换、端点连接等繁重负载。
基本示例
使用 Apache Camel 的先决条件是 −
- Java
- Maven
- Redhat JBoss Fuse 6.1-GA-379
创建应用程序的基本框架
mvn:archetype generate –DgroupId = com.tutorialpoint.app –DartifactId = camel-first-app –DarchetypeGroupId = org.apache.camel.archetypes –DarchetypeArtifactId = camel-archetype-spring –DinteractiveMode = false -X
这应该会生成以下目录结构。

这是我们正在生成的 Camel 应用程序的基本框架。
编辑 camel-context.xml
编辑 camel-first-app → src → main → resources → META-INF\spring\camel-context.xml 以匹配以下内容
<?xml version = "1.0" encoding = "UTF-8"?> <!-- Configures the Camel Context--> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <camelContext xmlns = "http://camel.apache.org/schema/spring"> <!-- here is a sample which processes the input file (leaving them in place - see the 'noop' flag) then performs content based routing on the message using XPath --> <route> <from uri = "file:///d:/src/data?noop=false"/> <choice> <when> <xpath>/person/city = 'London'</xpath> <log message = "UK message"/> <to uri = "file:///d:/target/messages/uk"/> </when> <otherwise> <log message = "Other message"/> <to uri = "file:///d:/target/messages/others"/> </otherwise> </choice> </route> </camelContext> </beans>
编辑 pom.xml
在 <plugins></plugins> 内添加以下代码
<plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <version>2.3.4</version> <extensions>true</extensions> <configuration> <instructions> <Bundle-SymbolicName> ${project.artifactId} </Bundle-SymbolicName> <Import-Package>*</Import-Package> </instructions> </configuration> </plugin>
从 jar → bundle 更改打包类型。
<packaging>bundle</packaging>
使用以下命令构建项目 −
mvn clean install
将项目安装到 Fuse
使用 Fuse.bat/start.bat 启动 Fuse。如果使用 start.bat 启动 Fuse,请使用 client.bat 连接到 Fuse。您应该获得如以下屏幕截图所示的 UI。

这是用于访问 Karaf 和 Fuse 命令的 CLI。
install –s mvn:com.tutorialpoint.app/camel-firt-app/1.0-SNAPSHOT
测试您的项目是否正在运行
现在您的应用程序应该安装在 Fuse 中。复制 camel-first-app 内的数据目录并将其放置在 D:/src/ 中,它应该将 city = London 的消息复制到 D:/target/merssages/uk 中。
将输入文件放置在 D:/src/data
中输入
Message1.xml
<?xml version = "1.0" encoding = "UTF-8"?> <person user = "james"> <firstName>James</firstName> <lastName>Strachan</lastName> <city>London</city> </person>
Message2.xml
<?xml version = "1.0" encoding = "UTF-8"?> <person user = "hiram"> <firstName>Hiram</firstName> <lastName>Chirino</lastName> <city>Tampa</city> </person>
输出
在 D:/target/messages/uk
<?xml version = "1.0" encoding = "UTF-8"?> <person user = "james"> <firstName>James</firstName> <lastName>Strachan</lastName> <city>London</city> </person>
在 D:/target/messages/others
<?xml version = "1.0" encoding = "UTF-8"?> <person user = "hiram"> <firstName>Hiram</firstName> <lastName>Chirino</lastName> <city>Tampa</city> </person>
JBoss Fuse - Camel 概念
在本章中,我们将了解不同的 Camel 概念。让我们先从一个基本示例开始,以了解核心概念。
CamelContext
每个 Camel 应用程序至少有一个 CamelContext。这是我们添加 Camel 路由的地方。它类似于 Spring 的 ApplicationContext。
Camel 上下文可以被认为是一个将所有事物放在一起的容器。一个 Camel 上下文可以包含多个路由。
路由
CamelContext 可能包含一个或多个路由。路由是集成逻辑,它定义了数据在 Camel 上下文中如何从一个端点流向另一个端点。
端点
端点是系统可以发送或接收消息的通道的端点。这就是我们在通信语言中所说的目的地或源。
组件
组件是 Camel 中的扩展点。组件可以是技术、数据格式、转换器等的接口。它们还可以充当端点的工厂。

EIP
EIP 代表企业集成模式。这些是针对重复出现的问题而确定的、众所周知的解决方案。 Camel 支持大多数企业集成模式。
基于内容的路由器
CBR 模式允许我们根据输入文件的内容路由数据。

当我们必须根据输入正文的内容路由值时,使用此模式。
以下示例将从 D:/data/input 目录读取数据。读取后,它将检查数据标记内的值标记。如果值标记包含 value1,它将被发送到 D:/value1,如果它包含 value2,它将被发送到 D:/value2,如果这两者都不包含,那么它将被发送到其他位置。
<CamelContext xmlns = "http://camel.apache.org/schema/spring"> <route> <from uri = "file:///D:/data/input"/> <choice> <when> <xpath>/data/value = 'value1'</xpath> <to uri = "file:///D:/value1"/> </when> <when> <xpath>/data/value = 'value2'</xpath> <to uri = "file:///D:/value2"/> </when> <otherwise> <to uri = "file:///D:/others "/> </otherwise> </choice> </route> </camelContext>
输入
D:/data/input/message1.xml
<data> <value>value1</value> </data>
D:/data/input/message2.xml
<data> <value>value2</value> </data>
输出
D:/value1/
<data> <value>value1</value> </data>
D:/value2/
<data> <value>value2</value> </data>
分割器
分割器模式用于将输入数据分割成较小的块。

此模式大多数情况下用于需要分割成块的大量数据输入,以便可以处理。它根据输入标记字符串将输入分解为较小的片段。
<CamelContext xmlns = "http://camel.apache.org/schema/spring"> <route> <from uri = "file:///D:/inbox"/> <split streaming = "true"> <tokenize token = "order" xml = "true"/> <to uri = "activemq:queue:order"/> </split> </route> </CamelContext>
输入
D:/inbox/message.xml
<order> <data> <value>value1</value> </data> </order> <order> <data> <value>value2</value> </data> </order> <order> <data> <value>value3</value> </data> </order>
输出
如果您检查 AMQ,您会发现已发布 3 条消息。
<order> <data> <value>value4</value> </data> </order>
收件人列表
当需要从消息正文本身检索收件人列表时,使用收件人列表模式。

在以下示例中,将向客户标签中列出的所有收件人发送一条消息,这些收件人以逗号分隔的字符串列表形式列出。
<CamelContext xmlns = "http://camel.apache.org/schema/spring"> <route> <from uri = "jms:xmlOrders" /> <recipientList> <xpath>/order/customer</xpath> </recipientList> </route> </camelContext>
其他 EIP
Camel 支持几乎所有已识别的 EIP。下面列出了一些常用的 EIP。
Log − 记录完整消息或部分消息
Message Filter − 过滤消息内容
Re-Sequencer − 按顺序获取所有令牌
Wiretap −检查传输消息
EIP 的完整列表及其用法可在 Camel 的官方文档中找到 http://camel.apache.org/eip.html
Camel 中的异常处理
使用错误处理程序 − 这是在 Camel 中处理异常的最简单方法。
要使用它,我们必须配置错误处理程序类 bean 并将其作为对 CamelContext errorHandlerRef 属性的引用提供。
<bean id = "loggingErrorHandler" class = "org.apache.camel.builder.LoggingErrorHandler"> <property name = "logName" value = "mylogger.name"/> <property name = "level" value = "DEBUG"/> </bean> <camelContext errorHandlerRef = " loggingErrorHandler" > … </camelContext>
使用 Try Catch Finally
Camel 还支持 Java 风格的 Try Catch Finally 块 用于错误处理。
与 Java 一样,它具有以下三个块 −
doTry 块包含可能产生异常的代码。
doCatch 块包含在发生异常时需要执行的代码。
doFinally 块包含无论是否发生异常都必须执行的代码。无论是否引发异常,它都会始终执行。
注意 − Mock 是测试组件,不建议用于其他目的。它是 Camel 中用于测试的组件,就像测试驱动开发中的 jMOck 组件一样。
<route> <from uri = "direct:start"/> <doTry> <process ref = "someProcesorThatmayFail"/> <to uri = "mock:result"/> <doCatch> <exception>java.io.IOException</exception> <exception>java.lang.IllegalStateException</exception> <to uri = "mock:catch"/> </doCatch> <doFinally> <to uri = "mock:finally"/> </doFinally> </doTry> </route>
在上面的例子中,我们可以给出需要由 catch 块处理的异常列表。
在 Fuse 中部署 Bundle
使用 Fuse.bat/start.bat 启动 Fuse。
如果使用 start.bat 启动 Fuse,请使用 client.bat 连接到 Fuse。您应该获得如以下屏幕截图所示的 UI。

这是用于访问 Karaf 和 Fuse 命令的 CLI。
install –s mvn:group.id /artifact.id/version e.g. install –s mvn:com.tutorialpoint.app/camel-firt-app/1.0-SNAPSHOT
JBoss Fuse - Apache CXF
在本章中,我们将讨论什么是 Apache CXF,以及它如何有助于开发 SOAP 和 Rest Web 服务。
什么是 Apache CXF?
Apache CXF 是一个 Web 服务开发框架,可用于开发 SOAP 和 Rest Web 服务。CXF 完全符合 JAX-RS 和 JAX-Ws 标准。
它是目前使用最广泛的 Web 服务开发框架。 CXF 吸取了 Axis2 的教训并进行了改进,而 Axis2 现已逐渐被 CXF 取代。
CXF 与 Axis2
CXF | Axis2 | |
---|---|---|
改进 | CXF 是目前使用最广泛的框架。 与 Axis2 相比,它有很多改进 |
Axis2 正逐渐被 CXf 取代。 与 Axis2 相比,它需要更多代码CXF |
所需代码 | 与 Axis2 相比,CXF 所需的代码较少 |
Axis2 所需的代码相对较多 |
标准合规性 | CSF 完全符合 JAX-RS 和 JAX-WS |
Axis2 不完全符合 JAX-RS 和 JAX-WS |
与 Spring 兼容 | 是 |
否 |
前端分离 | 前端与 JAX-WS 代码的清晰分离 |
未提供清晰的分离 |
SOAP
SOAP 代表简单对象访问协议。它是一种在两个系统之间通过 Web 服务交换结构化信息的协议。它主要依靠 XML 来构造数据,并使用 HTTP 或 SMTP 进行消息协商和传输。
开发 SOAP Web 服务有两种方法 −
代码优先 − 在这种方法中,WSDL 是从代码生成的。
契约优先 −首先,在 contract 中,代码是从 WSDL 生成的。
使用 CXF 进行 SOAP 开发
配置 Maven
将以下配置文件添加到 Maven 的 settings.xml 中。
<profiles> <profile> <id>Jboss-Fuse</id> <activation> <activeByDefault>true</activeByDefault> </activation> <repositories> <repository> <id>fusesource</id> <url>http://repo.fusesource.com/nexus/content/groups/public/</url> <snapshots> <enabled>false</enabled> </snapshots> <releases> <enabled>true</enabled> </releases> </repository> </repositories> </profile> </profiles>
创建 Skeleton
mvn archetype:generate -DarchetypeGroupId = org.apache.servicemix.tooling -DarchetypeArtifactId = servicemix-cxf-code-first-osgi-bundle -DarchetypeVersion=2012.01.0.redhat-60024 -DgroupId = org.fusesource.example -DartifactId = cxf-basic -Dversion = 1.0-SNAPSHOT
构建 Web 服务项目。
mvn clean install
使用以下命令将 web 服务安装到 Fuse 中。
JBossFuse:karaf@root>install -s mvn:org.fusesource.example/cxf-basic/1.0-SNAPSH
检查 bundle 是否已注册 SOQP web 服务
打开 URL http://localhost:8181/cxf

web 服务应按如下方式列出。
测试 Web 服务
mvn -Pclient
INFO − 从类 com.to 创建服务 {http://ws.totorials.com/} PersonService
torials.ws.Person Invoking getPerson... getPerson._getPerson_personId = Guillaume getPerson._getPerson_ssn = 000-000-0000 getPerson._getPerson_name = Guillaume [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 30.668 s [INFO] Finished at: 2016-02-15T21:01:20+05:30 [INFO] Final Memory: 10M/37M [INFO] ------------------------------------------------------------------------
JBoss Fuse - Rest Web 服务
首先,REST 代表表述性状态转移。它是一种基于无状态、可缓存、客户端-服务器协议(大多数情况下为 HTTP)开发 Web 服务的方式。
REST Web 服务使用 HTTP 请求从网络发布、获取和删除数据。
使用 CXF 进行 REST 开发
创建一个简单的 Maven 快速启动项目
mvn archetype:generate -DgroupId = com.tuts.abhinav -DartifactId = rest-service -DarchetypeArtifactId = maven-archetype-quickstart -DinteractiveMode = false
添加依赖项
<dependency> <groupId>org.apache.servicemix.specs</groupId> <artifactId>org.apache.servicemix.specs.jsr311-api-1.1.1</artifactId> <version>1.9.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.servicemix</groupId> <artifactId>servicemix-http</artifactId> <version>2013.01</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.16</version> </dependency>
Add Build Instruction
<build> <defaultGoal>install</defaultGoal> <plugins> <plugin> <groupId>org.apache.felix</groupId> <artifalctId>maven-bundle-plugin</artifactId> <version>2.3.4</version> <extensions>true</extensions> <configuration> <instructions> <Bundle-SymbolicName>rest-example-database-post-method </Bundle-SymbolicName> <Import-Package>* </Import-Package> </instructions> </configuration> </plugin> </plugins> </build>
添加 Fuse 插件库
<pluginRepositories> <pluginRepository> <id>fusesource.m2</id> <name>FuseSource Community Release Repository</name> <url>http://repo.fusesource.com/nexus/content/repositories/releases</url> <snapshots> <enabled>false</enabled> </snapshots> <releases> <enabled>true</enabled> </releases> </pluginRepository> <pluginRepositories>
添加存储库
<repositories> <repository> <id>fusesource.m2</id> <name>FuseSource Community Release Repository</name> <url>http://repo.fusesource.com/nexus/content/repositories/releases</url> <snapshots> <enabled>false</enabled> </snapshots> <releases> <enabled>true</enabled> </releases> </repository> <repository> <id>fusesource.ea</id> <name>FuseSource Community Early Access Release Repository</name> <url>http://repo.fusesource.com/nexus/content/groups/ea</url> <snapshots> <enabled>false</enabled> </snapshots> <releases> <enabled>true</enabled> </releases> </repository> </repositories>
创建服务类
在 com/tuts/ 下创建类 UserService.java
package com.tuts; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path("/UserService_1") public class UserService { @GET @Path("/get_data") @Produces(MediaType.APPLICATION_JSON) public String getUser() { String reponse = "This is standard response from REST"; return reponse; } }
创建 Blueprint.xml
在/src/main/resources/OSGI-INF/blueprint下创建blueprint.xml blueprint.xml
<?xml version = "1.0" encoding = "UTF-8"?> <blueprint xmlns = "http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs = "http://cxf.apache.org/blueprint/jaxrs" xsi:schemaLocation = "http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd"> <jaxrs:server id = "service" address = "/users"> <jaxrs:serviceBeans> <ref component-id = "userService" /> </jaxrs:serviceBeans> </jaxrs:server> <bean id = "userService" class = "com.tuts.UserService" /> </blueprint>
在 Fuse 中安装 Rest 服务
install -s mvn:com.tuts.abhinav/rest-service/1.0-SNAPSHOT
检查 Bundle 是否有已注册的 Web 服务
打开 URL http://localhost:8181/cxf

测试 Web 服务
打开 URL http://localhost:8181/cxf/users12/UserService_1/get_data

JBoss Fuse - Apache AMQ
在本章中,我们将了解 ActiveMQ 以及它如何充当消息代理以允许应用程序相互通信。
什么是 AMQ?
ActiveMQ 是一个用 Java 编写的开源消息代理。它完全符合 JMS 1.1 标准。
JMS 是一种允许开发基于消息的系统的规范。 ActiveMQ 充当位于应用程序之间的消息代理,允许它们以异步和可靠的方式进行通信。

消息类型
为了更好地理解,下面解释了两种类型的消息选项。
点对点
在这种类型的通信中,代理只向一个消费者发送消息,而其他消费者将等待,直到他们从代理那里获得消息。没有消费者会收到相同的消息。
如果没有消费者,代理将保留消息,直到它找到一个消费者。这种类型的通信也称为基于队列的通信,其中生产者将消息发送到队列,并且只有一个消费者从队列中获取一条消息。如果有多个消费者,他们可能会收到下一条消息,但不会收到与其他消费者相同的消息。

发布/订阅
在这种类型的通信中,代理会向所有活跃消费者发送相同的消息副本。这种类型的通信也称为基于主题的通信,其中代理会向已订阅特定主题的所有活跃消费者发送相同的消息。此模型支持单向通信,无需验证传输的消息。

创建队列和主题
Fuse 与 ActiveMQ 捆绑在一起。我们可以使用 FMC 控制台(与 AMQ 配合使用的基于浏览器的界面)访问 ActiveMQ。
使用 localhost:8181 登录 FMC 并选择 ActiveMQ 选项卡。

- 单击 +Create
- 输入队列/主题名称
- 从单选按钮中选择队列/主题
- 单击创建队列/创建主题

现在您应该能够看到在 root 下创建的 TestQ →队列 →

要检查创建的主题,请按照 root → 主题操作。
浏览/删除队列的内容
使用 localhost:8181
登录 FMC
选择 ActiveMQ 选项卡
Root → 队列 → TestQ <选择要浏览的队列> →浏览

- 要检查此消息的内容,请单击该特定消息。

您可以通过单击右上角显示的删除按钮来删除特定消息
JBoss Fuse - AMQ 与 Camel
在本章中,我们将学习 ActiveMQ 如何与 Camel 配合使用的基础知识。
配置 ActiveMQ 组件
在代码中使用 ActiveMQ 队列或主题之前,我们必须配置 ActiveMQComponent。ActiveMQComponent 的最低配置可以按照以下程序所示完成 −
<bean id = "activemq" class = "org.apache.activemq.camel.component.ActiveMQComponent"> <property name = "brokerURL" value = "tcp://localhost:61616"/> <property name = "userName" value = "admin"/> <property name = "password" value = "admin"/> </bean>
brokerURL − 指定 AMQ Broker 的主机和端口。
username − 指定用于连接到 AMQ Broker 的用户名。
password − 指定用于连接到 AMQ Broker 的密码。
连接到队列
现在我们已经配置了 ActiveMQComponent,我们可以在 CamelContext 中将其用作端点。
我们将使用以下格式的 AMQ 端点 −
Activemq:[queue|topic]:[queueName|topicName]
将消息写入 AMQ
<?xml version = "1.0" encoding="UTF-8"?> <!-- Configures the Camel Context--> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
在 Fuse 容器中部署此包后,您应该能够看到发布到 AMQ 的消息,这些消息作为文件放置在 D:/src/data 中。
输入
D:/src/data/input.txt
Test me
输出

从 AMQ 读取
<?xml version = "1.0" encoding = "UTF-8"?> <!-- Configures the Camel Context--> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = " http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <camelContext xmlns = "http://camel.apache.org/schema/spring"> <!-- here is a sample which processes the input files (leaving them in place - see the 'noop' flag) then performs content based routing on the message using XPath --> <route> <from uri = "activemq:queue:TestQ"/> <to uri = "file:///d:/src"/> </route> </camelContext> <bean id = "activemq" class = "org.apache.activemq.camel.component.ActiveMQComponent"> <property name = "brokerURL" value = "tcp://localhost:61616"/> <property name = "userName" value = "admin"/> <property name = "password" value = "admin"/> </bean> </beans>
输入
部署此包后,您应该会看到在 D:/src 中生成一个文件,并且消息已被使用。还应该显示该队列的消费者。

输出
D:/src
Test me
写入主题
<?xml version = "1.0" encoding = "UTF-8"?> <!-- Configures the Camel Context--> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <camelContext xmlns = "http://camel.apache.org/schema/spring"> <!-- here is a sample which processes the input files (leaving them in place - see the 'noop' flag) then performs content based routing on the message using XPath --> <route> <from uri = "file:///d:/src"/> <to uri = "activemq:topic:TestTopic" /> </route> </camelContext> <bean id = "activemq" class = "org.apache.activemq.camel.component.ActiveMQComponent"> <property name = "brokerURL" value = "tcp://localhost:61616"/> <property name = "userName" value = "admin"/> <property name = "password" value = "admin"/> </bean> </beans>
从主题读取
<?xml version = "1.0" encoding = "UTF-8"?> <!-- Configures the Camel Context--> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = " http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <camelContext xmlns = "http://camel.apache.org/schema/spring"> <!-- here is a sample which processes the input files (leaving them in place - see the 'noop' flag) then performs content based routing on the message using XPath --> <route> <from uri = "activemq:topic:TestTopic"/> <to uri = "file:///d:/src2"/> </route> </camelContext> <bean id = "activemq" class = "org.apache.activemq.camel.component.ActiveMQComponent"> <property name = "brokerURL" value="tcp://localhost:61616"/> <property name = "userName" value = "admin"/> <property name = "password" value = "admin"/> </bean> </beans>
输入
D:/src/file1.xml
<order> <data> <value>value1</value> </data> </order> <order> <data> <value>value2</value> </data> </order> <order> <data> <value>value3</value> </data> </order>
输出
D:/src/
<order> <data> <value>value1</value> </data> </order> <order> <data> <value>value2</value> </data> </order> <order> <data> <value>value3</value> </data> </order>
JBoss Fuse - Fabric
什么是 Fabric?
Fabric 为多个 Fuse 实例提供管理和编排功能。Fabric 允许我们从单个点控制与其连接的所有 Fuse 实例。普通的 Fuse 容器可以转换为 Fabric。 Fabric 中有一个 Fabric 注册表,它充当数据存储,其中包含有关其管理的容器的所有信息。
为什么选择 Fabric?
Fabric 具有以下特殊功能,使其成为分布式环境中使用的理想选择。
- 监控 Fabric 中所有容器的状态。
- 启动和停止远程容器。
- 配置远程容器以运行特定应用程序。
- 升级应用程序并在实时系统中推出补丁。
- 快速启动和配置新容器,例如以应对系统负载的增加。

Fabric 设置
创建 Fabric
普通 Fuse 容器可以转换为 Fabric通过使用以下命令
fabric: create --clean --zookeeper-password myZooPass
将其他容器连接到 Fabric −
fabric:join --zookeeper-password myZooPass <fabric_host>:2181 Cont1
注意 − 请将 <fabric_host> 替换为 Fabric 正在运行的实际主机名。
当您使用 localhost:8181 从浏览器登录 Fuse 管理控制台时,您应该能够看到两个容器,如以下屏幕截图所示。 Fabric 容器前面有一个小云符号。

配置文件
配置文件包含以下信息 −
- 要安装的软件包
- 要安装的功能
- 要应用的配置
配置文件提供了一种在 Fabric 环境中在多台服务器上安装同一套软件包、功能和配置的方法。
如果将同一个配置文件应用于多个容器,并且我们从任何容器对该配置文件进行更改,则类似的更改将自动部署到应用该配置文件的其余容器。
创建配置文件
登录 FMC localhost:8181
运行时 → 管理
在左侧的配置文件菜单下单击 +

输入要为配置文件指定的名称,然后单击创建。

此后,应创建配置文件。
将配置文件应用于容器
运行时 → 容器 → root(选择您想要的容器)

单击添加,将弹出一个弹出框。搜索所需的配置文件,然后再次单击添加。

配置文件应显示在列表中,如以下屏幕截图所示。

部署捆绑包
要部署捆绑包,请使用以下路径 −
运行时 → 容器 → 根(选择所需的容器)→ First_profile(选择配置文件)

单击"捆绑包"选项卡。按以下格式设置包路径,然后单击 +。
mvn:group.id/artifact.id/version
例如:mvn:com.tutorialpoint.app/camel-firt-app/1.0-SNAPSHOT


包将添加到配置文件中,并将部署在分配了配置文件的所有容器上。
取消部署包
要取消部署包,请使用以下路径−
运行时 → 容器 → 根目录(选择所需容器)→ First_profile(选择配置文件)

单击"捆绑包"选项卡并搜索要删除的捆绑包,然后单击 X。捆绑包将从应用了配置文件的所有容器中删除。

JBoss Fuse - 子容器
子容器提供了管理不断增加的负载的最简单方法。当系统遇到流量突然增加且单个容器无法应对负载时,我们可以轻松创建一组子容器并在它们之间分配负载,而不是创建一个全新的容器。
创建子容器
使用 localhost:8181 登录 FMC
现在,按照路径:运行时 → 容器 → +创建(右侧按钮)

输入详细信息,如子容器名称、父容器实例数等。

单击创建并启动容器

管理子容器
子容器仅充当普通容器。
停止子容器
要停止子容器,请按照以下路径操作:运行时→ 容器 → Child1
单击"停止"以停止子容器。

启动子容器
要启动子容器,请按照以下路径操作:运行时 → 容器 → Child1
单击"启动"以启动子容器。

JBoss Fuse - 问题和解决方案
在本章中,我们将讨论您在使用 Fuse 时可能遇到的一些已知问题。我们还将讨论如何解决这些问题。
代码更改未反映出来
使用客户端脚本连接到 Fuse 实例。使用以下命令搜索您遇到问题的包。
JBossFuse:karaf@root > list|grep <Bundle Description> For Example: JBossFuse:karaf@root > list|grep Camel [ 255] [Active ] [ ] [ ] [ 60] Fabric8 :: Camel Component (1.0.0.redhat-379) [ 266] [Active ] [ ] [Started] [ 60] A Camel Spring Route (1.0.0.SNAPSHOT)
注意 − 从上述命令的输出中获取捆绑包的捆绑包 ID,并使用以下命令。
JBossFuse:karaf@root > update <bundle id> JBossFuse:karaf@root > update 266
未下载软件包
可能由于以下两个原因而发生这种情况 −
- 未指定 Maven 存储库
- 存储库中不存在软件包
未指定 Maven 存储库
Maven 是用于构建 Fuse 工件的构建工具。当我们发出安装工件的命令时,Fuse 首先在 Maven 本地存储库中搜索工件。所以我们必须让 Fuse 知道 Maven 的安装位置以及 Mavens 本地存储库的路径。
编辑 $FUSE_INSTALLATION_DIR/etc/org.ops4j.paxurl.mvn.cfg
更新以下两个属性 −
- org.ops4j.pax.url.mvn.settings = $M2_HOME/conf /settings.xml
- org.ops4j.pax.url.mvn.localRepository = $local_repo
注意 −请将 $local_repo 更改为 Mavens settings.xml 中提到的本地存储库的实际路径
存储库中不存在软件包
如果 Maven 设置已到位,但在下载软件包时仍然遇到问题,请确保软件包 JAR 位于 Maven 存储库中的正确位置。
例如,如果以下软件包在下载 − 时抛出错误
mvn:com.tutorialpoint.app/camel-first-app/1.0-SNAPSHOT
我们必须在 $M2_REPO/com/tutorialpoint/app/camel-first-app/1.0-SNAPSHOT 中检查是否存在实际 JAR。
注意 − $M2_REPO 需要替换为我们已配置 Fuse 使用的 Maven 存储库的实际路径。
无法登录 FMC(基于浏览器的 GUI)
未创建用户 −如果您看到以下 UI,但无法登录,并显示"无法登录,禁止登录"的消息。

检查您是否已在 $FUSE_INSTALLATION_HOME/etc/users.properties 中添加用户
添加用户的正确格式是 −
Username = Password,Role
HAWTIO 端口不同
如果您甚至无法在浏览器中获取 localhost:8181 的 UI,请检查您是否在URL。
$FUSE_INSTALLATION_HOME/etc/org.ops4j.pax.web.cfg
编辑文件中的以下属性以使用您要访问的端口。
org.osgi.service.http.port=8181
AMQ Broker 不工作
确保 61616 端口已打开且当前未被其他端口使用。如果您想更改其默认 61616 端口,您可以在 $FUSE_INSTALLATION_HOME/etc/System.properties 中编辑它
activemq.port = 61616