View Javadoc
1   /*
2    * Copyright 2006-2013 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.lang.StringUtils;
20  import org.junit.Before;
21  import org.junit.Test;
22  import org.kuali.rice.core.api.criteria.QueryByCriteria;
23  import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
24  import org.kuali.rice.krms.api.repository.action.ActionDefinition;
25  import org.kuali.rice.krms.api.repository.agenda.AgendaItemDefinition;
26  import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition;
27  import org.kuali.rice.krms.api.repository.rule.RuleDefinition;
28  import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition;
29  import org.kuali.rice.krms.impl.repository.ActionAttributeBo;
30  
31  import java.util.ArrayList;
32  import java.util.Arrays;
33  import java.util.Collection;
34  import java.util.HashMap;
35  import java.util.List;
36  import java.util.Map;
37  import java.util.Set;
38  
39  import static org.junit.Assert.*;
40  import static org.junit.Assert.assertEquals;
41  import static org.kuali.rice.core.api.criteria.PredicateFactory.equal;
42  import static org.kuali.rice.core.api.criteria.PredicateFactory.in;
43  
44  
45  /**
46   *   RuleManagementRuleDefinitionTest is to test the methods of ruleManagementServiceImpl relating to RuleDefinitions
47   *
48   *   Each test focuses on one of the methods.
49   */
50  public class RuleManagementRuleDefinitionTest  extends RuleManagementBaseTest{
51      @Override
52      @Before
53      public void setClassDiscriminator() {
54          // set a unique discriminator for test objects of this class
55          CLASS_DISCRIMINATOR = "RMRDT";
56      }
57  
58      /**
59       *  Test testGetRuleByNameAndNamespace()
60       *
61       *  This test focuses specifically on the RuleManagementServiceImpl .getRuleByNameAndNamespace("rule name", "namespace") method
62       */
63      @Test
64      public void testGetRuleByNameAndNamespace() {
65          // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class)
66          RuleManagementBaseTestObjectNames t0 =  new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t0");
67  
68          RuleDefinition ruleDefinition = buildTestRuleDefinition(t0.namespaceName, t0.object0);
69  
70          RuleDefinition returnRuleDefinition = ruleManagementService.getRuleByNameAndNamespace(
71                  ruleDefinition.getName(), ruleDefinition.getNamespace());
72  
73          assertEquals("rule not found", ruleDefinition.getId(), returnRuleDefinition.getId());
74  
75          // try getRuleByNameAndNamespace with null Name parameter
76          try {
77              ruleManagementService.getRuleByNameAndNamespace(null, t0.namespaceName);
78              fail("Should have thrown IllegalArgumentException: name is null or blank");
79          } catch (IllegalArgumentException e) {
80              // throws IllegalArgumentException: name is null or blank
81          }
82  
83          // try getRuleByNameAndNamespace with null Name parameter
84          try {
85              ruleManagementService.getRuleByNameAndNamespace("   ", t0.namespaceName);
86              fail("Should have thrown IllegalArgumentException: name is null or blank");
87          } catch (IllegalArgumentException e) {
88              // throws IllegalArgumentException: name is null or blank
89          }
90  
91          // try getRuleByNameAndNamespace with null namespace parameter
92          try {
93              ruleManagementService.getRuleByNameAndNamespace(ruleDefinition.getName(),null);
94              fail("should throw IllegalArgumentException: namespace is null or blank");
95          } catch (IllegalArgumentException e) {
96              // IllegalArgumentException: namespace is null or blank
97          }
98  
99          // try getRuleByNameAndNamespace with blank namespace parameter
100         try {
101             ruleManagementService.getRuleByNameAndNamespace(ruleDefinition.getName(),"    ");
102             fail("should throw IllegalArgumentException: namespace is null or blank");
103         } catch (IllegalArgumentException e) {
104             // IllegalArgumentException: namespace is null or blank
105         }
106 
107 
108     }
109 
110     /**
111      *  Test testCreateRule()
112      *
113      *  This test focuses specifically on the RuleManagementServiceImpl .createRule(RuleDefinition) method
114      */
115     @Test
116     public void testCreateRule() {
117         // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class)
118         RuleManagementBaseTestObjectNames t1 =  new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t1");
119 
120         // create a Rule
121         RuleDefinition ruleFirstCreate = buildTestRuleDefinition(t1.namespaceName, t1.object0);
122         assertTrue("created Rule not found", ruleManagementService.getRule(ruleFirstCreate.getId()).getId().contains(t1.rule_0_Id));
123 
124         // try to create a duplicate Rule
125         try {
126             RuleDefinition ruleSecondCreate = ruleManagementService.createRule(ruleFirstCreate);
127             fail("should have thrown RiceIllegalArgumentException");
128         } catch (RiceIllegalArgumentException e) {
129             //  throw new RiceIllegalArgumentException(ruleDefinition.getId());
130         }
131 
132         // try to create a malformed Rule
133         RuleDefinition malformedRule = buildTestRuleDefinition(t1.namespaceName, t1.object1);
134         RuleDefinition.Builder builder = RuleDefinition.Builder.create(malformedRule);
135         builder.setPropId("invalidValue");
136         malformedRule =  builder.build();
137         try {
138             ruleManagementService.createRule(malformedRule);
139             fail("should have thrown RiceIllegalArgumentException");
140         } catch (RiceIllegalArgumentException e) {
141             // throw new RiceIllegalArgumentException("propId does not match proposition.getId"
142         }
143     }
144 
145     /**
146      *  Test testUpdateRule()
147      *
148      *  This test focuses specifically on the RuleManagementServiceImpl .updateRule(RuleDefinition) method
149      */
150     @Test
151     public void testUpdateRule() {
152         // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class)
153         RuleManagementBaseTestObjectNames t2 =  new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t2");
154 
155         // build a rule to test with
156         RuleDefinition.Builder ruleBuilder0 = RuleDefinition.Builder.create(buildTestRuleDefinition(t2.namespaceName,
157                 t2.object0));
158 
159         // update the rule's Name
160         ruleBuilder0.setName("updatedName");
161         ruleManagementService.updateRule(ruleBuilder0.build());
162 
163         // verify update
164         RuleDefinition rule0 = ruleManagementService.getRule(t2.rule_0_Id);
165         assertNotEquals("Rule Name Not Updated", t2.rule_0_Name, rule0.getName());
166         assertEquals("Rule Name Not Updated", "updatedName", rule0.getName());
167 
168         // build new rule for test
169         RuleDefinition.Builder ruleBuilder1 = RuleDefinition.Builder.create(buildTestRuleDefinition(t2.namespaceName,
170                 t2.object1));
171         assertEquals("Expected Proposition not found in Rule",t2.proposition_1_Descr,ruleBuilder1.getProposition().getDescription());
172 
173         // create new proposition to update rule with
174         String newPropId = "PropNewId";
175         PropositionDefinition prop = createTestSimpleProposition(t2.namespaceName, newPropId, "TSI_"+newPropId,
176                 "ABC", "=", "java.lang.String", t2.rule_0_Id, "TSI_" + newPropId + "_Descr");
177         PropositionDefinition.Builder propBuilder = PropositionDefinition.Builder.create(prop);
178         ruleBuilder1.setPropId(newPropId);
179         ruleBuilder1.setProposition(propBuilder);
180 
181         // Update Proposition in rule
182         ruleManagementService.updateRule(ruleBuilder1.build());
183         rule0 = ruleManagementService.getRule(ruleBuilder1.getId());
184         assertEquals("Expected Proposition not found in Rule","PropNewId_simple_proposition",rule0.getProposition().getDescription());
185 
186         // build new rule for test
187         RuleDefinition.Builder ruleBuilder2 = RuleDefinition.Builder.create(buildTestRuleDefinition(t2.namespaceName,t2.object7));
188         createTestKrmsAttribute(t2.actionAttribute, t2.actionAttribute_Key, t2.namespaceName);
189         Map<String, String> attributes = new HashMap<String, String>();
190         attributes.put(t2.actionAttribute_Key, t2.actionAttribute_Value);
191         List<ActionDefinition.Builder> actionBuilders = new ArrayList<ActionDefinition.Builder>();
192         KrmsTypeDefinition krmsTypeDefinition = createKrmsActionTypeDefinition(t2.namespaceName);
193         ActionDefinition.Builder actionBuilder = ActionDefinition.Builder.create(t2.action_Id, t2.action_Name,
194                 t2.namespaceName, krmsTypeDefinition.getId(), rule0.getId(), 1);
195         actionBuilder.setDescription(t2.action_Descr);
196         actionBuilder.setAttributes(attributes);
197         actionBuilders.add(actionBuilder);
198         ruleBuilder2.setActions(actionBuilders);
199         ruleManagementService.updateRule(ruleBuilder2.build());
200 
201         // Update Action in rule
202         ruleBuilder2 = RuleDefinition.Builder.create(ruleManagementService.getRule(t2.rule_7_Id));
203         Map<String, String> newAttributes = new HashMap<String, String>();
204         newAttributes.put(t2.actionAttribute_Key, t2.actionAttribute1_Value);
205         for (ActionDefinition.Builder ruleActionBuilder : ruleBuilder2.getActions()) {
206             ruleActionBuilder.setAttributes(newAttributes);
207         }
208         ruleManagementService.updateRule(ruleBuilder2.build());
209         rule0 = ruleManagementService.getRule(t2.rule_7_Id);
210         assertEquals("Invalid AgendaItem Rule Actions count",1,rule0.getActions().size());
211         for (ActionDefinition action : rule0.getActions()) {
212             Map<String, Object> map = new HashMap<String, Object>();
213             map.put("actionId", action.getId());
214             Collection<ActionAttributeBo> actionAttributes = businessObjectService.findMatching(ActionAttributeBo.class, map);
215             assertEquals("Invalid AgendaItem Rule Actions attribute count",1,actionAttributes.size());
216             for (ActionAttributeBo actionAttribute : actionAttributes) {
217                 String expectedAttribute = t2.actionAttribute1_Value;
218                 String actualAttribute = actionAttribute.getValue();
219                 assertEquals("Invalid AgendaItem Rule Actions attribute",expectedAttribute,actualAttribute);
220             }
221         }
222     }
223 
224     /**
225      *  Test testDeleteRule()
226      *
227      *  This test focuses specifically on the RuleManagementServiceImpl .deleteRule("rule id") method
228      */
229     @Test
230     public void testDeleteRule() {
231         // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class)
232         RuleManagementBaseTestObjectNames t3 =  new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t3");
233 
234         // create a Rule
235         RuleDefinition rule = buildTestRuleDefinition(t3.namespaceName, t3.object0);
236         assertTrue("created Rule not found", ruleManagementService.getRule(rule.getId()).getId().contains(t3.rule_0_Id));
237         String propositionId = rule.getPropId();
238         assertEquals("Proposition for Rule not found", t3.proposition_0_Descr,
239                 ruleManagementService.getProposition(propositionId).getDescription());
240 
241 
242         ruleManagementService.deleteRule(rule.getId());
243 
244         assertNull("Rule was not deleted", ruleManagementService.getRule(rule.getId()));
245 
246         // make sure proposition was cleaned up when rule was deleted
247         try {
248             ruleManagementService.deleteProposition(propositionId);
249             fail("should fail with IllegalStateException: the Proposition to delete does not exists");
250         } catch (IllegalStateException e) {
251             // IllegalStateException: the Proposition to delete does not exists
252         }
253     }
254 
255     /**
256      *  Test testFindRuleIds()
257      *
258      *  This test focuses specifically on the RuleManagementServiceImpl .findRuleIds( QueryByCriteria) method
259      */
260     @Test
261     public void testFindRuleIds() {
262         // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class)
263         RuleManagementBaseTestObjectNames t4 =  new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t4");
264 
265         RuleDefinition rule0 = buildTestRuleDefinition(t4.namespaceName, t4.object0);
266         RuleDefinition rule1 = buildTestRuleDefinition(t4.namespaceName, t4.object1);
267         RuleDefinition rule2 = buildTestRuleDefinition(t4.namespaceName, t4.object2);
268         RuleDefinition rule3 = buildTestRuleDefinition(t4.namespaceName, t4.object3);
269         String ruleNameSpace = rule0.getNamespace();
270         List<String> ruleNames =  new ArrayList<String>();
271         ruleNames.add(rule0.getName());
272         ruleNames.add(rule1.getName());
273         ruleNames.add(rule2.getName());
274         ruleNames.add(rule3.getName());
275 
276         QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
277 
278         builder.setPredicates(equal("namespace", ruleNameSpace), in("name", ruleNames.toArray(new String[]{})));
279 
280         List<String> ruleIds = ruleManagementService.findRuleIds(builder.build());
281         assertEquals("Wrong number of RuleIds returned", 4, ruleIds.size());
282 
283         if(!ruleIds.contains(rule0.getId())){
284             fail("RuleId not found in results");
285         }
286     }
287 
288     /**
289      *  Test testGetRule()
290      *
291      *  This test focuses specifically on the RuleManagementServiceImpl .getRule("rule id") method
292      */
293     @Test
294     public void testGetRule() {
295         // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class)
296         RuleManagementBaseTestObjectNames t5 =  new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t5");
297 
298         // create a rule to test with
299         RuleDefinition ruleDefinition = buildTestRuleDefinition(t5.namespaceName, t5.object0);
300 
301         assertNotNull(ruleManagementService.getRule(ruleDefinition.getId()));
302 
303         assertNull("Should have returned null", ruleManagementService.getRule(null));
304         assertNull("Should have returned null", ruleManagementService.getRule("   "));
305         assertNull("Should have returned null", ruleManagementService.getRule("badValueId"));
306     }
307 
308     /**
309      *  Test testGetRules()
310      *
311      *  This test focuses specifically on the RuleManagementServiceImpl .getRules(List<String> ruleIds) method
312      */
313     @Test
314     public void testGetRules() {
315         // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class)
316         RuleManagementBaseTestObjectNames t6 =  new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t6");
317 
318         // build two rules for testing
319         buildTestRuleDefinition(t6.namespaceName, t6.object0);
320         buildTestRuleDefinition(t6.namespaceName, t6.object1);
321 
322         // build List rule ids for the rules created
323         List<String> ruleIds = new ArrayList<String>();
324         ruleIds.add(t6.rule_0_Id);
325         ruleIds.add(t6.rule_1_Id);
326 
327         // get test rules by List of rule ids
328         List<RuleDefinition> ruleDefinitions = ruleManagementService.getRules(ruleIds);
329         assertEquals("Two RuleDefintions should have been returned",2,ruleDefinitions.size());
330 
331         for(RuleDefinition ruleDefinition : ruleDefinitions) {
332             if (!ruleIds.contains(ruleDefinition.getId())) {
333                 fail("Invalid RuleDefinition returned");
334             }
335         }
336 
337         try {
338             ruleManagementService.getRules(null);
339             fail("Should have failed with RiceIllegalArgumentException: ruleIds must not be null");
340         } catch (RiceIllegalArgumentException e) {
341             // throws RiceIllegalArgumentException: ruleIds must not be null
342         }
343 
344         assertEquals("No RuleDefinitions should have been returned",0,
345                 ruleManagementService.getRules(new ArrayList<String>()).size());
346 
347         ruleIds = Arrays.asList("badValueId");
348         assertEquals("No RuleDefinitions should have been returned",0, ruleManagementService.getRules(ruleIds).size());
349     }
350 
351     /**
352      * Tests whether the {@code RuleDefinition} cache is being evicted properly by checking the status the dependent
353      * objects before and after creating an {@code RuleDefinition} (and consequently emptying the cache).
354      *
355      * <p>
356      * The following object caches are affected:
357      * {@code RuleDefinition}, {@code PropositionDefinition}, {@code ActionDefinition}, {@code AgendaItemDefinition}
358      * </p>
359      */
360     @Test
361     public void testRuleCacheEvict() {
362         // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class)
363         RuleManagementBaseTestObjectNames t7 =  new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t7");
364 
365         verifyEmptyRule(t7);
366 
367         String ruleId = buildTestRuleDefinition(t7.namespaceName, t7.object0).getId();
368         buildTestActionDefinition(t7.action_Id, t7.action_Name, t7.action_Descr, 1, ruleId, t7.namespaceName);
369         String agendaId = createTestAgenda(t7.object0).getId();
370         buildTestAgendaItemDefinition(t7.agendaItem_Id, agendaId, ruleId);
371 
372         verifyFullRule(t7);
373     }
374 
375     private void verifyEmptyRule(RuleManagementBaseTestObjectNames t) {
376         RuleDefinition rule = ruleManagementService.getRule(t.rule_Id);
377         assertNull("Rule is not null", rule);
378 
379         Set<PropositionDefinition> propositions = ruleManagementService.getPropositionsByRule(t.rule_Id);
380         assertFalse("Rule in Proposition found", propositions != null && !propositions.isEmpty());
381 
382         ActionDefinition action = ruleManagementService.getAction(t.action_Id);
383         assertFalse("Rule in Action found", action != null);
384 
385         AgendaItemDefinition agendaItem = ruleManagementService.getAgendaItem(t.agendaItem_Id);
386         assertFalse("Rule in AgendaItem found", agendaItem != null);
387     }
388 
389     private void verifyFullRule(RuleManagementBaseTestObjectNames t) {
390         RuleDefinition rule = ruleManagementService.getRule(t.rule_Id);
391         assertNotNull("Rule is null", rule);
392 
393         boolean foundRule = false;
394         Set<PropositionDefinition> propositions = ruleManagementService.getPropositionsByRule(t.rule_Id);
395         if (propositions != null) {
396             for (PropositionDefinition proposition : propositions) {
397                 if (StringUtils.equals(t.rule_Id, proposition.getRuleId())) {
398                     foundRule = true;
399                     break;
400                 }
401             }
402         }
403         assertTrue("Rule in Proposition not found", foundRule);
404 
405         ActionDefinition action = ruleManagementService.getAction(t.action_Id);
406         assertTrue("Rule in Action not found", action != null);
407         assertTrue("Rule in Action not found", StringUtils.equals(t.rule_Id, action.getRuleId()));
408 
409         AgendaItemDefinition agendaItem = ruleManagementService.getAgendaItem(t.agendaItem_Id);
410         assertTrue("Rule in AgendaItem not found", agendaItem != null);
411         assertTrue("Rule in AgendaItem not found", StringUtils.equals(t.rule_Id, agendaItem.getRuleId()));
412     }
413 }