1. Overview
1.概述
In this article, we’ll introduce Camel and explore one of its core concepts – message routing.
在这篇文章中,我们将介绍Camel并探讨其核心概念之一–消息路由。
We’ll start by covering these foundational concepts and terminology and we’ll then present two main options for defining routes – Java DSL and Spring DSL.
我们将首先介绍这些基础概念和术语,然后我们将介绍定义路由的两个主要选择–Java DSL和Spring DSL。
We’ll also demonstrate these on an example – by defining a route which consumes files from one folder and moves them to another while prepending a timestamp to each file name.
我们还将在一个例子上演示这些–通过定义一个路由,该路由从一个文件夹中消耗文件并将它们移动到另一个文件夹,同时为每个文件名预设一个时间戳。
2. About Apache Camel
2.关于Apache Camel
Apache Camel is an open source integration framework designed to make integrating systems simple and easy.
Apache Camel是一个开源的集成框架,旨在使集成系统变得简单和容易。
It allows end users to integrate various systems using the same API, providing support for multiple protocols and data types, while being extensible and allowing the introduction of custom protocols.
它允许终端用户使用相同的API集成各种系统,提供对多种协议和数据类型的支持,同时具有可扩展性,允许引入自定义协议。
3. Maven Dependencies
3.Maven的依赖性
In order to use Camel, we need to first add the Maven dependency:
为了使用Camel,我们需要首先添加Maven的依赖性。
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.18.0</version>
</dependency>
The latest version of the Camel artifact can be found here.
骆驼神器的最新版本可以在这里找到。
3. Domain-Specific Language
3.特定领域的语言
Routes and routing engine are the central part of Camel. Routes contain the flow and logic of integration between different systems.
路由和路由引擎是Camel的核心部分。路由包含了不同系统之间集成的流程和逻辑。
In order to define routes more easy and clean, Camel offers several different domain-specific languages (DSL) for programming languages like Java or Groovy. On the other hand, it also provides defining routes in XML with Spring DSL.
为了使定义路由更容易、更简洁,Camel为Java或Groovy等编程语言提供了几种不同的特定领域语言(DSL)。另一方面,它也提供了用Spring DSL在XML中定义路由的功能。
Using either Java DSL or Spring DSL is mostly user preference, as most of the features are available in both.
使用Java DSL或Spring DSL主要是用户的偏好,因为大部分的功能在两者中都有。
Java DSL offers a bit more features which are not supported in Spring DSL. However, Spring DSL is sometimes more beneficial as XML can be changed without the need to recompile the code.
Java DSL提供了一些Spring DSL不支持的功能。然而,Spring DSL有时更有利,因为可以改变XML而不需要重新编译代码。
4. Terminology and Architecture
4.术语和结构
Let’s now discuss the basic Camel terminology and architecture.
现在我们来讨论一下Camel的基本术语和架构。
First, we’ll have a look at the core Camel concepts here:
首先,我们来看看这里的核心Camel概念。
- Message contains data which is being transferred to a route. Each message has a unique identifier and it’s constructed out of a body, headers, and attachments
- Exchange is the container of a message and it is created when a message is received by a consumer during the routing process. Exchange allows different types of interaction between systems – it can define a one-way message or a request-response message
- Endpoint is a channel through which system can receive or send a message. It can refer to a web service URI, queue URI, file, email address, etc
- Component acts as an endpoint factory. To put it simply, components offer an interface to different technologies using the same approach and syntax. Camel already supports a lot of components in its DSLs for almost every possible technology, but it also gives the ability for writing custom components
- Processor is a simple Java interface which is used to add custom integration logic to a route. It contains a single process method used to preform custom business logic on a message received by a consumer
At a high level, the architecture of Camel is simple. CamelContext represents the Camel runtime system and it wires different concepts such as routes, components or endpoints.
从高层次来看,Camel的架构很简单。CamelContext代表Camel运行时系统,它连接不同的概念,如路由、组件或端点。
And below that, processors handle routing and transformations between endpoints, while endpoints integrate different systems.
而在这之下,处理器处理端点之间的路由和转换,而端点则整合不同的系统。
5. Defining a Route
5.定义路线
Routes can be defined with Java DSL or Spring DSL.
路由可以用Java DSL或Spring DSL来定义。
We’ll illustrate both styles by defining a route which consumes files from one folder and moves them into another folder while prepending a timestamp to each file name.
我们将通过定义一个路由来说明这两种风格,该路由从一个文件夹中消耗文件并将它们移到另一个文件夹中,同时为每个文件名预设一个时间戳。
5.1. Routing With Java DSL
5.1.用Java DSL进行路由选择
To define a route with Java DSL we will first need to create a DefaultCamelContext instance. After that, we need to extend RouteBuilder class and implement the configure method which will contain route flow:
要用Java DSL定义一个路由,我们首先需要创建一个DefaultCamelContext实例。之后,我们需要扩展RouteBuilder类并实现configure方法,其中将包含路由流。
private static final long DURATION_MILIS = 10000;
private static final String SOURCE_FOLDER = "src/test/source-folder";
private static final String DESTINATION_FOLDER
= "src/test/destination-folder";
@Test
public void moveFolderContentJavaDSLTest() throws Exception {
CamelContext camelContext = new DefaultCamelContext();
camelContext.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
from("file://" + SOURCE_FOLDER + "?delete=true").process(
new FileProcessor()).to("file://" + DESTINATION_FOLDER);
}
});
camelContext.start();
Thread.sleep(DURATION_MILIS);
camelContext.stop();
}
The configure method can be read like this: read files from the source folder, processes them with FileProcessor and send the result to a destination folder. Setting delete=true means the file will be deleted from source folder after it is processed successfully.
configure方法可以这样理解:从源文件夹读取文件,用FileProcessor处理它们,并将结果发送到一个目标文件夹。设置delete=true意味着文件处理成功后将从源文件夹中删除。
In order to start Camel, we need to call start method on CamelContext. Thread.sleep is invoked in order to allow Camel the time necessary to move the files from one folder to another.
为了启动Camel,我们需要在CamelContext上调用start方法。Thread.sleep被调用,以便让Camel有必要的时间将文件从一个文件夹移到另一个。
FileProcessor implements Processor interface and contains single process method which contains logic for modifying file names:
FileProcessor实现了Processor接口,并包含单个process方法,其中包含修改文件名的逻辑。
public class FileProcessor implements Processor {
public void process(Exchange exchange) throws Exception {
String originalFileName = (String) exchange.getIn().getHeader(
Exchange.FILE_NAME, String.class);
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy-MM-dd HH-mm-ss");
String changedFileName = dateFormat.format(date) + originalFileName;
exchange.getIn().setHeader(Exchange.FILE_NAME, changedFileName);
}
}
In order to retrieve file name, we have to retrieve an incoming message from an exchange and access its header. Similar to that, to modify file name, we have to update message header.
为了检索文件名,我们必须从交易所检索一个传入的信息,并访问其头。与此类似,为了修改文件名,我们必须更新消息头。
5.2. Routing With Spring DSL
5.2.使用Spring DSL进行路由选择
When defining a route with Spring DSL, we use an XML file to set up our routes and processors. This allows us to configure routes using no code by using Spring and ultimately, gives us the benefit of total inversion of control.
在用Spring DSL定义路由时,我们使用一个XML文件来设置我们的路由和处理器。这使得我们可以通过使用Spring来配置路由,不使用任何代码,并最终使我们获得完全倒置控制的好处。
This was already covered in existing article, so we will focus on using both Spring DSL along with Java DSL, which is commonly a preferred way of defining routes.
这在现有的文章中已经介绍过了,所以我们将重点介绍Spring DSL和Java DSL的使用,这通常是定义路由的首选方式。
In this arrangement, CamelContext is defined in Spring XML file using custom XML syntax for Camel, but without the route definition like in the case of “pure” Spring DSL using XML:
在这种安排下,CamelContext被定义在Spring XML文件中,使用Camel的自定义XML语法,但没有像使用XML的 “纯 “Spring DSL那样的路由定义。
<bean id="fileRouter" class="com.baeldung.camel.file.FileRouter" />
<bean id="fileProcessor"
class="com.baeldung.camel.file.FileProcessor" />
<camelContext xmlns="http://camel.apache.org/schema/spring">
<routeBuilder ref="fileRouter" />
</camelContext>
This way we tell Camel to use FileRouter class which holds the definition of our route in Java DSL:
这样,我们告诉Camel使用FileRouter class,它持有我们在Java DSL中的路由定义。
public class FileRouter extends RouteBuilder {
private static final String SOURCE_FOLDER =
"src/test/source-folder";
private static final String DESTINATION_FOLDER =
"src/test/destination-folder";
@Override
public void configure() throws Exception {
from("file://" + SOURCE_FOLDER + "?delete=true").process(
new FileProcessor()).to("file://" + DESTINATION_FOLDER);
}
}
In order to test this, we have to create an instance of ClassPathXmlApplicationContext which will load up our CamelContext in Spring:
为了测试这一点,我们必须创建一个ClassPathXmlApplicationContext的实例,这将在Spring中加载我们的CamelContext。
@Test
public void moveFolderContentSpringDSLTest() throws InterruptedException {
ClassPathXmlApplicationContext applicationContext =
new ClassPathXmlApplicationContext("camel-context.xml");
Thread.sleep(DURATION_MILIS);
applicationContext.close();
}
By using this approach, we get additional flexibility and benefits provided by Spring, as well as all the possibilities of Java language by using Java DSL.
通过使用这种方法,我们可以获得Spring提供的额外的灵活性和好处,以及通过使用Java DSL获得Java语言的所有可能性。
6. Conclusion
6.结论
In this quick article, we presented an introduction to Apache Camel and demonstrated benefits of using Camel for integration tasks such as routing files from one folder to another.
在这篇快速文章中,我们介绍了Apache Camel,并展示了使用Camel进行集成任务的好处,如将文件从一个文件夹路由到另一个文件夹。
In our example, we saw that Camel lets you focus on business logic and reduces the amount of boilerplate code.
在我们的例子中,我们看到Camel让你专注于业务逻辑,减少了模板代码的数量。
Code from this article can be found over on GitHub.
本文的代码可以在GitHub上找到over。