Как получить доступ к обмену вызовами с помощью ZipAggregationStrategy от Camel

#java #zip #apache-camel

#java #zip #apache-camel

Вопрос:

Я создаю zip-файлы в Camel с помощью ZipAggregationStrategy и должен установить имя выходного файла на основе пользовательского свойства, установленного в вызывающем exchange. Однако обмен, который я получаю после моей агрегации zip, не содержит ни одного из моих свойств.

Мой общий поток:

  1. Процессор, который устанавливает пользовательские свойства для exchange (динамический, основанный на запросе к базе данных)
  2. Компонент, который создает List содержимое zip-файла
  3. aggregator Использование Camel ZipAggregationStrategy , основанное на примере в документации Camel.

После шага 3. Я хочу динамически присвоить zip-файлу имя на основе свойств, которые я установил на exchange на шаге 1., Но exchange содержит только свойства Camel ( CamelFileExchangeFile с путем к zip-файлу и т. Д.), Потому что Новый exchange создается в aggregate() :

 @Override
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
    File zipFile;
    Exchange answer = oldExchange;

    // ...

    DefaultEndpoint endpoint = (DefaultEndpoint) newExchange.getFromEndpoint();
    answer = endpoint.createExchange();
    answer.addOnCompletion(new DeleteZipFileOnCompletion(zipFile));

    // ...

    genericFile.bindToExchange(answer);  

    // ...

    return answer;
}
  

Комментарии:

1. Camel не предполагает копирования свойств в агрегатор по умолчанию, поскольку трудно определить, какое свойство необходимо копировать, если обмены используют разные свойства. Если вы хотите задать ИМЯ_ФАЙЛА, вы можете просто поместить пользовательский процесс перед DSL setHeader.

2. Проблема с этим заключается в том, что в моей ситуации пользовательский процесс может быть выполнен только до того, как произойдет агрегирование. Имя файла должно быть динамическим, и после агрегации в настоящее время нет средств для его создания. Подход Питера — единственный способ, который в настоящее время работает, но он немного запутан.

Ответ №1:

Я думаю, это ошибка. Свойства должны быть сохранены и не удаляться стратегией агрегации. Я открыл проблему с Jira в надежде, что это будет исправлено: CAMEL-7555.

Как обходной путь расширить ZipAggregationStrategy и переопределить aggregate :

 public class MyZipAggregationStrategy extends ZipAggregationStrategy {
    @Override
    public Exchange aggregate(final Exchange oldExchange, final Exchange newExchange) {
        final Exchange answer = super.aggregate(oldExchange, newExchange);
        answer.setProperty("myZipName", newExchange.getProperty("myZipName")); // Hack!!
        return answer;
    }
}
  

Используйте MyZipAggregationStrategy следующим образом:

 public class MyRouteBuilder extends RouteBuilder {
    @Override
    public void configure() {
        from("file:zipper/in?include=.*.xmlamp;noop=true")
            .process(new Processor() {
                @Override
                public void process(final Exchange exchange) throws Exception {
                    exchange.setProperty("myZipName", "messages.zip");
                }
            })
            .aggregate(new MyZipAggregationStrategy())
            .constant(true)
            .completionFromBatchConsumer()
            .eagerCheckCompletion()
            .setHeader(Exchange.FILE_NAME, simple("${property.myZipName}")) // setting ZIP file name
            .to("file:zipper/out");
    }
}
  

Комментарии:

1. Спасибо, Питер, это сработало. Я начал задаваться вопросом, была ли это просто ошибка!