Как использовать динамический URI в From()
Как упоминалось в Apache Camel, он позволяет записывать динамический URI в To(), позволяет ли он записывать динамический URI в From(). Потому что мне нужно вызвать несколько FTP-сайтов для загрузки файлов на основе конфигурации, которую я собираюсь сохранить в базе данных.
(FTPHost, FTPUser, FTPPassword, FTPSourceDir, FTPDestDir)
Я прочитаю эту конфигурацию из БД и передам ее динамическому маршруту Camel во время выполнения.
Пример: это пример верблюжьего маршрута, который я должен написать динамически
<Route>
<from uri="ftp://${ftpUser}@${ftpHost}:${ftpPort}/${FTPSourceDir}?password=${ftpPassword}&delete=true"/>
<to uri="${ftpDestinationDir}"/>
</Route>
Как вы видите в примере, мне нужно передать эти параметры динамически. Итак, как использовать динамический URI в From ()
5 ответов
Начиная с верблюда 2.16, мы можем использовать компонент pollenrich для определения потребителя опроса, такого как файл, ftp..etc со значением динамического URL / параметра, как показано ниже
<route>
<from uri="direct:start"/>
<pollEnrich>
<simple>file:inbox?fileName=${body.fileName}</simple>
</pollEnrich>
<to uri="direct:result"/>
</route>
Это потрясающе!!!
Вы можете прочитать его из файла свойств следующим образом:
<bean id="bridgePropertyPlaceholder" class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer">
<property name="location" value="classpath:/config/Test.properties"/>
</bean>
<Route>
<from uri="ftp://{{ftpUser})@${{ftpHost}}:{{ftpPort}}/${{FTPSourceDir}}?password={{ftpPassword}}&delete=true"/>
<to uri="{{ftpDestinationDir}}"/>
</Route>
ftpUser, ftpHost.... - все это ключи, объявленные в Test.properties
Если вы хотите получить эти переменные из вашего обмена динамически, вы не можете делать это обычным способом, как вы упомянули в своем примере. Вы должны использовать потребительский шаблон следующим образом,
Exchange exchange = consumerTemplate.receive("ftp:"+url);
producerTemplate.send("direct:uploadFileFTP",exchange );
Вы должны сделать это от весеннего производителя бобов или верблюда. Шаблон потребителя будет потребляться из данного компонента, и этот шаблон производителя будет вызывать прямой компонент, объявленный в вашем camel-context.xml
Примечание. Шаблоны Consumer и Producer немного дороги. Вы можете впрыснуть оба в контейнере пружины и позволить пружине справиться с жизненным циклом
Я помогаю команде, которая управляет брокером сообщений, переключая около миллиона сообщений в день. Существует более 50 направлений, из которых мы должны опрашивать файлы по всем брендам обмена файлами (FTP, SFTP, NFS/file: ...). Поддержка до 50 развертываний, каждое из которых прослушивает другой локальный / удаленный каталог, действительно является дополнительной нагрузкой по сравнению с одним соединителем FILE, способным опрашивать файлы в 50 местах в соответствии с конкретным расписанием и настройками безопасности каждого... Та же история для получения электронная почта из почтовых ящиков pop3 и IMAP.
В Camel схема решения выглядит следующим образом:
- у вас нет другого выбора, кроме как использовать java DSL для настройки как минимум части from() ваших маршрутов с URI, который вы действительно можете прочитать / построить из базы данных или получить по запросу администратора для инициирования нового маршрута. XML DSL позволяет вводить свойства, которые разрешаются только один раз при создании контекста Camel, и никогда больше.
- Основная идея состоит в том, чтобы запустить маршруты, позволить им запускаться (прослушивать или опрашивать точный ресурс), а затем отключать и перестраивать их по требованию, используя контекстные API-интерфейсы Camel для управления состоянием RouteDefinitions, Routes и, возможно, конечных точек.
- лично мне нравится реализовывать такую динамическую реализацию from() на минималистических маршрутах, используя только часть маршрута from, т.е.
from(uri).to("direct:inboundQueue").routeId("myRoute")
, а затем определить - в Java или XML - общий блок маршрута, который обрабатывает остальную часть процесса:from("direct:inboundQueue").process(..).etc... .to(outUri)
- Я настоятельно рекомендую объединить Camel с платформой Spring и, в частности, Spring MVC (или Spring Integration HttpGateway), чтобы вы могли быстро создавать интерфейсы компонентов REST, SOAP, HTTP/JSP или JMX для администрирования создания маршрутов., уничтожение и обновления внутри контейнера Spring + Camel, оба прекрасно интегрированы.
- Затем вы можете объявить в контексте приложения Spring компонент, который расширяет
SpringRouteBuilder
как обычно при построении маршрутов Camel с помощью Java DSL весной; в обязательном порядке@Override configure()
реализации метода, вы должны сохранить ваш объект routeDefinition, созданныйfrom(uri)
метод, и назначить его известнымString
идентификатор маршрута с.routeId(route-id)
Способ; Вы можете, например, использовать идентификатор маршрута в качестве ключа на карте ваших объектов определения маршрута, уже созданных и запущенных, а также в качестве ключа в вашей базе данных URI. - тогда вы продлите
SpringRouteBuilder
bean-компонент, который вы объявили с помощью новых методов createRoute(идентификатор маршрута), updateRoute(идентификатор маршрута) и removeRoute (идентификатор маршрута); Соответствующие параметры идентификатора маршрута, необходимые для создания или обновления, будут получены из базы данных или другого реестра, а соответствующий метод, работающий в компоненте RouteBuilder, воспользуется преимуществом средства getContext() для получения текущегоModelCamelContext
который в свою очередь используется дляstopRoute(route-id)
,removeRoute(route-id)
, а потомaddRouteDefinition(
здесь вам нужен объект routeDefinition)
, и наконецstartRoute(route-id)
(Примечание: остерегайтесь возможных конечных точек-призраков, которые не будут удалены, как описано в javadoc removeRoute()) - ваш административный интерфейс (который обычно принимает форму компонента / bean-компонента Spring @Controller, который обрабатывает трафик HTTP/REST/SOAP) действительно будет легко получить ранее созданный
SpringRouteBuilder
Расширение Bean вводится Spring в bean-компонент контроллера и, таким образом, получает доступ ко всем необходимымcreateRoute(route-id)
,updateRoute(route-id)
, а такжеremoveRoute(route-id)
методы, которые вы добавили кSpringRouteBuilder
Боб
И это прекрасно работает. Точная реализация со всем применимым кодом обработки ошибок и проверки - слишком много кода для размещения здесь, но у вас есть все ссылки на соответствующие "как" в приведенном выше.
Я думаю, что вы можете выполнить свое требование в рамках маршрута Camel.
Поскольку вы хотите опросить несколько FTP-сайтов, вам придется как-то инициировать этот процесс. Может быть, вы могли бы сделать это на основе таймера Quartz2. После запуска вы можете прочитать настроенные FTP-сайты из вашей базы данных.
Для опроса заданных FTP-сайтов вы можете использовать шаблон Content Enricher для опроса (см.: pollEnrich) динамически оцениваемого URI.
Ваш окончательный базовый маршрут может выглядеть примерно так (псевдокод):
from("quarz...")
to("sql...")
pollEnrich("ftp...")
...
Use Camel endpoint with spring spel expression.
Set up a Camel endpoint in the context so it can be accessed from any bean:
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<endpoint id="inventoryQueue" uri="#{config.jms.inventoryQueueFromUri}"/>
</camelContext>
Now you can reference the inventoryQueue endpoint within the `@Consume` annotation as follows:
@org.apache.camel.Consume(ref = "inventoryQueue")
public void updateInventory(Inventory inventory) {
// update
}
Or:
<route>
<from ref="inventoryQueue"/>
<to uri="jms:incomingOrders"/>
</route>