summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/imagemaster/ftp/ImageProcessor.java
blob: 8359e5a4c5f18e0214bcd9c80140ee523297f3c6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
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.DbFtpUser;
import org.openslx.imagemaster.db.DbImage;
import org.openslx.imagemaster.db.DbUser;
import org.openslx.imagemaster.thrift.iface.ImageData;
import org.openslx.imagemaster.thrift.iface.ImageDataError;
import org.openslx.imagemaster.thrift.iface.ImageDataException;

public class ImageProcessor
{

	private static Logger log = Logger.getLogger( ImageProcessor.class );
	// key: ftpUser, value: imageData
	private static HashMap<String, ImageData> images = new HashMap<>();
	
	/**
	 * After (re)starting server: check for dead !uploading! images in database
	 */
	public static void checkUploading() {
		long timeout = Globals.getPropertyInt( PropInt.FTPTIMEOUT ) * 60L * 1000L;
		List<DbImage> uploadingImages = DbImage.getUploadingImages();
		
		log.info( uploadingImages.size() + " image(s) are uploading" );
		
		if (uploadingImages.isEmpty()) return;
		
		Iterator<DbImage> iter = uploadingImages.iterator();
		while (iter.hasNext()) {
			DbImage dbImage = iter.next();
			log.debug( "Akutlle Systemzeit: " + System.currentTimeMillis() );
			log.debug( "Timestamp: " + dbImage.timestamp.getTime() );
			log.debug( "Differenz: " + (System.currentTimeMillis() - dbImage.timestamp.getTime()) );
			log.debug( "Timeout: " + timeout );
			if (System.currentTimeMillis() - dbImage.timestamp.getTime() >= timeout) {
				DbImage.delete( dbImage.UUID );
				log.info( "Deleted dbimage from db: " + dbImage.UUID  + " due to timeout");
			} else {
				// re add users to ftpserver
				App.ftpServer.addUser( dbImage.ftpUser,  DbFtpUser.getUserByName( dbImage.ftpUser ).password, MasterFtpServer.Mode.UPLOADING, "" );
				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
	 * @exception ImageDataException If the imagedata contains errors
	 */
	public static void addImageDataToProcess( ImageData imageData, String username, String password ) throws ImageDataException
	{
		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() ) {
			throw new ImageDataException(ImageDataError.INVALID_DATA, "Missing arguments.");
		}

		if (!imageData.uuid.matches( "^[0-9a-f]{8}\\-[0-9a-f]{4}\\-[0-9a-f]{4}\\-[0-9a-f]{4}\\-[0-9a-f]{12}$" )) {
			throw new ImageDataException(ImageDataError.INVALID_DATA, "UUID not valid.");
		} else if (!imageData.imageName.matches( "^[a-zA-Z0-9_\\-]{5,50}$" )) {
			throw new ImageDataException(ImageDataError.INVALID_DATA, "ImageName not valid. (Length must be 5 to 50)");
		} else if (DbUser.getUserIdByName( imageData.imageOwner ) != 0) {
			throw new ImageDataException(ImageDataError.INVALID_DATA, "ImageOwner not valid.");
		} else if (!imageData.conentOperatingSystem.matches( "^[\\w][-0-9a-zA-Z]{3,20}$" )) {
			throw new ImageDataException(ImageDataError.INVALID_DATA, "ContentOperatingSystem not valid. (Length must be 3 to 20)");
		} else if (!imageData.imageShortDescription.matches( "^[-\\w!\"§$%&/()=?+*#'^]$" )) {
			throw new ImageDataException(ImageDataError.INVALID_DATA, "ImageShortDescription is not valid.");
		} else if (!imageData.imageLongDescription.matches( "^[-\\w!\"§$%&/()=?+*#'^]$" )) {
			throw new ImageDataException(ImageDataError.INVALID_DATA, "ImageLongDescription is not valid.");
		} else if ( imageData.fileSize <= 0 ) {
			throw new ImageDataException(ImageDataError.INVALID_DATA, "Filesize needs to be greater than 0.");
		}
		
		
		// TODO: check some more regex
		

		if ( DbImage.exists( imageData ) ) {
			throw new ImageDataException( ImageDataError.INVALID_DATA, "Image with this UUID is already existing." );
		}

		// if everything went fine, add image to db
		DbImage.insert( imageData, System.currentTimeMillis(), username, password);

		// and to processinglist
		images.put( username, imageData );
	}
	
	/**
	 * 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;
	}
}