View Javadoc

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