1. Overview
1.概述
Mule ESB is a lightweight Java-based Enterprise Service Bus. It allows developers to connect multiple applications together by exchanging data in different formats. It carries data in the form of a message.
Mule ESB是一个基于Java的轻量级企业服务总线。它允许开发人员通过交换不同格式的数据将多个应用程序连接在一起。它以消息的形式携带数据。
ESBs offer powerful capabilities by providing a number of services, such as:
ESB通过提供一些服务来提供强大的功能,如:。
- Service creation and hosting
- Service mediation
- Message routing
- Data transformation
We’ll find ESBs useful if we need to integrate multiple applications together, or if we have the notion of adding more applications in the future.
如果我们需要将多个应用程序整合在一起,或者我们有在未来增加更多应用程序的概念,我们会发现ESB很有用。
ESB is also used for dealing with more than one type of communication protocol and when message routing capabilities are required.
ESB也用于处理一种以上的通信协议,并在需要消息路由能力时使用。
Let’s create a sample project in Section 5 using AnyPoint Studio which is available for download here.
让我们使用AnyPoint Studio在第5节中创建一个示例项目,该项目可在这里下载。
2. Mule Message Structure
2.Mule消息结构
Simply put, the primary purpose of an ESB is to mediate between services and route messages to various endpoints. So it needs to deal with different types of content or payload.
简单地说,ESB的主要目的是在服务之间进行调解,并将消息路由到各个终端。因此,它需要处理不同类型的内容或有效载荷。
The message structure is divided into two parts:
信息结构分为两部分。
- The header, which contains message metadata
- The payload, which contains business-specific data
The message is embedded within a message object. We can retrieve the message object from the context. We can change its properties and payload using custom Java components and transformers inside a Mule flow.
该消息被嵌入到一个消息对象中。我们可以从上下文中检索到消息对象。我们可以在Mule流程中使用自定义的Java组件和转换器来改变其属性和有效载荷。
Each application consists of one or more flows.
每个应用程序由一个或多个流程组成。
In a flow, we can use components to access, filter or alter a message and its different properties.
在一个流程中,我们可以使用组件来访问、过滤或改变一个消息及其不同的属性。
For example, we can obtain an instance of a message using Java component. This component class implements a Callable interface from org.mule.api.lifecycle package:
例如,我们可以使用Java组件获得一个消息的实例。这个组件类实现了Callable接口,来自org.mule.api.lifecycle包。
public Object onCall(MuleEventContext eventContext) throws Exception {
MuleMessage message = eventContext.getMessage();
message.setPayload("Message payload is changed here.");
return message;
}
3. Properties and Variables
3.属性和变量
Message metadata consists of properties. Variables represent data about a message. How properties and variables are applied across the message’s life-cycle is defined by their scopes. Properties can be of two types, based on their scope: inbound and outbound.
消息元数据由属性组成。变量代表关于消息的数据。属性和变量在消息生命周期中的应用方式是由它们的作用域定义的。根据其范围,属性可以有两种类型:入站和出站。
Inbound properties contain metadata that prevents messages to become scrambled while traversing across flows. Inbound properties are immutable and cannot be altered by the user. They’re present only for the duration of the flow – once the message exits the flow, inbound properties are no longer there.
入站属性包含元数据,防止消息在穿越流量时被扰乱。入站属性是不可改变的,不能由用户改变。它们只在流的持续时间内存在,一旦消息退出流,入站属性就不再存在。
Outbound properties can be set automatically by Mule, or a user can set them through flow configuration. These properties are mutable. They become inbound properties when a message enters another flow after crossing transport-barriers.
出站属性可以由Mule自动设置,或者用户可以通过流程配置来设置。这些属性是可变的。当一个消息在跨越运输障碍后进入另一个流时,它们就变成了入站属性。
We can set and get outbound and inbound properties respectively by calling associated setter and getter methods in their respective scopes:
我们可以通过在各自的作用域中调用相关的setter和getter方法来分别设置和获取出站和入站属性。
message.setProperty(
"outboundKey", "outboundpropertyvalue", PropertyScope.OUTBOUND);
String inboundProp = (String) message.getInboundProperty("outboundKey");
There are two types of variables available to declare in applications.
在应用程序中,有两种类型的变量可供声明。
One is flow variable which is local to a Mule flow and available across the flow, sub-flows and private flows.
一个是流量变量,它是一个Mule流量的本地变量,可用于整个流量、子流量和私人流量。
Session variables once declared become available across the entire application.
会话变量一旦被声明就会在整个应用程序中可用。
4. Transport Barriers and flow-ref
4.运输障碍和流动-ref
Transport barriers are HTTP-connectors, VMs, JMS or similar connectors that require paths or endpoints for messages to be routed. Flow variables aren’t available across transport barriers, but session variables are available across the project in all flows.
传输障碍是HTTP连接器、虚拟机、JMS或类似的连接器,它们需要路径或端点来路由消息。流程变量在传输障碍中不可用,但是会话变量在整个项目的所有流程中都可用。
When we need to create sub-flow or private flow, we can refer to the flow from a parent or another flow using flow-ref component. Both flow variables and session variables are available in sub-flows and private flows referred to using flow-ref.
当我们需要创建子流程或私有流程时,我们可以使用flow-ref组件从父流程或其他流程中引用该流程。在使用flow-ref引用的子流程和私有流程中,流量变量和会话变量都是可用的。
5. Example Project
5.项目实例
Let’s create an application in Anypoint Studio that contains multiple flows, which communicate between themselves through inbound and outbound connectors.
让我们在Anypoint Studio中创建一个包含多个流的应用程序,它们之间通过入站和出站连接器进行通信。
Let’s look at the first flow:
让我们来看看第一个流程。
We can configure an HTTP listener as:
我们可以将HTTP监听器配置为。
<http:listener-config name="HTTP_Listener_Configuration"
host="localhost" port="8081" doc:name="HTTP Listener Configuration"/>
Flow components must be inside a <flow> tag. So, an example flow with multiple components is:
流程组件必须在一个<flow>标签内。因此,一个有多个组件的流程例子是。
<flow name="Flow">
<http:listener
config-ref="HTTP_Listener_Configuration"
path="/" doc:name="HTTP"
allowedMethods="POST"/>
<logger message="Original
paylaod: #[payload]"
level="INFO" doc:name="Logger"/>
<custom-transformer
class="com.baeldung.transformer.InitializationTransformer"
doc:name="Java"/>
<logger message="Payload After Initialization: #[payload]"
level="INFO" doc:name="Logger"/>
<set-variable variableName="f1"
value="#['Flow Variable 1']" doc:name="F1"/>
<set-session-variable variableName="s1"
value="#['Session variable 1']" doc:name="S1"/>
<vm:outbound-endpoint exchange-pattern="request-response"
path="test" doc:name="VM"/>
</flow>
Inside the flow, we’re providing a reference to a configured HTTP listener. Then we’re keeping a logger to log the payload that HTTP listener is receiving through POST method.
在流程中,我们提供了一个对配置的HTTP监听器的引用。然后我们保留一个记录器来记录HTTP监听器通过POST方法接收的有效载荷。
After that, a custom Java transformer class is placed, that transforms the payload after receiving the message:
之后,一个自定义的Java转化器类被放置,它在收到消息后对有效载荷进行转化。
public Object transformMessage(
MuleMessage message,
String outputEncoding) throws TransformerException {
message.setPayload("Payload is transferred here.");
message.setProperty(
"outboundKey", "outboundpropertyvalue", PropertyScope.OUTBOUND);
return message;
}
The transformer class must extend AbstractMessageTransformer. We’re also setting an outbound property inside the class.
转换器类必须扩展AbstractMessageTransformer。我们还在该类内部设置一个出站属性。
Now, we have already converted payload inside the message object, and have logged that in the console using logger. We’re setting a flow variable and a session variable.
现在,我们已经在消息对象中转换了有效载荷,并使用logger将其记录在控制台。我们正在设置一个流量变量和一个会话变量。
Finally, we are sending our payload through outbound VM connector. The path in VM connector determines the receiving endpoint:
最后,我们通过出站的VM连接器发送我们的有效载荷。VM连接器中的路径决定了接收端点:。
The message carried and transformed by the initial flow reaches Flow1 through an inbound VM endpoint.
由初始流携带和转换的消息通过一个入站的虚拟机端点到达Flow1。
The Java component retrieves outbound properties set by the first flow and returns the object which becomes the message payload.
Java组件检索由第一个流程设置的出站属性,并返回成为消息有效载荷的对象。
The transformMessage() method for this task:
这个任务的transformMessage()方法。
public Object transformMessage(
MuleMessage message,
String outputEncoding) throws TransformerException {
return (String) message.getInboundProperty("outboundKey");
}
Then, flow and session variables are set to the second flow. After that, we’ve got a reference to Flow2 using flow-ref component.
然后,flow和session变量被设置为第二个flow。之后,我们使用flow-ref组件得到了对Flow2的引用。
In Flow2, we’ve transformed the message using Java component class and logged it in the console. We’ve also set a flow variable F3.
在Flow2中,我们使用Java组件类转换了消息,并在控制台中记录了它。我们还设置了一个流程变量F3。
After calling Flow2 using flow-ref, Flow1 will wait for the message to be processed in Flow2.
在使用flow-ref调用Flow2后,Flow1将等待消息在Flow2中被处理。
Any flow variable set in Flow1 and Flow2 will be available in both flows since these flows aren’t separated by any transport barriers.
在Flow1和Flow2中设置的任何流量变量都将在两个流量中可用,因为这些流量没有被任何传输障碍分开。
Finally, the message is sent back to the HTTP requester through VMs. We configured all VMs as request-response.
最后,消息通过虚拟机被送回给HTTP请求者。我们将所有的虚拟机配置为请求-响应。
We can invoke this application from any REST client by posting any JSON data in the body. The URL will be localhost:8081 as configured in HTTP listener.
我们可以通过在正文中发布任何JSON数据,从任何REST客户端调用这个应用程序。URL将是HTTP监听器中配置的localhost:8081。
6. Maven Archetype
6.Maven原型
We can build a Mule ESB project using Mulesoft’s Maven archetype.
我们可以使用Mulesoft的Maven原型建立一个Mule ESB项目。
In Maven’s settings.xml file, we first need to add the org.mule.tools plugin group:
在Maven的settings.xml文件中,我们首先需要添加org.mule.tools插件组。
<pluginGroups>
<pluginGroup>org.mule.tools</pluginGroup>
</pluginGroups>
Then, we need to add a profile tag that says where Maven should look for Mulesoft artifacts:
然后,我们需要添加一个profiletag,说明Maven应该在哪里寻找Mulesoft工件。
<profile>
<id>Mule Org</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>mulesoft-releases</id>
<name>MuleSoft Repository</name>
<url>https://repository.mulesoft.org/releases/</url>
<layout>default</layout>
</repository>
</repositories>
</profile>
Finally, we can create the project using mule-project-archetype:create:
最后,我们可以使用mule-project-archetype:create来创建这个项目。
mvn mule-project-archetype:create -DartifactId=muleesb -DmuleVersion=3.9.0
After configuring our project, we can create a deployable archive using mvn package.
配置好我们的项目后,我们可以使用mvn package创建一个可部署的归档文件。
After that, we’d deploy the archive into the apps folder of any standalone Mule server.
之后,我们会将档案部署到任何独立的Mule服务器的apps 文件夹中。
7. A Standalone Mule Server via MuleSoft’s Maven Repository
7.通过MuleSoft的Maven仓库建立独立的Mule服务器
As just noted, the project we just created requires a standalone Mule server.
正如刚才所指出的,我们刚刚创建的项目需要一个独立的Mule服务器。
If we don’t already have one, we can edit our pom.xml to pull one from MuleSoft’s Maven repository:
如果我们还没有,我们可以编辑我们的pom.xml 从MuleSoft的Maven资源库中提取一个。
<plugin>
<groupId>org.mule.tools.maven</groupId>
<artifactId>mule-maven-plugin</artifactId>
<version>2.2.1</version>
<configuration>
<deploymentType>standalone</deploymentType>
<muleVersion>3.9.0</muleVersion>
</configuration>
<executions>
<execution>
<id>deploy</id>
<phase>deploy</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
</plugin>
8. Conclusion
8.结语
In this article, we’ve gone through different necessary concepts of building as ESB application in Mule. We’ve created a sample project illustrating all the described concepts.
在这篇文章中,我们已经经历了在Mule中构建ESB应用的不同的必要概念。我们已经创建了一个示例项目来说明所有描述的概念。
We can now start creating ESB application using Anypoint Studio to meet our various needs.
现在我们可以开始使用Anypoint Studio创建ESB应用程序,以满足我们的各种需求。
As usual, the complete project can be found over on GitHub.
像往常一样,完整的项目可以在GitHub上找到超过。