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