1. Обзор
В этой статье мы представим Camel и рассмотрим одну из его основных концепций — маршрутизацию сообщений .
Мы начнем с рассмотрения этих основных понятий и терминологии, а затем представим два основных варианта определения маршрутов — Java DSL и Spring DSL.
Мы также продемонстрируем это на примере — определив маршрут, который использует файлы из одной папки и перемещает их в другую, добавляя временную метку к каждому имени файла.
2. Об Apache Camel
Apache Camel — это среда интеграции с открытым исходным кодом, разработанная для простой и легкой интеграции систем.
Он позволяет конечным пользователям интегрировать различные системы с использованием одного и того же API, обеспечивая поддержку нескольких протоколов и типов данных, будучи расширяемым и позволяя вводить пользовательские протоколы.
3. Зависимости Maven
Чтобы использовать Camel, нам нужно сначала добавить зависимость Maven:
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.18.0</version>
</dependency>
Последнюю версию артефакта Camel можно найти здесь .
3. Язык предметной области
Маршруты и механизм маршрутизации являются центральной частью Camel. Маршруты содержат поток и логику интеграции между различными системами.
Для более простого и четкого определения маршрутов Camel предлагает несколько различных предметно-ориентированных языков (DSL) для таких языков программирования, как Java или Groovy. С другой стороны, он также обеспечивает определение маршрутов в XML с помощью Spring DSL.
Использование Java DSL или Spring DSL в основном является предпочтением пользователя, поскольку большинство функций доступны в обоих.
Java DSL предлагает немного больше функций, которые не поддерживаются в Spring DSL. Однако Spring DSL иногда более выгоден, поскольку XML можно изменить без необходимости перекомпилировать код.
4. Терминология и архитектура
Давайте теперь обсудим основную терминологию и архитектуру Camel.
Во-первых, мы рассмотрим основные концепции Camel здесь:
- Сообщение содержит данные, которые передаются по маршруту. Каждое сообщение имеет уникальный идентификатор и состоит из тела, заголовков и вложений.
- Exchange — это контейнер сообщения, который создается при получении сообщения потребителем в процессе маршрутизации. Exchange допускает различные типы взаимодействия между системами — он может определять одностороннее сообщение или сообщение типа «запрос-ответ».
- Конечная точка — это канал, по которому система может получать или отправлять сообщения. Он может относиться к URI веб-службы, URI очереди, файлу, адресу электронной почты и т. д.
- Компонент действует как фабрика конечных точек. Проще говоря, компоненты предлагают интерфейс для различных технологий, используя один и тот же подход и синтаксис. Camel уже поддерживает множество компонентов в своих DSL практически для всех возможных технологий, но также дает возможность писать собственные компоненты.
- Процессор — это простой интерфейс Java, который используется для добавления пользовательской логики интеграции в маршрут. Он содержит один метод
процесса
, используемый для предварительной обработки пользовательской бизнес-логики в сообщении, полученном потребителем.
На высоком уровне архитектура Camel проста. CamelContext
представляет систему времени выполнения Camel и связывает различные концепции, такие как маршруты, компоненты или конечные точки.
И ниже этого процессоры обрабатывают маршрутизацию и преобразования между конечными точками, в то время как конечные точки интегрируют разные системы.
5. Определение маршрута
Маршруты могут быть определены с помощью Java DSL или Spring DSL.
Мы проиллюстрируем оба стиля, определив маршрут, который использует файлы из одной папки и перемещает их в другую папку, добавляя временную метку к каждому имени файла.
5.1. Маршрутизация с помощью Java DSL
Чтобы определить маршрут с помощью 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();
}
Метод configure
можно прочитать так: читать файлы из исходной папки, обрабатывать их с помощью FileProcessor
и отправлять результат в папку назначения. Установка delete=true
означает, что файл будет удален из исходной папки после успешной обработки.
Чтобы запустить Camel, нам нужно вызвать метод start для
CamelContext
. Thread.sleep
вызывается, чтобы дать Camel время, необходимое для перемещения файлов из одной папки в другую.
FileProcessor
реализует интерфейс Processor
и содержит единственный метод процесса
, который содержит логику для изменения имен файлов:
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);
}
}
Чтобы получить имя файла, мы должны получить входящее сообщение от обмена и получить доступ к его заголовку. Аналогично этому, чтобы изменить имя файла, мы должны обновить заголовок сообщения.
5.2. Маршрутизация с помощью Spring DSL
При определении маршрута с помощью Spring DSL мы используем файл XML для настройки наших маршрутов и процессоров. Это позволяет нам настраивать маршруты без использования кода с помощью Spring и, в конечном итоге, дает нам преимущество полной инверсии управления.
Это уже было описано в существующей статье , поэтому мы сосредоточимся на использовании как Spring DSL, так и Java DSL, который обычно является предпочтительным способом определения маршрутов.
В этом случае CamelContext определяется в XML-файле Spring с использованием пользовательского синтаксиса XML для Camel, но без определения маршрута, как в случае «чистого» Spring DSL с использованием XML:
<bean id="fileRouter" class="com.foreach.camel.file.FileRouter" />
<bean id="fileProcessor"
class="com.foreach.camel.file.FileProcessor" />
<camelContext xmlns="http://camel.apache.org/schema/spring">
<routeBuilder ref="fileRouter" />
</camelContext>
Таким образом, мы говорим Camel использовать класс FileRouter
, который содержит определение нашего маршрута в 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);
}
}
Чтобы проверить это, мы должны создать экземпляр ClassPathXmlApplicationContext
, который загрузит наш CamelContext
весной:
@Test
public void moveFolderContentSpringDSLTest() throws InterruptedException {
ClassPathXmlApplicationContext applicationContext =
new ClassPathXmlApplicationContext("camel-context.xml");
Thread.sleep(DURATION_MILIS);
applicationContext.close();
}
При таком подходе мы получаем дополнительную гибкость и преимущества, предоставляемые Spring, а также все возможности языка Java за счет использования Java DSL.
6. Заключение
В этой быстрой статье мы представили введение в Apache Camel и продемонстрировали преимущества использования Camel для задач интеграции, таких как маршрутизация файлов из одной папки в другую.
В нашем примере мы увидели, что Camel позволяет сосредоточиться на бизнес-логике и сокращает объем стандартного кода.
Код из этой статьи можно найти на GitHub .