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  package org.kuali.rice.kew.xml.export;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.commons.lang.time.DateUtils;
20  import org.junit.Test;
21  import org.kuali.rice.core.api.CoreApiServiceLocator;
22  import org.kuali.rice.core.api.util.ClasspathOrFileResourceLoader;
23  import org.kuali.rice.kew.export.KewExportDataSet;
24  import org.kuali.rice.kew.rule.RuleBaseValues;
25  import org.kuali.rice.kew.rule.RuleDelegationBo;
26  import org.kuali.rice.kew.rule.RuleExtensionBo;
27  import org.kuali.rice.kew.rule.RuleExtensionValue;
28  import org.kuali.rice.kew.rule.RuleResponsibilityBo;
29  import org.kuali.rice.kew.rule.web.WebRuleUtils;
30  import org.kuali.rice.kew.service.KEWServiceLocator;
31  import org.kuali.rice.test.BaselineTestCase;
32  import org.kuali.rice.test.ClearDatabaseLifecycle;
33  
34  import java.io.BufferedInputStream;
35  import java.io.ByteArrayInputStream;
36  import java.util.ArrayList;
37  import java.util.Calendar;
38  import java.util.HashSet;
39  import java.util.Iterator;
40  import java.util.List;
41  import java.util.Set;
42  
43  import static org.junit.Assert.*;
44  
45  
46  /**
47   * Tests the RuleXmlExporter by importing XML, exporting it, and then re-importing the xml.<br><br>
48   *
49   * NOTE: It's important to note that the success of this test depends on all of the Rules in any
50   * XML having unique descriptions as this is the only way for the test to identify
51   * the rules from the original imported XML and the XML imported from the export.
52   *
53   * @author Kuali Rice Team (rice.collab@kuali.org)
54   */
55  @BaselineTestCase.BaselineMode(BaselineTestCase.Mode.NONE)
56  public class RuleXmlExporterTest extends XmlExporterTestCase {
57  
58  	@Test public void testExport() throws Exception {
59          ClasspathOrFileResourceLoader rl = new ClasspathOrFileResourceLoader();
60          loadXmlFile("org/kuali/rice/kew/actions/ActionsConfig.xml");
61          loadXmlStream(rl.getResource("classpath:org/kuali/rice/kew/batch/data/RuleAttributeContent.xml").getInputStream());
62          loadXmlStream(rl.getResource("classpath:org/kuali/rice/kew/batch/data/RuleTemplateContent.xml").getInputStream());
63          loadXmlStream(rl.getResource("classpath:org/kuali/rice/kew/batch/data/DocumentTypeContent.xml").getInputStream());
64          loadXmlStream(rl.getResource("classpath:org/kuali/rice/kew/batch/data/RuleContent.xml").getInputStream());
65          assertRuleBaseValuesStateIndependence();
66          assertExport();
67      }
68  
69      /**
70       * Note that the assertion here will fail if you have multiple rules with the same description.
71       */
72      protected void assertExport() throws Exception {
73          // export all existing rules and their dependencies (document types, rule templates, rule attributes)
74          List oldRules = KEWServiceLocator.getRuleService().fetchAllRules(true);
75          assertAllRulesHaveUniqueNames(oldRules);
76          List oldRuleDelegations = KEWServiceLocator.getRuleDelegationService().findAllCurrentRuleDelegations();
77          assertAllRuleDelegationsHaveUniqueNames(oldRuleDelegations);
78  
79          KewExportDataSet dataSet = new KewExportDataSet();
80          dataSet.getRules().addAll(oldRules);
81          dataSet.getRuleDelegations().addAll(oldRuleDelegations);
82          dataSet.getDocumentTypes().addAll(KEWServiceLocator.getDocumentTypeService().findAllCurrent());
83          dataSet.getRuleTemplates().addAll(KEWServiceLocator.getRuleTemplateService().findAll());
84          dataSet.getRuleAttributes().addAll(KEWServiceLocator.getRuleAttributeService().findAll());
85          byte[] xmlBytes = CoreApiServiceLocator.getXmlExporterService().export(dataSet.createExportDataSet());
86          assertTrue("XML should be non empty.", xmlBytes != null && xmlBytes.length > 0);
87          
88          // now clear the tables
89          ClearDatabaseLifecycle clearLifeCycle = new ClearDatabaseLifecycle();
90          clearLifeCycle.getTablesToClear().add("KREW_RULE_T");
91          clearLifeCycle.getTablesToClear().add("KREW_RULE_RSP_T");
92          clearLifeCycle.getTablesToClear().add("KREW_DLGN_RSP_T");
93          clearLifeCycle.getTablesToClear().add("KREW_RULE_ATTR_T");
94          clearLifeCycle.getTablesToClear().add("KREW_RULE_TMPL_T");
95          clearLifeCycle.getTablesToClear().add("KREW_DOC_TYP_T");
96          clearLifeCycle.start();
97          new ClearCacheLifecycle().stop();
98  
99          // import the exported xml
100         loadXmlStream(new BufferedInputStream(new ByteArrayInputStream(xmlBytes)));
101 
102         List newRules = KEWServiceLocator.getRuleService().fetchAllRules(true);
103         assertEquals("Should have same number of old and new Rules.", oldRules.size(), newRules.size());
104         for (Iterator iterator = oldRules.iterator(); iterator.hasNext();) {
105             RuleBaseValues oldRule = (RuleBaseValues) iterator.next();
106             boolean foundRule = false;
107             for (Iterator iterator2 = newRules.iterator(); iterator2.hasNext();) {
108                 RuleBaseValues newRule = (RuleBaseValues) iterator2.next();
109                 if (oldRule.getDescription().equals(newRule.getDescription())) {
110                     assertRuleExport(oldRule, newRule);
111                     foundRule = true;
112                 }
113             }
114             assertTrue("Could not locate the new rule for description " + oldRule.getDescription(), foundRule);
115         }
116         
117         List newRuleDelegations = KEWServiceLocator.getRuleDelegationService().findAllCurrentRuleDelegations();
118         assertDelegations(oldRuleDelegations, newRuleDelegations);
119     }
120     
121     /**
122      * verifies that rule exports are the same regardless of whether the rule is ready for render, or
123      * for persistance.
124      */
125     protected void assertRuleBaseValuesStateIndependence() throws Exception {
126     	for (Object o : KEWServiceLocator.getRuleService().fetchAllRules(true)) {
127         	RuleBaseValues rule = (RuleBaseValues)o;
128         	KewExportDataSet dataSet = new KewExportDataSet();
129         	dataSet.getRules().add(rule);
130         	
131         	// first, do a conversion in the just-loaded state:
132         	byte[] saveXmlBytes = CoreApiServiceLocator.getXmlExporterService().export(dataSet.createExportDataSet());
133         	String saveStr = new String(saveXmlBytes);
134         	
135         	// now, convert for render:
136         	WebRuleUtils.populateRuleMaintenanceFields(rule);
137         	
138         	// do another conversion in the ready-for-render state:
139         	byte[] loadXmlBytes = CoreApiServiceLocator.getXmlExporterService().export(dataSet.createExportDataSet());
140         	String loadStr = new String(loadXmlBytes);
141 
142             // FIXME: currently failing due to:
143             // * WebRuleUtils.populateRuleMaintenanceFields clears rule extensions
144             // * RuleXmlExporter detects missing extensions and re-adds them: but in a different order...
145 
146         	// check that the results are identical:
147         	assertTrue("The load/render state of the RuleBaseValues shouldn't effect the export: \n" + 
148         			saveStr + "\n\n != \n\n" + loadStr, 
149         			StringUtils.equals(saveStr, loadStr));
150         }
151     }
152 
153     private void assertRuleExport(RuleBaseValues oldRule, RuleBaseValues newRule) {
154         assertFalse("Ids should be different.", oldRule.getId().equals(newRule.getId()));
155         assertEquals(oldRule.isActive(), newRule.isActive());
156         assertEquals(DateUtils.round(oldRule.getActivationDate(), Calendar.DATE), DateUtils.round(newRule.getActivationDate(), Calendar.DATE));
157         assertEquals(oldRule.getName(), newRule.getName());
158         assertEquals(oldRule.getCurrentInd(), newRule.getCurrentInd());
159         assertEquals(oldRule.getDeactivationDate(), newRule.getDeactivationDate());
160         assertEquals(oldRule.getDelegateRule(), newRule.getDelegateRule());
161         assertEquals(oldRule.getDescription(), newRule.getDescription());
162         assertEquals(oldRule.getDocTypeName(), newRule.getDocTypeName());
163         
164         if (oldRule.getFromDateValue() == null) {
165         	assertNull(newRule.getFromDateValue());
166         } else {
167         	assertEquals(DateUtils.round(oldRule.getFromDateValue(), Calendar.DATE), DateUtils.round(newRule.getFromDateValue(), Calendar.DATE));
168         }
169         if (oldRule.getToDateValue() == null) {
170         	assertNull(newRule.getToDateValue());
171         } else {
172         	assertEquals(DateUtils.round(oldRule.getToDateValue(), Calendar.DATE), DateUtils.round(newRule.getToDateValue(), Calendar.DATE));
173         }
174         assertEquals(oldRule.getFromDateString(),newRule.getFromDateString() );
175         assertEquals(oldRule.getToDateString(),newRule.getToDateString() );
176         
177         assertEquals(oldRule.isForceAction(), newRule.isForceAction());
178         
179         if(!oldRule.getDelegateRule().booleanValue())
180         	assertEquals(oldRule.getPreviousRuleId(), newRule.getPreviousRuleId());
181         
182         assertEquals(oldRule.getDocumentId(), newRule.getDocumentId());
183         
184         if (oldRule.getRuleTemplate() == null) {
185             assertNull(newRule.getRuleTemplate());
186         } else {
187             assertEquals(oldRule.getRuleTemplate().getName(), newRule.getRuleTemplate().getName());
188         }
189         if (oldRule.getRuleExpressionDef() == null) {
190             assertNull(newRule.getRuleExpressionDef());
191         } else {
192             assertEquals(oldRule.getRuleExpressionDef().getExpression(), newRule.getRuleExpressionDef().getExpression());
193             assertEquals(oldRule.getRuleExpressionDef().getType(), newRule.getRuleExpressionDef().getType());
194         }
195         if(!oldRule.getDelegateRule().booleanValue())
196         	assertEquals(oldRule.getVersionNbr(), newRule.getVersionNbr());
197 
198         assertRuleExtensions(oldRule.getRuleExtensions(), newRule.getRuleExtensions());
199         assertResponsibilities(oldRule.getRuleResponsibilities(), newRule.getRuleResponsibilities());
200 
201 
202     }
203 
204     private void assertRuleExtensions(List oldRuleExtensions, List newRuleExtensions) {
205         assertEquals(oldRuleExtensions.size(), newRuleExtensions.size());
206         for (Iterator iterator = oldRuleExtensions.iterator(); iterator.hasNext();) {
207             RuleExtensionBo oldExtension = (RuleExtensionBo) iterator.next();
208             boolean foundExtension = false;
209             for (Iterator iterator2 = newRuleExtensions.iterator(); iterator2.hasNext();) {
210                 RuleExtensionBo newExtension = (RuleExtensionBo) iterator2.next();
211                 if (oldExtension.getRuleTemplateAttribute().getRuleAttribute().getName().equals(newExtension.getRuleTemplateAttribute().getRuleAttribute().getName()) &&
212                         oldExtension.getRuleTemplateAttribute().getRuleTemplate().getName().equals(newExtension.getRuleTemplateAttribute().getRuleTemplate().getName())) {
213                         assertExtensionValues(oldExtension.getExtensionValues(), newExtension.getExtensionValues());
214                         foundExtension = true;
215                         break;
216                 }
217             }
218             assertTrue("Could not locate rule extension.", foundExtension);
219         }
220     }
221 
222     private void assertExtensionValues(List oldExtensionValues, List newExtensionValues) {
223         assertEquals(oldExtensionValues.size(), newExtensionValues.size());
224         for (Iterator iterator = oldExtensionValues.iterator(); iterator.hasNext();) {
225             RuleExtensionValue oldValue = (RuleExtensionValue) iterator.next();
226             boolean foundValue = false;
227             for (Iterator iterator2 = oldExtensionValues.iterator(); iterator2.hasNext();) {
228                 RuleExtensionValue newValue = (RuleExtensionValue) iterator2.next();
229                 if (oldValue.getKey().equals(newValue.getKey())) {
230                     assertEquals(oldValue.getValue(), newValue.getValue());
231                     foundValue = true;
232                     break;
233                 }
234             }
235             assertTrue("Could not locate extension value.", foundValue);
236         }
237     }
238 
239     private void assertResponsibilities(List oldResps, List newResps) {
240         assertEquals(oldResps.size(), newResps.size());
241         for (Iterator iterator = oldResps.iterator(); iterator.hasNext();) {
242             RuleResponsibilityBo oldResp = (RuleResponsibilityBo) iterator.next();
243             boolean foundResp = false;
244             for (Iterator iterator2 = newResps.iterator(); iterator2.hasNext();) {
245                 RuleResponsibilityBo newResp = (RuleResponsibilityBo) iterator2.next();
246                 if (oldResp.getRuleResponsibilityName().equals(newResp.getRuleResponsibilityName())) {
247                     assertEquals(oldResp.getActionRequestedCd(), newResp.getActionRequestedCd());
248                     assertEquals(oldResp.getApprovePolicy(), newResp.getApprovePolicy());
249                     assertEquals(oldResp.getResolvedRoleName(), newResp.getResolvedRoleName());
250                     assertEquals(oldResp.getRole(), newResp.getRole());
251                     assertEquals(oldResp.getRuleResponsibilityType(), newResp.getRuleResponsibilityType());
252                     assertEquals(oldResp.getPriority(), newResp.getPriority());
253                     foundResp = true;
254                     break;
255                 }
256             }
257             assertTrue("Could not locate responsibility "+oldResp.getRuleResponsibilityName()+" on rule "+oldResp.getRuleBaseValues().getDescription(), foundResp);
258         }
259     }
260 
261     private void assertDelegations(List oldDelegations, List newDelegations) {
262         assertEquals(oldDelegations.size(), newDelegations.size());
263         for (Iterator iterator = oldDelegations.iterator(); iterator.hasNext();) {
264             RuleDelegationBo oldDelegation = (RuleDelegationBo) iterator.next();
265             boolean foundDelegation = false;
266             for (Iterator iterator2 = newDelegations.iterator(); iterator2.hasNext();) {
267                 RuleDelegationBo newDelegation = (RuleDelegationBo) iterator2.next();
268                 if (oldDelegation.getDelegationRule().getName().equals(newDelegation.getDelegationRule().getName())) {
269                     assertEquals(oldDelegation.getDelegationType(), newDelegation.getDelegationType());
270                     assertFalse(oldDelegation.getResponsibilityId().equals(newDelegation.getResponsibilityId()));
271                     assertRuleExport(oldDelegation.getDelegationRule(), newDelegation.getDelegationRule());
272                     foundDelegation = true;
273                     break;
274                 }
275             }
276             assertTrue("Could not locate delegation.", foundDelegation);
277         }
278     }
279 
280     private void assertAllRulesHaveUniqueNames(List rules) throws Exception {
281     	Set<String> ruleDescriptions = new HashSet<String>();
282     	for (Iterator iterator = rules.iterator(); iterator.hasNext();) {
283 			RuleBaseValues rule = (RuleBaseValues) iterator.next();
284 			assertFalse("Found 2 rules with the same description '" + rule.getDescription() + "'.  " +
285 					"In order for this test to work, all rules in the configuration files must have unique descriptions.",
286 					ruleDescriptions.contains(rule.getDescription()));
287 			ruleDescriptions.add(rule.getDescription());
288 		}
289     }
290     
291     private void assertAllRuleDelegationsHaveUniqueNames(List<RuleDelegationBo> ruleDelegations) throws Exception {
292     	List<RuleBaseValues> rules = new ArrayList<RuleBaseValues>();
293     	for (RuleDelegationBo ruleDelegation : ruleDelegations) {
294     		rules.add(ruleDelegation.getDelegationRule());
295     	}
296     	assertAllRulesHaveUniqueNames(rules);
297     }
298 
299 }