summaryrefslogblamecommitdiffstats
path: root/src/main/java/org/openslx/imagemaster/serverconnection/ImageProcessor.java
blob: d4ae7179f26baa8358478e6423111f5cc3faf77a (plain) (tree)


























































































































                                                                                                                                                  
package org.openslx.imagemaster.serverconnection;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.Logger;
import org.openslx.imagemaster.Globals;
import org.openslx.imagemaster.db.DbImage;
import org.openslx.imagemaster.thrift.iface.ImageData;
import org.openslx.imagemaster.thrift.iface.UploadInfos;
import org.openslx.imagemaster.util.RandomString;

public class ImageProcessor
{
	private static Logger log = Logger.getLogger( ImageProcessor.class );

	/**
	 * The amount of blocks that is return in UploadInfos (after request of satellite)
	 */
	private static final int AMOUNT = 20;
	/**
	 * The uploading images.
	 * Key:		imageUUID, 
	 * Value:	imageInfos
	 */
	private static HashMap<String, ImageInfos> uploadingImages = new HashMap<>();

	/**
	 * Checks if this image is already uploading and returns a new list with missing blocks if so.
	 * Puts the new image into processing list else.
	 * @param serverSessionId The uploading server
	 * @param imageData The data of the image
	 * @return
	 */
	public static UploadInfos getUploadInfos( String serverSessionId, ImageData imageData )
	{
		// check image data
		// TODO: do security checks
		
		String uuid = imageData.uuid;
		
		// check if image is already uploading
		if ( uploadingImages.containsKey( uuid ) ) {
			List<Integer> missing = getMissingBlocks( uuid, AMOUNT );
			if ( missing.isEmpty() ) {
				String token = uploadingImages.get( uuid ).getToken();
				uploadDone( uuid );
				return new UploadInfos( token, missing );
			}
			uploadingImages.get( uuid ).setLastSentBlocks( missing );
			return new UploadInfos( uploadingImages.get( uuid ).getToken(), missing );
		}
		
		// insert new image and generate token
		synchronized (uploadingImages) {
			int nBlocks = (int)Math.ceil(imageData.fileSize / Globals.blockSize);
			List<Integer> allBlocks = new LinkedList<>();
			for (int i = 0; i < nBlocks; i++) {			// fill empty list with all block numbers
				allBlocks.add( i );
			}
			String token = RandomString.generate( 100, false );
			// TODO: init updownloader class
			uploadingImages.put( uuid, new ImageInfos(token, allBlocks, serverSessionId, new Timestamp(System.currentTimeMillis())) );
			DbImage.insert( imageData, System.currentTimeMillis(), token, allBlocks, serverSessionId );
			
			List<Integer> missing = getMissingBlocks( uuid, AMOUNT );
			if ( missing.isEmpty() ) {
				uploadDone( uuid );
			}
			uploadingImages.get( uuid ).setLastSentBlocks( missing );
			return new UploadInfos( token, missing );
		}
	}
	
	/**
	 * Returns a specified number of missing blocks.
	 * @param imageUUID The image of which you want to get the missing blocks from
	 * @param amount The amount of blocks that you want to get
	 * @return The missing blocksht
	 */
	private static List<Integer> getMissingBlocks( String imageUUID, int amount )
	{
		List<Integer> list = uploadingImages.get( imageUUID ).getMissingBlocks();
		List<Integer> result = new LinkedList<>();
		
		if ( amount > list.size() )
			amount = list.size();
		
		for ( int i = 0; i < amount; i++ ) {
			result.add( list.get( i ) );
		}
		return result;
	}
	
	/**
	 * Is triggered when an upload of an image is done.
	 * Removes image from process list, updates db entry and moves file on hard drive.
	 * @param uuid
	 */
	private static void uploadDone( String uuid ) {
		synchronized(uploadingImages) {
			uploadingImages.remove( uuid );
			DbImage.updateMissingBlocks( uuid, null );
		}
		// file was already downloaded in the right location by the updownloader class.
	}
	
	/**
	 * Checks pending uploads in database and adds them to process list again.
	 */
	public static void checkUploading() {
		List<DbImage> list = DbImage.getUploadingImages();
		for (DbImage image : list) {
			// TODO: init updownloader class
			String token = RandomString.generate( 100, false );
			ImageInfos infos = new ImageInfos(token, image.missingBlocks, image.serverSessionId, image.timestamp);
			uploadingImages.put( image.UUID, infos);
		}
		log.info("Added " + list.size() + " pending upload(s) to process list again.");
	}
}