главной веб-странице (и в
Руководстве пользователя 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.
/** * 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». В некоторых случаях я могу захотеть «переместить» файлы, а не «скопировать» их. В таких случаях ?delete=true
может быть указано вместо ?noop=true
указания конечной точки «from». Другими словами, строка 19, приведенная выше, может быть заменена на эту, чтобы файлы удалялись из каталога «input» при помещении в каталог «output». Если на входе не указано ни одного параметра (ни того, ?noop=true
ни другого ?delete=true
), то происходит действие, попадающее между ними: файлы во «входе»каталог перемещается в специально созданный новый подкаталог в каталоге «input».camel
, Три случая выделены следующим.
Файлы, скопированные из файлов данных \ input в datafiles \ output без влияния на исходные файлы
from("file:C:\\datafiles\\input?noop=true").to("file:C:\\datafiles\\output");
Файлы, перемещенные из файлов данных \ input в datafiles \ output
from("file:C:\\datafiles\\input?delete=true").to("file:C:\\datafiles\\output");
Файлы, скопированные из файлов данных \ input в datafiles \ output и исходные файлы, перемещены в подкаталог .camel
from("file:C:\\datafiles\\input").to("file:C:\\datafiles\\output");
В качестве примечания, использование беглого «от» и «до» является примером Java DSL Camel . Camel реализует это с помощью наследования реализации (такие методы, как «from» и «to» определены в классе RouteBuilder ), а не с помощью статического импорта (подход, часто используемый для DSL на основе Java.)
Несмотря на то, что анонимные экземпляры обычно передаются RouteBuilder
в Camel Context, это не является обязательным требованием. Могут быть ситуации, в которых выгодно иметь автономные классы, которые расширяются RouteBuilder
и экземпляры этих расширенных классов передаются в Camel Context. Я буду использовать этот подход, чтобы продемонстрировать все три случая, которые я описал ранее. Следующий листинг кода показывает класс, который расширяется RouteBuilder
. Во многих случаях у меня был бы конструктор без аргументов, но в этом случае я использую конструктор, чтобы определить, какой тип передачи файлов должен поддерживаться маршрутом Camel.
В следующем листинге кода показан именованный автономный класс, который обрабатывает все три случая, показанные выше (копирование, копирование с архивированием входных файлов и перемещение). Это единственное расширение RouteBuilder
принимает перечисление в своем конструкторе, чтобы определить, как настроить конечную точку ввода.
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 поддерживает гораздо больше, чем показано в этом простом примере.