View Javadoc
1   /*
2    * Copyright 2005-2014 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  
17  package org.kuali.rice.krms.test;
18  
19  import org.apache.commons.collections.CollectionUtils;
20  import org.junit.Before;
21  import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
22  import org.kuali.rice.krad.data.DataObjectService;
23  import org.kuali.rice.krad.util.ObjectUtils;
24  import org.kuali.rice.krms.api.repository.LogicalOperator;
25  import org.kuali.rice.krms.api.repository.RuleManagementService;
26  import org.kuali.rice.krms.api.repository.action.ActionDefinition;
27  import org.kuali.rice.krms.api.repository.agenda.AgendaDefinition;
28  import org.kuali.rice.krms.api.repository.agenda.AgendaItemDefinition;
29  import org.kuali.rice.krms.api.repository.context.ContextDefinition;
30  import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplate;
31  import org.kuali.rice.krms.api.repository.language.NaturalLanguageUsage;
32  import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition;
33  import org.kuali.rice.krms.api.repository.proposition.PropositionParameter;
34  import org.kuali.rice.krms.api.repository.proposition.PropositionParameterType;
35  import org.kuali.rice.krms.api.repository.proposition.PropositionType;
36  import org.kuali.rice.krms.api.repository.reference.ReferenceObjectBinding;
37  import org.kuali.rice.krms.api.repository.rule.RuleDefinition;
38  import org.kuali.rice.krms.api.repository.term.TermSpecificationDefinition;
39  import org.kuali.rice.krms.api.repository.type.KrmsAttributeDefinition;
40  import org.kuali.rice.krms.api.repository.type.KrmsTypeAttribute;
41  import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition;
42  import org.kuali.rice.krms.api.repository.type.KrmsTypeRepositoryService;
43  import org.kuali.rice.krms.impl.repository.ActionBoService;
44  import org.kuali.rice.krms.impl.repository.AgendaBoService;
45  import org.kuali.rice.krms.impl.repository.ContextBoService;
46  import org.kuali.rice.krms.impl.repository.FunctionBoServiceImpl;
47  import org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService;
48  import org.kuali.rice.krms.impl.repository.KrmsRepositoryServiceLocator;
49  import org.kuali.rice.krms.impl.repository.RuleBoService;
50  import org.kuali.rice.krms.impl.repository.TermBoService;
51  import org.kuali.rice.test.BaselineTestCase;
52  
53  import java.util.ArrayList;
54  import java.util.Collections;
55  import java.util.HashMap;
56  import java.util.List;
57  import java.util.Map;
58  
59  import static org.junit.Assert.assertEquals;
60  
61  /**
62   * Base test case and methods for testing RuleManagementServiceImpl
63   */
64  @BaselineTestCase.BaselineMode(BaselineTestCase.Mode.CLEAR_DB)
65  public abstract class RuleManagementBaseTest extends KRMSTestCase {
66  
67      protected RuleManagementService ruleManagementService;
68      protected TermBoService termBoService;
69      protected ContextBoService contextRepository;
70      protected KrmsTypeRepositoryService krmsTypeRepository;
71      protected RuleBoService ruleBoService;
72      protected AgendaBoService agendaBoService;
73      protected ActionBoService actionBoService;
74      protected FunctionBoServiceImpl functionBoService;
75      protected KrmsAttributeDefinitionService krmsAttributeDefinitionService;
76      protected DataObjectService dataObjectService;
77  
78      protected String CLASS_DISCRIMINATOR;
79  
80      private static String lastTestClass = null;
81  
82      @Before
83      public void setup() {
84          // Reset TestActionTypeService
85          TestActionTypeService.resetActionsFired();
86  
87          ruleManagementService = KrmsRepositoryServiceLocator.getService("ruleManagementService");
88          termBoService = KrmsRepositoryServiceLocator.getTermBoService();
89          contextRepository = KrmsRepositoryServiceLocator.getContextBoService();
90          krmsTypeRepository = KrmsRepositoryServiceLocator.getKrmsTypeRepositoryService();
91          ruleBoService = KrmsRepositoryServiceLocator.getRuleBoService();
92          agendaBoService = KrmsRepositoryServiceLocator.getAgendaBoService();
93          actionBoService = KrmsRepositoryServiceLocator.getBean("actionBoService");
94          functionBoService = KrmsRepositoryServiceLocator.getBean("functionRepositoryService");
95          krmsAttributeDefinitionService = KrmsRepositoryServiceLocator.getKrmsAttributeDefinitionService();
96          dataObjectService = (DataObjectService)GlobalResourceLoader.getService("dataObjectService");
97      }
98  
99      /**
100      * Extending test classes can override setClassDiscriminator method and set a unique value for the class
101      *
102      *   The override method should be called @before tests to ensure a unique discriminator for the class
103      *
104      *  Test object naming is comprised of class, test and object uniqueness discriminators.
105      *     The Class Discriminator is set by this method
106      *
107      *     A Test Discriminator may be used to set unique test names at the start of each test.
108      *        ex: RuleManagementBaseTestObjectNames.setTestObjectNames(testDiscriminator)
109      *     The Object Discriminators are Sequential (object0, object1 ...)
110      */
111     @Before
112     public void setClassDiscriminator() {
113         // set a unique discriminator for test objects of this class should be uniquely set by each extending class
114         CLASS_DISCRIMINATOR = "BaseTest";
115     }
116 
117     /**
118      *
119      * Setting it up so that KRMS tables are not reset between test methods to make it run much faster
120      *
121      * @return
122      */
123     @Override
124     protected List<String> getPerTestTablesNotToClear() {
125         List<String> tablesNotToClear = super.getPerTestTablesNotToClear();
126 
127         // HACK: clear KRMS tables for first test method run, but not subsequent methods in the same class
128         if (getClass().getName().equals(lastTestClass)) { //
129             tablesNotToClear.add("KRMS_.*");
130         }
131         lastTestClass = getClass().getName();
132 
133         return tablesNotToClear;
134     }
135 
136     /**
137      *   buildTestRuleDefinition will create a RuleDefinition entry in the database
138      *
139      * @param namespace
140      * @param objectDiscriminator
141      *
142      * @return {@link RuleDefinition}
143      */
144     protected RuleDefinition buildTestRuleDefinition(String namespace, String objectDiscriminator) {
145         PropositionDefinition propositionDefinition = createTestPropositionForRule(objectDiscriminator);
146 
147         String ruleId = "RuleId" + objectDiscriminator;
148         String name = "RuleName" + objectDiscriminator;
149         String propId = propositionDefinition.getId();
150         RuleDefinition.Builder ruleDefinitionBuilder = RuleDefinition.Builder.create(ruleId, name, namespace, null, propId);
151         ruleDefinitionBuilder.setProposition(PropositionDefinition.Builder.create(propositionDefinition));
152 
153         String id = ruleManagementService.createRule(ruleDefinitionBuilder.build()).getId();
154         RuleDefinition ruleDefinition = ruleManagementService.getRule(id);
155 
156         return ruleDefinition;
157     }
158 
159     /**
160      *  buildTestAgendaItemDefinition will build aAgendaItemDefinition for testing
161      *
162      * @param agendaItemId
163      * @param agendaId
164      * @param ruleId
165      *
166      * @return {@link AgendaItemDefinition}
167      */
168     protected AgendaItemDefinition buildTestAgendaItemDefinition(String agendaItemId, String agendaId, String ruleId) {
169         AgendaItemDefinition.Builder agendaItemDefinitionBuilder = AgendaItemDefinition.Builder.create(agendaItemId,
170                 agendaId);
171         agendaItemDefinitionBuilder.setRuleId(ruleId);
172 
173         AgendaItemDefinition agendaItemDefinition =
174                 ruleManagementService.createAgendaItem(agendaItemDefinitionBuilder.build());
175 
176         AgendaDefinition agendaDefinition = ruleManagementService.getAgenda(agendaId);
177         AgendaDefinition.Builder agendaDefinitionBuilder = AgendaDefinition.Builder.create(agendaDefinition);
178         agendaDefinitionBuilder.setFirstItemId(agendaItemDefinition.getId());
179         ruleManagementService.updateAgenda(agendaDefinitionBuilder.build());
180 
181         // re-fetch the item because it's version field will have changed in the above update
182         agendaItemDefinition = ruleManagementService.getAgendaItem(agendaItemDefinition.getId());
183 
184         return agendaItemDefinition;
185     }
186 
187     /**
188      *   buildTestActionDefinition creates Actions in the database for testing
189      *
190      * @param actionId
191      * @param actionName
192      * @param actionDescr
193      * @param actionSequence
194      * @param ruleId
195      * @param namespace
196      *
197      * @return {@link ActionDefinition}
198      */
199     protected ActionDefinition buildTestActionDefinition(String actionId, String actionName, String actionDescr, int actionSequence, String ruleId, String namespace) {
200         return buildTestActionDefinition(actionId, actionName, actionDescr, actionSequence, ruleId, namespace, new HashMap<String, String>());
201     }
202 
203     /**
204      *   buildTestActionDefinition creates Actions in the database for testing
205      *
206      * @param actionId
207      * @param actionName
208      * @param actionDescr
209      * @param actionSequence
210      * @param ruleId
211      * @param namespace
212      * @param attributes
213      *
214      * @return {@link ActionDefinition}
215      */
216     protected ActionDefinition buildTestActionDefinition(String actionId, String actionName, String actionDescr, int actionSequence, String ruleId, String namespace, Map<String, String> attributes) {
217         KrmsTypeDefinition krmsTypeDefinition = createKrmsActionTypeDefinition(namespace);
218 
219         ActionDefinition.Builder actionDefinitionBuilder = ActionDefinition.Builder.create(actionId, actionName,
220                 namespace, krmsTypeDefinition.getId(), ruleId, actionSequence);
221         actionDefinitionBuilder.setDescription(actionDescr);
222         actionDefinitionBuilder.setAttributes(attributes);
223         String id =  ruleManagementService.createAction(actionDefinitionBuilder.build()).getId();
224         ActionDefinition actionDefinition = ruleManagementService.getAction(id);
225 
226         return actionDefinition;
227     }
228 
229     /**
230      *  createTestPropositionForRule will create a PropositionDefinition entry in the database for test purposes
231      *
232      *    The form of the Proposition is   propId_simple_proposition   "SIMPLE"   "TSI_" + propId  "ABC"  "="
233      * @param objectDiscriminator
234      *
235      * @return {@link PropositionDefinition}
236      */
237     protected PropositionDefinition createTestPropositionForRule(String objectDiscriminator) {
238         createKrmsActionTypeDefinition("Namespace" + objectDiscriminator);
239 
240         String namespace = "Namespace" + objectDiscriminator;
241         String propId = "P" + objectDiscriminator;
242         String termSpecId = "TSI_" + propId;
243         String ruleId = "RuleId" + objectDiscriminator;
244         String termSpecDescr = "TSI_" + propId + "_Descr";
245 
246         return createTestSimpleProposition(namespace, propId, termSpecId, "ABC", "=", "java.lang.String", ruleId, termSpecDescr);
247     }
248 
249     /**
250      *  createTestPropositionForTranslation
251      *
252      * @param objectDiscriminator
253      * @param namespace
254      * @param typeName
255      *
256      * @return {@link PropositionDefinition}
257      */
258     protected PropositionDefinition createTestPropositionForTranslation(String objectDiscriminator, String namespace, String typeName) {
259         createKrmsTypeDefinition("TypeId" + objectDiscriminator, namespace, typeName, null);
260 
261         String ruleId = "RuleId" + objectDiscriminator;
262         String propId = "P" + objectDiscriminator;
263 
264         return createTestSimpleProposition(namespace, propId, typeName, "ABC", "=", "java.lang.String", ruleId,
265                 "TSI_" + propId + "_Descr");
266     }
267 
268     /**
269      *   createTestSimpleProposition creates a SIMPLE PropositionDefinition set of entries in the database
270      *
271      * @param namespace of the proposition type
272      * @param propId
273      * @param termSpecId
274      * @param propConstant
275      * @param propOperator
276      * @param termSpecType
277      * @param ruleId
278      * @param termSpecDescr
279      *
280      * @return {@link PropositionDefinition}
281      */
282     protected PropositionDefinition createTestSimpleProposition(String namespace, String propId, String termSpecId, String propConstant, String propOperator, String termSpecType, String ruleId, String termSpecDescr){
283         createTestTermSpecification(termSpecId, termSpecId, namespace, termSpecType, termSpecDescr);
284         KrmsTypeDefinition krmsTypeDefinition = createKrmsTypeDefinition(null, namespace, termSpecId, "testTypeService");
285 
286         PropositionDefinition.Builder propBuilder = PropositionDefinition.Builder.create(null,
287                 PropositionType.SIMPLE.getCode(), ruleId, krmsTypeDefinition.getId(), Collections.<PropositionParameter.Builder>emptyList());
288         propBuilder.setDescription(propId + "_simple_proposition");
289 
290         PropositionDefinition propositionDefinition = ruleManagementService.createProposition(propBuilder.build());
291 
292         List<PropositionParameter.Builder> propParam =  new ArrayList<PropositionParameter.Builder>();
293         propParam.add(PropositionParameter.Builder.create(propId + "_0", propositionDefinition.getId(), termSpecId,
294                 PropositionParameterType.TERM.getCode(), 0));
295         propParam.add(PropositionParameter.Builder.create(propId + "_1", propositionDefinition.getId(), propConstant,
296                 PropositionParameterType.CONSTANT.getCode(), 1));
297         propParam.add(PropositionParameter.Builder.create(propId + "_2", propositionDefinition.getId(), propOperator,
298                 PropositionParameterType.OPERATOR.getCode(), 2));
299 
300         propBuilder = PropositionDefinition.Builder.create(propositionDefinition);
301         propBuilder.setParameters(propParam);
302 
303         ruleManagementService.updateProposition(propBuilder.build());
304         // re-fetch to get the updated version numbers
305         propositionDefinition = ruleManagementService.getProposition(propositionDefinition.getId());
306 
307         return propositionDefinition;
308     }
309 
310     /**
311      *   createTestTermSpecification
312      *
313      * @param termSpecId
314      * @param termSpecName
315      * @param namespace
316      * @param type
317      * @param termSpecDescr
318      *
319      * @return {@link TermSpecificationDefinition}
320      */
321     protected TermSpecificationDefinition createTestTermSpecification(String termSpecId, String termSpecName, String namespace, String type, String termSpecDescr){
322         TermSpecificationDefinition termSpecificationDefinition = termBoService.getTermSpecificationByNameAndNamespace(
323                 termSpecName, namespace);
324 
325         if (termSpecificationDefinition == null) {
326             TermSpecificationDefinition.Builder termSpecificationDefinitionBuilder =
327                     TermSpecificationDefinition.Builder.create(null, termSpecName, namespace, type);
328             termSpecificationDefinitionBuilder.setDescription(termSpecDescr);
329             String id = termBoService.createTermSpecification(termSpecificationDefinitionBuilder.build()).getId();
330             termSpecificationDefinition = termBoService.getTermSpecificationById(id);
331         }
332 
333         return termSpecificationDefinition;
334     }
335 
336     /**
337      * createKrmsTypeDefinition
338      *
339      * @param typeId
340      * @param nameSpace
341      * @param typeName
342      * @param serviceName
343      * @param typeAttributes
344      *
345      * @return {@link KrmsTypeDefinition}
346      */
347     protected KrmsTypeDefinition createKrmsTypeDefinition(String typeId, String nameSpace, String typeName, String serviceName, List<KrmsTypeAttribute.Builder> typeAttributes) {
348         KrmsTypeDefinition krmsTypeDefinition =  krmsTypeRepository.getTypeByName(nameSpace, typeName);
349 
350         if (krmsTypeDefinition == null) {
351             KrmsTypeDefinition.Builder krmsTypeDefnBuilder = KrmsTypeDefinition.Builder.create(typeName, nameSpace);
352 
353             if (!CollectionUtils.isEmpty(typeAttributes)) {
354                 krmsTypeDefnBuilder.setAttributes(typeAttributes);
355             }
356 
357             krmsTypeDefnBuilder.setId(typeId);
358             krmsTypeDefnBuilder.setServiceName(serviceName);
359             String id = krmsTypeRepository.createKrmsType(krmsTypeDefnBuilder.build()).getId();
360             krmsTypeDefinition = krmsTypeRepository.getTypeById(id);
361         }
362 
363         return krmsTypeDefinition;
364     }
365 
366     /**
367      * createKrmsTypeDefinition
368      *
369      * @param typeId
370      * @param nameSpace
371      * @param typeName
372      * @param serviceName
373      *
374      * @return {@link KrmsTypeDefinition}
375      */
376     protected KrmsTypeDefinition createKrmsTypeDefinition(String typeId, String nameSpace, String typeName, String serviceName) {
377         return createKrmsTypeDefinition(typeId, nameSpace, typeName, serviceName, null);
378     }
379 
380     /**
381      * Creates a test agenda setting the createAttributes flag to false
382      * @see #createTestAgenda(String, boolean)
383      */
384     protected AgendaDefinition createTestAgenda(String objectDiscriminator) {
385         return createTestAgenda(objectDiscriminator, false);
386     }
387 
388     /**
389      *   createTestAgenda creates a Agenda set of entries in the database for testing
390      *
391      *       Context ("ContextId0", "Namespace0", "ContextName0")
392      *       Agenda  ("AgendaId0", "AgendaName0")
393      *          AgendaItem ("AI0")
394      *              Rule ("RuleId0")
395      *      where 0 represents a discriminator value
396      *
397      * @param objectDiscriminator
398      * @param createAttributes flag to have an attribute definition, a type attribute and an agenda attribute created
399      *
400      * @return {@link AgendaDefinition.Builder}
401      */
402     protected AgendaDefinition createTestAgenda(String objectDiscriminator, boolean createAttributes) {
403         String namespace =  "Namespace" + objectDiscriminator;
404         String typeId = "TypeId" + objectDiscriminator;
405         String typeName = "TypeName" + objectDiscriminator;
406         String agendaId = "AgendaId" + objectDiscriminator;
407         String agendaName = "AgendaName" + objectDiscriminator;
408 
409         List<KrmsTypeAttribute.Builder> typeAttrs = Collections.emptyList();
410 
411         String attrDefName = "AttrName" + objectDiscriminator;
412         String attrValue = "AttrVal" + objectDiscriminator;
413 
414         if (createAttributes) {
415             // create an attribute definition
416             String attrDefId = "KRTEST" + objectDiscriminator;
417             String attrNamespace = "Namespace" + objectDiscriminator;
418 
419             KrmsAttributeDefinition attrDef = createTestKrmsAttribute(attrDefId, attrDefName, attrNamespace);
420 
421             typeAttrs = Collections.singletonList(KrmsTypeAttribute.Builder.create(null, attrDef.getId(), 1));
422         }
423 
424         // create a type
425         KrmsTypeDefinition krmsTypeDefinition = createKrmsTypeDefinition(typeId, namespace, typeName, null, typeAttrs);
426 
427         // create a context
428         ContextDefinition contextDefinition = buildTestContext(objectDiscriminator);
429 
430         // create an agenda (an agendaItem cannot be created without an existing agenda).
431         AgendaDefinition.Builder agendaBuilder = AgendaDefinition.Builder.create(agendaId, agendaName,
432                 krmsTypeDefinition.getId(), contextDefinition.getId());
433 
434         if (createAttributes) {
435             agendaBuilder.setAttributes(Collections.singletonMap(attrDefName, attrValue));
436         }
437 
438         String id = ruleManagementService.createAgenda(agendaBuilder.build()).getId();
439         AgendaDefinition agendaDefinition = ruleManagementService.getAgenda(id);
440 
441         return agendaDefinition;
442     }
443 
444     protected AgendaDefinition.Builder buildComplexAgenda(RuleManagementBaseTestObjectNames names) {
445         String namespace = "Namespace" + names.discriminator;
446         return createComplexAgenda(namespace, "AGENDA", names);
447     }
448 
449     /**
450      *   createComplexAgenda creates a "complex" agenda object in the database for testing
451      *
452      *   Structure of the created agenda is as shown here.
453      *           // agenda
454      //   agendaItem0 ( rule0)
455      //       WhenTrue   agendaItem1( rule1 )
456      //       WhenFalse  agendaItem2( rule2 )
457      //       Always     agendaItem3( rule3 )
458      //   agendaItem1 ( rule1 )
459      //       Always     agendaItem5
460      //   agendaItem2 ( rule2 )
461      //       WhenFalse  agendaItem4
462      //       Always     agendaItem6
463      //   agendaItem3 ( rule3 )
464      //   agendaItem4 ( rule4 )
465      //   agendaItem5 ( rule5 )
466      //   agendaItem6 ( rule6 )
467      //   agendaItem7 ( rule7 )
468      //       action  ( key, value )
469      *
470      * @param namespace of the KRMS Agenda to be created
471      * @param namespaceType of the namepace passed (Namespace will be created if it does not exist.)
472      * @param {@link RuleManagementBaseTestObjectNames}  Unique discriminator names to base created Agenda upon
473      *
474      * @return {@link AgendaDefinition.Builder} populated from the built agenda
475      */
476     protected AgendaDefinition.Builder createComplexAgenda(String namespace, String namespaceType,
477             RuleManagementBaseTestObjectNames names) {
478         // create a context
479         ContextDefinition.Builder contextBuilder = ContextDefinition.Builder.create(
480                 namespace, names.contextName);
481         contextBuilder.setId(names.contextId);
482         ContextDefinition context = contextBuilder.build();
483         ruleManagementService.createContext(context );
484 
485         // create krms type AGENDA
486         createKrmsTypeDefinition(null, namespace, namespaceType, null);
487 
488         // create a agenda
489         AgendaDefinition.Builder agendaBuilder = AgendaDefinition.Builder.create(
490                 names.agenda_Id, names.agenda_Name, namespaceType, names.contextId);
491         AgendaDefinition agenda = agendaBuilder.build();
492         agenda = ruleManagementService.createAgenda(agenda);
493 
494         // create rules
495         RuleDefinition rule0 = buildTestRuleDefinition(namespace, names.object0);
496         RuleDefinition rule1 = buildTestRuleDefinition(namespace, names.object1);
497         RuleDefinition rule2 = buildTestRuleDefinition(namespace, names.object2);
498         RuleDefinition rule3 = buildTestRuleDefinition(namespace, names.object3);
499         RuleDefinition rule4 = buildTestRuleDefinition(namespace, names.object4);
500         RuleDefinition rule5 = buildTestRuleDefinition(namespace, names.object5);
501         RuleDefinition rule6 = buildTestRuleDefinition(namespace, names.object6);
502         RuleDefinition rule7 = buildTestRuleDefinition(namespace, names.object7);
503 
504         // register attribute types
505         createTestKrmsAttribute(names.actionAttribute0, names.actionAttribute0_Key, names.namespaceName);
506         createTestKrmsAttribute(names.actionAttribute1, names.actionAttribute1_Key, names.namespaceName);
507 
508         // create rule action attributes
509         Map<String, String> actionAttributesOBJECT7 = new HashMap<String, String>();
510         actionAttributesOBJECT7.put(names.actionAttribute_Key, names.actionAttribute_Value);
511 
512         // create rule actions
513         buildTestActionDefinition(names.action_Id, names.action_Name, names.action_Descr, 1, rule7.getId(),
514                 names.namespaceName, actionAttributesOBJECT7);
515 
516         // create agendaItems
517         buildTestAgendaItemDefinition(names.agendaItem_7_Id, agenda.getId(), rule7.getId());
518 
519         AgendaItemDefinition agendaItemOBJECT6 = buildTestAgendaItemDefinition(names.agendaItem_6_Id, agenda.getId(),
520                 rule6.getId());
521 
522         AgendaItemDefinition agendaItemOBJECT5 = buildTestAgendaItemDefinition(names.agendaItem_5_Id, agenda.getId(),
523                 rule5.getId());
524 
525         AgendaItemDefinition agendaItemOBJECT4 = buildTestAgendaItemDefinition(names.agendaItem_4_Id, agenda.getId(),
526                 rule4.getId());
527 
528         AgendaItemDefinition agendaItemOBJECT3 = buildTestAgendaItemDefinition(names.agendaItem_3_Id, agenda.getId(),
529                 rule3.getId());
530 
531         AgendaItemDefinition agendaItemOBJECT2 = buildTestAgendaItemDefinition(names.agendaItem_2_Id, agenda.getId(),
532                 rule2.getId());
533 
534         AgendaItemDefinition.Builder itemBuilderOBJECT2 = AgendaItemDefinition.Builder.create(agendaItemOBJECT2);
535         AgendaItemDefinition.Builder itemBuilderOBJECT4 = AgendaItemDefinition.Builder.create(agendaItemOBJECT4);
536         itemBuilderOBJECT2.setWhenFalse(itemBuilderOBJECT4);
537         itemBuilderOBJECT2.setWhenFalseId(itemBuilderOBJECT4.getId());
538         AgendaItemDefinition.Builder itemBuilderOBJECT6 = AgendaItemDefinition.Builder.create(agendaItemOBJECT6);
539         itemBuilderOBJECT2.setAlways(itemBuilderOBJECT6);
540         itemBuilderOBJECT2.setAlwaysId(itemBuilderOBJECT6.getId());
541 
542         // update and re-fetch
543         ruleManagementService.updateAgendaItem(itemBuilderOBJECT2.build());
544         itemBuilderOBJECT2 =
545                 AgendaItemDefinition.Builder.create(ruleManagementService.getAgendaItem(itemBuilderOBJECT2.getId()));
546 
547         AgendaItemDefinition agendaItemOBJECT1 = buildTestAgendaItemDefinition(names.agendaItem_1_Id, agenda.getId(),
548                 rule1.getId());
549         AgendaItemDefinition.Builder itemBuilderOBJECT1 = AgendaItemDefinition.Builder.create(agendaItemOBJECT1);
550         AgendaItemDefinition.Builder itemBuilderOBJECT5 = AgendaItemDefinition.Builder.create(agendaItemOBJECT5);
551         itemBuilderOBJECT1.setAlways(itemBuilderOBJECT5);
552         itemBuilderOBJECT1.setAlwaysId(itemBuilderOBJECT5.getId());
553         itemBuilderOBJECT1 = AgendaItemDefinition.Builder.create(ruleManagementService.createAgendaItem(
554                 itemBuilderOBJECT1.build()));
555 
556         AgendaItemDefinition agendaItemOBJECT0 = buildTestAgendaItemDefinition(names.agendaItem_0_Id, agenda.getId(),
557                 rule0.getId());
558         AgendaItemDefinition.Builder itemBuilderOBJECT0 = AgendaItemDefinition.Builder.create(agendaItemOBJECT0);
559         itemBuilderOBJECT1 = AgendaItemDefinition.Builder.create(ruleManagementService.getAgendaItem(itemBuilderOBJECT1.getId()));
560         itemBuilderOBJECT0.setWhenTrue(itemBuilderOBJECT1);
561         itemBuilderOBJECT0.setWhenTrueId(itemBuilderOBJECT1.getId());
562         itemBuilderOBJECT2 = AgendaItemDefinition.Builder.create(ruleManagementService.getAgendaItem(itemBuilderOBJECT2.getId()));
563         itemBuilderOBJECT0.setWhenFalse(itemBuilderOBJECT2);
564         itemBuilderOBJECT0.setWhenFalseId(itemBuilderOBJECT2.getId());
565         AgendaItemDefinition.Builder itemBuilderOBJECT3 = AgendaItemDefinition.Builder.create(agendaItemOBJECT3);
566         itemBuilderOBJECT0.setAlways(itemBuilderOBJECT3);
567         itemBuilderOBJECT0.setAlwaysId(itemBuilderOBJECT3.getId());
568         itemBuilderOBJECT0 = AgendaItemDefinition.Builder.create(ruleManagementService.createAgendaItem(itemBuilderOBJECT0.build()));
569 
570         agendaBuilder = AgendaDefinition.Builder.create(ruleManagementService.getAgenda(agenda.getId()));
571         agendaBuilder.setFirstItemId(itemBuilderOBJECT0.getId());
572         ruleManagementService.updateAgenda(agendaBuilder.build());
573         List<AgendaItemDefinition> agendaItems = ruleManagementService.getAgendaItemsByContext(names.contextId);
574 
575         assertEquals("Invalid number of agendaItems created", 8, agendaItems.size());
576 
577         return AgendaDefinition.Builder.create(ruleManagementService.getAgenda(agenda.getId()));
578     }
579 
580     /**
581      *  createTestReferenceObjectBinding creates a ReferenceObjectBinding entry in the database for testing
582      *
583      * @param objectDiscriminator
584      *
585      * @return {@link ReferenceObjectBinding.Builder}
586      */
587     protected ReferenceObjectBinding.Builder createTestReferenceObjectBinding(String objectDiscriminator) {
588         String namespace = "Namespace" + objectDiscriminator;
589         AgendaDefinition agendaDefinition = createTestAgenda(objectDiscriminator);
590         // create krms type for AgendaOBJECT
591         KrmsTypeDefinition krmsTypeDefinition = createKrmsTypeDefinition(null, namespace, "AgendaType" + objectDiscriminator, null);
592 
593         return createReferenceObjectBinding("ParkingPolicies", agendaDefinition.getId(), krmsTypeDefinition.getId(),
594                 namespace, "PA" + objectDiscriminator, "ParkingAffiliationType", true);
595     }
596 
597     /**
598      *   createReferenceObjectBinding create a ReferenceObjectBinding entry in the database for testing
599      * @param collectionName
600      * @param krmsObjectId
601      * @param krmsDiscriminatorType
602      * @param namespace
603      * @param referenceObjectId
604      * @param referenceDiscriminatorType
605      * @param active
606      *
607      * @return {@link ReferenceObjectBinding.Builder}
608      */
609     protected ReferenceObjectBinding.Builder createReferenceObjectBinding(String collectionName, String krmsObjectId,
610             String krmsDiscriminatorType, String namespace, String referenceObjectId, String referenceDiscriminatorType,
611             boolean active) {
612 
613         ReferenceObjectBinding.Builder refObjBindingBuilder = ReferenceObjectBinding.Builder.
614                 create(krmsDiscriminatorType, krmsObjectId, namespace, referenceDiscriminatorType,   referenceObjectId);
615         refObjBindingBuilder.setCollectionName(collectionName);
616         refObjBindingBuilder.setActive(active);
617 
618         return  ReferenceObjectBinding.Builder.create(ruleManagementService.createReferenceObjectBinding(
619                 refObjBindingBuilder.build()));
620     }
621 
622     /**
623      * Used to create a NaturalLanguageTemplate in the database for testing.
624      *
625      * @param namespace of the KRMS Type which may be created
626      * @param langCode  The two character code of applicable language
627      * @param nlObjectName  Seed value to create unique Template and Usage records
628      * @param template The text of the template for the Template record
629      *
630      * @return {@link NaturalLanguageTemplate} for the created Template
631      */
632     protected NaturalLanguageTemplate createTestNaturalLanguageTemplate(String namespace, String langCode,
633             String nlObjectName, String template, boolean createIdFromLangCodeAndNlObjectName) {
634         return createTestNaturalLanguageTemplate(namespace, langCode,
635                 nlObjectName, template, "krms.nl." + nlObjectName, createIdFromLangCodeAndNlObjectName);
636     }
637 
638     /**
639      * Used to create a NaturalLanguageTemplate in the database for testing.
640      *
641      * @param namespace of the KRMS Type which may be created
642      * @param langCode  The two character code of applicable language
643      * @param nlObjectName  Seed value to create unique Template and Usage records
644      * @param template The text of the template for the Template record
645      * @param nlUsage NaturalLanguateUsageId for the Template record
646      *
647      * @return {@link NaturalLanguageTemplate} for the created Template
648      */
649     protected NaturalLanguageTemplate createTestNaturalLanguageTemplate(String namespace, String langCode,
650             String nlObjectName, String template, String nlUsage, boolean createIdFromLangCodeAndNlObjectName) {
651         KrmsTypeDefinition  krmsType = createKrmsTypeDefinition(null, namespace, nlObjectName, null);
652 
653         // create NaturalLanguageUsage if it does not exist
654         if (ObjectUtils.isNull(ruleManagementService.getNaturalLanguageUsage(nlUsage))) {
655             NaturalLanguageUsage.Builder naturalLanguageUsageBuilder =  NaturalLanguageUsage.Builder.create(nlObjectName,namespace );
656             naturalLanguageUsageBuilder.setId(nlUsage);
657             naturalLanguageUsageBuilder.setDescription("Description-" + nlObjectName);
658             naturalLanguageUsageBuilder.setActive(true);
659             NaturalLanguageUsage naturalLangumageUsage =  ruleManagementService.createNaturalLanguageUsage(naturalLanguageUsageBuilder.build());
660         }
661 
662         // create  NaturalLanguageTemplate attributes if they don't exist
663         createTestKrmsAttribute(langCode + "_" + nlObjectName + "Attribute1",  nlObjectName + "TemplateAttributeName1", namespace);
664         createTestKrmsAttribute(langCode + "_" + nlObjectName + "Attribute2",  nlObjectName + "TemplateAttributeName2", namespace);
665         Map<String, String> nlAttributes = new HashMap<String, String>();
666         nlAttributes.put( nlObjectName + "TemplateAttributeName1","value1");
667         nlAttributes.put( nlObjectName + "TemplateAttributeName2","value2");
668 
669         // create NaturalLanguageTemplate
670         String naturalLanguageUsageId = nlUsage;
671         String typeId = krmsType.getId();
672         NaturalLanguageTemplate.Builder naturalLanguageTemplateBuilder = NaturalLanguageTemplate.Builder.create(
673                 langCode, naturalLanguageUsageId, template, typeId);
674         naturalLanguageTemplateBuilder.setActive(true);
675         if (createIdFromLangCodeAndNlObjectName) {
676             naturalLanguageTemplateBuilder.setId(langCode + "-" + nlObjectName);
677         }
678         naturalLanguageTemplateBuilder.setAttributes(nlAttributes);
679 
680         return ruleManagementService.createNaturalLanguageTemplate(naturalLanguageTemplateBuilder.build());
681     }
682 
683     /**
684      *  createTestKrmsAttribute create KrmsAttribute in the database
685      *
686      * @param id
687      * @param name
688      * @param namespace
689      *
690      * @return {@link KrmsAttributeDefinition}
691      */
692     protected KrmsAttributeDefinition createTestKrmsAttribute(String id, String name, String namespace) {
693         // if the AttributeDefinition does not exist, create it
694 
695         if (ObjectUtils.isNull(krmsAttributeDefinitionService.getAttributeDefinitionById(id))) {
696             KrmsAttributeDefinition.Builder krmsAttributeDefinitionBuilder = KrmsAttributeDefinition.Builder.create(id, name, namespace);
697             KrmsAttributeDefinition  krmsAttributeDefinition = krmsAttributeDefinitionService.createAttributeDefinition(krmsAttributeDefinitionBuilder.build());
698         }
699 
700         return krmsAttributeDefinitionService.getAttributeDefinitionById(id);
701     }
702 
703     /**
704      * Used to build a NaturalLanguageUsage entry in the database for testing.
705      *
706      *    The test NaturalLanguageUsage object wll have the form
707      *        Namespace    as passed
708      *        Name         nlUsageName as passed
709      *        Id           "krms.nl." with nlUsageName appended
710      *        Description  "Description" with nlUsageName appended
711      *        Active       set to true
712      *
713      *    A krms type entry will be created for the namespace name passed (if it doesn't already exist)
714      *
715      * @param namespace will be used as namespace name
716      * @param nlUsageName is the name of the NaturalLanguageUsage to be create
717      *
718      * @return {@link NaturalLanguageUsage}
719      */
720     protected NaturalLanguageUsage buildTestNaturalLanguageUsage(String namespace, String nlUsageName ) {
721         KrmsTypeDefinition  krmsType = createKrmsTypeDefinition(null, namespace, nlUsageName, null);
722 
723         // create NaturalLanguageUsage
724         NaturalLanguageUsage.Builder naturalLanguageUsageBuilder =  NaturalLanguageUsage.Builder.create(nlUsageName,namespace );
725         naturalLanguageUsageBuilder.setId("krms.nl." + nlUsageName);
726         naturalLanguageUsageBuilder.setDescription("Description-" + nlUsageName);
727         naturalLanguageUsageBuilder.setActive(true);
728 
729         return  ruleManagementService.createNaturalLanguageUsage(naturalLanguageUsageBuilder.build());
730     }
731 
732     /**
733      * Used to build a ContextDefinition in the database for testing.
734      *
735      *    The test Context created will have the form ContextId0", "Namespace0", "ContextName0"
736      *        where 0 represents the objectDiscriminator passed
737      *
738      * @param objectDiscriminator is a value use to create a unique test Context
739      *
740      * @return {@link ContextDefinition} for the created Template
741      */
742     protected ContextDefinition buildTestContext(String objectDiscriminator) {
743         String namespace =  "Namespace" + objectDiscriminator;
744         String contextId = "ContextId" + objectDiscriminator;
745         String contextName = "ContextName" + objectDiscriminator;
746 
747         ContextDefinition.Builder contextDefinitionBuilder = ContextDefinition.Builder.create(namespace, contextName);
748         contextDefinitionBuilder.setId(contextId);
749         String id = ruleManagementService.createContext(contextDefinitionBuilder.build()).getId();
750         ContextDefinition contextDefinition = ruleManagementService.getContext(id);
751 
752         return contextDefinition;
753     }
754 
755     /**
756      *  createTestCompoundProposition Create a complex Compound Proposition entry in the database
757      // **************************
758      // Compound Proposition (True if Account is 54321 and Occasion is either a Conference or Training)
759      // ***************************
760      //  C1_compound_proposition            "COMPOUND" "S1_simple_proposition"  "S2_simple_proposition"   "&"
761      //      S1_simple_proposition          "SIMPLE"   "Account"                "54321"                   "="
762      //      S2_simple_proposition          "SIMPLE"   "Occasion"               "Conference"              "="
763 
764      * @param t0
765      * @return
766      */
767     protected PropositionDefinition createTestCompoundProposition(RuleManagementBaseTestObjectNames t0){
768         // create a child proposition record
769         PropositionDefinition propS2 = createTestSimpleProposition(
770                 t0.namespaceName, "S2", "Occasion", "Conference", "=", "java.lang.String", t0.rule_0_Id, "Special Event");
771         PropositionDefinition.Builder propBuilderS2 = PropositionDefinition.Builder.create(propS2);
772 
773         // create a child proposition record
774         PropositionDefinition propS1 = createTestSimpleProposition(
775                 t0.namespaceName, "S1", "Account", "54321", "=", "java.lang.String", t0.rule_0_Id, "Charged To Account");
776         PropositionDefinition.Builder propBuilderS1 = PropositionDefinition.Builder.create(propS1);
777 
778         // create a compound proposition record (referencing the two child records
779         KrmsTypeDefinition krmsTypeDefinition = createKrmsTypeDefinition(null, t0.namespaceName, "proposition", "testTypeService");
780         PropositionDefinition.Builder propBuilderC1 = PropositionDefinition.Builder.create(
781                 null,PropositionType.COMPOUND.getCode(),t0.rule_0_Id,null,new ArrayList<PropositionParameter.Builder>());
782         propBuilderC1.compoundOpCode(LogicalOperator.AND.getCode());
783         List<PropositionDefinition.Builder> compoundComponentsC1 = new ArrayList<PropositionDefinition.Builder>();
784         compoundComponentsC1.add(propBuilderS1);
785         compoundComponentsC1.add(propBuilderS2);
786         propBuilderC1.setCompoundComponents(compoundComponentsC1);
787         propBuilderC1.setDescription("C1_compound_proposition");
788         propBuilderC1.setTypeId(krmsTypeDefinition.getId());
789 
790         return ruleManagementService.createProposition(propBuilderC1.build());
791     }
792 
793     protected KrmsTypeDefinition createKrmsActionTypeDefinition(String nameSpace) {
794         String ACTION_TYPE_NAME = "KrmsActionResolverType";
795         KrmsTypeDefinition krmsActionTypeDefinition =  krmsTypeRepository.getTypeByName(nameSpace, ACTION_TYPE_NAME);
796 
797         if (krmsActionTypeDefinition == null) {
798             KrmsTypeDefinition.Builder krmsActionTypeDefnBuilder = KrmsTypeDefinition.Builder.create(ACTION_TYPE_NAME, nameSpace);
799             krmsActionTypeDefnBuilder.setServiceName("testActionTypeService");
800             krmsActionTypeDefinition = krmsTypeRepository.createKrmsType(krmsActionTypeDefnBuilder.build());
801         }
802 
803         return krmsActionTypeDefinition;
804     }
805 }