Spring integration 文件入站通道适配器spring集成,用于将多个文件聚合到一个主文件中以进行作业处理

Spring integration 文件入站通道适配器spring集成,用于将多个文件聚合到一个主文件中以进行作业处理,spring-integration,Spring Integration,我已经编写了一个代码,将多个文件合并到一个主文件中。 问题在于int-transformer,虽然我在文件入站通道适配器的复合过滤器中聚合了文件列表,但我一次只能得到一个文件。复合筛选器中的文件列表大小是正确的,但在Transformer bean中,文件列表大小始终是一个,并且无法通过筛选器获得正确的聚合文件列表大小 这是我的配置: <!-- Auto Wiring --> <context:component-scan base-package="com.nt.na21.n

我已经编写了一个代码,将多个文件合并到一个主文件中。 问题在于int-transformer,虽然我在文件入站通道适配器的复合过滤器中聚合了文件列表,但我一次只能得到一个文件。复合筛选器中的文件列表大小是正确的,但在Transformer bean中,文件列表大小始终是一个,并且无法通过筛选器获得正确的聚合文件列表大小

这是我的配置:

<!-- Auto Wiring -->
<context:component-scan base-package="com.nt.na21.nam.integration.*" />
<!-- intercept and log every message -->
<int:logging-channel-adapter id="logger"
    level="DEBUG" />
<int:wire-tap channel="logger" />

<!-- Aggregating the processed Output for OSS processing -->

<int:channel id="networkData" />
<int:channel id="requests" />

<int-file:inbound-channel-adapter id="pollProcessedNetworkData"
    directory="file:${processing.files.directory}" filter="compositeProcessedFileFilter"
    channel="networkData">
    <int:poller default="true" cron="*/20 * * * * *" />

</int-file:inbound-channel-adapter>

<bean id="compositeProcessedFileFilter"
    class="com.nt.na21.nam.integration.file.filter.CompositeFileListFilterForBaseLine" />

<int:transformer id="aggregateNetworkData"
    input-channel="networkData" output-channel="requests">
    <bean id="networkData" class="com.nt.na21.nam.integration.helper.CSVFileAggregator">
    </bean>
</int:transformer>

这里有人能帮我找出过滤器的问题吗?同样的过滤器并不是为转换而收集的

提前谢谢

问题在于int:aggregator,因为我不确定如何调用它。我以前在设计中使用过这个,但根本没有执行。谢谢你的快速回复

对于这个问题,我编写了一个FileScaner实用程序,它将扫描文件夹中的所有文件,聚合工作得非常好

请找到配置与聚合器不工作,因此我分裂了两个轮询器的设计首先产生了所有的CSV文件,第二次收集和聚合它

<!-- Auto Wiring -->
<context:component-scan base-package="com.bt.na21.nam.integration.*" />
<!-- intercept and log every message -->
<int:logging-channel-adapter id="logger" level="DEBUG" />
<int:wire-tap channel = "logger" />

<int:channel id="fileInputChannel" datatype="java.io.File" />
<int:channel id="error" />
<int:channel id="requestsCSVInput" />

<int-file:inbound-channel-adapter id="pollNetworkFile"
    directory="file:${input.files.directory}" channel="fileInputChannel"
    filter="compositeFileFilter" prevent-duplicates="true">
    <int:poller default="true" cron="*/20 * * * * *"
        error-channel="error" />
</int-file:inbound-channel-adapter>

<bean id="compositeFileFilter"
    class="com.nt.na21.nam.integration.file.filter.CompositeFileListFilterForTodayFiles" />

<int:transformer id="transformInputZipCSVFileIntoCSV"
    input-channel="fileInputChannel" output-channel="requestsCSVInput">
    <bean id="transformZipFile"
        class="com.nt.na21.nam.integration.file.net.NetRecordFileTransformation" />
</int:transformer>

<int:router ref="docTypeRouter" input-channel="requestsCSVInput"
    method="resolveObjectTypeChannel">
</int:router>

<int:channel id="Vlan" />
<int:channel id="VlanShaper" />
<int:channel id="TdmPwe" />

<bean id="docTypeRouter"
    class="com.nt.na21.nam.integration.file.net.DocumentTypeMessageRouter" />

<int:service-activator ref="vLanMessageHandler" output-channel="newContentItemNotification" input-channel="Vlan" method="handleFile" />

<bean id="vLanMessageHandler" class="com.nt.na21.nam.integration.file.handler.VLanRecordsHandler" />

<int:service-activator ref="VlanShaperMessageHandler" output-channel="newContentItemNotification" input-channel="VlanShaper" method="handleFile" />

<bean id="VlanShaperMessageHandler" class="com.nt.na21.nam.integration.file.handler.VlanShaperRecordsHandler" />

<int:service-activator ref="PweMessageHandler" output-channel="newContentItemNotification" input-channel="TdmPwe" method="handleFile" />

<bean id="PweMessageHandler" class="com.nt.na21.nam.integration.file.handler.PseudoWireRecordsHandler" />


<int:channel id="newContentItemNotification" />

<!-- Adding for aggregating the records in one place for OSS output -->

 <int:aggregator input-channel="newContentItemNotification" method="aggregate"
    ref="netRecordsResultAggregator" output-channel="net-records-aggregated-reply"
    message-store="netRecordsResultMessageStore"
    send-partial-result-on-expiry="true">
 </int:aggregator>

 <int:channel id="net-records-aggregated-reply" />
 <bean id="netRecordsResultAggregator" class="com.nt.na21.nam.integration.aggregator.NetRecordsResultAggregator" />

 <!-- Define a store for our network records results and set up a reaper that will
    periodically expire those results. -->
<bean id="netRecordsResultMessageStore" class="org.springframework.integration.store.SimpleMessageStore" />


 <int-file:outbound-channel-adapter id="filesOut"
                               directory="file:${output.files.directory}" 
                               delete-source-files="true">

 </int-file:outbound-channel-adapter>


该代码工作正常,直到路由到以下所有通道:

<int:channel id="Vlan" />
<int:channel id="VlanShaper" />
<int:channel id="TdmPwe" />

我正在尝试从上面包含CSV数据的通道的进程返回LinkedHashSet,我需要聚合所有合并

LinkedHashSet vAllAttributes to get the master output CSV file.
List<String> masterList = new ArrayList<String>(vAllAttributes);
Collections.sort(masterList);
LinkedHashSet VallatAttributes以获取主输出CSV文件。
列表主列表=新的ArrayList(VallatAttributes);
集合。排序(主列表);

嗯,看起来你有点误解了你的行为。它的本质是为
频道
生成每条消息
一个文件。它不依赖于
FileListFilter
的逻辑。结果是:

  • FileReadingMessageSource
    使用
    DirectoryScanner
    将文件从提供的目录检索到要接收的内部
    队列

  • 由于我们扫描目录中的文件,
    DirectoryScanner
    的设计类似于
    列表文件(文件目录)
    。我想这已经把你引入歧途了

  • 之后,
    过滤器将应用于原始文件列表,并仅返回适当的文件

  • 它们被存储到
    待接收
    队列

  • 只有在这之后,
    FileReadingMessageSource
    才会轮询队列中的一个项目,为输出通道生成消息

  • 要实现您的
    聚合
    需求,您确实应该在
    之间使用

    您可以使用
    max messages per poll=“-1”
    标记
    ,以便在单个计划任务期间真正轮询所有文件。但是无论如何,只要你的
    过滤器返回文件,就会有同样多的消息

    之后,您必须接受
    的一些技巧:

  • correlationKey
    -允许您的文件消息组合到单个
    消息组
    ,以便发布单个消息以进一步
    。由于我们没有来自
    的任何上下文,但我们知道所有消息都是由单个轮询任务和调度线程提供的(您不在
    上使用
    任务执行器
    ),因此我们可以简单地使用
    相关键

    correlation-strategy-expression="T(Thread).currentThread().id"
    
  • 但这还不够,因为无论如何,我们最终都应该以某种方式产生一条信息。不幸的是,我们不知道允许聚合阶段的
    发布策略返回
    true
    的文件数(但是您可以通过自定义
    文件列表过滤器中的
    线程本地
    来实现)。因此,我们从未有过正常的
    组完成
    。但是我们可以从聚合器中强制释放未完成的组,以使用
    上的
    MessageGroupStoreReaper
    组超时

  • 除上述条款外,您还应在
    上提供以下选项:

  • 就这些。没有理由提供任何自定义的
    聚合函数
    ref
    /
    方法
    表达式
    ),因为默认的on仅使用组中所有消息的
    有效负载
    列表
    构建单个消息。这适用于您的
    CSVFileAggregator
    。虽然您可以避免使用聚合函数的
    CSVFileAggregator

    希望我明白

    <int:channel id="Vlan" />
    <int:channel id="VlanShaper" />
    <int:channel id="TdmPwe" />
    
    LinkedHashSet vAllAttributes to get the master output CSV file.
    List<String> masterList = new ArrayList<String>(vAllAttributes);
    Collections.sort(masterList);
    
    correlation-strategy-expression="T(Thread).currentThread().id"
    
    send-partial-result-on-expiry="true"
    expire-groups-upon-completion="true"