Как использовать динамический 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>

Это потрясающе!!!

См. http://camel.apache.org/content-enricher.html

Вы можете прочитать его из файла свойств следующим образом:

<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>
Другие вопросы по тегам