在 mule esb 中使用 drools 时如何动态替换 .drl 文件?

How to replace .drl file dynamically while using drools in mule esb?

我需要的是动态替换 .drl 文件。通过一些讨厌的代码,我能够加载 .drl 文件并更改内容,但似乎 drools 保留了它的初始文件。

这些是我的配置文件(以防万一):

骡子-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:http="http://www.mulesoft.org/schema/mule/http"
    xmlns="http://www.mulesoft.org/schema/mule/core"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:spring="http://www.springframework.org/schema/beans"
      xmlns:quartz="http://www.mulesoft.org/schema/mule/quartz"
      xmlns:vm="http://www.mulesoft.org/schema/mule/vm"
      xmlns:jms="http://www.mulesoft.org/schema/mule/jms"
      xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting"
      xmlns:bpm="http://www.mulesoft.org/schema/mule/bpm"
      xmlns:client="http://www.mulesoft.org/schema/mule/client"

        xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" 
        xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
        xmlns:context="http://www.springframework.org/schema/context"   
        xmlns:management="http://www.mulesoft.org/schema/mule/management"


    xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd 
        http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/3.2/mule.xsd
        http://www.mulesoft.org/schema/mule/quartz http://www.mulesoft.org/schema/mule/quartz/3.2/mule-quartz.xsd
        http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/3.2/mule-vm.xsd
        http://www.mulesoft.org/schema/mule/jms http://www.mulesoft.org/schema/mule/jms/3.2/mule-jms.xsd
        http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/3.2/mule-scripting.xsd
        http://www.mulesoft.org/schema/mule/bpm http://www.mulesoft.org/schema/mule/bpm/3.2/mule-bpm.xsd
        http://www.mulesoft.org/schema/mule/client http://www.mulesoft.org/schema/mule/client/3.2/mule-client.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

    http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.mulesoft.org/schema/mule/management http://www.mulesoft.org/schema/mule/management/current/mule-management.xsd

        ">

    <bpm:jbpm /> 
    <bpm:drools />    

    <!-- Define EMC Routing facts bean -->
    <spring:bean name="NoFactsBean" class="java.util.ArrayList"/>

    <jms:activemq-connector 
                    name="jms-connector"                     
                    brokerURL="tcp://localhost:61616" 
                    disableTemporaryReplyToDestinations="true"
                    specification="1.1"/>

    <jms:endpoint name="UnsortedOrders" queue="UnsortedOrders"/>                
    <jms:endpoint name="DestinationEMC" queue="DestinationEMC"/>                
    <jms:endpoint name="DestinationOriginal" queue="DestinationOriginal"/>                

    <vm:endpoint name="DroolsEndpoint" path="drools"/>

   <!-- GOLI --> 
   <spring:beans>
        <spring:bean id="dto-convertor" class="com.hamgam.hit.esb.XMLToDTO" scope="singleton" />
        <spring:bean id="rule-convertor" class="com.hamgam.hit.esb.RuleXMLToDRL" scope="singleton" />           
    </spring:beans>
    <http:listener-config name="HTTP_Listener" host="localhost" port="8084" doc:name="HTTP Listener Configuration" />
    <!-- /GOLI --> 

    <flow name="RestEtryPoint">
        <http:listener config-ref="HTTP_Listener" path="/{name}" doc:name="HTTP" />
        <set-variable variableName="name" value="#[message.inboundProperties['http.uri.params']['name']]" />        
        <set-variable variableName="msg" value="#[payload]"/>
        <expression-component>
            app.registry['dto'] = app.registry['dto-convertor'].convert(flowVars['name']);
        </expression-component>
        <set-payload value="#[app.registry['dto']]"/>                    
        <jms:outbound-endpoint ref="UnsortedOrders"/>
        <logger level="INFO" doc:name="Logger" message="***************Entry***************" />         

    </flow>                    

    <flow name="jBPMProcess">
        <composite-source>
            <vm:inbound-endpoint path="in" exchange-pattern="request-response"/>
            <jms:inbound-endpoint ref="UnsortedOrders"/>
        </composite-source>  
        <!-- TODO streaming="false"Transform XML to object -->
        <bpm:process processName="DecisionRouting" processDefinition="routing-process.jpdl.xml"/>    
        <logger level="INFO" doc:name="Logger" message="***************JBPM Process***************" />                                                                       
    </flow>

    <flow name="DroolsFlow">
        <vm:inbound-endpoint ref="DroolsEndpoint" exchange-pattern="request-response"/>
        <bpm:rules rulesDefinition="emcRoutingRules.drl" initialFacts-ref="NoFactsBean" />
        <expression-transformer evaluator="groovy" expression="message.getPayload().getObject()"/>
        <logger level="INFO" doc:name="Logger" message="***************Drools Flow***************" />

    </flow> 


     <flow name="ConsumeEmcQ">
        <jms:inbound-endpoint ref="DestinationEMC"/>
        <logger level="INFO" doc:name="Logger" message="*************Consume Q4 DestinationEMC*****************" />

        <logger level="INFO" doc:name="Logger" message="#[payload]" />              
    </flow>
    <flow name="ConsumeOrigQ">
        <jms:inbound-endpoint ref="DestinationOriginal"/>
        <logger level="INFO" doc:name="Logger" message="*************Consume Q4 DestinationOriginal*****************" />                   
    </flow>


</mule>

这是路由-process.jpdl.xml:

<?xml version="1.0" encoding="UTF-8"?>

<process description="routing example" name="DecisionRouting" xmlns="http://jbpm.org/4.3/jpdl">

    <mule-receive name="unsortedOrder" endpoint="UnsortedOrders" type="com.hamgam.hit.esb.XMLDTO" var="order">
        <transition to="sendToDrools" />
    </mule-receive>

    <mule-send name="sendToDrools" expr="#{order}" endpoint="DroolsEndpoint" exchange-pattern="request-response" var="order">
        <transition to="defineDestination" />
    </mule-send>

    <decision name="defineDestination">
        <transition to="sendToEMC">
            <condition expr="#{order.destination == 'EMC'}" />
        </transition>
        <transition to="sendToOriginalDest">
            <condition expr="#{order.destination == 'ORIG'}" />
        </transition>

        <transition to="routingFailed" />
    </decision>

    <mule-send name="sendToEMC"
          expr="#{order}" endpoint="DestinationEMC" exchange-pattern="one-way">
        <transition to="routingSuccessful" />
    </mule-send>

    <mule-send name="sendToOriginalDest"
          expr="#{order}" endpoint="DestinationOriginal" exchange-pattern="one-way">
        <transition to="routingSuccessful" />
    </mule-send>

    <end name="routingSuccessful" />

    <end name="routingFailed" />

</process>

这是最初放在资源文件夹中的 emcRoutingRules.drl :

package com.hamgam.hit.esb

import com.hamgam.hit.esb.*; 
import org.mule.MessageExchangePattern

global org.mule.module.bpm.MessageService mule;

# default dialect for the semantic code will be MVEL
dialect "mvel"

declare XMLDTO
    @role( event )
end 

rule "Select Emc"
    lock-on-active

when
     $x:XMLDTO(inputXML == "moien")    
then
   modify( $x ) { setDestination("EMC") }
end

rule "Select Original Destination"
    lock-on-active

when
    $x:XMLDTO( inputXML == "goli" )
then
   modify( $x ) { setDestination("ORIG") }
end

这就是我替换 .drl 文件的方式:

private void generateFile(String rule) throws IOException{
PrintWriter writer;
try {
    ClassLoader classLoader = RuleXMLToDRL.class.getClassLoader();
    File file =
      new File(classLoader.getResource("emcRoutingRules.drl").getFile());
    writer = new PrintWriter(file, "UTF-8");
    writer.println(""
            + "package com.hamgam.hit.esb "
            + "import com.hamgam.hit.esb.*; "
            + "import org.mule.MessageExchangePattern "
            + "global org.mule.module.bpm.MessageService mule; "
            + "dialect \"mvel\" declare XMLDTO @role( event ) end");
    writer.println(rule);
    writer.close();
} catch (FileNotFoundException | UnsupportedEncodingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
}

我并不骄傲,但我想出了一个黑客解决方案:

正如我之前提到的,对 mule-config.xml 文件的任何更改都会导致 mule 重建,因此在更改 .drl 文件后,我也对 mule-config.xml 文件进行了虚拟更改。

        PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("mule-config.xml", true)));
        out.println("<!-- -->");
        out.flush();

请注意,如果您从 Anypoint studio 吃午饭,该解决方案将不起作用。但是将它部署在 mule standalone 中并且它会工作。

直到我找到更好的解决方案,这个工作得很好;)