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.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.KrmsAttributeDefinition;
46  import org.kuali.rice.krms.api.repository.type.KrmsTypeAttribute;
47  import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition;
48  import org.kuali.rice.krms.api.repository.type.KrmsTypeRepositoryService;
49  import org.kuali.rice.krms.impl.repository.ActionBoService;
50  import org.kuali.rice.krms.impl.repository.AgendaBoService;
51  import org.kuali.rice.krms.impl.repository.ContextAttributeBo;
52  import org.kuali.rice.krms.impl.repository.ContextBoService;
53  import org.kuali.rice.krms.impl.repository.FunctionBoServiceImpl;
54  import org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService;
55  import org.kuali.rice.krms.impl.repository.KrmsRepositoryServiceLocator;
56  import org.kuali.rice.krms.impl.repository.RuleBoService;
57  import org.kuali.rice.krms.impl.repository.TermBo;
58  import org.kuali.rice.krms.impl.repository.TermBoService;
59  import org.kuali.rice.test.BaselineTestCase.BaselineMode;
60  import org.kuali.rice.test.BaselineTestCase.Mode;
61  import org.springframework.transaction.annotation.Transactional;
62  
63  import java.util.ArrayList;
64  import java.util.Collections;
65  import java.util.HashMap;
66  import java.util.List;
67  import java.util.Map;
68  
69  import static org.junit.Assert.*;
70  
71  @BaselineMode(Mode.CLEAR_DB)
72  public class RepositoryCreateAndExecuteIntegrationTest extends AbstractBoTest {
73  
74      public static final String CAMPUS_CODE_TERM_NAME = "campusCodeTermSpec";
75  
76      static final String NAMESPACE1 = "KRMS_TEST_1";
77      static final String NAMESPACE2 = "KRMS_TEST_2";
78      static final String TSUNAMI_EVENT = "Tsunami";
79      static final String EARTHQUAKE_EVENT = "Earthquake";
80      static final String CONTEXT1 = "Context1";
81      static final String CONTEXT2 = "Context2";
82      static final String NAME = "name";
83      static final String CONTEXT1_QUALIFIER = "Context1Qualifier";
84      static final String CONTEXT1_QUALIFIER_VALUE = "BLAH1";
85      static final String CONTEXT2_QUALIFIER = "Context2Qualifier";
86      static final String CONTEXT2_QUALIFIER_VALUE = "BLAH2";
87      static final String AGENDA1 = "TestAgenda1";
88      static final String AGENDA2 = "Agenda2";
89      static final String AGENDA3 = "Agenda3";
90      static final String AGENDA4 = "Agenda4";
91      static final String PREREQ_TERM_NAME = "prereqTermSpec";
92      static final String PREREQ_TERM_VALUE = "prereqValue";
93      static final String NAMESPACE_CODE = "namespaceCode";
94      static final String BOOL1 = "bool1";
95      static final String BOOL2 = "bool2";
96  
97      // Services needed for creation:
98  	private TermBoService termBoService;
99  	private ContextBoService contextRepository;
100     private KrmsTypeRepositoryService krmsTypeRepository;
101 
102 //    private PropositionBoService propositionBoService;
103     private RuleBoService ruleBoService;
104     private AgendaBoService agendaBoService;
105     private ActionBoService actionBoService;
106     private FunctionBoServiceImpl functionBoService;
107     private KrmsAttributeDefinitionService krmsAttributeDefinitionService;
108 
109     /**
110      *
111      * Setting it up so that KRMS tables are not reset between test methods to make it run much faster
112      *
113      * @return
114      */
115     protected List<String> getPerTestTablesNotToClear() {
116         List<String> tablesNotToClear = super.getPerTestTablesNotToClear();
117 
118         tablesNotToClear.add("KRMS_.*");
119 
120         return tablesNotToClear;
121     }
122 
123 
124 
125 	@Before
126     public void setup() {
127         // Reset TestActionTypeService
128         TestActionTypeService.resetActionsFired();
129 
130         termBoService = KrmsRepositoryServiceLocator.getTermBoService();
131         contextRepository = KrmsRepositoryServiceLocator.getContextBoService();
132         krmsTypeRepository = KrmsRepositoryServiceLocator.getKrmsTypeRepositoryService();
133 
134         ruleBoService = KrmsRepositoryServiceLocator.getRuleBoService();
135         agendaBoService = KrmsRepositoryServiceLocator.getAgendaBoService();
136         actionBoService = KrmsRepositoryServiceLocator.getBean("actionBoService");
137         functionBoService = KrmsRepositoryServiceLocator.getBean("functionRepositoryService");
138         krmsAttributeDefinitionService = KrmsRepositoryServiceLocator.getKrmsAttributeDefinitionService();
139 
140         ContextDefinition contextDefintion1 = contextRepository.getContextByNameAndNamespace(CONTEXT1, NAMESPACE1);
141 
142         // only set this stuff up if we don't already have Context1 (we don't clear out KRMS tables between test methods)
143         if (contextDefintion1 == null) {
144             PerformanceLogger perfLog = new PerformanceLogger();
145             perfLog.log("starting agenda creation");
146 
147             contextDefintion1 = createContextDefinition(NAMESPACE1, CONTEXT1, Collections.singletonMap(
148                     CONTEXT1_QUALIFIER, CONTEXT1_QUALIFIER_VALUE));
149             createAgendaDefinition(AGENDA1, contextDefintion1, TSUNAMI_EVENT, NAMESPACE1);
150 
151             ContextDefinition contextDefinition2 = createContextDefinition(NAMESPACE2, CONTEXT2, Collections.singletonMap(
152                     CONTEXT2_QUALIFIER, CONTEXT2_QUALIFIER_VALUE));
153 
154             // Create multiple agendas so that we can test selection
155             createAgendaDefinition(AGENDA2, contextDefinition2, EARTHQUAKE_EVENT, NAMESPACE2);
156             createAgendaDefinition(AGENDA3, contextDefinition2, EARTHQUAKE_EVENT, NAMESPACE2);
157             createAgendaDefinition(AGENDA4, contextDefinition2, TSUNAMI_EVENT, NAMESPACE2);
158 
159             perfLog.log("finished agenda creation", true);
160         }
161     }
162 
163 
164     @Transactional
165     @Test
166     public void testSelectAgendaByAttributeAndName() {
167 
168         Map<String,String> contextQualifiers = new HashMap<String,String>();
169         contextQualifiers.put(NAMESPACE_CODE, NAMESPACE1);
170         contextQualifiers.put(NAME, CONTEXT1);
171         contextQualifiers.put(CONTEXT1_QUALIFIER, CONTEXT1_QUALIFIER_VALUE);
172 
173         Map<String,String> agendaQualifiers = new HashMap<String,String>();
174         agendaQualifiers.put(AgendaDefinition.Constants.EVENT, TSUNAMI_EVENT);
175         agendaQualifiers.put(NAME, AGENDA1);
176 
177         DateTime now = new DateTime();
178 
179         SelectionCriteria sc1 = SelectionCriteria.createCriteria(now, contextQualifiers,
180                 Collections.singletonMap(AgendaDefinition.Constants.EVENT, TSUNAMI_EVENT));
181 
182         Facts.Builder factsBuilder1 = Facts.Builder.create();
183         factsBuilder1.addFact(CAMPUS_CODE_TERM_NAME, "BL");
184         factsBuilder1.addFact(BOOL1, "true");
185         factsBuilder1.addFact(BOOL2, Boolean.TRUE);
186         factsBuilder1.addFact(PREREQ_TERM_NAME, PREREQ_TERM_VALUE);
187 
188         ExecutionOptions xOptions1 = new ExecutionOptions();
189         xOptions1.setFlag(ExecutionFlag.LOG_EXECUTION, true);
190 
191         PerformanceLogger perfLog = new PerformanceLogger();
192         perfLog.log("starting rule execution");
193         EngineResults eResults1 = KrmsApiServiceLocator.getEngine().execute(sc1, factsBuilder1.build(), xOptions1);
194         perfLog.log("finished rule execution", true);
195         List<ResultEvent> rEvents1 = eResults1.getAllResults();
196 
197         List<ResultEvent> ruleEvaluationResults1 = eResults1.getResultsOfType(ResultEvent.RULE_EVALUATED.toString());
198 
199         assertEquals("4 rules should have been evaluated", 4, ruleEvaluationResults1.size());
200 
201         assertTrue("rule 0 should have evaluated to true", ruleEvaluationResults1.get(0).getResult());
202         assertFalse("rule 1 should have evaluated to false", ruleEvaluationResults1.get(1).getResult());
203         assertTrue("rule 2 should have evaluated to true", ruleEvaluationResults1.get(2).getResult());
204 
205         // ONLY agenda 1 should have been selected
206         assertTrue(TestActionTypeService.actionFired("TestAgenda1::Rule1::TestAction"));
207         assertFalse(TestActionTypeService.actionFired("TestAgenda1::Rule2::TestAction"));
208         assertTrue(TestActionTypeService.actionFired("TestAgenda1::Rule3::TestAction"));
209 
210         assertAgendaDidNotExecute(AGENDA2);
211         assertAgendaDidNotExecute(AGENDA3);
212         assertAgendaDidNotExecute(AGENDA4);
213     }
214 
215     @Transactional
216     @Test
217     public void testSelectAgendaByName() {
218         Map<String,String> contextQualifiers = new HashMap<String,String>();
219         contextQualifiers.put(NAMESPACE_CODE, NAMESPACE2);
220         contextQualifiers.put(NAME, CONTEXT2);
221         contextQualifiers.put(CONTEXT2_QUALIFIER, CONTEXT2_QUALIFIER_VALUE);
222         Map<String,String> agendaQualifiers = new HashMap<String,String>();
223 
224         /*
225          * We'll specifically NOT select this attribute to make sure that matching only takes place against qualifiers
226          * in the selection criteria
227          */
228         // agendaQualifiers.put(AgendaDefinition.Constants.EVENT, EARTHQUAKE_EVENT);
229 
230         agendaQualifiers.put(NAME, AGENDA3);
231         DateTime now = new DateTime();
232 
233         SelectionCriteria selectionCriteria = SelectionCriteria.createCriteria(now, contextQualifiers, agendaQualifiers);
234 
235         Facts.Builder factsBuilder2 = Facts.Builder.create();
236         factsBuilder2.addFact(BOOL1, "true");
237         factsBuilder2.addFact(BOOL2, Boolean.TRUE);
238         factsBuilder2.addFact(CAMPUS_CODE_TERM_NAME, "BL");
239         factsBuilder2.addFact(PREREQ_TERM_NAME, PREREQ_TERM_VALUE);
240 
241         ExecutionOptions xOptions2 = new ExecutionOptions();
242         xOptions2.setFlag(ExecutionFlag.LOG_EXECUTION, true);
243 
244 
245         PerformanceLogger perfLog = new PerformanceLogger();
246         perfLog.log("starting rule execution 1");
247         EngineResults eResults1 = KrmsApiServiceLocator.getEngine().execute(selectionCriteria, factsBuilder2.build(), xOptions2);
248         perfLog.log("finished rule execution 1");
249         List<ResultEvent> rEvents1 = eResults1.getAllResults();
250 
251         List<ResultEvent> ruleEvaluationResults1 = eResults1.getResultsOfType(ResultEvent.RULE_EVALUATED.toString());
252 
253         selectionCriteria = SelectionCriteria.createCriteria(now, contextQualifiers, agendaQualifiers);
254 
255         assertEquals("4 rules should have been evaluated", 4, ruleEvaluationResults1.size());
256 
257         assertAgendaDidNotExecute(AGENDA1);
258         assertAgendaDidNotExecute(AGENDA2);
259 
260         // ONLY agenda 3 should have been selected
261         assertTrue(TestActionTypeService.actionFired("Agenda3::Rule1::TestAction"));
262         assertFalse(TestActionTypeService.actionFired("Agenda3::Rule2::TestAction"));
263         assertTrue(TestActionTypeService.actionFired("Agenda3::Rule3::TestAction"));
264 
265         assertAgendaDidNotExecute(AGENDA4);
266     }
267 
268 
269     @Transactional
270     @Test
271     public void testSelectMultipleAgendasByAttribute() {
272         Map<String,String> contextQualifiers = new HashMap<String,String>();
273         contextQualifiers.put(NAMESPACE_CODE, NAMESPACE2);
274         contextQualifiers.put(NAME, CONTEXT2);
275         contextQualifiers.put(CONTEXT2_QUALIFIER, CONTEXT2_QUALIFIER_VALUE);
276 
277         Map<String,String> agendaQualifiers = new HashMap<String,String>();
278         agendaQualifiers.put(AgendaDefinition.Constants.EVENT, EARTHQUAKE_EVENT);
279 
280         DateTime now = new DateTime();
281 
282         SelectionCriteria selectionCriteria = SelectionCriteria.createCriteria(now, contextQualifiers, agendaQualifiers);
283 
284         Facts.Builder factsBuilder2 = Facts.Builder.create();
285         factsBuilder2.addFact(BOOL1, "true");
286         factsBuilder2.addFact(BOOL2, Boolean.TRUE);
287         factsBuilder2.addFact(CAMPUS_CODE_TERM_NAME, "BL");
288         factsBuilder2.addFact(PREREQ_TERM_NAME, PREREQ_TERM_VALUE);
289 
290         ExecutionOptions xOptions2 = new ExecutionOptions();
291         xOptions2.setFlag(ExecutionFlag.LOG_EXECUTION, true);
292 
293 
294         PerformanceLogger perfLog = new PerformanceLogger();
295         perfLog.log("starting rule execution 1");
296         EngineResults eResults1 = KrmsApiServiceLocator.getEngine().execute(selectionCriteria, factsBuilder2.build(), xOptions2);
297         perfLog.log("finished rule execution 1");
298         List<ResultEvent> rEvents1 = eResults1.getAllResults();
299 
300         List<ResultEvent> ruleEvaluationResults1 = eResults1.getResultsOfType(ResultEvent.RULE_EVALUATED.toString());
301 
302         selectionCriteria = SelectionCriteria.createCriteria(now, contextQualifiers, agendaQualifiers);
303 
304         assertEquals("8 rules should have been evaluated", 8, ruleEvaluationResults1.size());
305 
306         assertAgendaDidNotExecute(AGENDA1);
307 
308         // ONLY agendas 2 & 3 should have been selected
309 
310         assertTrue(TestActionTypeService.actionFired("Agenda2::Rule1::TestAction"));
311         assertFalse(TestActionTypeService.actionFired("Agenda2::Rule2::TestAction"));
312         assertTrue(TestActionTypeService.actionFired("Agenda2::Rule3::TestAction"));
313 
314         assertTrue(TestActionTypeService.actionFired("Agenda3::Rule1::TestAction"));
315         assertFalse(TestActionTypeService.actionFired("Agenda3::Rule2::TestAction"));
316         assertTrue(TestActionTypeService.actionFired("Agenda3::Rule3::TestAction"));
317 
318         assertAgendaDidNotExecute(AGENDA4);
319     }
320 
321     private void assertAgendaDidNotExecute(String agendaName) {
322         assertFalse(TestActionTypeService.actionFired(agendaName+"::Rule1::TestAction"));
323         assertFalse(TestActionTypeService.actionFired(agendaName+"::Rule2::TestAction"));
324         assertFalse(TestActionTypeService.actionFired(agendaName+"::Rule3::TestAction"));
325     }
326 
327     private ContextDefinition createContextDefinition(String nameSpace, String name, Map<String, String> contextAttributes) {
328         // Attributes for context;
329         List<KrmsTypeAttribute.Builder> contextAttributeBuilders = new ArrayList<KrmsTypeAttribute.Builder>();
330         int contextAttrSequenceIndex = 0;
331 
332         List<KrmsAttributeDefinition> attributeDefintions = new ArrayList<KrmsAttributeDefinition>();
333         
334         if (contextAttributes != null) for (Map.Entry<String,String> entry : contextAttributes.entrySet()) {
335             KrmsAttributeDefinition.Builder contextTypeAttributeDefnBuilder = KrmsAttributeDefinition.Builder.create(null, entry.getKey(), nameSpace);
336             contextTypeAttributeDefnBuilder.setLabel(entry.getKey() + " attribute label");
337             KrmsAttributeDefinition contextTypeAttributeDefinition = krmsAttributeDefinitionService.createAttributeDefinition(contextTypeAttributeDefnBuilder.build());
338             attributeDefintions.add(contextTypeAttributeDefinition);
339 
340             // Attr for context;
341             contextAttributeBuilders.add(KrmsTypeAttribute.Builder.create(null, contextTypeAttributeDefinition.getId(),
342                     contextAttrSequenceIndex));
343             contextAttrSequenceIndex += 1;
344         }
345 
346         // KrmsType for context
347         KrmsTypeDefinition.Builder krmsContextTypeDefnBuilder = KrmsTypeDefinition.Builder.create("KrmsTestContextType", nameSpace);
348         krmsContextTypeDefnBuilder.setAttributes(contextAttributeBuilders);
349         KrmsTypeDefinition krmsContextTypeDefinition = krmsContextTypeDefnBuilder.build();
350         krmsContextTypeDefinition = krmsTypeRepository.createKrmsType(krmsContextTypeDefinition);
351 
352         // Context
353         ContextDefinition.Builder contextBuilder = ContextDefinition.Builder.create(nameSpace, name);
354         contextBuilder.setTypeId(krmsContextTypeDefinition.getId());
355         ContextDefinition contextDefinition = contextBuilder.build();
356         contextDefinition = contextRepository.createContext(contextDefinition);
357 
358         // Context Attribute
359         // TODO: do this fur eel
360         for (KrmsAttributeDefinition contextTypeAttributeDefinition : attributeDefintions) {
361             ContextAttributeBo contextAttribute = new ContextAttributeBo();
362             contextAttribute.setAttributeDefinitionId(contextTypeAttributeDefinition.getId());
363             contextAttribute.setContextId(contextDefinition.getId());
364             contextAttribute.setValue(contextAttributes.get(contextTypeAttributeDefinition.getName()));
365             getBoService().save(contextAttribute);
366         }
367 
368         return contextDefinition;
369     }
370 
371     private void createAgendaDefinition(String agendaName, ContextDefinition contextDefinition, String eventName, String nameSpace ) {
372         KrmsTypeDefinition krmsGenericTypeDefinition = createKrmsGenericTypeDefinition(nameSpace, "testAgendaTypeService");
373 
374         AgendaDefinition agendaDef =
375             AgendaDefinition.Builder.create(null, agendaName, krmsGenericTypeDefinition.getId(), contextDefinition.getId()).build();
376         agendaDef = agendaBoService.createAgenda(agendaDef);
377 
378         AgendaItemDefinition.Builder agendaItemBuilder1 = AgendaItemDefinition.Builder.create(null, agendaDef.getId());
379         agendaItemBuilder1.setRuleId(createRuleDefinition1(contextDefinition, agendaName, nameSpace).getId());
380 
381         AgendaItemDefinition.Builder agendaItemBuilder2 = AgendaItemDefinition.Builder.create(null, agendaDef.getId());
382         agendaItemBuilder1.setAlways(agendaItemBuilder2);
383         agendaItemBuilder2.setRuleId(createRuleDefinition2(contextDefinition, agendaName, nameSpace).getId());
384 
385         AgendaItemDefinition.Builder agendaItemBuilder3 = AgendaItemDefinition.Builder.create(null, agendaDef.getId());
386         agendaItemBuilder2.setAlways(agendaItemBuilder3);
387         agendaItemBuilder3.setRuleId(createRuleDefinition3(contextDefinition, agendaName, nameSpace).getId());
388 
389         AgendaItemDefinition.Builder agendaItemBuilder4 = AgendaItemDefinition.Builder.create(null, agendaDef.getId());
390         agendaItemBuilder3.setAlways(agendaItemBuilder4);
391         agendaItemBuilder4.setRuleId(createRuleDefinition4(contextDefinition, agendaName, nameSpace).getId());
392 
393         // String these puppies together.  Kind of a PITA because you need the id from the next item before you insert the previous one
394         AgendaItemDefinition agendaItem4 = agendaBoService.createAgendaItem(agendaItemBuilder4.build());
395         agendaItemBuilder3.setAlwaysId(agendaItem4.getId());
396         AgendaItemDefinition agendaItem3 = agendaBoService.createAgendaItem(agendaItemBuilder3.build());
397         agendaItemBuilder2.setAlwaysId(agendaItem3.getId());
398         AgendaItemDefinition agendaItem2 = agendaBoService.createAgendaItem(agendaItemBuilder2.build());
399         agendaItemBuilder1.setAlwaysId(agendaItem2.getId());
400         AgendaItemDefinition agendaItem1 = agendaBoService.createAgendaItem(agendaItemBuilder1.build());
401 
402         AgendaDefinition.Builder agendaDefBuilder1 = AgendaDefinition.Builder.create(agendaDef);
403         agendaDefBuilder1.setAttributes(Collections.singletonMap("Event", eventName));
404         agendaDefBuilder1.setFirstItemId(agendaItem1.getId());
405         agendaDef = agendaDefBuilder1.build();
406 
407         agendaBoService.updateAgenda(agendaDef);
408     }
409 
410     private KrmsTypeDefinition createKrmsActionTypeDefinition(String nameSpace) {
411         String ACTION_TYPE_NAME = "KrmsActionResolverType";
412         KrmsTypeDefinition krmsActionTypeDefinition =  krmsTypeRepository.getTypeByName(nameSpace, ACTION_TYPE_NAME);
413 
414         if (krmsActionTypeDefinition == null) {
415             KrmsTypeDefinition.Builder krmsActionTypeDefnBuilder = KrmsTypeDefinition.Builder.create(ACTION_TYPE_NAME, nameSpace);
416             krmsActionTypeDefnBuilder.setServiceName("testActionTypeService");
417             krmsActionTypeDefinition = krmsTypeRepository.createKrmsType(krmsActionTypeDefnBuilder.build());
418         }
419 
420         return krmsActionTypeDefinition;
421     }
422 
423 
424     private KrmsTypeDefinition createKrmsGenericTypeDefinition(String nameSpace, String serviceName) {
425         KrmsTypeDefinition krmsGenericTypeDefinition = krmsTypeRepository.getTypeByName(nameSpace, "KrmsTestGenericType");
426 
427         if (null == krmsGenericTypeDefinition) {
428 
429             // Attribute Defn for generic type;
430             KrmsAttributeDefinition.Builder genericTypeAttributeDefnBuilder = KrmsAttributeDefinition.Builder.create(null, "Event", nameSpace);
431             genericTypeAttributeDefnBuilder.setLabel("event name");
432             KrmsAttributeDefinition genericTypeAttributeDefinition1 = krmsAttributeDefinitionService.createAttributeDefinition(genericTypeAttributeDefnBuilder.build());
433 
434             // Attr for generic type;
435             KrmsTypeAttribute.Builder genericTypeAttrBuilder = KrmsTypeAttribute.Builder.create(null, genericTypeAttributeDefinition1.getId(), 1);
436 
437             // Can use this generic type for KRMS bits that don't actually rely on services on the bus at this point in time
438             KrmsTypeDefinition.Builder krmsGenericTypeDefnBuilder = KrmsTypeDefinition.Builder.create("KrmsTestGenericType", nameSpace);
439             krmsGenericTypeDefnBuilder.setServiceName(serviceName);
440             krmsGenericTypeDefnBuilder.setAttributes(Collections.singletonList(genericTypeAttrBuilder));
441             krmsGenericTypeDefinition = krmsTypeRepository.createKrmsType(krmsGenericTypeDefnBuilder.build());
442 
443         }
444 
445         return krmsGenericTypeDefinition;
446     }
447 
448 
449     private RuleDefinition createRuleDefinition(String nameSpace, String ruleName, ContextDefinition contextDefinition,
450             LogicalOperator operator, PropositionParametersBuilder ... pbs) {
451         RuleDefinition.Builder ruleDefBuilder =
452                 RuleDefinition.Builder.create(null, ruleName, nameSpace, null, null);
453         RuleDefinition ruleDef1 = ruleBoService.createRule(ruleDefBuilder.build());
454 
455         PropositionDefinition.Builder parentProposition =
456                 PropositionDefinition.Builder.create(null, PropositionType.COMPOUND.getCode(), ruleDef1.getId(), null, null);
457         parentProposition.setCompoundComponents(new ArrayList<PropositionDefinition.Builder>());
458 
459         if (operator != null ) { parentProposition.setCompoundOpCode(operator.getCode()); }
460 
461         ruleDefBuilder = RuleDefinition.Builder.create(ruleDef1);
462 
463         for (PropositionParametersBuilder params : pbs) {
464 
465             StringBuilder propositionNameBuilder = new StringBuilder(ruleName);
466 
467             propositionNameBuilder.append("::");
468             for (Object[] param : params.params) {
469                 propositionNameBuilder.append(param[0].toString());
470                 propositionNameBuilder.append("--");
471             }
472 
473             PropositionDefinition.Builder propositionBuilder =
474                     createPropositionDefinition(propositionNameBuilder.toString(), params, ruleDef1);
475 
476             if (pbs.length > 1) {
477                 // add it to the compound prop
478                 parentProposition.getCompoundComponents().add(propositionBuilder);
479             } else {
480                 // if there is only one proposition to build, make it the parent
481                 parentProposition = propositionBuilder;
482             }
483         }
484 
485         ruleDefBuilder.setProposition(parentProposition);
486         ruleDef1 = ruleDefBuilder.build();
487         ruleBoService.updateRule(ruleDef1);
488 
489         // Action
490         ActionDefinition.Builder actionDefBuilder1 = ActionDefinition.Builder.create(null, ruleName + "::TestAction", nameSpace, createKrmsActionTypeDefinition(nameSpace).getId(), ruleDef1.getId(), 1);
491         ActionDefinition actionDef1 = actionBoService.createAction(actionDefBuilder1.build());
492 
493         return ruleDef1;
494     }
495 
496 
497 
498     private RuleDefinition createRuleDefinition1(ContextDefinition contextDefinition, String agendaName, String nameSpace) {
499 
500         PropositionParametersBuilder params1 = new PropositionParametersBuilder();
501         params1.add(createTermDefinition(CAMPUS_CODE_TERM_NAME, String.class, contextDefinition).getId(), PropositionParameterType.TERM);
502         params1.add("QC", PropositionParameterType.CONSTANT);
503         params1.add("=", PropositionParameterType.OPERATOR);
504 
505         PropositionParametersBuilder params2 = new PropositionParametersBuilder();
506         params2.add(createTermDefinition(CAMPUS_CODE_TERM_NAME, String.class, contextDefinition).getId(), PropositionParameterType.TERM);
507         params2.add("BL", PropositionParameterType.CONSTANT);
508         params2.add("=", PropositionParameterType.OPERATOR);
509 
510         return createRuleDefinition(nameSpace, agendaName+"::Rule1", contextDefinition, LogicalOperator.OR, params1, params2);
511     }
512 
513 
514     private PropositionDefinition.Builder createPropositionDefinition(String propDescription, PropositionParametersBuilder params, RuleDefinition parentRule) {
515         // Proposition for rule 2
516         PropositionDefinition.Builder propositionDefBuilder1 =
517                 PropositionDefinition.Builder.create(null, PropositionType.SIMPLE.getCode(), parentRule.getId(),
518                         null /* type code is only for custom props */, Collections.<PropositionParameter.Builder>emptyList());
519         propositionDefBuilder1.setDescription(propDescription);
520 
521         // PropositionParams for rule 2
522         List<PropositionParameter.Builder> propositionParams1 = params.build();
523 
524 
525         // set the parent proposition so the builder will not puke
526         for (PropositionParameter.Builder propositionParamBuilder : propositionParams1) {
527             propositionParamBuilder.setProposition(propositionDefBuilder1);
528         }
529 
530         propositionDefBuilder1.setParameters(propositionParams1);
531 
532         return propositionDefBuilder1;
533     }
534     
535     
536     
537     private TermDefinition createTermDefinition(String termName, Class termValueType, ContextDefinition contextDefinition) {
538 
539         // this may be called more than once, we only want to create one though
540         Map<String, String> queryArgs = new HashMap<String, String>();
541         queryArgs.put("specification.namespace", contextDefinition.getNamespace());
542         queryArgs.put("specification.name", termName);
543         TermBo termBo = getBoService().findByPrimaryKey(TermBo.class, queryArgs);
544         if (termBo != null) {
545             return TermBo.to(termBo);
546         }
547         
548         // campusCode TermSpec
549         TermSpecificationDefinition termSpec =
550             TermSpecificationDefinition.Builder.create(null, termName, contextDefinition.getNamespace(),
551                     termValueType.getCanonicalName()).build();
552 
553         termSpec = termBoService.createTermSpecification(termSpec);
554         
555         // Term 1
556         TermDefinition termDefinition =
557             TermDefinition.Builder.create(null, TermSpecificationDefinition.Builder.create(termSpec), null).build();
558         termDefinition = termBoService.createTermDefinition(termDefinition);
559 
560         return termDefinition;
561     }
562 
563 
564     private RuleDefinition createRuleDefinition2(ContextDefinition contextDefinition, String agendaName, String nameSpace) {
565 
566         PropositionParametersBuilder params1 = new PropositionParametersBuilder();
567         params1.add(createTermDefinition2(contextDefinition, nameSpace).getId(), PropositionParameterType.TERM);
568         params1.add("RESULT1", PropositionParameterType.CONSTANT);
569         params1.add("=", PropositionParameterType.OPERATOR);
570 
571         PropositionParametersBuilder params2 = new PropositionParametersBuilder();
572         params2.add(createTermDefinition2(contextDefinition, nameSpace).getId(), PropositionParameterType.TERM);
573         params2.add("NotGonnaBeEqual", PropositionParameterType.CONSTANT);
574         params2.add("=", PropositionParameterType.OPERATOR);
575 
576         return createRuleDefinition(nameSpace, agendaName+"::Rule2", contextDefinition, LogicalOperator.AND, params1, params2);
577     }
578 
579     private RuleDefinition createRuleDefinition3(ContextDefinition contextDefinition, String agendaName, String nameSpace) {
580 
581         FunctionDefinition gcdFunction = functionBoService.getFunctionByNameAndNamespace("gcd", contextDefinition.getNamespace());
582 
583         if (null == gcdFunction) {
584             // better configure a custom fuction for this
585             // KrmsType for custom function
586             KrmsTypeDefinition.Builder krmsFunctionTypeDefnBuilder = KrmsTypeDefinition.Builder.create("KrmsTestFunctionType", nameSpace);
587             krmsFunctionTypeDefnBuilder.setServiceName("testFunctionTypeService");
588             KrmsTypeDefinition krmsFunctionTypeDefinition = krmsTypeRepository.createKrmsType(krmsFunctionTypeDefnBuilder.build());
589 
590             FunctionDefinition.Builder functionBuilder =
591                     FunctionDefinition.Builder.create(contextDefinition.getNamespace(), "gcd", Integer.class.getName(), krmsFunctionTypeDefinition.getId());
592 
593             functionBuilder.getParameters().add(FunctionParameterDefinition.Builder.create("arg0", Integer.class.getName(), 0));
594             functionBuilder.getParameters().add(FunctionParameterDefinition.Builder.create("arg1", Integer.class.getName(), 1));
595             functionBuilder.setReturnType(Integer.class.getName());
596 
597             gcdFunction = functionBoService.createFunction(functionBuilder.build());
598         }
599 
600         PropositionParametersBuilder params = new PropositionParametersBuilder();
601 
602         // leverage our stack based evaluation in reverse polish notation
603         params.add("1024", PropositionParameterType.CONSTANT);
604         params.add("768", PropositionParameterType.CONSTANT);
605         params.add(gcdFunction.getId(), PropositionParameterType.FUNCTION); // this should evaluate first: gcd(1024, 768)
606         params.add("256", PropositionParameterType.CONSTANT);
607         params.add("=", PropositionParameterType.OPERATOR); // this should evaluate second: gcdResult == 256
608 
609         return createRuleDefinition(nameSpace, agendaName+"::Rule3", contextDefinition, null, params);
610     }
611 
612 
613     private RuleDefinition createRuleDefinition4(ContextDefinition contextDefinition, String agendaName, String nameSpace) {
614 
615         PropositionParametersBuilder params1 = new PropositionParametersBuilder();
616         params1.add(createTermDefinition(BOOL1, Boolean.class, contextDefinition).getId(), PropositionParameterType.TERM);
617         params1.add(createTermDefinition(BOOL2, Boolean.class, contextDefinition).getId(), PropositionParameterType.TERM);
618         params1.add("=", PropositionParameterType.OPERATOR);
619 
620         PropositionParametersBuilder params2 = new PropositionParametersBuilder();
621         params2.add(createTermDefinition(BOOL2, Boolean.class, contextDefinition).getId(), PropositionParameterType.TERM);
622         params2.add(createTermDefinition(BOOL1, Boolean.class, contextDefinition).getId(), PropositionParameterType.TERM);
623         params2.add("=", PropositionParameterType.OPERATOR);
624 
625         return createRuleDefinition(nameSpace, agendaName+"::Rule4", contextDefinition, LogicalOperator.AND, params1, params2);
626     }
627 
628 
629     private TermDefinition createTermDefinition2(ContextDefinition contextDefinition, String nameSpace) {
630 
631         Map<String, String> queryArgs = new HashMap<String, String>();
632         queryArgs.put("specification.namespace", contextDefinition.getNamespace());
633         queryArgs.put("specification.name", "outputTermSpec");
634         TermBo result = getBoService().findByPrimaryKey(TermBo.class, queryArgs);
635         if (result != null) return TermBo.to(result);
636 
637         // output TermSpec
638         TermSpecificationDefinition outputTermSpec =
639             TermSpecificationDefinition.Builder.create(null, "outputTermSpec", contextDefinition.getNamespace(),
640                     "java.lang.String").build();
641         outputTermSpec = termBoService.createTermSpecification(outputTermSpec);
642 
643         // prereq TermSpec
644         TermSpecificationDefinition prereqTermSpec =
645             TermSpecificationDefinition.Builder.create(null, PREREQ_TERM_NAME, contextDefinition.getNamespace(),
646                     "java.lang.String").build();
647         prereqTermSpec = termBoService.createTermSpecification(prereqTermSpec);
648 
649         // Term Param
650         TermParameterDefinition.Builder termParamBuilder2 =
651             TermParameterDefinition.Builder.create(null, null, "testParamName", "testParamValue");
652 
653         // Term
654         TermDefinition termDefinition2 =
655             TermDefinition.Builder.create(null, TermSpecificationDefinition.Builder.create(outputTermSpec), Collections.singletonList(termParamBuilder2)).build();
656         termDefinition2 = termBoService.createTermDefinition(termDefinition2);
657 
658 		// KrmsType for TermResolver
659 		KrmsTypeDefinition.Builder krmsTermResolverTypeDefnBuilder = KrmsTypeDefinition.Builder.create("KrmsTestResolverType", nameSpace);
660 		krmsTermResolverTypeDefnBuilder.setServiceName("testTermResolverTypeService");
661 
662 		KrmsTypeDefinition krmsTermResolverTypeDefinition = krmsTypeRepository.createKrmsType(krmsTermResolverTypeDefnBuilder.build());
663 
664         // TermResolver
665 		TermResolverDefinition termResolverDef =
666 			TermResolverDefinition.Builder.create(null, contextDefinition.getNamespace(), "testResolver1", krmsTermResolverTypeDefinition.getId(),
667 					TermSpecificationDefinition.Builder.create(outputTermSpec),
668 					Collections.singleton(TermSpecificationDefinition.Builder.create(prereqTermSpec)),
669 					null,
670 					Collections.singleton("testParamName")).build();
671 		termResolverDef = termBoService.createTermResolver(termResolverDef);
672 
673         return termDefinition2;
674     }
675 
676     private static class PropositionParametersBuilder {
677         
678         // poor OOD but this is quick and dirty :-P
679         private List<Object[]> params = new ArrayList<Object[]>();
680         
681         public PropositionParametersBuilder add(String value, PropositionParameterType type) {
682             if (type == null) throw new IllegalArgumentException("type must not be null");
683             params.add(new Object[]{value, type});
684             return this;
685         }
686         
687         public List<PropositionParameter.Builder> build() {
688             int seqCounter = 0;
689             
690             List<PropositionParameter.Builder> results = new ArrayList<PropositionParameter.Builder>();
691             
692             for (Object[] param : params) {
693                 results.add(PropositionParameter.Builder.create(null, null, (String)param[0], ((PropositionParameterType)param[1]).getCode(), seqCounter++));
694             }
695 
696             return results;
697         }
698     }
699 
700 }