Collections 使用Mule和收集聚合器保留不完整数据集的数据处理

Collections 使用Mule和收集聚合器保留不完整数据集的数据处理,collections,mule,flow-control,aggregator,Collections,Mule,Flow Control,Aggregator,我需要收集和处理其他组织生成的文件集。为简单起见,假设集合由两个文件组成,一个摘要文件和一个名为SUM20150701.dat和DTL20150701.dat的详细文件,这将构成日期20150701的集合。问题是,集合需要按顺序处理,并且从外部组织传输文件可能容易出错,从而导致文件丢失。如果发生这种情况,这组文件应保持不变,找到的任何以下文件集也应保持不变。例如,在mule过程开始时,源文件夹中可能有:SUM20150701.dat、SUM20150703.dat、DTL20150703.dat

我需要收集和处理其他组织生成的文件集。为简单起见,假设集合由两个文件组成,一个摘要文件和一个名为SUM20150701.dat和DTL20150701.dat的详细文件,这将构成日期20150701的集合。问题是,集合需要按顺序处理,并且从外部组织传输文件可能容易出错,从而导致文件丢失。如果发生这种情况,这组文件应保持不变,找到的任何以下文件集也应保持不变。例如,在mule过程开始时,源文件夹中可能有:SUM20150701.dat、SUM20150703.dat、DTL20150703.dat。也就是说,20150701的数据集不完整,而20150703的数据集完整。我需要保持两个数据集,直到DTL20150701.dat到达,然后按顺序处理它们

在我的mule进程的这种简化形式中,监视源文件夹中的文件。找到后,它们将被移动到存档文件夹,并使用日期作为序列和相关性值传递给集合聚合器。当一个集合完成时,它将被移动到目标文件夹。收集器上使用较长的超时时间,以确保不处理不完整的集合:

<file:connector name="File" autoDelete="false" streaming="false" validateConnections="true" doc:name="File">
    <file:expression-filename-parser />
</file:connector>

<file:connector name="File1" autoDelete="false" outputAppend="true" streaming="false" validateConnections="true" doc:name="File" />

<vm:connector name="VM" validateConnections="true" doc:name="VM">
    <receiver-threading-profile maxThreadsActive="1"></receiver-threading-profile>
</vm:connector>

<flow name="fileaggreFlow2" doc:name="fileaggreFlow2">
    <file:inbound-endpoint path="G:\SourceDir" moveToDirectory="g:\SourceDir\Archive" connector-ref="File1" doc:name="get-working-files"                            
             responseTimeout="10000" pollingFrequency="5000" fileAge="600000" >
        <file:filename-regex-filter pattern="DTL(.*).dat|SUM(.*).dat" caseSensitive="false"/>
    </file:inbound-endpoint>

    <message-properties-transformer overwrite="true" doc:name="Message Properties">
        <add-message-property key="MULE_CORRELATION_ID" value="#[message.inboundProperties.originalFilename.substring(5, message.inboundProperties.originalFilename.lastIndexOf('.'))]"/>
        <add-message-property key="MULE_CORRELATION_GROUP_SIZE" value="2"/>
        <add-message-property key="MULE_CORRELATION_SEQUENCE" value="#[message.inboundProperties.originalFilename.substring(5, message.inboundProperties.originalFilename.lastIndexOf('.'))]"/>       
    </message-properties-transformer>

    <vm:outbound-endpoint exchange-pattern="one-way" path="Merge" doc:name="VM" connector-ref="VM"/>
</flow>


<flow name="fileaggreFlow1" doc:name="fileaggreFlow1" processingStrategy="synchronous">
    <vm:inbound-endpoint exchange-pattern="one-way" path="Merge" doc:name="VM" connector-ref="VM"/>

    <processor-chain doc:name="Processor Chain">
        <collection-aggregator timeout="1000000" failOnTimeout="true" doc:name="Collection Aggregator"/>

        <foreach doc:name="For Each">
            <file:outbound-endpoint path="G:\DestDir1" outputPattern="#[function:datestamp:yyyyMMdd.HHmmss].#[message.inboundProperties.originalFilename]" responseTimeout="10000" connector-ref="File1" doc:name="Destination"/>
        </foreach>
    </processor-chain>

如果所有集合都已完成,则正确地按顺序处理找到的集合。它正确地等待不完整的集合填充,但不保存以下集合,即在上面的示例中,集合20150703将处理,而20150701仍在等待DTL文件

是否存在一个设置或另一个构造,如果存在未完成的早期集合,该设置或构造将强制集合聚合器元素等待?


我将文件名的日期部分用于关联ID和序列ID,如果所有集合都已完成,则该ID将控制按我希望的顺序设置进程。如果日期不存在(如本例中的20150702),则不重要,只需按顺序处理现有文件,并且集合必须完整。

最后,我无法让集合聚合器执行此操作。为了克服这个问题,我构建了一个Java类,其中包含SUM和DTL文件的映射,相关ID作为键,以及打开键的排序列表

然后,Java类在最小的键上监视一个完整的集合,并在该集合可用于处理时向Mule流发回信号

在处理文件时,Mule流必须处于同步模式,以防止出现数据争用情况。完成后,它向Java类发出信号,表示处理已完成,可以从列表/映射中删除该数据集,并接收返回的指示,指示下一个数据集是否已准备好处理


它不是最漂亮的,我本不想为此使用自定义功能,但它完成了任务。

最后,我无法让集合聚合器完成此任务。为了克服这个问题,我构建了一个Java类,其中包含SUM和DTL文件的映射,相关ID作为键,以及打开键的排序列表

然后,Java类在最小的键上监视一个完整的集合,并在该集合可用于处理时向Mule流发回信号

在处理文件时,Mule流必须处于同步模式,以防止出现数据争用情况。完成后,它向Java类发出信号,表示处理已完成,可以从列表/映射中删除该数据集,并接收返回的指示,指示下一个数据集是否已准备好处理

它不是最漂亮的,我本不希望使用自定义功能,但它完成了任务