Apache Camel - передача файлов по определенному маршруту

Я пытаюсь создать веб-сервис, который при вызове просматривает локальный каталог, забирает файлы оттуда и загружает на ftp-сервер.

Я могу создать простой маршрут, который выбирает файл из локального каталога и загружает его на ftp-сервер. Ниже приведен код:

<route>
        <from uri="file://D:\\FTPTest?noop=true&amp;delay=2000" />
        <to uri="ftp://[email protected]:21/public_html/EnterpriseProject?password=password123#"/>
        <to uri="bean:myBean?method=test" />
    </route>

Но я хочу, чтобы эта передача файлов вызывалась при вызове определенного маршрута через веб-сервис restlet, я пробовал использовать следующий код, но это не сработало:

<route>
        <from uri="direct:fileTransferRoute" />
            <to uri="file://D:\\FTPTest?noop=true&amp;delay=2000" />
            <to uri="ftp://[email protected]:21/public_html/EnterpriseProject?password=password123#"/>
        </route>

Вышеупомянутый маршрут вызывается рестлетом из следующего маршрута:

<route>
<from
            uri="restlet:http://0.0.0.0:9080/csitec/{serviceName}?restletMethod=post" />
        <process ref="serviceRouteProcessor" />
        <toD uri="direct:${in.header.nextRoute}" />

    </route>

Вот код моего serviceRouteProcessor:

public void process(Exchange exchange) throws Exception {
    String body = exchange.getIn().getBody(String.class);
    String serviceName = exchange.getIn().getHeader(Constants.SERVICE_NAME).toString();
    String nextRoute = serviceName+Constants.NEXT_ROUTE_APPENDER;
    exchange.getOut().setHeader(Constants.NEXT_ROUTE, nextRoute);
    exchange.getOut().setBody(body);
}

Пожалуйста, помогите мне и предложите внести изменения, чтобы он работал так.


person Siddharth Sachdeva    schedule 24.11.2016    source источник


Ответы (2)


Вам следует попробовать функцию pollEnrich в content-enricher

В разделе примеров вы можете найти пример файлов.

Ваш маршрут должен выглядеть примерно так (я работаю только с camel java dsl, поэтому это немного псевдокод xml):

<route>
    <from uri="direct:fileTransferRoute" />
        <pollEnrich uri="file://D:\\FTPTest?fileName=data.txt....." />
        <to uri="ftp://[email protected]:21/public_html/EnterpriseProject?password=password123#"/>
    </route>
person soilworker    schedule 24.11.2016
comment
Я добавил ваш маршрут в качестве примера к своему ответу. - person soilworker; 24.11.2016
comment
Атрибут uri не может быть указан в элементе pollEnrich. Странно, что я получаю эту ошибку. Тем не менее, он отлично работает с: ‹pollEnrich› ‹constant› file: // D: \\ FTPTest? Noop = truedelay = 2000; ‹/constant› ‹/pollEnrich› Это то, что я действительно искал, большое спасибо - person Siddharth Sachdeva; 24.11.2016
comment
@Siddharth ошибка зависит от того, что до верблюда 2.15 синтаксис enrich и pollEnrich был похож на ответ, из верблюда 2.16 синтаксис немного изменился и работает как ваш комментарий. - person Alessandro Da Rugna; 25.11.2016

Отредактировано:

вы должны сначала понять одну вещь: to производитель, а не потребитель <to uri="file://D:\\FTPTest?noop=true&amp;delay=2000" />

Что вы можете сделать,

@Autowired
private CamelContext context;// if you have more than one camel context use @Qualifier and wire by bean id


public void process(Exchange exchange) throws Exception {
    String body = exchange.getIn().getBody(String.class);
    String serviceName = exchange.getIn().getHeader(Constants.SERVICE_NAME).toString();
    context.startRoute(serviceName+Constants.NEXT_ROUTE_APPENDER);// here in nextroute you must give the routeid
}

ваш маршрут должен выглядеть

 <route id = "<value of serviceName+Constants.NEXT_ROUTE_APPENDER>" autoStartup = "false">
                <from uri="file://D:\\FTPTest..." />
                <onCompletion onFailureOnly="true">
                  <choice>
                    <when>
                        <simple>${property.CamelBatchComplete}</simple>
                    <process ref="asyncSelfShutdownProcessor"/>
                    </when>
                  </choice>
                </onCompletion>
                <to uri="ftp://[email protected]:21..."/>
            </route>

И добавьте asyncSelfShutdownProcessor в контекст Spring

@Component
public class AsyncSelfShutdownProcessor implements AsyncProcessor {

    @Autowired
    private CamelContext context

     public boolean process(Exchange exchange, AsyncCallback callback){

          new Thread(() -> context.stopRoute(exchange.getFromRouteId())).start();
     }
}

############################################ ############################# Старая версия:

Хорошо, я понимаю, что вам нужно - у вас есть маршрут, который перемещает файл из файловой системы на ftp-сервер, все, что вам нужно, - это этот маршрут, который будет выполняться только при запуске из службы отдыха. Я бы так сделал,

* Я проложу маршрут autoStartup = "false" и назначу его как id = "fs-to-ftp".

<route id = "fs-to-ftp" autoStartup = "false">
            <from uri="file://D:\\FTPTest..." />
            <onCompletion onFailureOnly="true">
                <process ref="asyncSelfShutdownProcessor"/>
            </onCompletion>
            <to uri="ftp://[email protected]:21..."/>
        </route>

** Добавьте асинхронный процесс самоотключения в onComplete к маршруту «fs-to-ftp». Асинхронный процессор

asyncSelfShutdownProcessor= AsyncProcessorConverterHelper.convert(exchange -> {
            new Thread(() -> context.stopRoute("fs-to-ftp")).start();
        });

*** Добавьте зависимость контекста верблюда для службы отдыха и запустите маршрут по идентификатору в службе отдыха context.startRoute("fs-to-ftp")

person Sagar    schedule 24.11.2016
comment
Спасибо за ответ @Sagar, на самом деле я вызываю другие маршруты из рестлета с помощью ‹toD .... /› так, как я могу вызвать маршрут с определенным идентификатором в этом? - person Siddharth Sachdeva; 24.11.2016
comment
Могу ли я передать ‹from uri = direct: fileTransferRoute /› это в свой маршрут и выполнить процесс передачи файлов? - person Siddharth Sachdeva; 24.11.2016
comment
На самом деле, если вы хотите использовать <from uri="direct:fileTransferRoute" />, вы должны читать и передавать файлы в "direct:fileTransferRoute" программно, и верблюд не будет выбирать сам - person Sagar; 24.11.2016
comment
Возможно, вам стоит добавить код успокаивающего сервиса для лучшего понимания вашего сценария. - person Sagar; 24.11.2016
comment
Я добавил весь соответствующий код, пожалуйста, помогите мне. - person Siddharth Sachdeva; 24.11.2016
comment
Теперь маршрут не останавливается, вот журналы: 2016-11-24 13:38:24 ИНФОРМАЦИЯ [Camel (camel-1) thread # 5 - ShutdownTask] DefaultShutdownStrategy: 628 - Ожидание, так как есть еще 2 обмена в полете и ожидающие завершения , таймаут через 227 секунд. На каждом маршруте: [fileTransfer = 2] 2016-11-24 13:38:24 DEBUG [Camel (camel-1) thread # 5 - ShutdownTask] DefaultShutdownStrategy: 757 - Имеется 1 обмен на борту: InflightExchange: [exchangeId = ID- dell-52675-1479974705034-0-7, fromRouteId = fileTransfer, routeId = fileTransfer, nodeId = to4, elaps - person Siddharth Sachdeva; 24.11.2016
comment
у вас есть более одного файла в папке .. в этом случае вы должны использовать пакетный потребитель - person Sagar; 24.11.2016
comment
Да, у него более одного файла, любая ссылка на реализацию пакетного потребителя будет действительно полезна. - person Siddharth Sachdeva; 24.11.2016
comment
просто добавьте к вам & antInclude = * из ‹from uri = file: // D: \\ FTPTest? noop = truedelay = 2000antInclude = * /› и добавьте условие в onCompletion для свойства CamelBatchComplete в значение true - person Sagar; 24.11.2016
comment
Даже в случае одного файла его не выключить. Показано, что есть 1 обмен в полете - person Siddharth Sachdeva; 24.11.2016
comment
Я не могу сейчас позвонить в другие службы. Поскольку этот не отключается. - person Siddharth Sachdeva; 24.11.2016
comment
AsyncProcessor - это не класс, это интерфейс, также я получаю синтаксическую ошибку в новой строке потока. пожалуйста, проверьте братан. - person Siddharth Sachdeva; 24.11.2016
comment
есть проблема с этой строкой, попробуйте в своей среде IDE: new Thread (() - ›context.stopRoute (exchange.getFromRouteId ())). start (); - person Siddharth Sachdeva; 24.11.2016
comment
И логическое значение вернуть? - person Siddharth Sachdeva; 24.11.2016