Jboss Fuse 简明教程

JBoss Fuse - Quick Guide

JBoss Fuse - Introduction To ESB

在本章中,我们将从企业服务总线的要点开始。以下是对 ESB 的详细解释,以及它的优点、缺点和一些便于理解的图表。

What is ESB?

ESB 代表企业服务总线。最简单的形式的 ESB 是一个中间件,充当一条信息高速公路,帮助多个应用程序进行通信。

在企业世界中,我们针对许多事物开发解决方案。这些解决方案可能会使用不同的技术和不同的数据格式。由于这些技术中通信或数据格式的兼容性差异,将这些解决方案一起使用变得很困难。因此,我们需要一种允许在这些不同的解决方案之间@(s0)的技术。

ESB 旨在通过成为坐落在所有应用程序中间的“枢纽”来简化这个问题并促进它们之间的消息路由。ESB 充当信息高速公路的中介,负责数据转换路由,而编码器或开发人员则专注于其自己的应用程序逻辑。

当理解 ESB 的设计目的和解决方案后,理解 ESB 变得非常简单。在使用不同的语言编写、在不同的机器上运行和应用于不同的数据格式以共享信息并形成一个集成业务平台的许多分散系统间启用互通性的方式上,应该有一个明确的了解。

The Integration Problem

在企业平台中,多个应用程序相互协作并作为一个整体提供业务功能是很常见的,但集成这些应用程序是最常出现的问题。应用程序在增长时,集成会变得更加困难。

每个应用程序都可以以自己的格式输入和输出数据。如果应用程序数量较少,这种方法很有效,但随着应用程序数量的增加,集成环节也需要采用更好的方法进行精简。例如,如果业务中的某个特定应用程序需要进行更改,所有依赖于该主应用程序的应用程序的输出或输入数据格式都会受到影响。

这种方法对于期望有紧密耦合架构的集成而言是最重要的障碍。这就是 ESB 发挥作用的地方。每个应用程序不必直接与其他应用程序通信;相反,所有应用程序都与 ESB 通信,而 ESB 处理信息的路由以及内部数据格式转换。

integration problem

Why ESB?

以下是说明为什么企业服务总线必不可少的一些要点。

  1. ESB 旨在简化与各种兼容应用程序的集成问题。

  2. 它充当中间件,充当所有应用程序的中介并促进它们之间的消息路由。

  3. 现在,每个应用程序只需与 ESB 建立一个接口,而不必与其他每个应用程序直接交互。

  4. ESB 负责将消息翻译成/从通用格式并将其路由到其目标。

  5. 如果您必须更换现有应用程序之一的任何一项,这种方法的主要好处是一大福音。现在,不必编写一连串的新接口,只需关注一个接口(在您的应用程序和 ESB 之间)即可。

esb

SOA & ESB?

SOA 和 ESB 通常可以互换使用,但它们是完全不同的。

SOA 是一种设计模式,允许应用程序通过通信协议将其功能作为服务通过网络公开,而 ESB 是一个促进不同系统之间通信的模型,但可以在实现 SOA 时将 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 的一个稳定版本,可以从其官方网站下载。

Architecture

Fuse 将多种技术组合在一起作为单一产品。

architecture

Components

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 实例提供集中式管理。

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 后,你将在解压缩的目录中找到以下目录:

  1. bin

  2. etc

  3. deploy

  4. lib

  5. licenses

  6. extras

  7. quickstarts

其中,我们将仅使用两个目录 binetc

实际上,在解压缩 Fuse 之后,我们应该能够直接启动 Fuse,但这将使用所有默认配置启动 Fuse,这对于生成环境来说不可取。强烈建议在启动 Fuse 之前进行以下更改。

Set Environment variables

  1. 设置以下环境变量 - JAVA_HOME

  2. 此变量应指向 Java 安装目录 - M2_HOME

  3. 此变量应指向 Maven 安装目录 - PATH

  4. 将路径变量设置为包括 Java 和 Maven 可执行文件。

Windows

在 Windows 中,可通过以下给出的说明完成设置 −

开始 → 我的电脑 → 右键单击 → 属性 → 高级系统设置 → 环境变量。

UNIX & Clones

*nix 操作系统中,每个用户都有一个 bash 个人信息档案。我们可以通过更改这个文件来添加或编辑现有的系统变量。

$ vi ~/.bash_proflle

Note − 此文件中任何所做的更改都是永久性的。强烈建议在更改原始文件前备份现有的文件。

Basic Configuration

我们将讨论有关 JBoss Fuse 的基本配置,为此,我们必须从以下命令 Edit $FUSE_INSTALLATION_DIR/etc/ 开始

  1. user.properties #admin=admin,admin 根据需要的第一个管理员(用户名)、第二个管理员(密码)来进行更改,第三个可保留原样,因为它表示角色,不要忘记删除 # 例如 - FuseAdmin = FusePAss,admin

basic configuration
  1. System.properties karafName = root,表示您想要赋予 Karaf 实例的名字。我们可以给出自己希望的名字,比如 Cont1。确保您给的名字是唯一的名字,且尚未被另一个 Fuse 实例使用。

  2. org.ops4j.pax.web.cfg Org.osgi.service.http.port = 8181 此属性表示用于访问浏览器基础界面 HAWTIO 的端口,该界面由 Fuse 提供 HAWTIO 是一个自 6.0 起可用的面向 Fuse 的内置浏览器界面

  3. 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

更新以下两个属性 −

  1. org.ops4j.pax.url.mvn.settings = $M2_HOME/conf /settings.xml

  2. org.ops4j.pax.url.mvn.localRepository = $local_repo

Note − 请使用 Mavens settings.xml 中提到的本地存储库的实际路径,更改 $local_repo

Run

设置完成基本配置更改后,我们现在可以启动 Fuse。所有用于与 Fuse 搭配使用的二进制文件都位于 $FUSE_INSTALLATION_DIR

有两种启动 Fuse 的方法 −

  1. 使用 ./fuse 这会让您能够在启动 Fuse 的同一窗口中看到所有进度和日志。它会在同一终端中提供给您 Karaf 控制台,如下所示。

Note − 此命令会以控制台模式启动 Fuse,这意味着当用户退出会话或关闭终端(这是生产或开发场景中不希望出现的)时,Fuse 进程也会停止。这个脚本应该只用于调试 Fuse。

  1. 使用 ./start 这不会在屏幕上显示任何日志,甚至不会显示进度,但这将在后台启动 Fuse,并且当用户退出会话或关闭终端时 Fuse 服务并不会停止。在现实世界的应用程序中,需要此类行为。即使我们关闭终端,Fuse 也应该在后台运行。如果你想连接到在后台运行的 Fuse,可以使用 client 脚本,该脚本位于同一文件夹中。你应该获得下图所示的显示。退出客户端脚本不会停止 Fuse 服务。它只会关闭 Fuse 控制台。

configuring maven

HAWTIO

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

hawtio

我们通过执行命令所做的所有事情,也可以通过访问此基于浏览器的 GUI 来完成。当我们有多个容器并运行在 Fabric 环境中时,这会变得非常有用。

JBoss Fuse - Apache Karaf

在本章中,我们将讨论 Apache Karaf 及其为何被称为轻量级 OSGi 容器,以及它的优点和其他重要功能。

The JVM Problem

JVM 或 Java 虚拟机并不作为真正的虚拟机。它允许你随时停止、启动或重新启动在其中运行的组件。它有时允许在类级别热部署,但你不可能在不重新启动虚拟机的情况下部署或取消部署应用程序的组件。

为了解决这一问题并允许 Java 应用程序模块化,Fuse 使用了称为 Apache Karaf 基于 OSGi 的运行时。

OSGi

OSGi 技术是一组规范,为 Java 定义了动态组件系统。这些规范允许开发模型,其中应用程序(动态地)由许多不同的(可重用)组件组成。

Benefits of OSGi

  1. Reduced Complexity - 应用程序构建为协作组件,这些组件隐藏了它们各自的实现细节,从而降低了复杂性。

  2. Reusability - 许多组件可以利用容器中部署的同一组件。

  3. Deployment - OSGi 通过其生命周期管理 API 支持组件的启动、停止和更新,而无需重新启动容器。

Bundles Vs Features

以下是包和功能之间的比较。

Bundles

包与 OSGi 等效,jar 与 JVM 等效。包是可部署到 OSGi 容器中的工件。包是共同或独立协作以形成应用程序的组件。

这些包可以在运行时安装、卸载、更新、启动或停止,而无需重新启动容器。

Features

功能是一种将多个包一起部署的方法。有时将包按组部署更有意义。功能允许我们仅使用一个命令部署一组包。

Why another Container?

Apache Karaf 是基于 OSGi 的运行时,它是我们的应用程序包运行的位置。Fuse 使用 Apache Karaf 作为其运行时,其中包运行和协作以提供业务功能。

Karaf 建立在 OSGi 框架 Felix 和 Equinox 之上。

Karaf Architecture

karaf architecture

Apache Karaf 向基本的 OSGi 运行时添加了以下附加功能。

Hot Deployment

Karaf 支持热部署。它包含一个热部署目录。放置在此目录中的任何内容都会自动部署并以包形式安装到 Karaf 中。

Logging

Karaf 通过在 $Fuse_home/data/log 中生成所有包的日志提供集中式记录。我们可以在 org.ops4j.pax.logging.cfg$Fuse_home/etc directory 中编辑记录器配置。

Admin console

Karaf 提供了一个复杂而清晰的管理控制台,可与正在运行的 Fuse 实例进行交互。它还提供了一组预安装的命令,可用于在运行时管理和监视组件(包)。此控制台是可扩展的,因此它允许我们通过向控制台添加新包来向控制台添加新命令。

admin console

SSH Access

Karaf 允许通过 SSH 远程访问此管理控制台。拥有有效凭证的任何人都可以通过 SSH 终端连接到 Karaf 管理控制台。

JBoss Fuse - Apache Camel

在本章中,我们将讨论 Apache Camel 是什么,以及它如何有效地在端点之间路由数据,其中包括一些示例。

What is Apache Camel?

Apache Camel 是一个开源集成框架,始于 2007 年初。

它是一种基于 EIP(企业集成模式)的方法,提供可用于解决企业集成问题的几种开箱即用的模式实现。EIP 是针对企业集成中记录良好且经常出现的问题的久经考验的解决方案。

Camel 也称为路由和中介引擎,因为它能够有效地在端点之间路由数据,同时承担诸如数据格式转换、端点连接等繁重负载。

Basic Example

使用 Apache Camel 的前提条件如下−

  1. Java

  2. Maven

  3. 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

这将生成以下目录结构。

directory structure

这是我们正在生成的 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。

install project in fuse

这是用于访问 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 可以容纳多个路由。

Routes

CamelContext 可能包含一条或多条路由。路由是集成逻辑,定义了数据如何在 camel context 从一个端点流到另一个端点。

Endpoint

端点是通道的末端,系统可以通过它发送或接收消息。这就是我们在通信语言中所说的目的地或来源。

Components

组件是 Camel 中的扩展点。组件可以作为技术、数据格式、转换器等的接口。它们还可以充当端点的工厂。

components

EIP

EIP 代表企业集成模式。这些是针对重复出现的问题而确定的众所周知的解决方案。Camel 支持大多数企业集成模式。

Content Based Router

CBR 模式允许我们根据输入文件的内容路由数据。

content based router

当我们必须根据输入正文的内容路由值时,将使用此模式。

以下示例将从 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

拆分模式用于将输入数据拆分成更小的块。

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

当需要从消息正文中检索收件人列表时,将使用收件人列表模式。

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 如下所述。

  1. Log − 记录消息全部或部分内容

  2. Message Filter − 过滤消息内容

  3. Re-Sequencer − 获取序列中的所有令牌

  4. 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 一样,它有以下三个块:

  1. doTry 块包含可能生成异常的代码。

  2. doCatch 块包含在异常情况下需要执行的代码。

  3. 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 块处理的异常列表。

Deploying Bundle in Fuse

使用 Fuse.bat/start.bat 启动 Fuse。

如果你使用 start.bat 启动 Fuse,请使用 client.bat 连接到 Fuse。你应当获得以下屏幕截图中所示的 UI。

deploying bundle in fuse

这是用于访问 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 服务中有帮助。

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 服务 −

  1. Code first − 在此方法中,WSDL 由代码生成。

  2. 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

soqp web service

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>

Install Rest service in Fuse

install -s mvn:com.tuts.abhinav/rest-service/1.0-SNAPSHOT

Check if Bundle has a Registered Web-Service

registered web service

JBoss Fuse - Apache AMQ

在本章中,我们将了解 ActiveMQ,以及它如何充当消息代理,允许应用程序相互通信。

What is AMQ?

ActiveMQ 是一个用 Java 编写的开源消息代理。它完全符合 JMS 1.1 标准。

JMS 是一个允许开发基于消息的系统的规范。ActiveMQ 充当消息代理,位于应用程序之间,并允许它们以异步且可靠的方式进行通信。

amq

Types of Messaging

为了便于理解,下面解释了两种类型的消息传递选项。

Point to Point

在这种通信方式中,代理只会向一个消费者发送消息,而其他消费者将等待从代理获得消息。没有消费者会收到相同的消息。

如果没有消费者,代理将一直持有消息,直到它得到消费者。这种通信方式也称为 Queue based communication ,生产者将消息发送到队列,并且只有一个消费者从队列中获取一条消息。如果有超过一个消费者,他们可能会获得下一条消息,但他们不会收到与其他消费者相同的消息。

point to point messaging

Publish/Subscribe

在这种通信方式中,代理会向所有活跃的消费者发送消息的同份副本。这种通信方式也称为 Topic based communication ,代理向所有为特定主题订阅的活跃消费者发送相同的消息。此模型支持单向通信,其中不期望对已传输的消息进行验证。

publish subscribe messaging

Creating Queue and Topics

Fuse 与 ActiveMQ 捆绑在一起。我们可以使用 FMC 控制台(用于处理 AMQ 的基于浏览器的界面)访问 ActiveMQ。

使用 localhost:8181 登录 FMC 并选择 ActiveMQ 选项卡。

activemq
  1. Click on +Create

  2. Enter Queue/Topic name

  3. 从单选按钮中选择队列/主题

  4. 单击创建队列/创建主题

queue create topic

现在,你应该可以看到 TestQ 在根目录 → 队列 → 下创建。

testq

要查看创建的主题,请遵循根目录 → 主题。

Browsing /Deleting Contents of the Queue

  1. 使用 localhost:8181 登录 FMC

  2. Select ActiveMQ tab

  3. 根目录 → 队列 → TestQ <选择要浏览的队列> → 浏览

fmc
  1. 要查看此消息的内容,请单击特定消息。

message
  1. 可以通过单击右上角显示的“删除”按钮来删除特定消息

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>
  1. brokerURL − 指定 AMQ Broker 的主机和端口。

  2. username − 指定用于连接到 AMQ Broker 的用户名。

  3. 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

writing messages to amq

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 中生成文件且消息已被使用。该队列还应当显示使用者。

reading from amq

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 具有以下特殊功能,使其成为在分布式环境中使用的理想候选者。

  1. 监视 Fabric 中所有容器的状态。

  2. 启动和停止远程容器。

  3. 提供远程容器来运行特定应用程序。

  4. 升级应用程序,并在实时系统中推出补丁。

  5. 为应对系统上的负载增加快速启动和采用新容器。

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 容器的前面有一个小的云符号。

fabric setup

Profiles

一个配置文件包含以下信息:

  1. Bundles to be installed

  2. Features to be installed

  3. Configurations to be applied

一个配置文件提供了在 Fabric 环境中在多台服务器上安装相同的一组 bundle、功能和配置的方法。

如果将同一个配置文件应用到多个容器,并且我们从任何容器对此配置文件进行更改,则类似的更改将自动部署到应用了它的其余容器。

Creating Profiles

  1. 登录到 FMC localhost:8181

  2. Runtime → Manage

  3. 在左侧的 Profile 菜单下,单击 +

creating profiles

输入您要分配给该配置文件的名称,然后单击创建。

creating new profile

在此之后,该配置文件应该已创建。

Applying Profile to Container

运行时 → 容器 → 根(选择您想要的容器)

applying profile to container

单击 Add ,它将打开一个弹出框。搜索您想要的配置文件,然后再次单击 Add

add profile to container

该配置文件应该显示在列表中,如下图所示。

profile screenshot

Deploying a Bundle

要部署 bundle,请使用以下路径:

运行时 → 容器 → 根(选择您想要的容器)→ First_profile(选择配置文件)

deploying a bundle

单击 Bundles 选项卡。按照以下格式设置 bundle 路径,然后单击 +

mvn:group.id/artifact.id/version

例如, mvn:com.tutorialpoint.app/camel-firt-app/1.0-SNAPSHOT

added bundle
deployed on containers

一个 bundle 将添加到配置文件中,并部署在分配给该配置文件的所有容器上。

Un-deploying a Bundle

要取消部署 bundle,请使用以下路径:

运行时 → 容器 → 根(选择您想要的容器)→ First_profile(选择配置文件)

undeploying a bundle

单击“捆绑”选项卡并搜索要删除的捆绑,然后单击 X 。系统会从应用配置文件的所有容器中删除该捆绑。

bundles tab

JBoss Fuse - Child Container

一个子容器提供了管理增加的负载的最简单方法。当系统遇到流量突发负载且单个容器无法应对负载时,我们可以轻松创建一组子容器并将负载分配给它们,而不是创建一个全新的容器。

Creating a Child Container

使用 localhost:8181 登录 FMC

现在,按照以下路径:运行时 → 容器 → +创建(右侧的按钮)

creating child container

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

creating new container

点击 Create And Start Container

create and start container

Managing a Child Container

子容器仅仅作为一个普通容器。

Stopping a Child Container

要停止子容器,请按照路径:运行时 → 容器 → 子 1。

单击停止可停止子容器。

stopping a child container

Starting a Child Container

要启动子容器,请按照路径:运行时 → 容器 → 子 1。

单击启动可启动子容器。

starting a 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

这可能是由于以下两个原因造成的 −

  1. Maven repository not specified

  2. 存储库中没有捆绑

Maven Repository not Specified

Maven 是用于构建 Fuse 制品的构建工具。当我们发出安装制品的命令时,Fuse 会首先在 Maven 本地存储库中搜索制品。因此,我们必须让 Fuse 知道 Maven 的安装位置和 Maven 本地存储库的路径。

编辑 $FUSE_INSTALLATION_DIR/etc/ org.ops4j.paxurl.mvn.cfg

更新以下两个属性 −

  1. org.ops4j.pax.url.mvn.settings = $M2_HOME/conf /settings.xml

  2. org.ops4j.pax.url.mvn.localRepository = $local_repo

Note − 请将 $local_repo 更改为 Maven 设置中的实际本地存储库路径。

Bundle not Present in Repository

如果 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。

Note − $M2_REPO 需要替换为我们配置 Fuse 使用的 Maven 存储库的实际路径。

Not Able to Login into FMC (Browser based GUI)

Users not Created − 如果你收到以下 UI 但无法登录且显示消息:“登录失败,禁止”。

users not created

检查你是否已在 $FUSE_INSTALLATION_HOME/etc/users.properties 中添加用户

添加用户的正确格式为 −

Username = Password,Role

HAWTIO Port is Different

如果你甚至无法在浏览器中获取 localhost:8181 的 UI,请检查是否在 URL 中提到了正确的端口。

$FUSE_INSTALLATION_HOME/etc/org.ops4j.pax.web.cfg

在文件中编辑以下属性,以使用要访问的端口。

org.osgi.service.http.port=8181

AMQ Broker is not working

确保 61616 端口已打开并且当前未被另一个端口使用。如果您想更改相同的默认 61616 端口,则可以在 $FUSE_INSTALLATION_HOME/etc/System.properties 中对其进行编辑

activemq.port = 61616