/* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jbpm.integrationtests; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.List; import org.drools.core.command.runtime.rule.FireAllRulesCommand; import org.drools.core.definitions.rule.impl.RuleImpl; import org.drools.core.event.DebugProcessEventListener; import org.jbpm.test.util.AbstractBaseTest; import org.junit.Test; import org.kie.api.command.Command; import org.kie.api.definition.type.FactType; import org.kie.api.event.rule.DebugAgendaEventListener; import org.kie.api.io.ResourceType; import org.kie.api.runtime.KieSession; import org.kie.api.runtime.rule.AgendaFilter; import org.kie.api.runtime.rule.Match; import org.kie.internal.KnowledgeBase; import org.kie.internal.KnowledgeBaseFactory; import org.kie.internal.builder.KnowledgeBuilder; import org.kie.internal.builder.KnowledgeBuilderFactory; import org.kie.internal.command.CommandFactory; import org.kie.internal.definition.KnowledgePackage; import org.kie.internal.io.ResourceFactory; import org.kie.internal.runtime.StatefulKnowledgeSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class AgendaFilterTest extends AbstractBaseTest { private static final Logger logger = LoggerFactory.getLogger(AgendaFilterTest.class); @Test public void testAgendaFilter() { // JBRULES-3374 String drl = "package org.drools\n" + " \n" + "import org.jbpm.integrationtests.AgendaFilterTest.Message\n" + " \n" + "rule \"R1\"\n" + "ruleflow-group \"node1\"\n" + "no-loop \n" + "salience 3\n" + " when\n" + " Message( status == Message.GOODBYE, myMessage : message )\n" + " then\n" + " System.out.println( \"R1\" );\n" + "end\n" + "\n" + "rule \"R2\"\n" + "ruleflow-group \"node1\"\n" + "no-loop \n" + "salience 2\n" + " when\n" + " m : Message( status == Message.HELLO, myMessage : message )\n" + " then\n" + " System.out.println( \"R2\" );\n" + " m.setMessage( \"Goodbye cruel world\" );\n" + " m.setStatus( Message.GOODBYE );\n" + " update( m );\n" + "end\n" + "\n" + "rule \"R3\"\n" + "ruleflow-group \"node2\"\n" + "no-loop \n" + " when\n" + " m: Message( status == Message.GOODBYE, myMessage : message )\n" + " then\n" + " System.out.println( \"R3\" );\n" + " m.setStatus(5);\n" + " update (m);\n" + " \n" + "end"; String rf = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> \n" + "<process xmlns=\"http://drools.org/drools-5.0/process\"\n" + " xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\"\n" + " xs:schemaLocation=\"http://drools.org/drools-5.0/process drools-processes-5.0.xsd\"\n" + " type=\"RuleFlow\" name=\"flow\" id=\"process-test\" package-name=\"com.sample\" >\n" + "\n" + " <header>\n" + " </header>\n" + "\n" + " <nodes>\n" + " <start id=\"1\" name=\"Start\" x=\"122\" y=\"96\" width=\"48\" height=\"48\" />\n" + " <ruleSet id=\"2\" name=\"Node1\" x=\"277\" y=\"96\" width=\"80\" height=\"48\" ruleFlowGroup=\"node1\" />\n" + " <ruleSet id=\"3\" name=\"Node2\" x=\"433\" y=\"98\" width=\"80\" height=\"48\" ruleFlowGroup=\"node2\" />\n" + " <end id=\"4\" name=\"End\" x=\"645\" y=\"96\" width=\"48\" height=\"48\" />\n" + " </nodes>\n" + "\n" + " <connections>\n" + " <connection from=\"1\" to=\"2\" />\n" + " <connection from=\"2\" to=\"3\" />\n" + " <connection from=\"3\" to=\"4\" />\n" + " </connections>\n" + "\n" + "</process>"; KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); kbuilder.add( ResourceFactory.newByteArrayResource(drl.getBytes()), ResourceType.DRL ); kbuilder.add( ResourceFactory.newByteArrayResource(rf.getBytes()), ResourceType.DRF ); if ( kbuilder.hasErrors() ) { fail( kbuilder.getErrors().toString() ); } KieSession ksession = createKieSession(kbuilder.getKnowledgePackages().toArray(new KnowledgePackage[0])); // go ! Message message = new Message(); message.setMessage("Hello World"); message.setStatus(Message.HELLO); ksession.insert(message); ksession.startProcess("process-test"); assertEquals("Goodbye cruel world", message.getMessage()); } public static class Message { public static final int HELLO = 0; public static final int GOODBYE = 1; private String message; private int status; public String getMessage() { return this.message; } public void setMessage(String message) { this.message = message; } public int getStatus() { return this.status; } public void setStatus(int status) { this.status = status; } } public static class SalienceFilter implements AgendaFilter { private Integer currentSalience = null; public boolean accept(Match activation) { RuleImpl rule = (RuleImpl)activation.getRule(); if (currentSalience == null){ currentSalience = rule.getSalience() != null ? Integer.valueOf(rule.getSalience().toString()) : 0; } boolean nocancel = currentSalience >= Integer.valueOf(rule.getSalience().toString()); if(!nocancel){ logger.info("cancelling -> {}", rule.getName()); } return nocancel; } } @Test public void testActivationCancelled() { // JBRULES-3376 String drl = "package org.jboss.qa.brms.agendafilter\n" + "declare CancelFact\n" + " cancel : boolean = true\n" + "end\n" + "rule NoCancel\n" + " ruleflow-group \"rfg\"\n" + " when\n" + " $fact : CancelFact ( cancel == false )\n" + " then\n" + " System.out.println(\"No cancel...\");\n" + " modify ($fact) {\n" + " setCancel(true);\n" + " }\n" + "end\n" + "rule PresenceOfBothFacts\n" + " ruleflow-group \"rfg\"\n" + " salience -1\n" + " when\n" + " $fact1 : CancelFact( cancel == false )\n" + " $fact2 : CancelFact( cancel == true )\n" + " then\n" + " System.out.println(\"Both facts!\");\n" + "end\n" + "rule PresenceOfFact\n" + " ruleflow-group \"rfg\"\n" + " when\n" + " $fact : CancelFact( )\n" + " then\n" + " System.out.println(\"We have a \" + ($fact.isCancel() ? \"\" : \"non-\") + \"cancelling fact!\");\n" + "end\n" + "rule Cancel\n" + " ruleflow-group \"rfg\"\n" + " when\n" + " $fact : CancelFact ( cancel == true )\n" + " then\n" + " System.out.println(\"Cancel!\");\n" + "end"; String rf = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> \n" + "<process xmlns=\"http://drools.org/drools-5.0/process\"\n" + " xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\"\n" + " xs:schemaLocation=\"http://drools.org/drools-5.0/process drools-processes-5.0.xsd\"\n" + " type=\"RuleFlow\" name=\"flow\" id=\"bz761715\" package-name=\"org.jboss.qa.brms.agendafilter\" >\n" + " <header>\n" + " </header>\n" + " <nodes>\n" + " <start id=\"1\" name=\"Start\" x=\"16\" y=\"16\" width=\"48\" height=\"48\" />\n" + " <ruleSet id=\"2\" name=\"Rule\" x=\"208\" y=\"16\" width=\"80\" height=\"48\" ruleFlowGroup=\"rfg\" />\n" + " <actionNode id=\"3\" name=\"Script\" x=\"320\" y=\"16\" width=\"80\" height=\"48\" >\n" + " <action type=\"expression\" dialect=\"java\" >System.out.println(\"Finishing process...\");</action>\n" + " </actionNode>\n" + " <end id=\"4\" name=\"End\" x=\"432\" y=\"16\" width=\"48\" height=\"48\" />\n" + " <actionNode id=\"5\" name=\"Script\" x=\"96\" y=\"16\" width=\"80\" height=\"48\" >\n" + " <action type=\"expression\" dialect=\"java\" >System.out.println(\"Starting process...\");</action>\n" + " </actionNode>\n" + " </nodes>\n" + " <connections>\n" + " <connection from=\"5\" to=\"2\" />\n" + " <connection from=\"2\" to=\"3\" />\n" + " <connection from=\"3\" to=\"4\" />\n" + " <connection from=\"1\" to=\"5\" />\n" + " </connections>\n" + "</process>"; KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); kbuilder.add( ResourceFactory.newByteArrayResource(drl.getBytes()), ResourceType.DRL ); kbuilder.add( ResourceFactory.newByteArrayResource(rf.getBytes()), ResourceType.DRF ); if ( kbuilder.hasErrors() ) { fail( kbuilder.getErrors().toString() ); } KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() ); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); ksession.addEventListener(new DebugAgendaEventListener()); ksession.addEventListener(new DebugProcessEventListener()); List<Command<?>> commands = new ArrayList<Command<?>>(); commands.add(CommandFactory.newInsert(newCancelFact(ksession, false))); commands.add(CommandFactory.newInsert(newCancelFact(ksession, true))); commands.add(CommandFactory.newStartProcess("bz761715")); commands.add(new FireAllRulesCommand(new CancelAgendaFilter())); commands.add(new FireAllRulesCommand(new CancelAgendaFilter())); commands.add(new FireAllRulesCommand(new CancelAgendaFilter())); ksession.execute(CommandFactory.newBatchExecution(commands)); } private Object newCancelFact(StatefulKnowledgeSession ksession, boolean cancel) { FactType type = ksession.getKieBase().getFactType("org.jboss.qa.brms.agendafilter", "CancelFact"); Object instance = null; try { instance = type.newInstance(); type.set(instance, "cancel", cancel); } catch (IllegalAccessException ex) { ex.printStackTrace(); } catch (InstantiationException ex) { ex.printStackTrace(); } return instance; } public static class CancelAgendaFilter implements AgendaFilter { public boolean accept(Match activation) { return !"Cancel".equals(activation.getRule().getName()); } } @Test public void testGetListeners() { // JBRULES-3378 KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); if (kbuilder.hasErrors()) { throw new RuntimeException(kbuilder.getErrors().toString()); } StatefulKnowledgeSession ksession = kbuilder.newKnowledgeBase().newStatefulKnowledgeSession(); ksession.getAgendaEventListeners(); ksession.getProcessEventListeners(); ksession.getRuleRuntimeEventListeners(); ksession.dispose(); } }