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         return agendaItemDefinition;
177     }
178 
179     /**
180      *   buildTestActionDefinition creates Actions in the database for testing
181      *
182      * @param actionId
183      * @param actionName
184      * @param actionDescr
185      * @param actionSequence
186      * @param ruleId
187      * @param namespace
188      *
189      * @return {@link ActionDefinition}
190      */
191     protected ActionDefinition buildTestActionDefinition(String actionId, String actionName, String actionDescr, int actionSequence, String ruleId, String namespace) {
192         return buildTestActionDefinition(actionId, actionName, actionDescr, actionSequence, ruleId, namespace, new HashMap<String, String>());
193     }
194 
195     /**
196      *   buildTestActionDefinition creates Actions in the database for testing
197      *
198      * @param actionId
199      * @param actionName
200      * @param actionDescr
201      * @param actionSequence
202      * @param ruleId
203      * @param namespace
204      * @param attributes
205      *
206      * @return {@link ActionDefinition}
207      */
208     protected ActionDefinition buildTestActionDefinition(String actionId, String actionName, String actionDescr, int actionSequence, String ruleId, String namespace, Map<String, String> attributes) {
209         KrmsTypeDefinition krmsTypeDefinition = createKrmsActionTypeDefinition(namespace);
210 
211         ActionDefinition.Builder actionDefinitionBuilder = ActionDefinition.Builder.create(actionId, actionName,
212                 namespace, krmsTypeDefinition.getId(), ruleId, actionSequence);
213         actionDefinitionBuilder.setDescription(actionDescr);
214         actionDefinitionBuilder.setAttributes(attributes);
215         String id =  ruleManagementService.createAction(actionDefinitionBuilder.build()).getId();
216         ActionDefinition actionDefinition = ruleManagementService.getAction(id);
217 
218         return actionDefinition;
219     }
220 
221     /**
222      *  createTestPropositionForRule will create a PropositionDefinition entry in the database for test purposes
223      *
224      *    The form of the Proposition is   propId_simple_proposition   "SIMPLE"   "TSI_" + propId  "ABC"  "="
225      * @param objectDiscriminator
226      *
227      * @return {@link PropositionDefinition}
228      */
229     protected PropositionDefinition createTestPropositionForRule(String objectDiscriminator) {
230         createKrmsActionTypeDefinition("Namespace" + objectDiscriminator);
231 
232         String namespace = "Namespace" + objectDiscriminator;
233         String propId = "P" + objectDiscriminator;
234         String termSpecId = "TSI_" + propId;
235         String ruleId = "RuleId" + objectDiscriminator;
236         String termSpecDescr = "TSI_" + propId + "_Descr";
237 
238         return createTestSimpleProposition(namespace, propId, termSpecId, "ABC", "=", "java.lang.String", ruleId, termSpecDescr);
239     }
240 
241     /**
242      *  createTestPropositionForTranslation
243      *
244      * @param objectDiscriminator
245      * @param namespace
246      * @param typeName
247      *
248      * @return {@link PropositionDefinition}
249      */
250     protected PropositionDefinition createTestPropositionForTranslation(String objectDiscriminator, String namespace, String typeName) {
251         createKrmsTypeDefinition("TypeId" + objectDiscriminator, namespace, typeName, null);
252 
253         String ruleId = "RuleId" + objectDiscriminator;
254         String propId = "P" + objectDiscriminator;
255 
256         return createTestSimpleProposition(namespace, propId, typeName, "ABC", "=", "java.lang.String", ruleId,
257                 "TSI_" + propId + "_Descr");
258     }
259 
260     /**
261      *   createTestSimpleProposition creates a SIMPLE PropositionDefinition set of entries in the database
262      *
263      * @param namespace of the proposition type
264      * @param propId
265      * @param termSpecId
266      * @param propConstant
267      * @param propOperator
268      * @param termSpecType
269      * @param ruleId
270      * @param termSpecDescr
271      *
272      * @return {@link PropositionDefinition}
273      */
274     protected PropositionDefinition createTestSimpleProposition(String namespace, String propId, String termSpecId, String propConstant, String propOperator, String termSpecType, String ruleId, String termSpecDescr){
275         createTestTermSpecification(termSpecId, termSpecId, namespace, termSpecType, termSpecDescr);
276         KrmsTypeDefinition krmsTypeDefinition = createKrmsTypeDefinition(null, namespace, termSpecId, "testTypeService");
277 
278         PropositionDefinition.Builder propBuilder = PropositionDefinition.Builder.create(null,
279                 PropositionType.SIMPLE.getCode(), ruleId, krmsTypeDefinition.getId(), Collections.<PropositionParameter.Builder>emptyList());
280         propBuilder.setDescription(propId + "_simple_proposition");
281 
282         PropositionDefinition propositionDefinition = ruleManagementService.createProposition(propBuilder.build());
283 
284         List<PropositionParameter.Builder> propParam =  new ArrayList<PropositionParameter.Builder>();
285         propParam.add(PropositionParameter.Builder.create(propId + "_0", propositionDefinition.getId(), termSpecId,
286                 PropositionParameterType.TERM.getCode(), 0));
287         propParam.add(PropositionParameter.Builder.create(propId + "_1", propositionDefinition.getId(), propConstant,
288                 PropositionParameterType.CONSTANT.getCode(), 1));
289         propParam.add(PropositionParameter.Builder.create(propId + "_2", propositionDefinition.getId(), propOperator,
290                 PropositionParameterType.OPERATOR.getCode(), 2));
291 
292         propBuilder = PropositionDefinition.Builder.create(propositionDefinition);
293         propBuilder.setParameters(propParam);
294 
295         ruleManagementService.updateProposition(propBuilder.build());
296         // re-fetch to get the updated version numbers
297         propositionDefinition = ruleManagementService.getProposition(propositionDefinition.getId());
298 
299         return propositionDefinition;
300     }
301 
302     /**
303      *   createTestTermSpecification
304      *
305      * @param termSpecId
306      * @param termSpecName
307      * @param namespace
308      * @param type
309      * @param termSpecDescr
310      *
311      * @return {@link TermSpecificationDefinition}
312      */
313     protected TermSpecificationDefinition createTestTermSpecification(String termSpecId, String termSpecName, String namespace, String type, String termSpecDescr){
314         TermSpecificationDefinition termSpecificationDefinition = termBoService.getTermSpecificationByNameAndNamespace(
315                 termSpecName, namespace);
316 
317         if (termSpecificationDefinition == null) {
318             TermSpecificationDefinition.Builder termSpecificationDefinitionBuilder =
319                     TermSpecificationDefinition.Builder.create(null, termSpecName, namespace, type);
320             termSpecificationDefinitionBuilder.setDescription(termSpecDescr);
321             String id = termBoService.createTermSpecification(termSpecificationDefinitionBuilder.build()).getId();
322             termSpecificationDefinition = termBoService.getTermSpecificationById(id);
323         }
324 
325         return termSpecificationDefinition;
326     }
327 
328     /**
329      * createKrmsTypeDefinition
330      *
331      * @param typeId
332      * @param nameSpace
333      * @param typeName
334      * @param serviceName
335      * @param typeAttributes
336      *
337      * @return {@link KrmsTypeDefinition}
338      */
339     protected KrmsTypeDefinition createKrmsTypeDefinition(String typeId, String nameSpace, String typeName, String serviceName, List<KrmsTypeAttribute.Builder> typeAttributes) {
340         KrmsTypeDefinition krmsTypeDefinition =  krmsTypeRepository.getTypeByName(nameSpace, typeName);
341 
342         if (krmsTypeDefinition == null) {
343             KrmsTypeDefinition.Builder krmsTypeDefnBuilder = KrmsTypeDefinition.Builder.create(typeName, nameSpace);
344 
345             if (!CollectionUtils.isEmpty(typeAttributes)) {
346                 krmsTypeDefnBuilder.setAttributes(typeAttributes);
347             }
348 
349             krmsTypeDefnBuilder.setId(typeId);
350             krmsTypeDefnBuilder.setServiceName(serviceName);
351             String id = krmsTypeRepository.createKrmsType(krmsTypeDefnBuilder.build()).getId();
352             krmsTypeDefinition = krmsTypeRepository.getTypeById(id);
353         }
354 
355         return krmsTypeDefinition;
356     }
357 
358     /**
359      * createKrmsTypeDefinition
360      *
361      * @param typeId
362      * @param nameSpace
363      * @param typeName
364      * @param serviceName
365      *
366      * @return {@link KrmsTypeDefinition}
367      */
368     protected KrmsTypeDefinition createKrmsTypeDefinition(String typeId, String nameSpace, String typeName, String serviceName) {
369         return createKrmsTypeDefinition(typeId, nameSpace, typeName, serviceName, null);
370     }
371 
372     /**
373      * Creates a test agenda setting the createAttributes flag to false
374      * @see #createTestAgenda(String, boolean)
375      */
376     protected AgendaDefinition createTestAgenda(String objectDiscriminator) {
377         return createTestAgenda(objectDiscriminator, false);
378     }
379 
380     /**
381      *   createTestAgenda creates a Agenda set of entries in the database for testing
382      *
383      *       Context ("ContextId0", "Namespace0", "ContextName0")
384      *       Agenda  ("AgendaId0", "AgendaName0")
385      *          AgendaItem ("AI0")
386      *              Rule ("RuleId0")
387      *      where 0 represents a discriminator value
388      *
389      * @param objectDiscriminator
390      * @param createAttributes flag to have an attribute definition, a type attribute and an agenda attribute created
391      *
392      * @return {@link AgendaDefinition.Builder}
393      */
394     protected AgendaDefinition createTestAgenda(String objectDiscriminator, boolean createAttributes) {
395         String namespace =  "Namespace" + objectDiscriminator;
396         String typeId = "TypeId" + objectDiscriminator;
397         String typeName = "TypeName" + objectDiscriminator;
398         String agendaId = "AgendaId" + objectDiscriminator;
399         String agendaName = "AgendaName" + objectDiscriminator;
400 
401         List<KrmsTypeAttribute.Builder> typeAttrs = Collections.emptyList();
402 
403         String attrDefName = "AttrName" + objectDiscriminator;
404         String attrValue = "AttrVal" + objectDiscriminator;
405 
406         if (createAttributes) {
407             // create an attribute definition
408             String attrDefId = "KRTEST" + objectDiscriminator;
409             String attrNamespace = "Namespace" + objectDiscriminator;
410 
411             KrmsAttributeDefinition attrDef = createTestKrmsAttribute(attrDefId, attrDefName, attrNamespace);
412 
413             typeAttrs = Collections.singletonList(KrmsTypeAttribute.Builder.create(null, attrDef.getId(), 1));
414         }
415 
416         // create a type
417         KrmsTypeDefinition krmsTypeDefinition = createKrmsTypeDefinition(typeId, namespace, typeName, null, typeAttrs);
418 
419         // create a context
420         ContextDefinition contextDefinition = buildTestContext(objectDiscriminator);
421 
422         // create an agenda (an agendaItem cannot be created without an existing agenda).
423         AgendaDefinition.Builder agendaBuilder = AgendaDefinition.Builder.create(agendaId, agendaName,
424                 krmsTypeDefinition.getId(), contextDefinition.getId());
425 
426         if (createAttributes) {
427             agendaBuilder.setAttributes(Collections.singletonMap(attrDefName, attrValue));
428         }
429 
430         String id = ruleManagementService.createAgenda(agendaBuilder.build()).getId();
431         AgendaDefinition agendaDefinition = ruleManagementService.getAgenda(id);
432 
433         return agendaDefinition;
434     }
435 
436     protected AgendaDefinition.Builder buildComplexAgenda(RuleManagementBaseTestObjectNames names) {
437         String namespace = "Namespace" + names.discriminator;
438         return createComplexAgenda(namespace, "AGENDA", names);
439     }
440 
441     /**
442      *   createComplexAgenda creates a "complex" agenda object in the database for testing
443      *
444      *   Structure of the created agenda is as shown here.
445      *           // agenda
446      //   agendaItem0 ( rule0)
447      //       WhenTrue   agendaItem1( rule1 )
448      //       WhenFalse  agendaItem2( rule2 )
449      //       Always     agendaItem3( rule3 )
450      //   agendaItem1 ( rule1 )
451      //       Always     agendaItem5
452      //   agendaItem2 ( rule2 )
453      //       WhenTrue  agendaItem7
454      //       WhenFalse  agendaItem4
455      //       Always     agendaItem6
456      //   agendaItem3 ( rule3 )
457      //   agendaItem4 ( rule4 )
458      //   agendaItem5 ( rule5 )
459      //   agendaItem6 ( rule6 )
460      //   agendaItem7 ( rule7 )
461      //       action  ( key, value )
462      *
463      * @param namespace of the KRMS Agenda to be created
464      * @param namespaceType of the namepace passed (Namespace will be created if it does not exist.)
465      * @param {@link RuleManagementBaseTestObjectNames}  Unique discriminator names to base created Agenda upon
466      *
467      * @return {@link AgendaDefinition.Builder} populated from the built agenda
468      */
469     protected AgendaDefinition.Builder createComplexAgenda(String namespace, String namespaceType,
470             RuleManagementBaseTestObjectNames names) {
471         // create a context
472         ContextDefinition.Builder contextBuilder = ContextDefinition.Builder.create(
473                 namespace, names.contextName);
474         contextBuilder.setId(names.contextId);
475         ContextDefinition context = contextBuilder.build();
476         ruleManagementService.createContext(context );
477 
478         // create krms type AGENDA
479         createKrmsTypeDefinition(null, namespace, namespaceType, null);
480 
481         // create a agenda
482         AgendaDefinition.Builder agendaBuilder = AgendaDefinition.Builder.create(
483                 names.agenda_Id, names.agenda_Name, namespaceType, names.contextId);
484         AgendaDefinition agenda = agendaBuilder.build();
485         agenda = ruleManagementService.createAgenda(agenda);
486 
487         // create rules
488         RuleDefinition rule0 = buildTestRuleDefinition(namespace, names.object0);
489         RuleDefinition rule1 = buildTestRuleDefinition(namespace, names.object1);
490         RuleDefinition rule2 = buildTestRuleDefinition(namespace, names.object2);
491         RuleDefinition rule3 = buildTestRuleDefinition(namespace, names.object3);
492         RuleDefinition rule4 = buildTestRuleDefinition(namespace, names.object4);
493         RuleDefinition rule5 = buildTestRuleDefinition(namespace, names.object5);
494         RuleDefinition rule6 = buildTestRuleDefinition(namespace, names.object6);
495         RuleDefinition rule7 = buildTestRuleDefinition(namespace, names.object7);
496 
497         // create agendaItems
498         AgendaItemDefinition agendaItemOBJECT7 = buildTestAgendaItemDefinition(names.agendaItem_7_Id, agenda.getId(), rule7.getId());
499 
500         AgendaItemDefinition agendaItemOBJECT6 = buildTestAgendaItemDefinition(names.agendaItem_6_Id, agenda.getId(),
501                 rule6.getId());
502 
503         AgendaItemDefinition agendaItemOBJECT5 = buildTestAgendaItemDefinition(names.agendaItem_5_Id, agenda.getId(),
504                 rule5.getId());
505 
506         AgendaItemDefinition agendaItemOBJECT4 = buildTestAgendaItemDefinition(names.agendaItem_4_Id, agenda.getId(),
507                 rule4.getId());
508 
509         AgendaItemDefinition agendaItemOBJECT3 = buildTestAgendaItemDefinition(names.agendaItem_3_Id, agenda.getId(),
510                 rule3.getId());
511 
512         AgendaItemDefinition agendaItemOBJECT2 = buildTestAgendaItemDefinition(names.agendaItem_2_Id, agenda.getId(),
513                 rule2.getId());
514 
515         AgendaItemDefinition.Builder itemBuilderOBJECT2 = AgendaItemDefinition.Builder.create(agendaItemOBJECT2);
516         AgendaItemDefinition.Builder itemBuilderOBJECT4 = AgendaItemDefinition.Builder.create(agendaItemOBJECT4);
517         AgendaItemDefinition.Builder itemBuilderOBJECT7 = AgendaItemDefinition.Builder.create(agendaItemOBJECT7);
518 
519         itemBuilderOBJECT2.setWhenTrue(itemBuilderOBJECT7);
520         itemBuilderOBJECT2.setWhenTrueId(itemBuilderOBJECT7.getId());
521         itemBuilderOBJECT2.setWhenFalse(itemBuilderOBJECT4);
522         itemBuilderOBJECT2.setWhenFalseId(itemBuilderOBJECT4.getId());
523         AgendaItemDefinition.Builder itemBuilderOBJECT6 = AgendaItemDefinition.Builder.create(agendaItemOBJECT6);
524         itemBuilderOBJECT2.setAlways(itemBuilderOBJECT6);
525         itemBuilderOBJECT2.setAlwaysId(itemBuilderOBJECT6.getId());
526 
527         // update and re-fetch
528         ruleManagementService.updateAgendaItem(itemBuilderOBJECT2.build());
529         itemBuilderOBJECT2 =
530                 AgendaItemDefinition.Builder.create(ruleManagementService.getAgendaItem(itemBuilderOBJECT2.getId()));
531 
532         AgendaItemDefinition agendaItemOBJECT1 = buildTestAgendaItemDefinition(names.agendaItem_1_Id, agenda.getId(),
533                 rule1.getId());
534         AgendaItemDefinition.Builder itemBuilderOBJECT1 = AgendaItemDefinition.Builder.create(agendaItemOBJECT1);
535         AgendaItemDefinition.Builder itemBuilderOBJECT5 = AgendaItemDefinition.Builder.create(agendaItemOBJECT5);
536         itemBuilderOBJECT1.setAlways(itemBuilderOBJECT5);
537         itemBuilderOBJECT1.setAlwaysId(itemBuilderOBJECT5.getId());
538         itemBuilderOBJECT1 = AgendaItemDefinition.Builder.create(ruleManagementService.createAgendaItem(
539                 itemBuilderOBJECT1.build()));
540 
541         AgendaItemDefinition agendaItemOBJECT0 = buildTestAgendaItemDefinition(names.agendaItem_0_Id, agenda.getId(),
542                 rule0.getId());
543         AgendaItemDefinition.Builder itemBuilderOBJECT0 = AgendaItemDefinition.Builder.create(agendaItemOBJECT0);
544 
545         itemBuilderOBJECT1 = AgendaItemDefinition.Builder.create(ruleManagementService.getAgendaItem(itemBuilderOBJECT1.getId()));
546         itemBuilderOBJECT0.setWhenTrue(itemBuilderOBJECT1);
547         itemBuilderOBJECT0.setWhenTrueId(itemBuilderOBJECT1.getId());
548 
549         itemBuilderOBJECT2 = AgendaItemDefinition.Builder.create(ruleManagementService.getAgendaItem(itemBuilderOBJECT2.getId()));
550         itemBuilderOBJECT0.setWhenFalse(itemBuilderOBJECT2);
551         itemBuilderOBJECT0.setWhenFalseId(itemBuilderOBJECT2.getId());
552 
553         AgendaItemDefinition.Builder itemBuilderOBJECT3 = AgendaItemDefinition.Builder.create(agendaItemOBJECT3);
554         itemBuilderOBJECT0.setAlways(itemBuilderOBJECT3);
555         itemBuilderOBJECT0.setAlwaysId(itemBuilderOBJECT3.getId());
556         itemBuilderOBJECT0 = AgendaItemDefinition.Builder.create(ruleManagementService.createAgendaItem(itemBuilderOBJECT0.build()));
557 
558         agendaBuilder = AgendaDefinition.Builder.create(ruleManagementService.getAgenda(agenda.getId()));
559         agendaBuilder.setFirstItemId(itemBuilderOBJECT0.getId());
560 
561         // register attribute types
562         createTestKrmsAttribute(names.actionAttribute0, names.actionAttribute0_Key, names.namespaceName);
563         createTestKrmsAttribute(names.actionAttribute1, names.actionAttribute1_Key, names.namespaceName);
564 
565         // create rule action attributes
566         Map<String, String> actionAttributesOBJECT7 = new HashMap<String, String>();
567         actionAttributesOBJECT7.put(names.actionAttribute_Key, names.actionAttribute_Value);
568 
569 
570         // create rule actions
571         buildTestActionDefinition(names.action_Id, names.action_Name, names.action_Descr, 1, rule7.getId(),
572                 names.namespaceName, actionAttributesOBJECT7);
573 
574 
575         ruleManagementService.updateAgenda(agendaBuilder.build());
576         List<AgendaItemDefinition> agendaItems = ruleManagementService.getAgendaItemsByContext(names.contextId);
577 
578 
579 
580         assertEquals("Invalid number of agendaItems created", 8, agendaItems.size());
581 
582         return AgendaDefinition.Builder.create(ruleManagementService.getAgenda(agenda.getId()));
583     }
584 
585     /**
586      *  createTestReferenceObjectBinding creates a ReferenceObjectBinding entry in the database for testing
587      *
588      * @param objectDiscriminator
589      *
590      * @return {@link ReferenceObjectBinding.Builder}
591      */
592     protected ReferenceObjectBinding.Builder createTestReferenceObjectBinding(String objectDiscriminator) {
593         String namespace = "Namespace" + objectDiscriminator;
594         AgendaDefinition agendaDefinition = createTestAgenda(objectDiscriminator);
595         // create krms type for AgendaOBJECT
596         KrmsTypeDefinition krmsTypeDefinition = createKrmsTypeDefinition(null, namespace, "AgendaType" + objectDiscriminator, null);
597 
598         return createReferenceObjectBinding("ParkingPolicies", agendaDefinition.getId(), krmsTypeDefinition.getId(),
599                 namespace, "PA" + objectDiscriminator, "ParkingAffiliationType", true);
600     }
601 
602     /**
603      *   createReferenceObjectBinding create a ReferenceObjectBinding entry in the database for testing
604      * @param collectionName
605      * @param krmsObjectId
606      * @param krmsDiscriminatorType
607      * @param namespace
608      * @param referenceObjectId
609      * @param referenceDiscriminatorType
610      * @param active
611      *
612      * @return {@link ReferenceObjectBinding.Builder}
613      */
614     protected ReferenceObjectBinding.Builder createReferenceObjectBinding(String collectionName, String krmsObjectId,
615             String krmsDiscriminatorType, String namespace, String referenceObjectId, String referenceDiscriminatorType,
616             boolean active) {
617 
618         ReferenceObjectBinding.Builder refObjBindingBuilder = ReferenceObjectBinding.Builder.
619                 create(krmsDiscriminatorType, krmsObjectId, namespace, referenceDiscriminatorType,   referenceObjectId);
620         refObjBindingBuilder.setCollectionName(collectionName);
621         refObjBindingBuilder.setActive(active);
622 
623         return  ReferenceObjectBinding.Builder.create(ruleManagementService.createReferenceObjectBinding(
624                 refObjBindingBuilder.build()));
625     }
626 
627     /**
628      * Used to create a NaturalLanguageTemplate in the database for testing.
629      *
630      * @param namespace of the KRMS Type which may be created
631      * @param langCode  The two character code of applicable language
632      * @param nlObjectName  Seed value to create unique Template and Usage records
633      * @param template The text of the template for the Template record
634      *
635      * @return {@link NaturalLanguageTemplate} for the created Template
636      */
637     protected NaturalLanguageTemplate createTestNaturalLanguageTemplate(String namespace, String langCode,
638             String nlObjectName, String template, boolean createIdFromLangCodeAndNlObjectName) {
639         return createTestNaturalLanguageTemplate(namespace, langCode,
640                 nlObjectName, template, "krms.nl." + nlObjectName, createIdFromLangCodeAndNlObjectName);
641     }
642 
643     /**
644      * Used to create a NaturalLanguageTemplate in the database for testing.
645      *
646      * @param namespace of the KRMS Type which may be created
647      * @param langCode  The two character code of applicable language
648      * @param nlObjectName  Seed value to create unique Template and Usage records
649      * @param template The text of the template for the Template record
650      * @param nlUsage NaturalLanguateUsageId for the Template record
651      *
652      * @return {@link NaturalLanguageTemplate} for the created Template
653      */
654     protected NaturalLanguageTemplate createTestNaturalLanguageTemplate(String namespace, String langCode,
655             String nlObjectName, String template, String nlUsage, boolean createIdFromLangCodeAndNlObjectName) {
656         KrmsTypeDefinition  krmsType = createKrmsTypeDefinition(null, namespace, nlObjectName, null);
657 
658         // create NaturalLanguageUsage if it does not exist
659         if (ObjectUtils.isNull(ruleManagementService.getNaturalLanguageUsage(nlUsage))) {
660             NaturalLanguageUsage.Builder naturalLanguageUsageBuilder =  NaturalLanguageUsage.Builder.create(nlObjectName,namespace );
661             naturalLanguageUsageBuilder.setId(nlUsage);
662             naturalLanguageUsageBuilder.setDescription("Description-" + nlObjectName);
663             naturalLanguageUsageBuilder.setActive(true);
664             NaturalLanguageUsage naturalLangumageUsage =  ruleManagementService.createNaturalLanguageUsage(naturalLanguageUsageBuilder.build());
665         }
666 
667         // create  NaturalLanguageTemplate attributes if they don't exist
668         createTestKrmsAttribute(langCode + "_" + nlObjectName + "Attribute1",  nlObjectName + "TemplateAttributeName1", namespace);
669         createTestKrmsAttribute(langCode + "_" + nlObjectName + "Attribute2",  nlObjectName + "TemplateAttributeName2", namespace);
670         Map<String, String> nlAttributes = new HashMap<String, String>();
671         nlAttributes.put( nlObjectName + "TemplateAttributeName1","value1");
672         nlAttributes.put( nlObjectName + "TemplateAttributeName2","value2");
673 
674         // create NaturalLanguageTemplate
675         String naturalLanguageUsageId = nlUsage;
676         String typeId = krmsType.getId();
677         NaturalLanguageTemplate.Builder naturalLanguageTemplateBuilder = NaturalLanguageTemplate.Builder.create(
678                 langCode, naturalLanguageUsageId, template, typeId);
679         naturalLanguageTemplateBuilder.setActive(true);
680         if (createIdFromLangCodeAndNlObjectName) {
681             naturalLanguageTemplateBuilder.setId(langCode + "-" + nlObjectName);
682         }
683         naturalLanguageTemplateBuilder.setAttributes(nlAttributes);
684 
685         return ruleManagementService.createNaturalLanguageTemplate(naturalLanguageTemplateBuilder.build());
686     }
687 
688     /**
689      *  createTestKrmsAttribute create KrmsAttribute in the database
690      *
691      * @param id
692      * @param name
693      * @param namespace
694      *
695      * @return {@link KrmsAttributeDefinition}
696      */
697     protected KrmsAttributeDefinition createTestKrmsAttribute(String id, String name, String namespace) {
698         // if the AttributeDefinition does not exist, create it
699 
700         if (ObjectUtils.isNull(krmsAttributeDefinitionService.getAttributeDefinitionById(id))) {
701             KrmsAttributeDefinition.Builder krmsAttributeDefinitionBuilder = KrmsAttributeDefinition.Builder.create(id, name, namespace);
702             KrmsAttributeDefinition  krmsAttributeDefinition = krmsAttributeDefinitionService.createAttributeDefinition(krmsAttributeDefinitionBuilder.build());
703         }
704 
705         return krmsAttributeDefinitionService.getAttributeDefinitionById(id);
706     }
707 
708     /**
709      * Used to build a NaturalLanguageUsage entry in the database for testing.
710      *
711      *    The test NaturalLanguageUsage object wll have the form
712      *        Namespace    as passed
713      *        Name         nlUsageName as passed
714      *        Id           "krms.nl." with nlUsageName appended
715      *        Description  "Description" with nlUsageName appended
716      *        Active       set to true
717      *
718      *    A krms type entry will be created for the namespace name passed (if it doesn't already exist)
719      *
720      * @param namespace will be used as namespace name
721      * @param nlUsageName is the name of the NaturalLanguageUsage to be create
722      *
723      * @return {@link NaturalLanguageUsage}
724      */
725     protected NaturalLanguageUsage buildTestNaturalLanguageUsage(String namespace, String nlUsageName ) {
726         KrmsTypeDefinition  krmsType = createKrmsTypeDefinition(null, namespace, nlUsageName, null);
727 
728         // create NaturalLanguageUsage
729         NaturalLanguageUsage.Builder naturalLanguageUsageBuilder =  NaturalLanguageUsage.Builder.create(nlUsageName,namespace );
730         naturalLanguageUsageBuilder.setId("krms.nl." + nlUsageName);
731         naturalLanguageUsageBuilder.setDescription("Description-" + nlUsageName);
732         naturalLanguageUsageBuilder.setActive(true);
733 
734         return  ruleManagementService.createNaturalLanguageUsage(naturalLanguageUsageBuilder.build());
735     }
736 
737     /**
738      * Used to build a ContextDefinition in the database for testing.
739      *
740      *    The test Context created will have the form ContextId0", "Namespace0", "ContextName0"
741      *        where 0 represents the objectDiscriminator passed
742      *
743      * @param objectDiscriminator is a value use to create a unique test Context
744      *
745      * @return {@link ContextDefinition} for the created Template
746      */
747     protected ContextDefinition buildTestContext(String objectDiscriminator) {
748         String namespace =  "Namespace" + objectDiscriminator;
749         String contextId = "ContextId" + objectDiscriminator;
750         String contextName = "ContextName" + objectDiscriminator;
751 
752         ContextDefinition.Builder contextDefinitionBuilder = ContextDefinition.Builder.create(namespace, contextName);
753         contextDefinitionBuilder.setId(contextId);
754         String id = ruleManagementService.createContext(contextDefinitionBuilder.build()).getId();
755         ContextDefinition contextDefinition = ruleManagementService.getContext(id);
756 
757         return contextDefinition;
758     }
759 
760     /**
761      *  createTestCompoundProposition Create a complex Compound Proposition entry in the database
762      // **************************
763      // Compound Proposition (True if Account is 54321 and Occasion is either a Conference or Training)
764      // ***************************
765      //  C1_compound_proposition            "COMPOUND" "S1_simple_proposition"  "S2_simple_proposition"   "&"
766      //      S1_simple_proposition          "SIMPLE"   "Account"                "54321"                   "="
767      //      S2_simple_proposition          "SIMPLE"   "Occasion"               "Conference"              "="
768 
769      * @param t0
770      * @return
771      */
772     protected PropositionDefinition createTestCompoundProposition(RuleManagementBaseTestObjectNames t0){
773         // create a child proposition record
774         PropositionDefinition propS2 = createTestSimpleProposition(
775                 t0.namespaceName, "S2", "Occasion", "Conference", "=", "java.lang.String", t0.rule_0_Id, "Special Event");
776         PropositionDefinition.Builder propBuilderS2 = PropositionDefinition.Builder.create(propS2);
777 
778         // create a child proposition record
779         PropositionDefinition propS1 = createTestSimpleProposition(
780                 t0.namespaceName, "S1", "Account", "54321", "=", "java.lang.String", t0.rule_0_Id, "Charged To Account");
781         PropositionDefinition.Builder propBuilderS1 = PropositionDefinition.Builder.create(propS1);
782 
783         // create a compound proposition record (referencing the two child records
784         KrmsTypeDefinition krmsTypeDefinition = createKrmsTypeDefinition(null, t0.namespaceName, "proposition", "testTypeService");
785         PropositionDefinition.Builder propBuilderC1 = PropositionDefinition.Builder.create(
786                 null,PropositionType.COMPOUND.getCode(),t0.rule_0_Id,null,new ArrayList<PropositionParameter.Builder>());
787         propBuilderC1.compoundOpCode(LogicalOperator.AND.getCode());
788         List<PropositionDefinition.Builder> compoundComponentsC1 = new ArrayList<PropositionDefinition.Builder>();
789         compoundComponentsC1.add(propBuilderS1);
790         compoundComponentsC1.add(propBuilderS2);
791         propBuilderC1.setCompoundComponents(compoundComponentsC1);
792         propBuilderC1.setDescription("C1_compound_proposition");
793         propBuilderC1.setTypeId(krmsTypeDefinition.getId());
794 
795         return ruleManagementService.createProposition(propBuilderC1.build());
796     }
797 
798     protected KrmsTypeDefinition createKrmsActionTypeDefinition(String nameSpace) {
799         String ACTION_TYPE_NAME = "KrmsActionResolverType";
800         KrmsTypeDefinition krmsActionTypeDefinition =  krmsTypeRepository.getTypeByName(nameSpace, ACTION_TYPE_NAME);
801 
802         if (krmsActionTypeDefinition == null) {
803             KrmsTypeDefinition.Builder krmsActionTypeDefnBuilder = KrmsTypeDefinition.Builder.create(ACTION_TYPE_NAME, nameSpace);
804             krmsActionTypeDefnBuilder.setServiceName("testActionTypeService");
805             krmsActionTypeDefinition = krmsTypeRepository.createKrmsType(krmsActionTypeDefnBuilder.build());
806         }
807 
808         return krmsActionTypeDefinition;
809     }
810 }