/*! ****************************************************************************** * * Pentaho Data Integration * * Copyright (C) 2002-2016 by Pentaho : http://www.pentaho.com * ******************************************************************************* * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ package org.pentaho.di.repository; import java.io.File; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.UUID; import org.apache.commons.io.FileUtils; import org.apache.commons.vfs2.FileObject; import org.apache.commons.vfs2.FileSelectInfo; import org.apache.commons.vfs2.FileSelector; import org.pentaho.di.core.Const; import org.pentaho.di.core.util.Utils; import org.pentaho.di.core.KettleEnvironment; import org.pentaho.di.core.exception.KettleException; import org.pentaho.di.core.vfs.KettleVFS; import org.pentaho.di.core.xml.XMLHandler; import org.pentaho.di.job.JobMeta; import org.pentaho.di.repository.filerep.KettleFileRepository; import org.pentaho.di.repository.filerep.KettleFileRepositoryMeta; import org.pentaho.di.trans.TransMeta; import org.pentaho.metastore.api.IMetaStore; import junit.framework.TestCase; public class KettleFileRepositoryTest extends TestCase { protected KettleFileRepositoryMeta repositoryMeta; protected KettleFileRepository repository; protected RepositoryDirectoryInterface tree; public void testDatabaseRepository() throws Exception { KettleEnvironment.init(); String dirName = System.getProperty( "java.io.tmpdir" ) + "/" + UUID.randomUUID(); File dirFile = new File( dirName ); if ( !dirFile.mkdir() ) { throw new KettleException( "bad luck, directory '" + dirName + "' already exists and can't be used to put a file repository in it." ); } System.out.println( "Using folder '" + dirName + "' to store a file repository in." ); try { repositoryMeta = new KettleFileRepositoryMeta( "KettleFileRepository", "FileRep", "File repository", dirName ); repository = new KettleFileRepository(); repository.init( repositoryMeta ); // Test connecting... (no security needed) // repository.connect( null, null ); assertTrue( repository.isConnected() ); // Test loading the directory tree // tree = repository.loadRepositoryDirectoryTree(); assertNotNull( tree ); // Test directory creation // RepositoryDirectoryInterface fooDirectory = repository.createRepositoryDirectory( tree, "foo" ); RepositoryDirectoryInterface barDirectory = repository.createRepositoryDirectory( fooDirectory, "bar" ); RepositoryDirectoryInterface samplesDirectory = repository.createRepositoryDirectory( fooDirectory, "samples" ); // Test directory path lookup RepositoryDirectoryInterface checkBar = tree.findDirectory( "/foo/bar" ); assertNotNull( checkBar ); assertTrue( checkBar.equals( barDirectory ) ); // Save all the transformations samples. // verifyTransformationSamples( samplesDirectory ); verifyJobSamples( samplesDirectory ); // Verify metastore functionality // IMetaStore metaStore = repository.getMetaStore(); KettleMetaStoreTestBase testBase = new KettleMetaStoreTestBase(); testBase.testFunctionality( metaStore ); // Test directory deletion repository.deleteRepositoryDirectory( samplesDirectory ); RepositoryDirectoryInterface checkDelete = tree.findDirectory( "/foo/bar/samples" ); assertNull( checkDelete ); // Finally test disconnecting repository.disconnect(); assertFalse( repository.isConnected() ); } catch ( Exception e ) { e.printStackTrace(); throw new KettleException( "Error during database repository unit testing", e ); } finally { // Remove all the files and folders in the repository... // FileUtils.deleteDirectory( dirFile ); } } private void verifyTransformationSamples( RepositoryDirectoryInterface samplesDirectory ) throws Exception { File transSamplesFolder = new File( "samples/transformations/" ); String[] files = transSamplesFolder.list( new FilenameFilter() { @Override public boolean accept( File dir, String name ) { return name.endsWith( ".ktr" ) && !name.contains( "HL7" ); } } ); Arrays.sort( files ); for ( String file : files ) { String transFilename = transSamplesFolder.getAbsolutePath() + "/" + file; System.out.println( "Storing/Loading/validating transformation '" + transFilename + "'" ); // Load the TransMeta object... // TransMeta transMeta = new TransMeta( transFilename ); transMeta.setFilename( null ); // The name is sometimes empty in the file, duplicates are present too... // Replaces slashes and the like as well... // transMeta.setName( Const.createName( file ) ); transMeta.setName( transMeta.getName().replace( '/', '-' ) ); // Save it in the repository in the samples folder // transMeta.setRepositoryDirectory( samplesDirectory ); repository.save( transMeta, "unit testing" ); assertNotNull( transMeta.getObjectId() ); // Load it back up again... // TransMeta repTransMeta = repository.loadTransformation( transMeta.getObjectId(), null ); String oneXml = repTransMeta.getXML(); // Save & load it again // repository.save( transMeta, "unit testing" ); repTransMeta = repository.loadTransformation( transMeta.getObjectId(), null ); String twoXml = repTransMeta.getXML(); // The XML needs to be identical after loading // // storeFile(oneXml, "/tmp/one.ktr"); // storeFile(twoXml, "/tmp/two.ktr"); assertEquals( oneXml, twoXml ); } // Verify the number of stored files, see if we can find them all again. // System.out.println( "Stored " + files.length + " transformation samples in folder " + samplesDirectory.getPath() ); String[] transformationNames = repository.getTransformationNames( samplesDirectory.getObjectId(), false ); assertEquals( files.length, transformationNames.length ); } private void verifyJobSamples( RepositoryDirectoryInterface samplesDirectory ) throws Exception { FileObject jobSamplesFolder = KettleVFS.getFileObject( "samples/jobs/" ); FileObject[] files = jobSamplesFolder.findFiles( new FileSelector() { @Override public boolean traverseDescendents( FileSelectInfo arg0 ) throws Exception { return true; } @Override public boolean includeFile( FileSelectInfo info ) throws Exception { return info.getFile().getName().getExtension().equalsIgnoreCase( "kjb" ); } } ); List<FileObject> filesList = Arrays.asList( files ); Collections.sort( filesList, new Comparator<FileObject>() { @Override public int compare( FileObject o1, FileObject o2 ) { return o1.getName().getPath().compareTo( o2.getName().getPath() ); } } ); for ( FileObject file : filesList ) { String jobFilename = file.getName().getPath(); System.out.println( "Storing/Loading/validating job '" + jobFilename + "'" ); // Load the JobMeta object... // JobMeta jobMeta = new JobMeta( jobFilename, repository ); jobMeta.setFilename( null ); // The name is sometimes empty in the file, duplicates are present too... // Replaces slashes and the like as well... // jobMeta.setName( Const.createName( file.getName().getBaseName() ) ); jobMeta.setName( jobMeta.getName().replace( '/', '-' ) ); if ( Utils.isEmpty( jobMeta.getName() ) ) { jobMeta.setName( Const.createName( file.getName().getBaseName() ) ); } if ( jobMeta.getName().contains( "/" ) ) { jobMeta.setName( jobMeta.getName().replace( '/', '-' ) ); } // Save it in the repository in the samples folder // jobMeta.setRepositoryDirectory( samplesDirectory ); repository.save( jobMeta, "unit testing" ); assertNotNull( jobMeta.getObjectId() ); // Load it back up again... // JobMeta repJobMeta = repository.loadJob( jobMeta.getObjectId(), null ); String oneXml = repJobMeta.getXML(); // Save & load it again // repository.save( jobMeta, "unit testing" ); repJobMeta = repository.loadJob( jobMeta.getObjectId(), null ); String twoXml = repJobMeta.getXML(); // The XML needs to be identical after loading // // storeFile(oneXml, "/tmp/one.ktr"); // storeFile(twoXml, "/tmp/two.ktr"); // assertEquals( oneXml, twoXml ); } // Verify the number of stored files, see if we can find them all again. // System.out.println( "Stored " + files.length + " job samples in folder " + samplesDirectory.getPath() ); String[] jobNames = repository.getJobNames( samplesDirectory.getObjectId(), false ); assertEquals( files.length, jobNames.length ); } protected void storeFile( String xml, String filename ) throws Exception { File file = new File( filename ); FileOutputStream fos = new FileOutputStream( file ); fos.write( XMLHandler.getXMLHeader( Const.XML_ENCODING ).getBytes( Const.XML_ENCODING ) ); fos.write( xml.getBytes( Const.XML_ENCODING ) ); fos.close(); } }