Как использовать разметку и ItemReader для получения файловых объектов? - PullRequest
0 голосов
/ 21 февраля 2019

Я думаю, что это должен быть довольно обычный случай использования, но я довольно новичок в Spring-Batch и смущен некоторыми концепциями.

Я хочу иметь пакетный процесс, который читает файлы из каталога (получаетих как File объект).Он также должен быть разделен и перезапускаем .

В результате поиска были получены в основном примеры для FlatFileItemReader, что, как мне кажется, не то, что мне нужно (я не хочупрочитайте их, просто отправьте их как файл на процессор).

В данный момент мой разделитель и считыватель выглядят следующим образом.

@Bean("partitioner")
@StepScope
public Partitioner partitioner() {
    MultiResourcePartitioner partitioner = new MultiResourcePartitioner();
    ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
    Resource[] resources = null;
    try {
        resources = resolver.getResources("classpath*:/*.json");
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    partitioner.setResources(resources);
    partitioner.partition(10);
    return partitioner;
}

@Bean
@StepScope
@Qualifier("fileItemReader")
@DependsOn("partitioner")
public  ItemReader<File> fileItemReader(@Value("#{stepExecutionContext['fileName']}") String fileName){
    log.info("fileName from stepExecutionContext is " + fileName);

        return new ItemReader<File>() {
            //Reader has to return null, when he ended
            boolean fileHasBeenRead = false;

            @Override
            public File read() throws CustomRetryableException, FileNotFoundException {

                if (fileHasBeenRead == true){
                    log.info("has been read already");
                    return null;
                }
                else {
                    fileHasBeenRead = true;
                    return ResourceUtils.getFile(fileName);
            }
        }
    };
}

Мне кажется, что реализация этого считывателя не очень хорошаи это также, кажется, не перезапускается.

Я нашел другой пример читателя, но не знаю, будет ли он работать с разбиением FileReader Пример .

У меня естьтакже наткнулся на MultiResourceItemReader, но я не уверен, может ли это также быть решением.

Каков наилучший способ использования секционирования и ItemReader для обработки объектов File, а также с возможностью перезапуска?

1 Ответ

0 голосов
/ 21 февраля 2019

Spring Batch не предлагает никакой реализации ItemReader, которая возвращает объект File, поэтому вы правы в том, что вам нужно реализовать свою собственную.Теперь давайте посмотрим, как Spring Batch обеспечивает перезапуск своих компонентов.

Основным интерфейсом, обеспечивающим возможность перезапуска, является интерфейс ItemStream.Этот интерфейс имеет три метода, как показано ниже:

public interface ItemStream {

    void open(ExecutionContext executionContext) throws ItemStreamException;

    void update(ExecutionContext executionContext) throws ItemStreamException;

    void close() throws ItemStreamException;
}

Метод open используется для установления состояния компонента и инициализации любых компонентов, которые в этом нуждаются (открыть файлы / и т. Д.).Это также место, где состояние компонента будет восстановлено при перезапуске задания.Состояние извлекается из ExecutionContext, который представляет собой не что иное, как карту пар ключ / значение, которая была сохранена в предыдущих выполнениях.

В методе update компоненту предоставляется возможность периодически сохранятьот его текущего состояния.Такие вещи, как количество прочитанных записей и т. Д., Будут храниться в ExecutionContext, который впоследствии сохраняется в репозитории заданий для последующей ссылки при перезапуске (с помощью метода open, описанного выше).

Наконец, *Метод 1018 * используется для освобождения любых ненужных ресурсов и выполнения окончательной очистки (закрытия файлов, подключений к базам данных и т. Д.).

При рассмотрении предыдущих методов перезапускаемый компонент реализует интерфейс ItemStream, поэтомучто метод update сохранит любое соответствующее состояние, необходимое для перезапуска, на ExecutionContext, а метод open будет искать это состояние и, если оно существует, восстановить его (если предыдущего состояния нет, это не перезапуск).

Имея все это в виду, теперь мы можем рассмотреть ваш конкретный пример использования реализации ItemReader, которая позволяет возвращать объект File и перезапускается.В этом случае вам действительно нужно определить две вещи:

  1. Как сделать набор данных статичным - В большинстве случаев перезапуска с Spring Batch предполагается, что набор данныхне изменился между пробегами.В вашем случае ожидается, что список файлов не изменился от исполнения к выполнению.Если это так, способность сделать его перезапускаемым становится более сложным.Хороший способ справиться с этим - для каждого экземпляра задания обрабатываемые файлы каким-либо образом помечаются (переименовываются) или перемещаются в каталог «обработки», который не изменяется от выполнения к выполнению.
  2. Какое состояние хранить - После того, как вы сделали статический набор данных, Spring Batch может помочь сделать его перезапускаемым.Я бы продлил AbstractItemCountingItemStreamItemReader.Этот родительский класс автоматически подсчитает количество предметов, которые были возвращены, и сохранит их в ExecutionContext для вас.Это означает, что при переборе массива объектов Resource, AbstractItemCountingItemStreamItemReader будет отслеживать индекс, на котором вы находитесь.Таким образом, в вашем методе open вы можете получить массив ресурсов и отсортировать его .Оттуда у вас есть согласованный набор данных, который вам нужен только для определения того, какие элементы были прочитаны, а какие нет.

Удачи, и я надеюсь, что это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...