Статьи

Изучение Apache Camel Core — Файловый компонент

File Poller — очень полезный механизм для решения типичных проблем в сфере ИТ. Встроенный file компонент Camel чрезвычайно гибок, и для его настройки доступно множество параметров. Давайте рассмотрим несколько общих способов использования.

Опрос каталога для входных файлов

Вот типичный верблюжий Route используемый каждую секунду для опроса каталога для входных файлов.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
import org.slf4j.*;
import org.apache.camel.*;
import org.apache.camel.builder.*;
import java.io.*;
 
public class FileRouteBuilder extends RouteBuilder {
    static Logger LOG = LoggerFactory.getLogger(FileRouteBuilder.class);
    public void configure() {
        from("file://target/input?delay=1000")
        .process(new Processor() {
            public void process(Exchange msg) {
                File file = msg.getIn().getBody(File.class);
                LOG.info("Processing file: " + file);
            }
        });
    }
}

Запустите это со следующим

1
mvn compile exec:java -Dexec.mainClass=org.apache.camel.main.Main -Dexec.args='-r camelcoredemo.FileRouteBuilder'

Программа начнет опрашивать вашу target/input папку в вашей текущей директории и будет ждать поступления файлов. Чтобы проверить входные файлы, вам нужно открыть другой терминал, а затем создать несколько файлов, как описано ниже.

1
2
echo 'Hello 1' > target/input/test1.txt
echo 'Hello 2' > target/input/test2.txt

Теперь вы должны увидеть, как первое окно подсказки начинает собирать файлы и переходить к следующему шагу Processor . В Processor мы получаем объект File из тела сообщения. Затем он просто записывает свое имя файла. Вы можете нажать CTRL+C когда закончите.

Существует много настраиваемых параметров из file компонента, которые вы можете использовать в URL-адресе, но большинство настроек по умолчанию достаточно, чтобы начать работу, как описано выше. Некоторые из этих стандартных действий таковы, что если папка ввода не существует, она создаст ее. И когда файл будет обработан Route , он будет перемещен в папку .camel . Если вам вообще не нужен файл после обработки, установите в URL-адресе delete=true .

Читать в файле содержимое и конвертировать в разные типы

По умолчанию file компонент создает объект org.apache.camel.component.file.GenericFile для каждого найденного файла и передает его по Route качестве тела сообщения. Вы можете получить всю информацию о вашем файле через этот объект. Или, в качестве альтернативы, вы также можете использовать Exchange API для автоматического преобразования объекта тела сообщения в тип, который вы ожидаете получить (например, как с msg.getIn().getBody(File.class) ). В приведенном выше примере File — это тип, который вы ожидаете получить из тела сообщения, и поэтому Camel попытается преобразовать его для вас. Верблюд использует пространство реестра контекста для предварительной регистрации многих TypeConverter , которые могут обрабатывать большинство распространенных типов данных (например, Java-примитив и т. Д.). Эти TypeConverter — это мощный способ сделать ваш Route и Processor более гибким и переносимым.

Camel не только преобразует ваш объект File из тела сообщения, но также может читать содержимое файла. Если ваши файлы основаны на символьном тексте, то вы можете просто сделать это.

1
2
3
4
5
6
7
from("file://target/input?charset=UTF-8")
        .process(new Processor() {
            public void process(Exchange msg) {
                String text = msg.getIn().getBody(String.class);
                LOG.info("Processing text: " + text);
            }
        });

Это оно! Просто укажите тип String , и Camel прочитает ваш файл и передаст все текстовое содержимое файла в виде основного сообщения. Вы даже можете использовать charset чтобы изменить кодировку.

Если вы имеете дело с двоичным файлом, просто попробуйте byte[] bytes = msg.getIn().getBody(byte[].class); преобразование вместо. Довольно круто, да?

Опрос и обработка больших файлов

При работе с большими файлами в file компоненте есть несколько параметров, которые вы можете использовать для обеспечения правильной обработки. Например, вы можете захотеть переместить входной файл в staging папку до того, как Route начнет обработку; и когда это будет сделано, переместите его в папку .completed .

1
2
3
4
5
6
7
from("file://target/input?preMove=staging&move=.completed")
        .process(new Processor() {
            public void process(Exchange msg) {
                File file = msg.getIn().getBody(File.class);
                LOG.info("Processing file: " + file);
            }
        });

Для правильной подачи входных файлов в папку опроса лучше всего, если отправитель сначала генерирует входные файлы во временной папке, и только когда он будет готов, затем переместите его в папку опроса. Это сведет к минимуму чтение неполного файла по Route если для создания входного файла может потребоваться время. Также еще одним решением этой проблемы является настройка конечной точки file для чтения папки опроса только при наличии сигнала или файла готового маркера. Например:

1
2
3
4
5
6
7
from("file://target/input?preMove=staging&move=.completed&doneFileName=ReadyFile.txt")
        .process(new Processor() {
            public void process(Exchange msg) {
                File file = msg.getIn().getBody(File.class);
                LOG.info("Processing file: " + file);
            }
        });

Выше будет считывать target/input папку только тогда, когда существует файл ReadyFile.txt . Файл маркера может быть просто пустым файлом, и он будет удален Camel после опроса. Это решение позволило бы отправителю генерировать входные файлы в любое время, которое может занять.

Другая проблема, связанная с обработкой больших файлов, заключается в том, чтобы избежать загрузки всего содержимого файла в память для обработки. Чтобы быть более практичным, вы хотите разделить файл на записи (например, на строку) и обработать его одну за другой (или это называется «потоковая передача»). Вот как вы это сделаете, используя Camel.

1
2
3
4
5
6
7
8
9
from("file://target/input?preMove=staging&move=.completed")
        .split(body().tokenize("\n"))
        .streaming()
        .process(new Processor() {
            public void process(Exchange msg) {
                String line = msg.getIn().getBody(String.class);
                LOG.info("Processing line: " + line);
            }
        });

Этот Route позволит вам обрабатывать файлы большого размера, не занимая слишком много памяти, и обрабатывать их построчно очень эффективно.

Запись сообщений обратно в файл

file компонент также может быть использован для записи сообщений в файлы. Напомним, что мы можем использовать компонент dataset для создания примеров сообщений. Мы будем использовать это для подачи Route и отправки в file компонент, чтобы вы могли видеть, что каждое сгенерированное сообщение будет сохранено в файл.

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
package camelcoredemo;
 
import org.slf4j.*;
import org.apache.camel.*;
import org.apache.camel.builder.*;
import org.apache.camel.main.Main;
import org.apache.camel.component.dataset.*;
 
public class FileDemoCamel extends Main {
    static Logger LOG = LoggerFactory.getLogger(FileDemoCamel.class);
    public static void main(String[] args) throws Exception {
        FileDemoCamel main = new FileDemoCamel();
        main.enableHangupSupport();
        main.addRouteBuilder(createRouteBuilder());
        main.bind("sampleGenerator", createDataSet());
        main.run(args);
    }
    static RouteBuilder createRouteBuilder() {
        return new RouteBuilder() {
            public void configure() {
                from("dataset://sampleGenerator")
                .to("file://target/output");
            }
        };
    }
    static DataSet createDataSet() {
        return new SimpleDataSet();
    }
}

Скомпилируйте и запустите

1
mvn compile exec:java -Dexec.mainClass=camelcoredemo.FileDemoCamel

По завершении вы увидите, что в target/output папке будет сгенерировано 10 файлов с именем файла в формате ID-<hostname>-<unique-number>-<msg-seq-num> .

В компоненте « Файл» доступны дополнительные параметры, которые вы можете изучить. Попробуйте это с маршрутом и убедитесь сами.

Ссылка: Изучение Apache Camel Core — Файловый компонент от нашего партнера JCG Земьяна Дена в блоге A Programmer’s Journal .