View Javadoc

1   /**
2    * Copyright 2005-2011 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krms.test;
17  
18  import org.joda.time.DateTime;
19  import org.junit.Before;
20  import org.junit.Test;
21  import org.kuali.rice.kew.util.PerformanceLogger;
22  import org.kuali.rice.krms.api.KrmsApiServiceLocator;
23  import org.kuali.rice.krms.api.engine.EngineResults;
24  import org.kuali.rice.krms.api.engine.ExecutionFlag;
25  import org.kuali.rice.krms.api.engine.ExecutionOptions;
26  import org.kuali.rice.krms.api.engine.Facts;
27  import org.kuali.rice.krms.api.engine.ResultEvent;
28  import org.kuali.rice.krms.api.engine.SelectionCriteria;
29  import org.kuali.rice.krms.api.repository.LogicalOperator;
30  import org.kuali.rice.krms.api.repository.action.ActionDefinition;
31  import org.kuali.rice.krms.api.repository.agenda.AgendaDefinition;
32  import org.kuali.rice.krms.api.repository.agenda.AgendaItemDefinition;
33  import org.kuali.rice.krms.api.repository.context.ContextDefinition;
34  import org.kuali.rice.krms.api.repository.function.FunctionDefinition;
35  import org.kuali.rice.krms.api.repository.function.FunctionParameterDefinition;
36  import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition;
37  import org.kuali.rice.krms.api.repository.proposition.PropositionParameter;
38  import org.kuali.rice.krms.api.repository.proposition.PropositionParameterType;
39  import org.kuali.rice.krms.api.repository.proposition.PropositionType;
40  import org.kuali.rice.krms.api.repository.rule.RuleDefinition;
41  import org.kuali.rice.krms.api.repository.term.TermDefinition;
42  import org.kuali.rice.krms.api.repository.term.TermParameterDefinition;
43  import org.kuali.rice.krms.api.repository.term.TermResolverDefinition;
44  import org.kuali.rice.krms.api.repository.term.TermSpecificationDefinition;
45  import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition;
46  import org.kuali.rice.krms.impl.repository.ActionBoService;
47  import org.kuali.rice.krms.impl.repository.AgendaBoService;
48  import org.kuali.rice.krms.impl.repository.FunctionBoServiceImpl;
49  import org.kuali.rice.krms.impl.repository.KrmsRepositoryServiceLocator;
50  import org.kuali.rice.krms.impl.repository.RuleBoService;
51  import org.kuali.rice.krms.impl.repository.TermBo;
52  import org.kuali.rice.krms.impl.repository.TermBoService;
53  import org.kuali.rice.test.BaselineTestCase.BaselineMode;
54  import org.kuali.rice.test.BaselineTestCase.Mode;
55  import org.springframework.transaction.annotation.Transactional;
56  
57  import java.util.ArrayList;
58  import java.util.Collections;
59  import java.util.HashMap;
60  import java.util.List;
61  import java.util.Map;
62  
63  import static org.junit.Assert.*;
64  
65  @BaselineMode(Mode.CLEAR_DB)
66  public class RepositoryCreateAndExecuteIntegrationTest extends AbstractAgendaBoTest {
67  
68      static final String NAME = "name";
69      static final String PREREQ_TERM_VALUE = "prereqValue";
70      static final String NAMESPACE_CODE = "namespaceCode";
71  
72      @Before
73      public void setUp() throws Exception {
74          // Reset TestActionTypeService
75          TestActionTypeService.resetActionsFired();
76  
77          termBoService = KrmsRepositoryServiceLocator.getTermBoService();
78          contextRepository = KrmsRepositoryServiceLocator.getContextBoService();
79          krmsTypeRepository = KrmsRepositoryServiceLocator.getKrmsTypeRepositoryService();
80  
81          ruleBoService = KrmsRepositoryServiceLocator.getRuleBoService();
82          agendaBoService = KrmsRepositoryServiceLocator.getAgendaBoService();
83          actionBoService = KrmsRepositoryServiceLocator.getBean("actionBoService");
84          functionBoService = KrmsRepositoryServiceLocator.getBean("functionRepositoryService");
85          krmsAttributeDefinitionService = KrmsRepositoryServiceLocator.getKrmsAttributeDefinitionService();
86  
87          ContextDefinition contextDefintion1 = contextRepository.getContextByNameAndNamespace(CONTEXT1, NAMESPACE1);
88  
89          // only set this stuff up if we don't already have Context1 (we don't clear out KRMS tables between test methods)
90          if (contextDefintion1 == null) {
91              PerformanceLogger perfLog = new PerformanceLogger();
92              perfLog.log("starting agenda creation");
93  
94              contextDefintion1 = createContextDefinition(NAMESPACE1, CONTEXT1, Collections.singletonMap(CONTEXT1_QUALIFIER,
95                      CONTEXT1_QUALIFIER_VALUE));
96              createAgendaDefinition(AGENDA1, contextDefintion1, TSUNAMI_EVENT, NAMESPACE1);
97  
98              ContextDefinition contextDefinition2 = createContextDefinition(NAMESPACE2, CONTEXT2,
99                      Collections.singletonMap(CONTEXT2_QUALIFIER, CONTEXT2_QUALIFIER_VALUE));
100 
101             ContextDefinition contextDefinition3 = createContextDefinition(NAMESPACE1, CONTEXT3,
102                     Collections.<String,String>emptyMap());
103 
104             // Create multiple agendas so that we can test selection
105             createAgendaDefinition(AGENDA2, contextDefinition2, EARTHQUAKE_EVENT, NAMESPACE2);
106             createAgendaDefinition(AGENDA3, contextDefinition2, EARTHQUAKE_EVENT, NAMESPACE2);
107             createAgendaDefinition(AGENDA4, contextDefinition2, TSUNAMI_EVENT, NAMESPACE2);
108             createAgendaDefinition2(AGENDA5, contextDefinition3, NAMESPACE1);
109 
110             perfLog.log("finished agenda creation", true);
111         }
112     }
113 
114     @Transactional
115     @Test
116     public void testNullFact() {
117 
118         Map<String,String> contextQualifiers = new HashMap<String,String>();
119         contextQualifiers.put(NAMESPACE_CODE, NAMESPACE1);
120         contextQualifiers.put(NAME, CONTEXT3);
121 
122         Map<String,String> agendaQualifiers = new HashMap<String,String>();
123         agendaQualifiers.put(NAME, AGENDA5);
124 
125         DateTime now = new DateTime();
126 
127         SelectionCriteria sc1 = SelectionCriteria.createCriteria(now, contextQualifiers, agendaQualifiers);
128 
129         Facts.Builder factsBuilder1 = Facts.Builder.create();
130         factsBuilder1.addFact(NULL_FACT, null);
131 
132         ExecutionOptions xOptions1 = new ExecutionOptions();
133         xOptions1.setFlag(ExecutionFlag.LOG_EXECUTION, true);
134 
135         PerformanceLogger perfLog = new PerformanceLogger();
136         perfLog.log("starting rule execution");
137         EngineResults eResults1 = KrmsApiServiceLocator.getEngine().execute(sc1, factsBuilder1.build(), xOptions1);
138         perfLog.log("finished rule execution", true);
139         List<ResultEvent> rEvents1 = eResults1.getAllResults();
140 
141         List<ResultEvent> ruleEvaluationResults1 = eResults1.getResultsOfType(ResultEvent.RULE_EVALUATED.toString());
142 
143         assertEquals("1 rules should have been evaluated", 1, ruleEvaluationResults1.size());
144 
145         assertTrue("rule 0 should have evaluated to true", ruleEvaluationResults1.get(0).getResult());
146 
147         // ONLY agenda 5 should have been selected
148         assertTrue(TestActionTypeService.actionFired("Agenda5::Rule5::TestAction"));
149 
150         assertAgendaDidNotExecute(AGENDA1);
151         assertAgendaDidNotExecute(AGENDA2);
152         assertAgendaDidNotExecute(AGENDA3);
153         assertAgendaDidNotExecute(AGENDA4);
154     }    
155 
156     @Transactional
157     @Test
158     public void testSelectAgendaByAttributeAndName() {
159 
160         Map<String,String> contextQualifiers = new HashMap<String,String>();
161         contextQualifiers.put(NAMESPACE_CODE, NAMESPACE1);
162         contextQualifiers.put(NAME, CONTEXT1);
163         contextQualifiers.put(CONTEXT1_QUALIFIER, CONTEXT1_QUALIFIER_VALUE);
164 
165         Map<String,String> agendaQualifiers = new HashMap<String,String>();
166         agendaQualifiers.put(AgendaDefinition.Constants.EVENT, TSUNAMI_EVENT);
167         agendaQualifiers.put(NAME, AGENDA1);
168 
169         DateTime now = new DateTime();
170 
171         SelectionCriteria sc1 = SelectionCriteria.createCriteria(now, contextQualifiers,
172                 Collections.singletonMap(AgendaDefinition.Constants.EVENT, TSUNAMI_EVENT));
173 
174         Facts.Builder factsBuilder1 = Facts.Builder.create();
175         factsBuilder1.addFact(CAMPUS_CODE_TERM_NAME, "BL");
176         factsBuilder1.addFact(BOOL1, "true");
177         factsBuilder1.addFact(BOOL2, Boolean.TRUE);
178         factsBuilder1.addFact(PREREQ_TERM_NAME, PREREQ_TERM_VALUE);
179 
180         ExecutionOptions xOptions1 = new ExecutionOptions();
181         xOptions1.setFlag(ExecutionFlag.LOG_EXECUTION, true);
182 
183         PerformanceLogger perfLog = new PerformanceLogger();
184         perfLog.log("starting rule execution");
185         EngineResults eResults1 = KrmsApiServiceLocator.getEngine().execute(sc1, factsBuilder1.build(), xOptions1);
186         perfLog.log("finished rule execution", true);
187         List<ResultEvent> rEvents1 = eResults1.getAllResults();
188 
189         List<ResultEvent> ruleEvaluationResults1 = eResults1.getResultsOfType(ResultEvent.RULE_EVALUATED.toString());
190 
191         assertEquals("4 rules should have been evaluated", 4, ruleEvaluationResults1.size());
192 
193         assertTrue("rule 0 should have evaluated to true", ruleEvaluationResults1.get(0).getResult());
194         assertFalse("rule 1 should have evaluated to false", ruleEvaluationResults1.get(1).getResult());
195         assertTrue("rule 2 should have evaluated to true", ruleEvaluationResults1.get(2).getResult());
196 
197         // ONLY agenda 1 should have been selected
198         assertTrue(TestActionTypeService.actionFired("TestAgenda1::Rule1::TestAction"));
199         assertFalse(TestActionTypeService.actionFired("TestAgenda1::Rule2::TestAction"));
200         assertTrue(TestActionTypeService.actionFired("TestAgenda1::Rule3::TestAction"));
201 
202         assertAgendaDidNotExecute(AGENDA2);
203         assertAgendaDidNotExecute(AGENDA3);
204         assertAgendaDidNotExecute(AGENDA4);
205         assertAgendaDidNotExecute(AGENDA5);
206     }
207 
208     @Transactional
209     @Test
210     public void testSelectAgendaByName() {
211         Map<String,String> contextQualifiers = new HashMap<String,String>();
212         contextQualifiers.put(NAMESPACE_CODE, NAMESPACE2);
213         contextQualifiers.put(NAME, CONTEXT2);
214         contextQualifiers.put(CONTEXT2_QUALIFIER, CONTEXT2_QUALIFIER_VALUE);
215         Map<String,String> agendaQualifiers = new HashMap<String,String>();
216 
217         /*
218          * We'll specifically NOT select this attribute to make sure that matching only takes place against qualifiers
219          * in the selection criteria
220          */
221         // agendaQualifiers.put(AgendaDefinition.Constants.EVENT, EARTHQUAKE_EVENT);
222 
223         agendaQualifiers.put(NAME, AGENDA3);
224         DateTime now = new DateTime();
225 
226         SelectionCriteria selectionCriteria = SelectionCriteria.createCriteria(now, contextQualifiers, agendaQualifiers);
227 
228         Facts.Builder factsBuilder2 = Facts.Builder.create();
229         factsBuilder2.addFact(BOOL1, "true");
230         factsBuilder2.addFact(BOOL2, Boolean.TRUE);
231         factsBuilder2.addFact(CAMPUS_CODE_TERM_NAME, "BL");
232         factsBuilder2.addFact(PREREQ_TERM_NAME, PREREQ_TERM_VALUE);
233 
234         ExecutionOptions xOptions2 = new ExecutionOptions();
235         xOptions2.setFlag(ExecutionFlag.LOG_EXECUTION, true);
236 
237 
238         PerformanceLogger perfLog = new PerformanceLogger();
239         perfLog.log("starting rule execution 1");
240         EngineResults eResults1 = KrmsApiServiceLocator.getEngine().execute(selectionCriteria, factsBuilder2.build(), xOptions2);
241         perfLog.log("finished rule execution 1");
242         List<ResultEvent> rEvents1 = eResults1.getAllResults();
243 
244         List<ResultEvent> ruleEvaluationResults1 = eResults1.getResultsOfType(ResultEvent.RULE_EVALUATED.toString());
245 
246         selectionCriteria = SelectionCriteria.createCriteria(now, contextQualifiers, agendaQualifiers);
247 
248         assertEquals("4 rules should have been evaluated", 4, ruleEvaluationResults1.size());
249 
250         assertAgendaDidNotExecute(AGENDA1);
251         assertAgendaDidNotExecute(AGENDA2);
252 
253         // ONLY agenda 3 should have been selected
254         assertTrue(TestActionTypeService.actionFired("Agenda3::Rule1::TestAction"));
255         assertFalse(TestActionTypeService.actionFired("Agenda3::Rule2::TestAction"));
256         assertTrue(TestActionTypeService.actionFired("Agenda3::Rule3::TestAction"));
257 
258         assertAgendaDidNotExecute(AGENDA4);
259         assertAgendaDidNotExecute(AGENDA5);
260     }
261 
262 
263     @Transactional
264     @Test
265     public void testSelectMultipleAgendasByAttribute() {
266         Map<String,String> contextQualifiers = new HashMap<String,String>();
267         contextQualifiers.put(NAMESPACE_CODE, NAMESPACE2);
268         contextQualifiers.put(NAME, CONTEXT2);
269         contextQualifiers.put(CONTEXT2_QUALIFIER, CONTEXT2_QUALIFIER_VALUE);
270 
271         Map<String,String> agendaQualifiers = new HashMap<String,String>();
272         agendaQualifiers.put(AgendaDefinition.Constants.EVENT, EARTHQUAKE_EVENT);
273 
274         DateTime now = new DateTime();
275 
276         SelectionCriteria selectionCriteria = SelectionCriteria.createCriteria(now, contextQualifiers, agendaQualifiers);
277 
278         Facts.Builder factsBuilder2 = Facts.Builder.create();
279         factsBuilder2.addFact(BOOL1, "true");
280         factsBuilder2.addFact(BOOL2, Boolean.TRUE);
281         factsBuilder2.addFact(CAMPUS_CODE_TERM_NAME, "BL");
282         factsBuilder2.addFact(PREREQ_TERM_NAME, PREREQ_TERM_VALUE);
283 
284         ExecutionOptions xOptions2 = new ExecutionOptions();
285         xOptions2.setFlag(ExecutionFlag.LOG_EXECUTION, true);
286 
287 
288         PerformanceLogger perfLog = new PerformanceLogger();
289         perfLog.log("starting rule execution 1");
290         EngineResults eResults1 = KrmsApiServiceLocator.getEngine().execute(selectionCriteria, factsBuilder2.build(), xOptions2);
291         perfLog.log("finished rule execution 1");
292         List<ResultEvent> rEvents1 = eResults1.getAllResults();
293 
294         List<ResultEvent> ruleEvaluationResults1 = eResults1.getResultsOfType(ResultEvent.RULE_EVALUATED.toString());
295 
296         selectionCriteria = SelectionCriteria.createCriteria(now, contextQualifiers, agendaQualifiers);
297 
298         assertEquals("8 rules should have been evaluated", 8, ruleEvaluationResults1.size());
299 
300         assertAgendaDidNotExecute(AGENDA1);
301 
302         // ONLY agendas 2 & 3 should have been selected
303 
304         assertTrue(TestActionTypeService.actionFired("Agenda2::Rule1::TestAction"));
305         assertFalse(TestActionTypeService.actionFired("Agenda2::Rule2::TestAction"));
306         assertTrue(TestActionTypeService.actionFired("Agenda2::Rule3::TestAction"));
307 
308         assertTrue(TestActionTypeService.actionFired("Agenda3::Rule1::TestAction"));
309         assertFalse(TestActionTypeService.actionFired("Agenda3::Rule2::TestAction"));
310         assertTrue(TestActionTypeService.actionFired("Agenda3::Rule3::TestAction"));
311 
312         assertAgendaDidNotExecute(AGENDA4);
313         assertAgendaDidNotExecute(AGENDA5);
314     }
315 
316     private void assertAgendaDidNotExecute(String agendaName) {
317         assertFalse(TestActionTypeService.actionFired(agendaName+"::Rule1::TestAction"));
318         assertFalse(TestActionTypeService.actionFired(agendaName+"::Rule2::TestAction"));
319         assertFalse(TestActionTypeService.actionFired(agendaName+"::Rule3::TestAction"));
320     }
321 
322 }