package org.openslx.imagemaster.ftp; import java.io.File; import java.util.HashMap; import java.util.Iterator; import java.util.List; import org.apache.log4j.Logger; import org.openslx.imagemaster.App; import org.openslx.imagemaster.Globals; import org.openslx.imagemaster.Globals.PropInt; import org.openslx.imagemaster.db.DbImage; import org.openslx.imagemaster.thrift.iface.ImageData; public class ImageProcessor { private static Logger log = Logger.getLogger( ImageProcessor.class ); // key: ftpUser, value: imageData private static HashMap images = new HashMap<>(); /** * After (re)starting server: check dead !uploading! images in database */ public static void checkUploading() { long timeout = Globals.getPropertyInt( PropInt.FTPTIMEOUT ) * 60L * 1000L; List uploadingImages = DbImage.getUploadingImages(); log.info( uploadingImages.size() + " image(s) are uploading" ); if (uploadingImages.isEmpty()) return; Iterator iter = uploadingImages.iterator(); while (iter.hasNext()) { DbImage dbImage = iter.next(); if (System.currentTimeMillis() - dbImage.timestamp.getTime() >= timeout) { DbImage.delete( dbImage.UUID ); log.info( "Deleted dbimage from db: " + dbImage.UUID + " due to timeout"); } else { // add ftpUser to list synchronized ( App.ftpServer.users ) { App.ftpServer.users.put( dbImage.ftpUser, dbImage.timestamp.getTime() ); } log.info( "Added user '" + dbImage.ftpUser + "' to list again." ); // add image to process list again ImageData imageData = new ImageData( dbImage.UUID, dbImage.imageVersion, dbImage.imageName, dbImage.imageCreateTime.getTime(), dbImage.imageUpdateTime.getTime(), dbImage.imageOwner, dbImage.contentOperatingSystem, dbImage.isValid, dbImage.isDeleted, dbImage.shortDescription, dbImage.longDescription, dbImage.fileSize ); images.put( dbImage.ftpUser, imageData ); log.info( "Added image to processlist again: " + dbImage.UUID ); } } } /** * Process an image after upload * * @param username the user that uploaded the file * @param filename the name of the file that was uploaded (_no_ absolute path) * @return */ public static boolean processImageAfterUpload( String username, String filename ) { if ( !images.containsKey( username ) ) { return false; } log.info( "Will now process '" + filename + "' from user '" + username + "'" ); // move image to right location String oldFileName = Globals.getPropertyString( Globals.PropString.FTPBASEDIR ) + "/" + username + "/" + filename; String newFileName = Globals.getPropertyString( Globals.PropString.IMAGEDIR ) + "/" + images.get( username ).uuid + ".vmdk"; File imageFile = new File( oldFileName ); if ( !imageFile.exists() ) { // image file does not exist return false; } imageFile.renameTo( new File( newFileName ) ); log.info( "Moved file from " + oldFileName + " to " + newFileName ); File tempUserDir = new File( Globals.getPropertyString( Globals.PropString.FTPBASEDIR ) + "/" + username ); tempUserDir.delete(); // update database DbImage.update( images.get( username ), newFileName ); log.info( "Updated db: " + images.get( username ).uuid ); images.remove( username ); return true; } /** * Try to add imageData to database. * * @param imageData * the data for the image to add * @return false if submit fails */ public static boolean addImageDataToProcess( ImageData imageData, String username ) { log.info( "Adding image to process list: " + imageData.imageName + ", submitted by " + username ); if ( imageData.uuid.isEmpty() || imageData.imageName.isEmpty() || imageData.imageOwner.isEmpty() || imageData.conentOperatingSystem.isEmpty() || imageData.imageShortDescription.isEmpty() || imageData.imageLongDescription.isEmpty() || imageData.fileSize == 0) { return false; } if (!imageData.uuid.matches( "^[0-9a-f]{8}\\-[0-9a-f]{4}\\-[0-9a-f]{4}\\-[0-9a-f]{4}\\-[0-9a-f]{12}$" )) { log.debug("UUID not valid"); return false; } else if (!imageData.imageName.matches( "^[a-zA-Z0-9_\\-]{50}$" )) { log.debug("ImageName not valid"); return false; } else if (!imageData.imageOwner.matches( "^[0-9]*$" )) { log.debug("ImageOwner not valid"); return false; } // TODO: check some more regex if ( DbImage.exists( imageData ) ) { return false; } // if everything went fine, add image to db DbImage.insert( imageData, System.currentTimeMillis(), username); // and to processinglist images.put( username, imageData ); return true; } /** * Removes image from process list (and also from db) * @param username the user that uploaded the image * @return */ public static boolean removeImageFromProcessList( String username) { if (!images.containsKey( username )) { return false; } DbImage.delete( images.get( username ).uuid ); images.remove( username ); log.info( "Deleted image from process list and db. (User: " + username + ")" ); return true; } }