Apache Camel описан на его главной веб-странице (и в Руководстве пользователя Camel ) как «универсальная инфраструктура интеграции с открытым исходным кодом, основанная на известных корпоративных шаблонах интеграции». Инфраструктура Camel основана на книге Enterprise Integration Patterns и предоставляет реализации шаблонов, описанных в этой книге . В этом посте я рассмотрел пример использования Hello World типа Camel.
Веб-страница Camel и руководство пользователя также ссылаются на ветку StackOverflow. Что такое Apache Camel? это включает в себя несколько хороших описаний Apache Camel. Дэвид Ньюкомб описал Верблюда там:
Apache Camel — это технология обмена сообщениями с возможностью маршрутизации. Он объединяет начальную и конечную точки обмена сообщениями, позволяя передавать сообщения из разных источников в разные места назначения. Например: JMS-> JSON, HTTP-> JMS или воронка FTP-> JMS, HTTP-> JMS, JMS => JSON.
В этой статье я рассмотрю простое использование Camel, которое не требует использования JMS-провайдера или даже FTP или HTTP. Простота примера упрощает использование Camel. В этом примере Camel используется для автоматической передачи файлов из указанного каталога в другой указанный каталог. Три случая будут продемонстрированы.
В первом случае файлы, помещенные в каталог «input», автоматически копируются в каталог «output», не затрагивая исходные файлы. Во втором случае файлы, помещенные в каталог «input», автоматически копируются в каталог «output», а затем файлы в каталоге «input» сохраняются в специальном подкаталоге «.camel» в каталоге «input». В третьем случае файлы удаляются из каталога «input» при копировании в каталог «output» (фактически это операция «move»). Все три случая реализованы с почти одинаковым кодом. Единственное различие между ними заключается в единственной строке, указывающей, как Camel должен обрабатывать передачу файлов.
В следующем листинге кода показан базовый код, необходимый для использования Camel для автоматического копирования файлов, помещенных во входной каталог, в другой выходной каталог с Camel.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
/** * Simple executable function to demonstrate Camel file transfer. * * @param arguments Command line arguments; excepting duration in milliseconds * as single argument. */public static void main(final String[] arguments){ final long durationMs = extractDurationMsFromCommandLineArgs(arguments); final CamelContext camelContext = new DefaultCamelContext(); try { camelContext.addRoutes( new RouteBuilder() { @Override public void configure() throws Exception { from('file:C:\\datafiles\\input?noop=true').to('file:C:\\datafiles\\output'); } }); camelContext.start(); Thread.sleep(durationMs); camelContext.stop(); } catch (Exception camelException) { LOGGER.log( Level.SEVERE, 'Exception trying to copy files - {0}', camelException.toString()); }} |
Приведенный выше код демонстрирует минимальное использование Camel API и поддержку Camel Java DSL. CamelContext определяется с использованием экземпляра DefaultCamelContext (строка 10). Строки 13-21 добавляют маршрут Camel к этому конкретному контексту, а строка 22 начинает контекст с строки 24, останавливая контекст. Все довольно просто, но наиболее интересная часть для меня — это спецификация маршрутизации в строке 19.
Поскольку экземпляр, реализующий интерфейс RoutesBuilder, предоставляемый для контекста Camel, требует переопределения только своего абстрактного метода configure, его легко создать как анонимный класс, встроенный в вызов CamelContext.addRoutes (RoutesBuilder) . Это то, что я сделал в приведенном выше коде, и то, что сделано во многих примерах Camel, которые доступны онлайн.
Строка 19 показывает хорошо читаемый синтаксис, описывающий «от» и «до» части маршрутизации. В этом случае файлы, помещенные во входной каталог («from»), должны быть скопированы в выходной каталог («to»). Протокол «file» используется как в частях «from», так и в частях «to», потому что файловая система — это то место, откуда приходит и собирается «сообщение». ‘? Noop = true’ в вызове ‘from’ указывает, что ничего не должно быть изменено в файлах в каталоге ‘input’ (обработка должна иметь эффект ‘noop’ для исходных файлов).
Как только что упомянуто, строка 19 в приведенном выше коде инструктирует Camel копировать файлы, уже находящиеся или помещенные в каталог «input», в указанный каталог «output», не затрагивая файлы в каталоге «input». В некоторых случаях я могу захотеть «переместить» файлы, а не «скопировать» их. В таких случаях можно указать ?noop=true вместо ?noop=true при указании конечной точки ‘from’. Другими словами, строка 19 выше может быть заменена на эту, чтобы файлы удалялись из каталога «input» при помещении в каталог «output». Если на входе не ?noop=true ни один параметр (ни ?noop=true ни ?delete=true ), то происходит действие, попадающее между ними: файлы в каталоге ‘input’ перемещаются в специально созданный новый подкаталог под ‘входной’ каталог называется .camel . Три случая выделены следующим.
Файлы, скопированные из файлов данных \ input в datafiles \ output без влияния на исходные файлы
|
1
|
from('file:C:\\datafiles\\input?noop=true').to('file:C:\\datafiles\\output'); |
Файлы, перемещенные из файлов данных \ input в datafiles \ output
|
1
|
from('file:C:\\datafiles\\input?delete=true').to('file:C:\\datafiles\\output'); |
Файлы, скопированные из файлов данных \ input в datafiles \ output и исходные файлы, перемещены в подкаталог .camel
|
1
|
from('file:C:\\datafiles\\input').to('file:C:\\datafiles\\output'); |
В качестве дополнительного примечания, использование беглого «от» и «до» является примером Java DSL Camel. Camel реализует это с помощью наследования реализации (такие методы, как «from» и «to» определены в классе RouteBuilder ), а не с помощью статического импорта (подход, часто используемый для DSL на основе Java).
Хотя обычно анонимные экземпляры RouteBuilder в Camel Context, это не является обязательным требованием. Могут быть ситуации, в которых выгодно иметь автономные классы, которые расширяют RouteBuilder и экземпляры этих расширенных классов передаются в контекст Camel. Я буду использовать этот подход, чтобы продемонстрировать все три случая, которые я описал ранее. Следующий листинг кода показывает класс, который расширяет RouteBuilder . Во многих случаях у меня был бы конструктор без аргументов, но в этом случае я использую конструктор, чтобы определить, какой тип передачи файлов должен поддерживаться маршрутом Camel.
В следующем листинге кода показан именованный автономный класс, который обрабатывает все три случая, показанные выше (копирование, копирование с архивированием входных файлов и перемещение). Это единственное расширение RouteBuilder использует перечисление в своем конструкторе, чтобы определить, как сконфигурировать входную конечную точку.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
package dustin.examples.camel;import org.apache.camel.builder.RouteBuilder;/** * Camel-based Route Builder for transferring files. * * @author Dustin */public class FileTransferRouteBuilder extends RouteBuilder{ public enum FileTransferType { COPY_WITHOUT_IMPACTING_ORIGINALS('C'), COPY_WITH_ARCHIVED_ORIGINALS('A'), MOVE('M'); private final String letter; FileTransferType(final String newLetter) { this.letter = newLetter; } public String getLetter() { return this.letter; } public static FileTransferType fromLetter(final String letter) { FileTransferType match = null; for (final FileTransferType type : FileTransferType.values()) { if (type.getLetter().equalsIgnoreCase(letter)) { match = type; break; } } return match; } } private final String fromEndPointString; private final static String FROM_BASE = 'file:C:\\datafiles\\input'; private final static String FROM_NOOP = FROM_BASE + '?noop=true'; private final static String FROM_MOVE = FROM_BASE + '?delete=true'; public FileTransferRouteBuilder(final FileTransferType newFileTransferType) { if (newFileTransferType != null) { switch (newFileTransferType) { case COPY_WITHOUT_IMPACTING_ORIGINALS : this.fromEndPointString = FROM_NOOP; break; case COPY_WITH_ARCHIVED_ORIGINALS : this.fromEndPointString = FROM_BASE; break; case MOVE : this.fromEndPointString = FROM_MOVE; break; default : this.fromEndPointString = FROM_NOOP; } } else { fromEndPointString = FROM_NOOP; } } @Override public void configure() throws Exception { from(this.fromEndPointString).to('file:C:\\datafiles\\output'); }} |
Этот блог продемонстрировал использование Camel для простой маршрутизации файлов из одного каталога в другой. Camel поддерживает множество других транспортных механизмов и форматов данных, которые здесь не показаны. Camel также поддерживает возможность трансформации маршрутизируемых сообщений / данных, что также здесь не показано. Этот пост был посвящен тому, что, вероятно, будет самым простым примером того, как применять Camel полезным способом, но Camel поддерживает гораздо больше, чем показано в этом простом примере.
Ссылка: Hello Camel: Автоматическая передача файлов от нашего партнера JCG Дастина Маркса в блоге Inspired by Actual Events .