/* * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH * under one or more contributor license agreements. See the NOTICE file * distributed with this work for additional information regarding copyright * ownership. Camunda licenses this file to you under the Apache License, * Version 2.0; you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * 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.camunda.bpm.dmn.engine.delegate; import static org.assertj.core.api.Assertions.assertThat; import java.util.List; import java.util.Map; import org.camunda.bpm.dmn.engine.DmnDecisionTableResult; import org.camunda.bpm.dmn.engine.DmnEngineConfiguration; import org.camunda.bpm.dmn.engine.impl.DefaultDmnEngineConfiguration; import org.camunda.bpm.dmn.engine.impl.DmnDecisionTableImpl; import org.camunda.bpm.dmn.engine.impl.hitpolicy.DefaultHitPolicyHandlerRegistry; import org.camunda.bpm.dmn.engine.impl.spi.hitpolicy.DmnHitPolicyHandler; import org.camunda.bpm.dmn.engine.impl.spi.hitpolicy.DmnHitPolicyHandlerRegistry; import org.camunda.bpm.dmn.engine.test.DecisionResource; import org.camunda.bpm.dmn.engine.test.DmnEngineTest; import org.camunda.bpm.engine.variable.Variables; import org.camunda.bpm.model.dmn.BuiltinAggregator; import org.camunda.bpm.model.dmn.HitPolicy; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; public class DmnDecisionTableEvaluationListenerTest extends DmnEngineTest { public static final String DMN_FILE = "org/camunda/bpm/dmn/engine/delegate/DmnDecisionTableListenerTest.test.dmn"; public static DmnHitPolicyHandlerRegistry hitPolicyHandlerRegistry; public TestDecisionTableEvaluationListener listener; @Override public DmnEngineConfiguration getDmnEngineConfiguration() { return new TestDecisionTableEvaluationListenerConfiguration(); } @BeforeClass public static void initHitPolicyHandlerRegistry() { hitPolicyHandlerRegistry = new DefaultHitPolicyHandlerRegistry(); } @Before public void initListener() { TestDecisionTableEvaluationListenerConfiguration configuration = (TestDecisionTableEvaluationListenerConfiguration) dmnEngine.getConfiguration(); listener = configuration.testDecisionTableListener; } @Test @DecisionResource(resource = DMN_FILE) public void testListenerIsCalled() { evaluateDecisionTable(true, "foo", "hello", "hello"); assertThat(listener.evaluationEvent).isNotNull(); } @Test @DecisionResource(resource = DMN_FILE) public void testExecutedDecisionElements() { // the number should be independent from input and result evaluateDecisionTable(true, "foo", false, "hello"); assertThat(listener.evaluationEvent.getExecutedDecisionElements()).isEqualTo(36); evaluateDecisionTable(false, "bar", true, "hello"); assertThat(listener.evaluationEvent.getExecutedDecisionElements()).isEqualTo(36); evaluateDecisionTable(false, "false", true, "hello"); assertThat(listener.evaluationEvent.getExecutedDecisionElements()).isEqualTo(36); } @Test @DecisionResource(resource = DMN_FILE) public void testInputValues() { evaluateDecisionTable(true, "foo", "test", "hello"); List<DmnEvaluatedInput> inputs = listener.evaluationEvent.getInputs(); assertThat(inputs).hasSize(3); DmnEvaluatedInput input1 = inputs.get(0); assertThat(input1.getId()).isEqualTo("input1"); assertThat(input1.getName()).isEqualTo("Input"); assertThat(input1.getInputVariable()).isEqualTo("cellInput"); assertThat(input1.getValue()).isEqualTo(Variables.untypedValue(true)); DmnEvaluatedInput input2 = inputs.get(1); assertThat(input2.getId()).isEqualTo("input2"); assertThat(input2.getName()).isNull(); assertThat(input2.getInputVariable()).isEqualTo("x"); assertThat(input2.getValue()).isEqualTo(Variables.untypedValue("foo")); DmnEvaluatedInput input3 = inputs.get(2); assertThat(input3.getId()).isEqualTo("input3"); assertThat(input3.getName()).isNull(); assertThat(input3.getInputVariable()).isEqualTo("cellInput"); assertThat(input3.getValue()).isEqualTo(Variables.untypedNullValue()); } @Test @DecisionResource(resource = DMN_FILE) public void testMatchingRules() { evaluateDecisionTable(true, "foo", "test", "hello"); List<DmnEvaluatedDecisionRule> matchingRules = listener.evaluationEvent.getMatchingRules(); assertThat(matchingRules).hasSize(1); DmnEvaluatedDecisionRule matchedRule = matchingRules.get(0); assertThat(matchedRule.getId()).isEqualTo("rule1"); assertThat(matchedRule.getOutputEntries()).hasSize(2); evaluateDecisionTable(true, "bar", "test", "hello"); matchingRules = listener.evaluationEvent.getMatchingRules(); assertThat(matchingRules).hasSize(0); evaluateDecisionTable(false, "bar", "test", "hello"); matchingRules = listener.evaluationEvent.getMatchingRules(); assertThat(matchingRules).hasSize(1); matchedRule = matchingRules.get(0); assertThat(matchedRule.getId()).isEqualTo("rule2"); assertThat(matchedRule.getOutputEntries()).hasSize(1); evaluateDecisionTable(false, "bar", true, "hello"); matchingRules = listener.evaluationEvent.getMatchingRules(); assertThat(matchingRules).hasSize(5); matchedRule = matchingRules.get(0); assertThat(matchedRule.getId()).isEqualTo("rule2"); assertThat(matchedRule.getOutputEntries()).hasSize(1); matchedRule = matchingRules.get(1); assertThat(matchedRule.getId()).isEqualTo("rule3"); assertThat(matchedRule.getOutputEntries()).hasSize(0); matchedRule = matchingRules.get(2); assertThat(matchedRule.getId()).isEqualTo("rule4"); assertThat(matchedRule.getOutputEntries()).hasSize(1); matchedRule = matchingRules.get(3); assertThat(matchedRule.getId()).isEqualTo("rule5"); assertThat(matchedRule.getOutputEntries()).hasSize(1); matchedRule = matchingRules.get(4); assertThat(matchedRule.getId()).isEqualTo("rule6"); assertThat(matchedRule.getOutputEntries()).hasSize(1); } @Test @DecisionResource(resource = DMN_FILE) public void testOutputs() { evaluateDecisionTable(true, "foo", "test", "hello"); List<DmnEvaluatedDecisionRule> matchingRules = listener.evaluationEvent.getMatchingRules(); Map<String, DmnEvaluatedOutput> outputs = matchingRules.get(0).getOutputEntries(); assertThat(outputs).hasSize(2) .containsKeys("out1", "out2"); DmnEvaluatedOutput output1 = outputs.get("out1"); assertThat(output1.getId()).isEqualTo("output1"); assertThat(output1.getName()).isEqualTo("Output 1"); assertThat(output1.getOutputName()).isEqualTo("out1"); assertThat(output1.getValue()).isEqualTo(Variables.untypedValue("hello")); DmnEvaluatedOutput output2 = outputs.get("out2"); assertThat(output2.getId()).isEqualTo("output2"); assertThat(output2.getName()).isNull(); assertThat(output2.getOutputName()).isEqualTo("out2"); assertThat(output2.getValue()).isEqualTo(Variables.untypedValue("camunda")); evaluateDecisionTable(false, "bar", "test", "hello"); matchingRules = listener.evaluationEvent.getMatchingRules(); outputs = matchingRules.get(0).getOutputEntries(); assertThat(outputs).hasSize(1) .containsKeys("out2"); output2 = outputs.get("out2"); assertThat(output2.getId()).isEqualTo("output2"); assertThat(output2.getName()).isNull(); assertThat(output2.getOutputName()).isEqualTo("out2"); assertThat(output2.getValue()).isEqualTo(Variables.untypedValue("camunda")); } @Test @DecisionResource(resource = DMN_FILE) public void testCollectResult() { setDecisionTableHitPolicy(HitPolicy.COLLECT, null); evaluateDecisionTable(true, "bar", true, "hello"); assertThat(listener.evaluationEvent.getCollectResultName()).isNull(); assertThat(listener.evaluationEvent.getCollectResultValue()).isNull(); List<DmnEvaluatedDecisionRule> matchingRules = listener.evaluationEvent.getMatchingRules(); assertThat(matchingRules).hasSize(4); assertThat(matchingRules.get(0).getId()).isEqualTo("rule3"); assertThat(matchingRules.get(1).getId()).isEqualTo("rule4"); assertThat(matchingRules.get(2).getId()).isEqualTo("rule5"); assertThat(matchingRules.get(3).getId()).isEqualTo("rule6"); } @Test @DecisionResource(resource = DMN_FILE) public void testCollectCountResult() { setDecisionTableHitPolicy(HitPolicy.COLLECT, BuiltinAggregator.COUNT); evaluateDecisionTable(true, "bar", true, "hello"); assertThat(listener.evaluationEvent.getCollectResultName()).isEqualTo("collectMe"); assertThat(listener.evaluationEvent.getCollectResultValue()).isEqualTo(Variables.integerValue(3)); List<DmnEvaluatedDecisionRule> matchingRules = listener.evaluationEvent.getMatchingRules(); assertThat(matchingRules).hasSize(4); assertThat(matchingRules.get(0).getId()).isEqualTo("rule3"); assertThat(matchingRules.get(1).getId()).isEqualTo("rule4"); assertThat(matchingRules.get(2).getId()).isEqualTo("rule5"); assertThat(matchingRules.get(3).getId()).isEqualTo("rule6"); } @Test @DecisionResource(resource = DMN_FILE) public void testCollectSumResult() { setDecisionTableHitPolicy(HitPolicy.COLLECT, BuiltinAggregator.SUM); evaluateDecisionTable(true, "bar", true, "hello"); assertThat(listener.evaluationEvent.getCollectResultName()).isEqualTo("collectMe"); assertThat(listener.evaluationEvent.getCollectResultValue()).isEqualTo(Variables.integerValue(90)); List<DmnEvaluatedDecisionRule> matchingRules = listener.evaluationEvent.getMatchingRules(); assertThat(matchingRules).hasSize(4); assertThat(matchingRules.get(0).getId()).isEqualTo("rule3"); assertThat(matchingRules.get(1).getId()).isEqualTo("rule4"); assertThat(matchingRules.get(2).getId()).isEqualTo("rule5"); assertThat(matchingRules.get(3).getId()).isEqualTo("rule6"); } @Test @DecisionResource(resource = DMN_FILE) public void testCollectMaxResult() { setDecisionTableHitPolicy(HitPolicy.COLLECT, BuiltinAggregator.MAX); evaluateDecisionTable(true, "bar", true, "hello"); assertThat(listener.evaluationEvent.getCollectResultName()).isEqualTo("collectMe"); assertThat(listener.evaluationEvent.getCollectResultValue()).isEqualTo(Variables.integerValue(50)); List<DmnEvaluatedDecisionRule> matchingRules = listener.evaluationEvent.getMatchingRules(); assertThat(matchingRules).hasSize(4); assertThat(matchingRules.get(0).getId()).isEqualTo("rule3"); assertThat(matchingRules.get(1).getId()).isEqualTo("rule4"); assertThat(matchingRules.get(2).getId()).isEqualTo("rule5"); assertThat(matchingRules.get(3).getId()).isEqualTo("rule6"); } @Test @DecisionResource(resource = DMN_FILE) public void testCollectMinResult() { setDecisionTableHitPolicy(HitPolicy.COLLECT, BuiltinAggregator.MIN); evaluateDecisionTable(true, "bar", true, "hello"); assertThat(listener.evaluationEvent.getCollectResultName()).isEqualTo("collectMe"); assertThat(listener.evaluationEvent.getCollectResultValue()).isEqualTo(Variables.integerValue(10)); List<DmnEvaluatedDecisionRule> matchingRules = listener.evaluationEvent.getMatchingRules(); assertThat(matchingRules).hasSize(4); assertThat(matchingRules.get(0).getId()).isEqualTo("rule3"); assertThat(matchingRules.get(1).getId()).isEqualTo("rule4"); assertThat(matchingRules.get(2).getId()).isEqualTo("rule5"); assertThat(matchingRules.get(3).getId()).isEqualTo("rule6"); } // helper public void setDecisionTableHitPolicy(HitPolicy hitPolicy, BuiltinAggregator aggregator) { DmnHitPolicyHandler handler = hitPolicyHandlerRegistry.getHandler(hitPolicy, aggregator); assertThat(handler).isNotNull(); DmnDecisionTableImpl decisionTable = (DmnDecisionTableImpl) this.decision.getDecisionLogic(); decisionTable.setHitPolicyHandler(handler); } public DmnDecisionTableResult evaluateDecisionTable(Object input1, Object input2, Object input3, Object output1) { variables.put("input1", input1); variables.put("input2", input2); variables.put("input3", input3); variables.put("output1", output1); return evaluateDecisionTable(); } public static class TestDecisionTableEvaluationListenerConfiguration extends DefaultDmnEngineConfiguration { public TestDecisionTableEvaluationListener testDecisionTableListener = new TestDecisionTableEvaluationListener(); public TestDecisionTableEvaluationListenerConfiguration() { customPostDecisionTableEvaluationListeners.add(testDecisionTableListener); } } public static class TestDecisionTableEvaluationListener implements DmnDecisionTableEvaluationListener { public DmnDecisionTableEvaluationEvent evaluationEvent; public void notify(DmnDecisionTableEvaluationEvent evaluationEvent) { this.evaluationEvent = evaluationEvent; } } }