001    /**
002     * Copyright 2005-2011 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    package org.kuali.rice.kew.batch;
017    
018    
019    import static org.junit.Assert.assertFalse;
020    import static org.junit.Assert.assertTrue;
021    
022    import java.io.File;
023    import java.io.IOException;
024    import java.util.ArrayList;
025    import java.util.Collection;
026    import java.util.Iterator;
027    import java.util.LinkedList;
028    import java.util.List;
029    import java.util.Map;
030    import java.util.Properties;
031    
032    import org.apache.commons.io.FileUtils;
033    import org.junit.Assert;
034    import org.junit.Ignore;
035    import org.junit.Test;
036    import org.kuali.rice.core.api.CoreApiServiceLocator;
037    import org.kuali.rice.core.api.impex.xml.FileXmlDocCollection;
038    import org.kuali.rice.core.api.impex.xml.XmlDocCollection;
039    import org.kuali.rice.edl.impl.bo.EDocLiteAssociation;
040    import org.kuali.rice.edl.impl.service.EdlServiceLocator;
041    import org.kuali.rice.edl.impl.xml.export.EdlExportDataSet;
042    import org.kuali.rice.kew.test.KEWTestCase;
043    import org.springframework.core.io.Resource;
044    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
045    import org.springframework.core.io.support.ResourcePatternResolver;
046    import org.springframework.util.FileCopyUtils;
047    
048    /**
049     * Tests XML "ingestion" pipeline
050     *
051     * @author Kuali Rice Team (rice.collab@kuali.org)
052     */
053    public class XmlIngestionTest extends KEWTestCase {
054    
055        private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(XmlIngestionTest.class);
056    
057        private static final File TMP_DIR = new File(System.getProperty("java.io.tmpdir"), "XmlIngestionTest_dir");
058        private static final File PENDING_DIR = new File(TMP_DIR, "pending");
059        private static final File LOADED_DIR = new File(TMP_DIR, "loaded");
060        private static final File PROBLEM_DIR = new File(TMP_DIR, "problem");
061    
062        public void setUp() throws Exception {
063            super.setUp();
064            deleteDirectories();
065            TMP_DIR.mkdirs();
066            PENDING_DIR.mkdirs();
067            LOADED_DIR.mkdirs();
068            PROBLEM_DIR.mkdirs();
069        }
070    
071        private void deleteContentsOfDir(File dir, int depth) {
072            File[] files = dir.listFiles();
073            if (files == null) return;
074            for (File file : files) {
075                if (file.isDirectory() && depth > 0) {
076                    // decrement depth
077                    // to avoid the possibility of inadvertent
078                    // recursive delete!
079                    deleteContentsOfDir(file, depth - 1);
080                }
081                boolean success = file.delete();
082                LOG.info("deleting: " + file + "..." + (success ? "succeeded" : "failed"));
083            }
084        }
085    
086        public void tearDown() throws Exception {
087            try {
088                deleteDirectories();
089            } finally {
090                super.tearDown();
091            }
092        }
093    
094        protected void deleteDirectories() {
095            deleteContentsOfDir(PENDING_DIR, 0);
096            deleteContentsOfDir(LOADED_DIR, 2);
097            deleteContentsOfDir(PROBLEM_DIR, 2);
098            deleteContentsOfDir(TMP_DIR, 0);
099            TMP_DIR.delete();
100        }
101    
102        protected boolean verifyFileExists(File dir, File file) throws IOException {
103            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
104            Resource[] resources = resolver.getResources(dir.toURL() + "/**/" + file.getName());
105            if (resources == null) {
106                return false;
107            }
108            for (int i = 0; i < resources.length; i++) {
109                if (resources[i].exists()) {
110                    return true;
111                }
112            }
113            return false;
114        }
115        
116    
117        @Ignore
118        public void testXmlReIngestion() throws Exception {
119    
120            // Define the path for the test environment
121            String relativeFolder = "/src/test/resources/org/kuali/rice/kew/batch/data/";
122            String filePath = getBaseDir() + relativeFolder + "widgetsTest.xml";
123            File ingestedFile = new File(filePath);
124            List<XmlDocCollection> collections = new ArrayList<XmlDocCollection>();
125            XmlDocCollection fileDoc = new FileXmlDocCollection(ingestedFile);
126            collections.add(fileDoc);
127            // ingest the collection and save it to the database
128            Collection<XmlDocCollection> ingestedXmlFile = null;
129            try {
130                ingestedXmlFile = CoreApiServiceLocator.getXmlIngesterService().ingest(collections);
131            } catch (Exception e) {
132                LOG.error("Error ingesting data", e);
133                //throw new RuntimeException(e);
134            }
135    
136            EdlExportDataSet dataSet = new EdlExportDataSet();
137    
138            //Cast this for now
139            List<EDocLiteAssociation> edla = EdlServiceLocator.getEDocLiteService().getEDocLiteAssociations();     
140            String style = null;
141            for (EDocLiteAssociation edl : edla) {
142                if (edl != null) {
143                    style = edl.getStyle();
144                    if ("widgetsTest".equals(style)) {
145                        dataSet.getEdocLites().add(edl);
146                    }
147                }
148            }
149            
150            byte[] xmlBytes = CoreApiServiceLocator.getXmlExporterService().export(dataSet.createExportDataSet());
151            // now export that xml into a file
152            File reingestFile = File.createTempFile("widgetsTestOutput", ".xml");           
153            FileUtils.writeByteArrayToFile(reingestFile, xmlBytes);
154            String ingestedString = FileUtils.readFileToString(ingestedFile);
155            String reingestedString = FileUtils.readFileToString(reingestFile);
156            //assertTrue(FileUtils.contentEquals(ingestedFile, reingestFile));
157        }
158    
159    
160        /**
161         * TODO: beef this up
162         * need a reliable way to test if the file arrived in the right date-stamped
163         * subdirectory (maybe just pick the last, or first directory?)
164         *
165         * @throws java.io.IOException
166         */
167        @Test
168        public void testXmlIngestion() throws IOException {
169            XmlPollerServiceImpl poller = new XmlPollerServiceImpl();
170            poller.setPollIntervalSecs(1);
171            poller.setXmlParentDirectory(TMP_DIR.toString());
172            poller.setXmlPendingLocation(PENDING_DIR.toString());
173            poller.setXmlCompletedLocation(LOADED_DIR.toString());
174            poller.setXmlProblemLocation(PROBLEM_DIR.toString());
175    
176            Properties filesToIngest = new Properties();
177            filesToIngest.load(getClass().getResourceAsStream("XmlIngestionTest.txt"));
178            List<File> pendingFiles = new LinkedList<File>();
179            List<File> shouldPass = new LinkedList<File>();
180            List<File> shouldFail = new LinkedList<File>();
181            Iterator<Map.Entry<Object, Object>> entries = filesToIngest.entrySet().iterator();
182            int i = 0;
183            while (entries.hasNext()) {
184                Map.Entry<?, ?> entry = entries.next();
185                String filePath = entry.getKey().toString();
186                filePath = filePath.replace("${basedir}", getBaseDir());
187                File testFile = new File(filePath);
188                File pendingDir = new File(PENDING_DIR + "/TestDoc-" + i);
189                Assert.assertTrue(pendingDir.mkdirs());
190                assertTrue(pendingDir.isDirectory());
191                File pending = new File(pendingDir, testFile.getName());
192                pendingFiles.add(pending);
193                if (Boolean.valueOf(entry.getValue().toString())) {
194                    shouldPass.add(pending);
195                } else {
196                    shouldFail.add(pending);
197                }
198                FileCopyUtils.copy(testFile, pending);
199                LOG.info("created: " + pending);
200                i++;
201            }
202    
203            // poller should not throw exceptions
204            poller.run();
205    
206            // check that all files have been processed
207            Iterator<File> it = pendingFiles.iterator();
208            while (it.hasNext()) {
209                File pending = it.next();
210                assertTrue(!pending.isFile());
211            }
212    
213            // check that they landed in the appropriate location
214    
215            // loaded files should be in the loaded dir...
216            it = shouldPass.iterator();
217            while (it.hasNext()) {
218                File file = it.next();
219                assertTrue("Loaded file " + file + " was not moved to loaded directory " + LOADED_DIR, verifyFileExists(LOADED_DIR, file));
220                assertFalse("Loaded file " + file + " was moved to problem directory " + PROBLEM_DIR, verifyFileExists(PROBLEM_DIR, file));
221            }
222            // and problem files should be in the problem dir...
223            it = shouldFail.iterator();
224            while (it.hasNext()) {
225                File file = it.next();
226                assertTrue("Problem file " + file + " was not moved to problem directory" + PROBLEM_DIR, verifyFileExists(PROBLEM_DIR, file));
227                assertFalse("Problem file " + file + " was moved to loaded directory" + LOADED_DIR, verifyFileExists(LOADED_DIR, file));
228            }
229        }
230    }