View Javadoc

1   /*
2    * Copyright 2005-2007 The Kuali Foundation
3    *
4    *
5    * Licensed under the Educational Community License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    * http://www.opensource.org/licenses/ecl2.php
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.kuali.rice.kew.rule;
18  
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  import org.apache.log4j.Logger;
25  import org.junit.Test;
26  import org.kuali.rice.core.config.ConfigContext;
27  import org.kuali.rice.kew.batch.KEWXmlDataLoader;
28  import org.kuali.rice.kew.exception.InvalidXmlException;
29  import org.kuali.rice.kew.exception.WorkflowServiceErrorException;
30  import org.kuali.rice.kew.rule.service.RuleService;
31  import org.kuali.rice.kew.service.KEWServiceLocator;
32  import org.kuali.rice.kew.test.KEWTestCase;
33  import org.kuali.rice.kew.test.TestUtilities;
34  import org.kuali.rice.kew.util.KEWConstants;
35  import org.kuali.rice.kew.xml.RuleXmlParser;
36  import org.springframework.test.AssertThrows;
37  
38  
39  public class RuleXmlParserTest extends KEWTestCase {
40      private static final Logger LOG = Logger.getLogger(RuleXmlParserTest.class);
41  
42      protected void loadTestData() throws Exception {
43          loadXmlFile("RouteTemplateConfig.xml");
44          loadXmlFile("DuplicateRuleToImport.xml");
45      }
46  
47      @Test public void testRuleXmlParserCacheUpdate() throws Exception {
48          RuleService ruleService = KEWServiceLocator.getRuleService();
49          int ruleSize = ruleService.fetchAllCurrentRulesForTemplateDocCombination("TestRuleTemplate", "TestDocumentType").size();
50  
51          List collections = new ArrayList();
52          //ultimately it is the content of RulesToImport that determines whether or not we're
53          //going to hit the rules xml parser
54          InputStream xmlFile = TestUtilities.loadResource(this.getClass(), "RulesToImport.xml");
55          collections.add(KEWXmlDataLoader.getFileXmlDocCollection(xmlFile, "WorkflowUnitTestTemp"));
56          KEWServiceLocator.getXmlIngesterService().ingest(collections, null);
57  
58          Thread.sleep(5000);//give cache time to reload;
59          int newRuleSize = ruleService.fetchAllCurrentRulesForTemplateDocCombination("TestRuleTemplate", "TestDocumentType").size();
60          assertEquals("Three more rules should have been returned from the cached service", ruleSize + 3, newRuleSize);
61      }
62  
63      @Test public void testDuplicateRule() throws IOException, InvalidXmlException {
64          InputStream stream = getClass().getResourceAsStream("DuplicateRuleToImport.xml");
65          assertNotNull(stream);
66          log.info("Importing duplicate again");
67          try {
68              KEWServiceLocator.getRuleService().loadXml(stream, null);
69          } catch (WorkflowServiceErrorException wsee) {
70              assertNotNull(TestUtilities.findExceptionInStack(wsee, InvalidXmlException.class));
71          }
72      }
73  
74      @Test public void testDuplicateRuleWithExpression() throws IOException, InvalidXmlException {
75          InputStream stream = getClass().getResourceAsStream("DuplicateRuleToImportWithExpression.xml");
76          assertNotNull(stream);
77          log.info("Importing duplicate again");
78          try {
79              KEWServiceLocator.getRuleService().loadXml(stream, null);
80          } catch (WorkflowServiceErrorException wsee) {
81              assertNotNull(TestUtilities.findExceptionInStack(wsee, InvalidXmlException.class));
82          }
83      }
84  
85      @Test public void testNotDuplicateRule() throws IOException, InvalidXmlException {
86          InputStream stream = getClass().getResourceAsStream("NotADuplicateRuleToImport.xml");
87          assertNotNull(stream);
88          log.info("Importing a unique rule");
89          // load the unique template first
90          KEWServiceLocator.getRuleTemplateService().loadXml(stream, null);
91          stream = getClass().getResourceAsStream("NotADuplicateRuleToImport.xml");
92          // then the rule
93          KEWServiceLocator.getRuleService().loadXml(stream, null);
94      }
95  
96      @Test public void testNotDuplicateRuleWithExpression() throws IOException, InvalidXmlException {
97          InputStream stream = getClass().getResourceAsStream("NotADuplicateRuleToImportWithExpression.xml");
98          assertNotNull(stream);
99          log.info("Importing a unique rule");
100         // load the unique template first
101         KEWServiceLocator.getRuleTemplateService().loadXml(stream, null);
102         stream = getClass().getResourceAsStream("NotADuplicateRuleToImportWithExpression.xml");
103         // then the rule
104         KEWServiceLocator.getRuleService().loadXml(stream, null);
105     }
106 
107     private static RuleExtensionValue getExtensionValue(List<RuleExtensionValue> list, String name) {
108         for (RuleExtensionValue extensionValue: list) {
109             if (name.equals(extensionValue.getKey())) return extensionValue;
110         }
111         return null;
112     }
113 
114     @Test public void testNamedRule() {
115         loadXmlFile("NamedRule.xml");
116         RuleService ruleService = KEWServiceLocator.getRuleService();
117         RuleBaseValues rule = ruleService.getRuleByName("ANamedRule");
118         assertNotNull(rule);
119         assertEquals("ANamedRule", rule.getName());
120         assertEquals("A named rule", rule.getDescription());
121         LOG.info("Before Testing  To and From Dates : " + rule.getToDateString()+" "+rule.getFromDateString());
122         assertNull(rule.getToDateString());
123         assertNull(rule.getFromDateString());
124         LOG.info("Rule To and From Dates : " + rule.getDocTypeName()+" "+rule.getName());
125         List extensions = rule.getRuleExtensions();
126         assertEquals(1, extensions.size());
127         RuleExtension extension = (RuleExtension) extensions.get(0);
128         assertEquals("TestRuleAttribute", extension.getRuleTemplateAttribute().getRuleAttribute().getName());
129         List extensionValues = extension.getExtensionValues();
130         assertEquals(2, extensionValues.size());
131         //RuleExtensionValue extensionValue = (RuleExtensionValue) extensionValues.get(0);
132         RuleExtensionValue extensionValue = getExtensionValue(extensionValues, "color");
133         assertEquals("color", extensionValue.getKey());
134         assertEquals("green", extensionValue.getValue());
135         //extensionValue = (RuleExtensionValue) extensionValues.get(1);
136         extensionValue = getExtensionValue(extensionValues, "shape");
137         assertEquals("shape", extensionValue.getKey());
138         assertEquals("square", extensionValue.getValue());
139         List responsibilities = rule.getResponsibilities();
140         assertEquals(1, responsibilities.size());
141         RuleResponsibility responsibility = (RuleResponsibility) responsibilities.get(0);
142         assertEquals("user1", responsibility.getPrincipal().getPrincipalName());
143         assertEquals("A", responsibility.getActionRequestedCd());
144     }
145 
146     @Test public void testNamedRuleWithExpression() {
147         loadXmlFile("NamedRuleWithExpression.xml");
148         RuleService ruleService = KEWServiceLocator.getRuleService();
149         RuleBaseValues rule = ruleService.getRuleByName("ANamedRule");
150         assertNotNull(rule);
151         assertEquals("ANamedRule", rule.getName());
152         assertEquals("A named rule", rule.getDescription());
153         List extensions = rule.getRuleExtensions();
154         assertEquals(1, extensions.size());
155         RuleExtension extension = (RuleExtension) extensions.get(0);
156         assertEquals("TestRuleAttribute", extension.getRuleTemplateAttribute().getRuleAttribute().getName());
157         List extensionValues = extension.getExtensionValues();
158         assertEquals(2, extensionValues.size());
159         //RuleExtensionValue extensionValue = (RuleExtensionValue) extensionValues.get(0);
160         RuleExtensionValue extensionValue = getExtensionValue(extensionValues, "color");
161         assertEquals("color", extensionValue.getKey());
162         assertEquals("green", extensionValue.getValue());
163         //extensionValue = (RuleExtensionValue) extensionValues.get(1);
164         extensionValue = getExtensionValue(extensionValues, "shape");
165         assertEquals("shape", extensionValue.getKey());
166         assertEquals("square", extensionValue.getValue());
167         List responsibilities = rule.getResponsibilities();
168         assertEquals(1, responsibilities.size());
169         RuleResponsibility responsibility = (RuleResponsibility) responsibilities.get(0);
170         assertEquals("user1", responsibility.getPrincipal().getPrincipalName());
171         assertEquals("A", responsibility.getActionRequestedCd());
172         assertNotNull(rule.getRuleExpressionDef());
173         assertEquals("someType", rule.getRuleExpressionDef().getType());
174         assertEquals("some expression", rule.getRuleExpressionDef().getExpression());
175     }
176 
177     @Test public void testUpdatedRule() {
178         testNamedRule();
179         
180         RuleService ruleService = KEWServiceLocator.getRuleService();
181         // let's grab the responsibility id from the original named rule
182         RuleBaseValues rule = ruleService.getRuleByName("ANamedRule");
183         Long responsibilityId = rule.getResponsibilities().get(0).getResponsibilityId();
184         Long ruleId = rule.getRuleBaseValuesId();
185         Integer versionNumber = rule.getVersionNbr();
186         
187         loadXmlFile("UpdatedNamedRule.xml");
188         rule = ruleService.getRuleByName("ANamedRule");
189         assertNotNull(rule);
190         assertEquals("ANamedRule", rule.getName());
191         assertTrue("Rule should be current.", rule.getCurrentInd());
192         assertFalse("Rule should not be a delegate rule.", rule.getDelegateRule());
193         assertFalse("Rule should not be a template rule.", rule.getTemplateRuleInd());
194         assertNull("Rule should not have a from date.", rule.getFromDate());
195         assertNull("Rule should not have a to date.", rule.getToDate());
196         
197         // check that the previous versions line up and that the rule is not the same
198         assertFalse("Rule ids should be different", ruleId.equals(rule.getRuleBaseValuesId()));
199         assertEquals("Previous version id should be correct", ruleId, rule.getPreviousVersionId());
200         assertEquals("Version ids are incorrect", new Integer(versionNumber + 1), rule.getVersionNbr());
201         // fetch the original rule and verify that it's no longer current
202         RuleBaseValues oldRule = ruleService.findRuleBaseValuesById(ruleId);
203         assertFalse("Old rule should no longer be current.", oldRule.getCurrentInd());
204         
205         assertEquals("A named rule with an updated description, rule extension values, and responsibilities", rule.getDescription());
206         List extensions = rule.getRuleExtensions();
207         assertEquals(1, extensions.size());
208         RuleExtension extension = (RuleExtension) extensions.get(0);
209         assertEquals("TestRuleAttribute", extension.getRuleTemplateAttribute().getRuleAttribute().getName());
210         List extensionValues = extension.getExtensionValues();
211         assertEquals(2, extensionValues.size());
212         //RuleExtensionValue extensionValue = (RuleExtensionValue) extensionValues.get(0);
213         RuleExtensionValue extensionValue = getExtensionValue(extensionValues, "flavor");
214         assertEquals("flavor", extensionValue.getKey());
215         assertEquals("vanilla", extensionValue.getValue());
216         //extensionValue = (RuleExtensionValue) extensionValues.get(1);
217         extensionValue = getExtensionValue(extensionValues, "value");
218         assertEquals("value", extensionValue.getKey());
219         assertEquals("10", extensionValue.getValue());
220         List responsibilities = rule.getResponsibilities();
221         assertEquals(2, responsibilities.size());
222         
223         // responsibility should have the same id as our original responsibility
224         RuleResponsibility responsibility = (RuleResponsibility) responsibilities.get(0);
225         assertEquals(responsibilityId, responsibility.getResponsibilityId());
226         assertEquals("user1", responsibility.getPrincipal().getPrincipalName());
227         assertEquals("A", responsibility.getActionRequestedCd());
228         assertEquals(new Integer(1), responsibility.getPriority());
229         
230         responsibility = (RuleResponsibility) responsibilities.get(1);
231         assertFalse(responsibilityId.equals(responsibility.getResponsibilityId()));
232         assertEquals("user2", responsibility.getPrincipal().getPrincipalName());
233         assertEquals("F", responsibility.getActionRequestedCd());
234         assertEquals(new Integer(1), responsibility.getPriority());
235     }
236 
237     @Test public void testUpdatedRuleWithExpression() {
238         testNamedRule();
239         loadXmlFile("UpdatedNamedRuleWithExpression.xml");
240         RuleService ruleService = KEWServiceLocator.getRuleService();
241         RuleBaseValues rule = ruleService.getRuleByName("ANamedRule");
242         assertNotNull(rule);
243         assertEquals("ANamedRule", rule.getName());
244         assertEquals("A named rule with an updated description, rule extension values, and responsibilities", rule.getDescription());
245         List extensions = rule.getRuleExtensions();
246         assertEquals(1, extensions.size());
247         RuleExtension extension = (RuleExtension) extensions.get(0);
248         assertEquals("TestRuleAttribute", extension.getRuleTemplateAttribute().getRuleAttribute().getName());
249         List extensionValues = extension.getExtensionValues();
250         assertEquals(2, extensionValues.size());
251         //RuleExtensionValue extensionValue = (RuleExtensionValue) extensionValues.get(0);
252         RuleExtensionValue extensionValue = getExtensionValue(extensionValues, "flavor");
253         assertEquals("flavor", extensionValue.getKey());
254         assertEquals("vanilla", extensionValue.getValue());
255         //extensionValue = (RuleExtensionValue) extensionValues.get(1);
256         extensionValue = getExtensionValue(extensionValues, "value");
257         assertEquals("value", extensionValue.getKey());
258         assertEquals("10", extensionValue.getValue());
259         List responsibilities = rule.getResponsibilities();
260         assertEquals(1, responsibilities.size());
261         RuleResponsibility responsibility = (RuleResponsibility) responsibilities.get(0);
262         assertEquals("user2", responsibility.getPrincipal().getPrincipalName());
263         assertEquals("F", responsibility.getActionRequestedCd());
264     }
265 
266     /**
267      * This test tests that an anonymous rule will still be checked against named rules for duplication.
268      */
269     @Test public void testAnonymousDuplicatesNamed() {
270         testNamedRule();
271 
272         final InputStream stream = getClass().getResourceAsStream("DuplicateAnonymousRule.xml");
273         assertNotNull(stream);
274         log.info("Importing anonymous duplicate rule");
275         AssertThrows at = new AssertThrows(WorkflowServiceErrorException.class, "Expected exception was not thrown") {
276             @Override
277             public void test() {
278                 KEWServiceLocator.getRuleService().loadXml(stream, null);
279             }
280         };
281         at.runTest();
282         assertNotNull("Expected exception was not thrown", TestUtilities.findExceptionInStack(at.getActualException(), InvalidXmlException.class));
283     }
284 
285     /**
286      * This test tests that an anonymous rule will still be checked against named rules for duplication.
287      */
288     @Test public void testAnonymousWithExpressionDuplicatesNamed() {
289         testNamedRuleWithExpression();
290 
291         final InputStream stream = getClass().getResourceAsStream("DuplicateAnonymousRuleWithExpression.xml");
292         assertNotNull(stream);
293         log.info("Importing anonymous duplicate rule");
294         AssertThrows at = new AssertThrows(WorkflowServiceErrorException.class, "Expected exception was not thrown") {
295             @Override
296             public void test() {
297                 KEWServiceLocator.getRuleService().loadXml(stream, null);
298             }
299         };
300         at.runTest();
301         assertNotNull("Expected exception was not thrown", TestUtilities.findExceptionInStack(at.getActualException(), InvalidXmlException.class));
302     }
303 
304     @Test public void testParameterReplacement() throws IOException, InvalidXmlException {
305         ConfigContext.getCurrentContextConfig().putProperty("test.replacement.user", "user3");
306         ConfigContext.getCurrentContextConfig().putProperty("test.replacement.workgroup", "WorkflowAdmin");
307         List<RuleBaseValues> rules = new RuleXmlParser().parseRules(getClass().getResourceAsStream("ParameterizedRule.xml"));
308         assertEquals(1, rules.size());
309         RuleBaseValues rule = rules.get(0);
310         assertEquals(2, rule.getResponsibilities().size());
311         RuleResponsibility resp = (RuleResponsibility) rule.getResponsibilities().get(0);
312 
313         if (resp.isUsingWorkflowUser()) {
314             assertEquals("user3", resp.getPrincipal().getPrincipalName());
315         } else {
316             assertEquals("WorkflowAdmin", resp.getGroup().getGroupName());
317         }
318 
319         ConfigContext.getCurrentContextConfig().putProperty("test.replacement.user", "user1");
320         ConfigContext.getCurrentContextConfig().putProperty("test.replacement.workgroup", "TestWorkgroup");
321         rules = new RuleXmlParser().parseRules(getClass().getResourceAsStream("ParameterizedRule.xml"));
322         assertEquals(1, rules.size());
323         rule = rules.get(0);
324         assertEquals(2, rule.getResponsibilities().size());
325         resp = (RuleResponsibility) rule.getResponsibilities().get(0);
326 
327         if (resp.isUsingWorkflowUser()) 
328         {
329             assertEquals("user1", resp.getPrincipal().getPrincipalName());   
330         } 
331         else 
332         {
333             assertEquals("TestWorkgroup", resp.getGroup().getGroupName());
334         }
335     }
336 
337     @Test public void removeTemplateFromNamedRule() {
338         RuleService ruleService = KEWServiceLocator.getRuleService();
339         int originalRuleCount = ruleService.fetchAllCurrentRulesForTemplateDocCombination("TestRuleTemplate", "TestDocumentType").size();
340 
341         testNamedRule();
342 
343         LOG.debug("Rules for doctype/template combo:");
344         int ruleCount = 0;
345         List<RuleBaseValues> list = ruleService.fetchAllCurrentRulesForTemplateDocCombination("TestRuleTemplate", "TestDocumentType");
346         if (list != null) {
347             ruleCount = list.size();
348             for (RuleBaseValues rbv: list) {
349                 LOG.info(rbv);
350             }
351         }
352 
353         loadXmlFile("NamedRuleWithoutTemplate.xml");
354 
355         LOG.debug("Rules for doctype/template combo after import of named rule:");
356         int ruleCountAfter = 0;
357         list = ruleService.fetchAllCurrentRulesForTemplateDocCombination("TestRuleTemplate", "TestDocumentType");
358         if (list != null) {
359             ruleCountAfter = list.size();
360             for (RuleBaseValues rbv: list) {
361                 LOG.info(rbv);
362             }
363         }
364 
365         RuleBaseValues rule = ruleService.getRuleByName("ANamedRule");
366 
367         assertNotNull(rule);
368         LOG.info("Rule id of latest version: " + rule.getRuleBaseValuesId());
369         assertEquals("ANamedRule", rule.getName());
370         assertEquals("A named rule with previously defined template removed", rule.getDescription());
371 
372         assertEquals("The rules for template/doctype combo should have been decreased by one after reimport of named rule without template", ruleCount - 1, ruleCountAfter);
373         assertEquals("Rule count should be original template/doctype combo rule count after removing template from named rule", originalRuleCount, ruleCountAfter);
374 
375         assertNull(rule.getRuleTemplate());
376 
377         // templateless rules cannot have extensions, so these should be removed
378         List extensions = rule.getRuleExtensions();
379         assertEquals(0, extensions.size());
380 
381         List responsibilities = rule.getResponsibilities();
382         assertEquals(1, responsibilities.size());
383         RuleResponsibility responsibility = (RuleResponsibility) responsibilities.get(0);
384         assertEquals("user2", responsibility.getPrincipal().getPrincipalName());
385         assertEquals("F", responsibility.getActionRequestedCd());
386     }
387 
388     @Test public void testInvalidTemplatelessNamedRule() {
389         testNamedRule();
390         try {
391         	loadXmlFile("InvalidTemplatelessNamedRule.xml");
392         	fail("Rule should have failed to load because it attempts to define extensions on a templateless rule.");
393         } catch (Exception e) {}
394     }
395     
396     @Test public void testRulesWithDifferentResponsibilityTypes() throws Exception {
397     	loadXmlFile("RulesWithDifferentResponsibilityTypes.xml");
398     	RuleService ruleService = KEWServiceLocator.getRuleService();
399     	
400     	RuleBaseValues rule = ruleService.getRuleByName("RespTypeTest1");
401     	assertNotNull(rule);
402     	assertEquals("Rule should have a principal responsibility", KEWConstants.RULE_RESPONSIBILITY_WORKFLOW_ID, rule.getResponsibilities().get(0).getRuleResponsibilityType());
403     	assertEquals("Rule should have a principal id of user1", "user1", rule.getResponsibilities().get(0).getRuleResponsibilityName());
404     	
405     	rule = ruleService.getRuleByName("RespTypeTest2");
406     	assertNotNull(rule);
407     	assertEquals("Rule should have a principal responsibility", KEWConstants.RULE_RESPONSIBILITY_WORKFLOW_ID, rule.getResponsibilities().get(0).getRuleResponsibilityType());
408     	assertEquals("Rule should have a principal id of user1", "user1", rule.getResponsibilities().get(0).getRuleResponsibilityName());
409     	
410     	rule = ruleService.getRuleByName("RespTypeTest3");
411     	assertNotNull(rule);
412     	assertEquals("Rule should have a group responsibility", KEWConstants.RULE_RESPONSIBILITY_GROUP_ID, rule.getResponsibilities().get(0).getRuleResponsibilityType());
413     	assertEquals("Rule should have a group id of 3001", "3001", rule.getResponsibilities().get(0).getRuleResponsibilityName());
414 
415     	rule = ruleService.getRuleByName("RespTypeTest4");
416     	assertNotNull(rule);
417     	assertEquals("Rule should have a group responsibility", KEWConstants.RULE_RESPONSIBILITY_GROUP_ID, rule.getResponsibilities().get(0).getRuleResponsibilityType());
418     	assertEquals("Rule should have a group id of 1", "1", rule.getResponsibilities().get(0).getRuleResponsibilityName());
419 
420     	rule = ruleService.getRuleByName("RespTypeTest5");
421     	assertNotNull(rule);
422     	assertEquals("Rule should have a role responsibility", KEWConstants.RULE_RESPONSIBILITY_ROLE_ID, rule.getResponsibilities().get(0).getRuleResponsibilityType());
423     	assertEquals("Invalid role name", "org.kuali.rice.kew.rule.TestRuleAttribute!TEST", rule.getResponsibilities().get(0).getRuleResponsibilityName());
424 
425     	rule = ruleService.getRuleByName("RespTypeTest6");
426     	assertNotNull(rule);
427     	assertEquals("Rule should have a role responsibility", KEWConstants.RULE_RESPONSIBILITY_ROLE_ID, rule.getResponsibilities().get(0).getRuleResponsibilityType());
428     	assertEquals("Invalid role name", "org.kuali.rice.kew.rule.TestRuleAttribute!TEST", rule.getResponsibilities().get(0).getRuleResponsibilityName());
429     }
430 }