Jboss Fuse 简明教程
JBoss Fuse - Introduction To ESB
在本章中,我们将从企业服务总线的要点开始。以下是对 ESB 的详细解释,以及它的优点、缺点和一些便于理解的图表。
What is ESB?
ESB 代表企业服务总线。最简单的形式的 ESB 是一个中间件,充当一条信息高速公路,帮助多个应用程序进行通信。
在企业世界中,我们针对许多事物开发解决方案。这些解决方案可能会使用不同的技术和不同的数据格式。由于这些技术中通信或数据格式的兼容性差异,将这些解决方案一起使用变得很困难。因此,我们需要一种允许在这些不同的解决方案之间@(s0)的技术。
ESB 旨在通过成为坐落在所有应用程序中间的“枢纽”来简化这个问题并促进它们之间的消息路由。ESB 充当信息高速公路的中介,负责数据转换路由,而编码器或开发人员则专注于其自己的应用程序逻辑。
当理解 ESB 的设计目的和解决方案后,理解 ESB 变得非常简单。在使用不同的语言编写、在不同的机器上运行和应用于不同的数据格式以共享信息并形成一个集成业务平台的许多分散系统间启用互通性的方式上,应该有一个明确的了解。
The Integration Problem
在企业平台中,多个应用程序相互协作并作为一个整体提供业务功能是很常见的,但集成这些应用程序是最常出现的问题。应用程序在增长时,集成会变得更加困难。
每个应用程序都可以以自己的格式输入和输出数据。如果应用程序数量较少,这种方法很有效,但随着应用程序数量的增加,集成环节也需要采用更好的方法进行精简。例如,如果业务中的某个特定应用程序需要进行更改,所有依赖于该主应用程序的应用程序的输出或输入数据格式都会受到影响。
这种方法对于期望有紧密耦合架构的集成而言是最重要的障碍。这就是 ESB 发挥作用的地方。每个应用程序不必直接与其他应用程序通信;相反,所有应用程序都与 ESB 通信,而 ESB 处理信息的路由以及内部数据格式转换。
What Is Fuse?
JBoss Fuse 是 Redhat 的一个开源 ESB 解决方案。它是一个基于社区项目 Apache Servicemix 的企业解决方案。
Integration to Fuse
JBoss Fuse 是一个轻量级且灵活的集成平台,允许快速集成企业应用程序。
Fuse 最初是由 Progressive 软件公司开发的,该公司于 2012 年被 Redhat 收购。JBoss Fuse 6.1.0.redhat-379 GA 是 Fuse 的一个稳定版本,可以从其官方网站下载。
Components
Apache Camel
Apache Camel 是一款基于 EIP 的集成框架。EIP 或企业集成模式是针对企业集成中的常见问题确定的解决方案。通过组合这些预定义的即用型模式,可快速实现完整的集成解决方案。
它允许用 Java、Spring DSL 和 Scala 等多种特定领域语言编写路由逻辑。
Installing Fuse
安装 Fuse 非常简单。与其他 JBoss 产品一样,Fuse 也以 zip 文件的形式提供,可以对其进行提取,并且在进行一些轻微的配置更改后,可以直接启动它。
安装 Fuse 是一个四步流程:
Download
从以下链接下载 Fuse 6.1.0 GA。 http://www.jboss.org/
Unzip
与所有其他 JBoss 产品一样,Fuse 也是一个与平台无关的 zip 文件。
将下载的文件解压缩到要作为 Fuse 安装目录的目标目录中。明智地选择此目录,因为在 Fuse 实例的生命周期中它应保持不变。
Note - 即使 Fuse 解压缩并像其他 JBoss 产品一样启动,也不建议在安装完成后将 Fuse 安装从一个位置移动到另一位置。
Configure
解压缩 Fuse 后,你将在解压缩的目录中找到以下目录:
-
bin
-
etc
-
deploy
-
lib
-
licenses
-
extras
-
quickstarts
其中,我们将仅使用两个目录 bin 和 etc 。
实际上,在解压缩 Fuse 之后,我们应该能够直接启动 Fuse,但这将使用所有默认配置启动 Fuse,这对于生成环境来说不可取。强烈建议在启动 Fuse 之前进行以下更改。
Basic Configuration
我们将讨论有关 JBoss Fuse 的基本配置,为此,我们必须从以下命令 Edit $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 此属性表示用于访问浏览器基础界面 HAWTIO 的端口,该界面由 Fuse 提供 HAWTIO 是一个自 6.0 起可用的面向 Fuse 的内置浏览器界面
-
在 org.ops4j.pax.url.mvn.cfg org.ops4j.pax.url.mvn.localRepository = D:/repository 此属性表示 Fuse 将从其安装工件的 Maven 的 localRepository 路径。 org.ops4j.pax.url.mvn.settings = D:/Maven/conf/settings.xml 此属性表示 Fuse 应使用的 settings.xml,以便从 Maven 获取工件。
Configuring Maven
Maven 是安装 Fuse 的先决条件。如果您不知道 maven 是什么,请参阅 http://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
Note − 请使用 Mavens settings.xml 中提到的本地存储库的实际路径,更改 $local_repo 。
Run
设置完成基本配置更改后,我们现在可以启动 Fuse。所有用于与 Fuse 搭配使用的二进制文件都位于 $FUSE_INSTALLATION_DIR 。
有两种启动 Fuse 的方法 −
-
使用 ./fuse 这会让您能够在启动 Fuse 的同一窗口中看到所有进度和日志。它会在同一终端中提供给您 Karaf 控制台,如下所示。
Note − 此命令会以控制台模式启动 Fuse,这意味着当用户退出会话或关闭终端(这是生产或开发场景中不希望出现的)时,Fuse 进程也会停止。这个脚本应该只用于调试 Fuse。
-
使用 ./start 这不会在屏幕上显示任何日志,甚至不会显示进度,但这将在后台启动 Fuse,并且当用户退出会话或关闭终端时 Fuse 服务并不会停止。在现实世界的应用程序中,需要此类行为。即使我们关闭终端,Fuse 也应该在后台运行。如果你想连接到在后台运行的 Fuse,可以使用 client 脚本,该脚本位于同一文件夹中。你应该获得下图所示的显示。退出客户端脚本不会停止 Fuse 服务。它只会关闭 Fuse 控制台。
HAWTIO
Fuse 还使用 FMC(Fuse 管理控制台)提供对它的完整 GUI 访问。你可以在 http://localhost:8181 的以下 URL 上找到 GUI。
我们通过执行命令所做的所有事情,也可以通过访问此基于浏览器的 GUI 来完成。当我们有多个容器并运行在 Fabric 环境中时,这会变得非常有用。
JBoss Fuse - Apache Karaf
在本章中,我们将讨论 Apache Karaf 及其为何被称为轻量级 OSGi 容器,以及它的优点和其他重要功能。
The JVM Problem
JVM 或 Java 虚拟机并不作为真正的虚拟机。它允许你随时停止、启动或重新启动在其中运行的组件。它有时允许在类级别热部署,但你不可能在不重新启动虚拟机的情况下部署或取消部署应用程序的组件。
为了解决这一问题并允许 Java 应用程序模块化,Fuse 使用了称为 Apache Karaf 基于 OSGi 的运行时。
Bundles Vs Features
以下是包和功能之间的比较。
Why another Container?
Apache Karaf 是基于 OSGi 的运行时,它是我们的应用程序包运行的位置。Fuse 使用 Apache Karaf 作为其运行时,其中包运行和协作以提供业务功能。
Karaf 建立在 OSGi 框架 Felix 和 Equinox 之上。
Logging
Karaf 通过在 $Fuse_home/data/log 中生成所有包的日志提供集中式记录。我们可以在 org.ops4j.pax.logging.cfg 中 $Fuse_home/etc directory 中编辑记录器配置。
JBoss Fuse - Apache Camel
在本章中,我们将讨论 Apache Camel 是什么,以及它如何有效地在端点之间路由数据,其中包括一些示例。
What is Apache Camel?
Apache Camel 是一个开源集成框架,始于 2007 年初。
它是一种基于 EIP(企业集成模式)的方法,提供可用于解决企业集成问题的几种开箱即用的模式实现。EIP 是针对企业集成中记录良好且经常出现的问题的久经考验的解决方案。
Camel 也称为路由和中介引擎,因为它能够有效地在端点之间路由数据,同时承担诸如数据格式转换、端点连接等繁重负载。
Basic Example
使用 Apache Camel 的前提条件如下−
-
Java
-
Maven
-
Redhat JBoss Fuse 6.1-GA-379
Create basic skeleton of Application
mvn:archetype generate
–DgroupId = com.tutorialpoint.app
–DartifactId = camel-first-app
–DarchetypeGroupId = org.apache.camel.archetypes
–DarchetypeArtifactId = camel-archetype-spring
–DinteractiveMode = false -X
这将生成以下目录结构。
这是我们正在生成的 Camel 应用程序的基本框架。
Edit 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>
Edit 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
Install Project into 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
Test if your Project is Running
现在,你的应用程序应安装在 Fuse 中。复制 camel-first-app 内的数据目录并将其放在 D:/src/ 中,它应将城市 = 伦敦的消息复制到 D:/target/merssages/uk 中。
将输入文件放在 D:/src/data 中
Input
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>
Output
在 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 Concepts
在本章中,我们将理解不同的 Camel 概念。让我们从举一个基本示例开始,首先了解核心概念。
CamelContext
每个 camel 应用程序至少具有一个 CamelContext。这是我们添加 camel 路由的位置。它类似于 Spring 的 ApplicationContext 。
Camel context 可以被认为是将所有内容组合在一起的容器。一个 camel context 可以容纳多个路由。
EIP
EIP 代表企业集成模式。这些是针对重复出现的问题而确定的众所周知的解决方案。Camel 支持大多数企业集成模式。
Content Based Router
CBR 模式允许我们根据输入文件的内容路由数据。
当我们必须根据输入正文的内容路由值时,将使用此模式。
以下示例将从 D:/data/input 目录读取数据。读取后,它将在 data 标记内部查找值标记。如果值标记包含 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>
Input
D:/data/input/message1.xml
<data>
<value>value1</value>
</data>
D:/data/input/message2.xml
<data>
<value>value2</value>
</data>
Output
D:/value1/
<data>
<value>value1</value>
</data>
D:/value2/
<data>
<value>value2</value>
</data>
Splitter
拆分模式用于将输入数据拆分成更小的块。
此模式通常用于大的数据输入,需要将其拆分成块,以便于处理。它根据输入令牌字符串将输入分解为更小的片段。
<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>
Input
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>
Output
如果您检查 AMQ,您会发现发布了 3 条消息。
<order>
<data>
<value>value4</value>
</data>
</order>
Recipient List
当需要从消息正文中检索收件人列表时,将使用收件人列表模式。
在以下示例中,将向作为逗号分隔字符串列表列在 customer 标记中的所有收件人发送消息。
<CamelContext xmlns = "http://camel.apache.org/schema/spring">
<route>
<from uri = "jms:xmlOrders" />
<recipientList>
<xpath>/order/customer</xpath>
</recipientList>
</route>
</camelContext>
Other EIPs
Camel 几乎支持所有已识别的 EIP。一些常用的 EIP 如下所述。
-
Log − 记录消息全部或部分内容
-
Message Filter − 过滤消息内容
-
Re-Sequencer − 获取序列中的所有令牌
-
Wiretap − 检查正在传输的消息
EIP 及其用法完整列表可在 Camel 官方文档 http://camel.apache.org/eip.html 中找到
Exception Handling in Camel
Using Error Handler − 这是在 Camel 中处理异常的最简单方法。
要使用此方法,我们必须配置 Error handler 类 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>
Using Try Catch Finally
Camel 还支持 Java 风格 Try Catch Finally block 进行错误处理。
就像 Java 一样,它有以下三个块:
-
doTry 块包含可能生成异常的代码。
-
doCatch 块包含在异常情况下需要执行的代码。
-
doFinally 块具有必须在不考虑异常的情况下执行的代码。无论是否引发异常,此块始终都会执行。
Note − Mock 是测试组件,不建议作它用。这是 Camel 中用于测试的组件,如同 Test 驱动的开发中的 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 块处理的异常列表。
JBoss Fuse - Apache CXF
在本章中,让我们讨论一下 Apache CXF 是什么,以及它如何在开发 SOAP 和 Rest Web 服务中有帮助。
What is Apache CXF?
Apache CXF 是一个 Web 服务开发框架,可用于开发 SOAP 和 Rest Web 服务。CXF 完全符合 JAX-RS and JAX-Ws 标准。
现在,它是最广泛使用的 Web 服务开发框架。 CXF 已经从 Axis2 中学习并进行了改进,现在 CXF 正在逐渐取代 Axis2。
CXF vs Axis2
CXF |
Axis2 |
|
Improvements |
CXF 现在是最常用的框架。它对 Axis2 进行了大量改进。 |
CXF 正在逐渐取代 Axis2。与 CXF 相比,它需要更多的代码。 |
Code required |
与 Axis2 相比,CXF 需要更少的代码。 |
与 Axis2 相比,它需要更多的代码。 |
Standard Compliance |
CSF 完全符合 JAX-RS 和 JAX-WS。 |
Axis2 并不完全符合 JAX-RS 和 JAX-WS。 |
Compatible with Spring |
Yes |
No |
Separation of front-ends |
与 JAX-WS 代码进行前台清洁分离。 |
不提供干净的分离。 |
SOAP
SOAP 代表简单对象访问协议。这是一种通过 Web 服务在两个系统之间交换结构化信息的协议。它主要依赖于 XML 来构建数据,并使用 HTTP 或 SMTP 来进行消息协商和传输。
有两种方法可以开发 SOAP Web 服务 −
-
Code first − 在此方法中,WSDL 由代码生成。
-
Contract first − 在契约优先的情况下,代码由 WSDL 生成。
SOAP Development Using CXF
Configure 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>
Create 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
Build Web Service Project 。
mvn clean install
Install web-service into Fuse using the following command 。
JBossFuse:karaf@root>install -s mvn:org.fusesource.example/cxf-basic/1.0-SNAPSH
Check if bundle has registered SOQP web-service
打开 URL http://localhost:8181/cxf
Web 服务应按以下方式列出。
Testing Web-Service
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 Services
首先,REST 代表表象状态传输。它是一种基于无状态、可缓存的客户端-服务器协议(大多数情况下是 HTTP)开发 Web 服务的方法。
REST Web 服务使用 HTTP 请求从网络发布、获取、删除数据。
REST Development using CXF
Create a simple Maven quick-start project
mvn archetype:generate
-DgroupId = com.tuts.abhinav
-DartifactId = rest-service
-DarchetypeArtifactId = maven-archetype-quickstart
-DinteractiveMode = false
Add dependencies
<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>
Add Fuse Plugin Repositories
<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>
Add Repositories
<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>
Create Service Class
在 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;
}
}
Create 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>
JBoss Fuse - Apache AMQ
在本章中,我们将了解 ActiveMQ,以及它如何充当消息代理,允许应用程序相互通信。
What is AMQ?
ActiveMQ 是一个用 Java 编写的开源消息代理。它完全符合 JMS 1.1 标准。
JMS 是一个允许开发基于消息的系统的规范。ActiveMQ 充当消息代理,位于应用程序之间,并允许它们以异步且可靠的方式进行通信。
Types of Messaging
为了便于理解,下面解释了两种类型的消息传递选项。
JBoss Fuse - AMQ With Camel
在本章中,我们将学习 ActiveMQ 与 Camel 配合使用的基础知识。
Configuring to ActiveMQ Component
在我们可以在代码中使用 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 的密码。
Connecting to Queue
既然我们已经配置了 ActiveMQComponent,我们可以将其作为端点在我们的 CamelContext 中使用。
我们将在以下格式中使用 AMQ 端点 −
Activemq:[queue|topic]:[queueName|topicName]
Writing Messages to 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 中。
Input
D:/src/data/input.txt
Test me
Output
Reading from 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>
Input
在部署此捆绑包后,你应当看到已在 D:/src 中生成文件且消息已被使用。该队列还应当显示使用者。
Output
D:/src
Test me
Writing to Topic
<?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>
Reading from Topic
<?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>
Input
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>
Output
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
What is Fabric?
Fabric 为多个 Fuse 实例提供管理和编排功能。Fabric 允许我们从单点控制连接到它的所有 Fuse 实例。可以将普通 Fuse 容器转换为充当 Fabric。Fabric 其中包含 Fabric 注册表,它用作数据存储,其中包含有关容器的所有信息,它进行管理。
Why Fabric?
Fabric 具有以下特殊功能,使其成为在分布式环境中使用的理想候选者。
-
监视 Fabric 中所有容器的状态。
-
启动和停止远程容器。
-
提供远程容器来运行特定应用程序。
-
升级应用程序,并在实时系统中推出补丁。
-
为应对系统上的负载增加快速启动和采用新容器。
Fabric Setup
Creating Fabric
可以使用以下命令将普通 Fuse 容器转换为 Fabric
fabric: create --clean --zookeeper-password myZooPass
连接其他容器到 Fabric −
fabric:join --zookeeper-password myZooPass <fabric_host>:2181 Cont1
Note − 请将 <fabric_host> 替换为运行 Fabric 的实际主机名。
当您使用 localhost:8181 通过浏览器登录 Fuse Management Console 时,您应该可以看到两个容器,如下图所示。Fabric 容器的前面有一个小的云符号。
Profiles
一个配置文件包含以下信息:
-
Bundles to be installed
-
Features to be installed
-
Configurations to be applied
一个配置文件提供了在 Fabric 环境中在多台服务器上安装相同的一组 bundle、功能和配置的方法。
如果将同一个配置文件应用到多个容器,并且我们从任何容器对此配置文件进行更改,则类似的更改将自动部署到应用了它的其余容器。
JBoss Fuse - Child Container
JBoss Fuse - Issues and Solutions
在本章中,我们将讨论在使用 Fuse 时可能遇到的几个已知问题。我们还将讨论如何解决这些问题。
Code Changes are not Reflected
使用客户端脚本连接到 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)
Note − 捆绑的捆绑 ID(来自上述命令的输出),然后使用以下命令。
JBossFuse:karaf@root > update <bundle id>
JBossFuse:karaf@root > update 266
Bundle not Being Downloaded
这可能是由于以下两个原因造成的 −
-
Maven repository not specified
-
存储库中没有捆绑
Maven Repository not Specified
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
Note − 请将 $local_repo 更改为 Maven 设置中的实际本地存储库路径。
Not Able to Login into FMC (Browser based GUI)
Users not Created − 如果你收到以下 UI 但无法登录且显示消息:“登录失败,禁止”。
检查你是否已在 $FUSE_INSTALLATION_HOME/etc/users.properties 中添加用户
添加用户的正确格式为 −
Username = Password,Role