Mule 集合聚合器上的动态超时

Mule 集合聚合器上的动态超时,mule,Mule,我需要使用消息头中传递的超时值作为集合聚合器的值 <collection-aggregator timeout="#[new Integer(header:SESSION:TIMEOUT)]" failOnTimeout="false" doc:name="Collection Aggregator"/> 我试着把它转换成一个数字,但它不接受。有人能举个例子说明我会怎么做吗 Mule配置 <flow name="workIn"> <http:in

我需要使用消息头中传递的超时值作为集合聚合器的值

<collection-aggregator timeout="#[new Integer(header:SESSION:TIMEOUT)]"    failOnTimeout="false" doc:name="Collection Aggregator"/>

我试着把它转换成一个数字,但它不接受。有人能举个例子说明我会怎么做吗

Mule配置

<flow name="workIn">
    <http:inbound-endpoint exchange-pattern="request-response" address="http://localhost:5455/SQSearcher" doc:name="HTTP">
        <cxf:jaxws-service serviceClass="com.ace.st.tf.web.ws.sq.ISQSearcher" doc:name="SQ Searcher"/>
        <message-properties-transformer scope="session">
            <add-message-property value="1" key="DOBSearch" />
        </message-properties-transformer>
    </http:inbound-endpoint>

    <logger message="SQSearcher Inbound Payload-&gt; #[payload]" level="INFO" doc:name="Logger"/>       

    <message-properties-transformer scope="session">
        <add-message-property value="#[new Integer(payload.getTimeout())]" key="TIMEOUT" />                 
    </message-properties-transformer>

    <custom-transformer class="com.ace.st.tf.web.ws.sq.transformer.CCDMessageTransformer" doc:name="Java"/>

    <request-reply storePrefix="workStore" doc:name="Put message for processing">
        <vm:outbound-endpoint path="dispatchIn">
            <message-properties-transformer scope="outbound">
                <delete-message-property key="MULE_REPLYTO" />
                <add-message-property value="#[message:id]" key="MULE_CORRELATION_ID" />                    
            </message-properties-transformer>
        </vm:outbound-endpoint>

        <vm:inbound-endpoint path="dispatchOut" />
    </request-reply>

    <custom-transformer class="com.ace.st.tf.web.ws.sq.transformer.CcdSearchResultTransformer" doc:name="Java"/>

</flow>

<flow name="workDispatcher">
    <vm:inbound-endpoint path="dispatchIn" />
    <flow-ref name="workWorker" />
</flow>

<flow name="workWorker">        

    <message-properties-transformer scope="outbound" doc:name="Remember correlation">
        <add-message-property value="#[header:OUTBOUND:MULE_CORRELATION_ID]" key="MULE_CORRELATION_ID" />
        <add-message-property value="2" key="MULE_CORRELATION_GROUP_SIZE" />
    </message-properties-transformer>

    <all>
        <vm:outbound-endpoint path="vm.flow.1"/>
        <vm:outbound-endpoint path="vm.flow.2"/>
    </all>

</flow>

<flow name="workAggregator">
    <vm:inbound-endpoint path="vm.aggregate" />
    <logger message="payload to aggregate-&gt; #[payload]" level="INFO" doc:name="Logger"/>     
    <custom-aggregator class="com.ace.st.tf.web.ws.sq.aggregator.CustomAggregator" storePrefix="header:SESSION:TIMEOUT" failOnTimeout="false"/>
    <logger message="Aggregated Payload-&gt; #[payload]" level="INFO" doc:name="Logger"/>
    <vm:outbound-endpoint path="dispatchOut" />
</flow>

<flow name="CCDClient" doc:name="CCDClient">
    <vm:inbound-endpoint path="vm.flow.1" doc:name="VM"/>
    <logger message="CCDClient correlation id inbound-&gt; #[header:OUTBOUND:MULE_CORRELATION_GROUP_SIZE]" level="INFO" doc:name="Logger"/>

    <choice doc:name="Choice">
        <when expression="header:SESSION:DOBSearch=1">
            <outbound-endpoint address="http://localhost:4723/CcdSearcher" doc:name="Generic">
                <cxf:jaxws-client clientClass="com.ace.st.tf.web.ws.sq.ccd.client.CcdSearcher_Service" port="CcdSearcherPort" wsdlLocation="classpath:CcdSearcher.wsdl" operation="searchByNameDob"/>
            </outbound-endpoint>
        </when>
        <otherwise>
            <expression-component doc:name="set error message">payload="NOT A DOB SEARCH"</expression-component>
        </otherwise>
    </choice>
    <vm:outbound-endpoint path="vm.aggregate" doc:name="VM">
        <message-properties-transformer scope="outbound">
            <add-message-property value="#[header:INBOUND:MULE_CORRELATION_ID]" key="MULE_CORRELATION_ID" />
            <add-message-property value="#[header:INBOUND:MULE_CORRELATION_GROUP_SIZE]" key="MULE_CORRELATION_GROUP_SIZE" />
        </message-properties-transformer>
    </vm:outbound-endpoint>
</flow>

<flow name="ATspCisClient" doc:name="ATspCisClient">
    <vm:inbound-endpoint path="vm.flow.2" doc:name="VM"/>
    <choice doc:name="Choice">
        <when expression="header:SESSION:DOBSearch=1">
            <outbound-endpoint address="http://localhost:4724/ATspCisSearcher" doc:name="Generic">
                <cxf:jaxws-client clientClass="com.ace.st.tf.web.ws.sq.atspcis.client.AtspcisSearcher_Service" port="AtspcisSearcherPort" wsdlLocation="classpath:ATspCisSearcher.wsdl" operation="atspSearchByNameDob"/>
            </outbound-endpoint>
        </when>
        <otherwise>
            <expression-component doc:name="set error message">payload="NOT A DOB SEARCH"</expression-component>
        </otherwise>
    </choice>
    <vm:outbound-endpoint path="vm.aggregate" doc:name="VM">
        <message-properties-transformer scope="outbound">
            <add-message-property value="#[header:INBOUND:MULE_CORRELATION_ID]" key="MULE_CORRELATION_ID" />
            <add-message-property value="#[header:INBOUND:MULE_CORRELATION_GROUP_SIZE]" key="MULE_CORRELATION_GROUP_SIZE" />
        </message-properties-transformer>
    </vm:outbound-endpoint>
</flow>

有效载荷=“不是DOB搜索”
有效载荷=“不是DOB搜索”
客户聚合器

public class CustomAggregator extends SimpleCollectionAggregator 
{

public String getStorePrefix() {
    return super.getStorePrefix();
}

public void setStorePrefix(String storePrefix) {
    super.setStorePrefix(storePrefix);
}

@Override
protected EventCorrelatorCallback getCorrelatorCallback(MuleContext muleContext) {

    return new CollectionCorrelatorCallback(muleContext,false,storePrefix) {
        @Override
        public MuleEvent aggregateEvents(EventGroup events) throws AggregationException {
            try {
                for (Iterator<MuleEvent> iterator = events.iterator(); iterator.hasNext();) {
                    MuleEvent event = iterator.next();
                    Object result = muleContext.getExpressionManager().evaluate("header:SESSION:TIMEOUT",event.getMessage());
                    setTimeout((java.lang.Integer)result);
                }
            }
            catch (ObjectStoreException e) {
                throw new AggregationException(events,null,e);
            }
            //return new DefaultMuleEvent(new DefaultMuleMessage(buffer.toString(), muleContext), events.getMessageCollectionEvent());
            return super.aggregateEvents(events);
        }
    };
}
}
公共类CustomAggregator扩展了SimpleCollectionAggregator
{
公共字符串getStorePrefix(){
返回super.getStorePrefix();
}
public void setStorePrefix(字符串storePrefix){
super.setStorePrefix(storePrefix);
}
@凌驾
受保护的事件CorrelatorCallback getCorrelatorCallback(MuleContext MuleContext){
返回新的CollectionCorrelatorCallback(muleContext、false、storePrefix){
@凌驾
公共多事件聚合事件(事件组事件)引发AggregationException{
试一试{
for(Iterator Iterator=events.Iterator();Iterator.hasNext();){
MuleEvent event=iterator.next();
对象结果=muleContext.getExpressionManager().evaluate(“头:会话:超时”,event.getMessage());
setTimeout((java.lang.Integer)结果);
}
}
捕获(ObjectStoreException e){
抛出新的AggregationException(事件,null,e);
}
//返回新的DefaultMuleEvent(新的DefaultMuleMessage(buffer.toString(),muleContext),events.getMessageCollectionEvent());
返回super.aggregateEvents(事件);
}
};
}
}

从我在代码库中看到的情况来看,
超时似乎不支持表达式

您必须通过扩展
org.mule.routing.SimpleCollectionAggregator
,覆盖
getTimeout()
并使用
引用它来创建自己的自定义聚合器

不幸的是,尽管有着激烈的骡夫式的战斗,我还是无法做到以下几点:

public class CustomAggregator extends SimpleCollectionAggregator
{
    private String timeoutExpression;

    public String getTimeoutExpression()
    {
        return timeoutExpression;
    }

    public void setTimeoutExpression(final String timeoutExpression)
    {
        this.timeoutExpression = timeoutExpression;
    }

    @Override
    public void initialise() throws InitialisationException
    {
        super.initialise();

        eventCorrelator = new EventCorrelator(getCorrelatorCallback(muleContext), next, messageInfoMapping,
            muleContext, flowConstruct.getName(), persistentStores, storePrefix)
        {
            @Override
            public long getTimeout()
            {
                return (Long) muleContext.getExpressionLanguage().evaluate(getTimeoutExpression(),
                    RequestContext.getEvent());
            }
        };
    }
}
配置有:

    <custom-aggregator class="com.helloworld.CustomAggregator" timeout="60000">
        <spring:property name="timeoutExpression" value="#[Integer.valueOf(sessionVars.TIMEOUT)]" />
    </custom-aggregator>

原因是负责获取过期关联组的线程看不到当前Mule事件上下文,因此无法基于动态属性计算任何内容


因此,虽然可以彻底检修
expiringgroupmonitoringread
机制以使用动态值,但我认为这是不可行的,现在应该被认为是“不可能的”。

我创建了一个自定义聚合器,但是当我传递Mule表达式时,我得到了NumberFormatException。它似乎没有评估它。原因:java.lang.NumberFormatException:对于输入字符串:“[T(java.lang.Integer).parseInt(头:会话:超时)]”导入org.mule.routing.SimpleCollectionAggregator;公共类CustomAggregator扩展SimpleCollectionAggregator{private String timeout;public void setTimeout(String timeout){super.setTimeout(Long.parseLong(timeout));}}}}您可以使用Mule上下文中的表达式计算器对接收到的表达式求值。另外,请更新您的原始问题,而不是在评论中发布不可读的代码。很抱歉在此处发布代码..我在Mule服务器上运行配置时遇到此错误。据我所知,我认为它会抱怨在需要数字时传递给timeout属性的字符串值。因此,该值不会传递给聚合器。然后将其传递给另一个属性。请在原始问题中分享您当前的代码和Mule配置,以便我们能更好地帮助您。David,我找到了另一种可行的方法。我更新了ExpiringGroupMonitoringRead以直接从会话获取超时,而不必计算表达式!你用的是什么骡子版本?