2011-05-03 12 views
8

Antecedentes:¿Cómo agrego datos a la memoria de trabajo en tiempo de ejecución en el DRL Drools y los recupero en los resultados de ejecución de una sesión sin estado?

Estoy trabajando en una aplicación que transforma un objeto de entrada en uno de dos objetos de salida en base a un conjunto de reglas Drools. El objeto de salida no se conoce hasta el tiempo de ejecución y se crea en la primera regla para ejecutar.

Esta es la regla que crea el objeto de salida y una regla de ejemplo de transformación:

rule "Initialization" 
    dialect "java" 
    salience 1000 
    no-loop true 
    when 
     t : Trade() 
    then 
     if(t.getTran().getInsType().equalsIgnoreCase("EEO") || 
      t.getTran().getInsType().equalsIgnoreCase("EEF")) 
     { 
      insert(new Option()); 
     } 
     else 
     { 
      insert(new Swap()); 
     } 
end 

rule "Example Rule" 
    dialect "java" 
    when 
     t : Trade() 
     opt : Option() 
    then 
     opt.setCounterpartyName(t.getTran().getCParty()); 
end 

Aquí está el código que llama a las reglas:

private void test(){ 
    for(File xmlFile : getXmlFilesFromDirectory(XML_DIRECTORY)) 
    { 
     Trade trade = (Trade)unmarshall(xmlFile, Trade.class); 

     KnowledgeBase kbase = readKnowledgeBase(); 

     StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession(); 
     KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newConsoleLogger(ksession); 

     List<Command> commands = new ArrayList<Command>(); 
     commands.add(CommandFactory.newInsert(trade, "trade")); 
     commands.add(CommandFactory.newFireAllRules()); 

     ExecutionResults results = ksession.execute(CommandFactory.newBatchExecution(commands)); 
     logger.close(); 
    } 
} 

private static KnowledgeBase readKnowledgeBase() throws Exception 
{ 
    KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); 
    kbuilder.add(ResourceFactory.newClassPathResource("security-transformation.drl"), ResourceType.DRL); 
    KnowledgeBuilderErrors errors = kbuilder.getErrors(); 
    if (errors.size() > 0) 
    { 
     for (KnowledgeBuilderError error: errors) 
     { 
      System.err.println(error); 
     } 

     throw new IllegalArgumentException("Could not parse knowledge."); 
    } 

    KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); 
    kbase.addKnowledgePackages(kbuilder.getKnowledgePackages()); 
    return kbase; 
} 

Problema:

Cuando ejecuto las reglas, no recibo el objeto de salida en mis datos devueltos. Recibo el objeto comercial nuevamente pero no recupero la opción o el objeto Swap dependiendo de cuál se haya agregado a la memoria operativa según la primera regla.

Pregunta:

¿Cómo agrego hechos a la memoria de trabajo en tiempo de ejecución en el drl y recuperarlos en los resultados de la ejecución de una sesión sin estado?

EDITAR: ¿Debo utilizar una consulta de drools?

+0

FaVoR suugest sobre esta cuestión. Gracias. http://stackoverflow.com/questions/20158726/dialect-error-message-drool – Kumar

Respuesta

10

Seguí y usé una consulta de drools. Publicaré el código para cualquier otra persona que aparezca.

de consulta añade a las reglas anteriores (Los objetos se extienden BaseTrade):

query "GetOutputObj" 
    baseTrade: BaseTrade() 
end 

código para recuperar los resultados de la consulta a partir de los resultados de la ejecución:

StatelessKnowledgeSession ksession = this.kbase.newStatelessKnowledgeSession(); 

    KnowledgeRuntimeLogger klogger = configureKnowledgeRuntimeLogger(ksession); 

    List<Command> commands = new ArrayList<Command>(); 
    commands.add(CommandFactory.newInsert(inputObj, "inputObj")); 
    commands.add(CommandFactory.newFireAllRules()); 
    commands.add(CommandFactory.newQuery("outputObj", "GetOutputObj")); 

    ExecutionResults results = ksession.execute(CommandFactory.newBatchExecution(commands)); 

    QueryResults queryResults = ((NativeQueryResults)results.getValue("baseTrade")).getResults(); 

    try 
    { 
     Iterator iter = queryResults.iterator(); 
     while(iter.hasNext()) 
     { 
      QueryResult result = iter.next(); 

      //There can be only one... just like Highlander 
      //Could switch this up and return a list, but we only expect one thing from here. 
      return (BaseTrade) result.get("baseTrade"); 
     } 
    } 
    finally 
    { 
     if(klogger != null) 
     { 
      klogger.close(); 
     } 
    } 
+0

Gracias por la valiosa publicación @gwhitake. Solo edité una parte de la solución para que quede claro para los primeros temporizadores. Recupere el objeto con el identificador. Use "outputObj" en lugar de "baseTrade". QueryResults queryResults = ((NativeQueryResults) results.getValue ("outputObj")). GetResults(); –

Cuestiones relacionadas