summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNils Schwabe2014-06-30 17:11:03 +0200
committerNils Schwabe2014-06-30 17:11:03 +0200
commit1a3dbab6ca7118f4ca9f61043f416f074ede13bc (patch)
treefad14555be544c3ba2afdf31b8f315364a67e7a6 /src
parent[Webinterface] Add "images" tab (diff)
downloadmasterserver-1a3dbab6ca7118f4ca9f61043f416f074ede13bc.tar.gz
masterserver-1a3dbab6ca7118f4ca9f61043f416f074ede13bc.tar.xz
masterserver-1a3dbab6ca7118f4ca9f61043f416f074ede13bc.zip
Add implementation for the new up- and download protocoll
Remove some old stuff that is not needed anymore Fix some small bugs
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/openslx/imagemaster/App.java26
-rw-r--r--src/main/java/org/openslx/imagemaster/Globals.java253
-rw-r--r--src/main/java/org/openslx/imagemaster/crcchecker/CRCChecker.java15
-rw-r--r--src/main/java/org/openslx/imagemaster/crcchecker/CRCFile.java2
-rw-r--r--src/main/java/org/openslx/imagemaster/crcchecker/ImageFile.java29
-rw-r--r--src/main/java/org/openslx/imagemaster/db/DbImage.java73
-rw-r--r--src/main/java/org/openslx/imagemaster/db/LdapUser.java19
-rw-r--r--src/main/java/org/openslx/imagemaster/ftp/FtpCredentialsScheduler.java79
-rw-r--r--src/main/java/org/openslx/imagemaster/ftp/ImageProcessor.java160
-rw-r--r--src/main/java/org/openslx/imagemaster/ftp/MasterFtpServer.java313
-rw-r--r--src/main/java/org/openslx/imagemaster/ftp/MasterFtplet.java97
-rw-r--r--src/main/java/org/openslx/imagemaster/server/ApiServer.java247
-rw-r--r--src/main/java/org/openslx/imagemaster/serverconnection/ImageInfos.java73
-rw-r--r--src/main/java/org/openslx/imagemaster/serverconnection/ImageProcessor.java123
-rw-r--r--src/main/java/org/openslx/imagemaster/serversession/ServerSession.java3
-rw-r--r--src/main/java/org/openslx/imagemaster/session/Session.java3
-rw-r--r--src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java22
-rw-r--r--src/main/thrift/imagemaster.thrift119
-rw-r--r--src/test/java/org/openslx/imagemaster/AppTest.java35
-rw-r--r--src/test/java/org/openslx/imagemaster/ServerTest.java223
20 files changed, 569 insertions, 1345 deletions
diff --git a/src/main/java/org/openslx/imagemaster/App.java b/src/main/java/org/openslx/imagemaster/App.java
index 7f004fd..c2b36c0 100644
--- a/src/main/java/org/openslx/imagemaster/App.java
+++ b/src/main/java/org/openslx/imagemaster/App.java
@@ -5,10 +5,7 @@ import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
-import org.openslx.imagemaster.Globals.PropInt;
-import org.openslx.imagemaster.ftp.FtpCredentialsScheduler;
-import org.openslx.imagemaster.ftp.ImageProcessor;
-import org.openslx.imagemaster.ftp.MasterFtpServer;
+import org.openslx.imagemaster.serverconnection.ImageProcessor;
import org.openslx.imagemaster.thrift.server.BinaryListener;
import org.slf4j.LoggerFactory;
@@ -19,8 +16,6 @@ public class App
private static List<Thread> servers = new ArrayList<>();
- public static final MasterFtpServer ftpServer = new MasterFtpServer();
-
static {
// TODO:
// This is a temporary workaround for this annoying log4j error msg.
@@ -35,7 +30,7 @@ public class App
// Load properties
try {
- Globals.loadProperties(); // don't need to check return, because this should be the first time where props are loaded.
+ Globals.loadProperties();
if ( !Globals.propertiesValid() ) {
log.error( "Config file contains errors." );
System.exit( 1 );
@@ -46,7 +41,6 @@ public class App
}
log.info( "Loaded config file" );
- log.info( "Checking !uploading! db entries." );
ImageProcessor.checkUploading();
// Create binary listener
@@ -54,23 +48,7 @@ public class App
t = new Thread( new BinaryListener(), "BinaryListener" );
servers.add( t );
t.start();
-
- // Create Ftp Server
- ftpServer.init( Globals.getPropertyInt( PropInt.FTPPORT ) ); // this init needs to be done, because we have to wait for the config file
- Thread f;
- f = new Thread( ftpServer, "FtpServer" );
- servers.add( f );
- f.start();
-
- // add ftp users from database
- ftpServer.addDbFtpUsers();
- // start FtpCredentialsScheduler
- FtpCredentialsScheduler.startScheduling();
-
- // testtesteset
- ftpServer.addUser( "asdfasdfasdf", MasterFtpServer.Mode.DOWNLOADING, "windows7.vmdk" );
-
// Run more servers
// ...
// Wait for all servers to die
diff --git a/src/main/java/org/openslx/imagemaster/Globals.java b/src/main/java/org/openslx/imagemaster/Globals.java
index a03d401..3eca269 100644
--- a/src/main/java/org/openslx/imagemaster/Globals.java
+++ b/src/main/java/org/openslx/imagemaster/Globals.java
@@ -14,196 +14,159 @@ public class Globals
private static Logger log = Logger.getLogger( Globals.class );
private static final Properties properties = new Properties();
private static boolean loadedProperties = false;
-
- public static enum PropInt
- {
- LDAPPORT, SESSIONTIMEOUTUSER, SESSIONTIMEOUTSERVER, FTPPORT, FTPTIMEOUT
- }
-
- public static enum PropString
- {
- IMAGEDIR, FTPKEYSTOREFILE, FTPKEYSTOREALIAS, FTPKEYSTOREPASSWORD, LDAPHOST, LDAPBINDQUERY, LDAPSEARCHBASEDN, LDAPSEARCHFILTER, LDAPKEYSTOREPASSWORD, LDAPKEYSTOREPATH, FTPBASEDIR
- }
-
- public static enum PropBool
- {
- LDAPSSL
- }
+ public final static int blockSize = 16 * 1024 * 1024;
/**
* Loads the properties from config/global.properties
- *
- * @return if the properties were loaded or not
* @throws IOException
*/
- public static boolean loadProperties() throws IOException
+ public static void loadProperties() throws IOException
{
- if ( loadedProperties )
- return false;
+ if ( loadedProperties ) return;
// Load properties
BufferedInputStream stream = new BufferedInputStream( new FileInputStream( "config/global.properties" ) );
properties.load( stream );
stream.close();
-
- return true;
+ loadedProperties = true;
}
public static boolean propertiesValid()
{
- if ( Globals.getPropertyString( PropString.IMAGEDIR ) == null
- || Globals.getPropertyString( PropString.IMAGEDIR ).isEmpty()
- || Globals.getPropertyString( PropString.LDAPHOST ) == null
- || Globals.getPropertyString( PropString.LDAPHOST ).isEmpty()
- || Globals.getPropertyString( PropString.LDAPBINDQUERY ) == null
- || Globals.getPropertyString( PropString.LDAPBINDQUERY ).isEmpty()
- || Globals.getPropertyString( PropString.LDAPSEARCHBASEDN ) == null
- || Globals.getPropertyString( PropString.LDAPSEARCHBASEDN ).isEmpty()
- || Globals.getPropertyString( PropString.LDAPSEARCHFILTER ) == null
- || Globals.getPropertyString( PropString.LDAPSEARCHFILTER ).isEmpty()
- || Globals.getPropertyString( PropString.LDAPKEYSTOREPASSWORD ) == null
- || Globals.getPropertyString( PropString.LDAPKEYSTOREPASSWORD ).isEmpty()
- || Globals.getPropertyString( PropString.LDAPKEYSTOREPATH ) == null
- || Globals.getPropertyString( PropString.LDAPKEYSTOREPATH ).isEmpty()
- || Globals.getPropertyString( PropString.FTPBASEDIR ) == null
- || Globals.getPropertyString( PropString.FTPBASEDIR ).isEmpty()
- || Globals.getPropertyString( PropString.FTPKEYSTOREFILE ) == null
- || Globals.getPropertyString( PropString.FTPKEYSTOREFILE ).isEmpty()
- || Globals.getPropertyString( PropString.FTPKEYSTOREALIAS ) == null
- || Globals.getPropertyString( PropString.FTPKEYSTOREALIAS ).isEmpty()
- || Globals.getPropertyString( PropString.FTPKEYSTOREPASSWORD ) == null
- || Globals.getPropertyString( PropString.FTPKEYSTOREPASSWORD ).isEmpty()
-
- || Globals.getPropertyInt( PropInt.LDAPPORT ) == 0
- || Globals.getPropertyInt( PropInt.SESSIONTIMEOUTUSER ) == 0
- || Globals.getPropertyInt( PropInt.SESSIONTIMEOUTSERVER ) == 0
- || Globals.getPropertyInt( PropInt.FTPPORT ) == 0
- || Globals.getPropertyInt( PropInt.FTPTIMEOUT ) == 0 ) {
+ if ( getImageDir() == null
+ || getImageDir().isEmpty()
+ || getLdapHost() == null
+ || getLdapHost().isEmpty()
+ || getLdapBindQuery() == null
+ || getLdapBindQuery().isEmpty()
+ || getLdapSearchBaseDn() == null
+ || getLdapSearchBaseDn().isEmpty()
+ || getLdapSearchFilter() == null
+ || getLdapSearchFilter().isEmpty()
+ || getLdapKeystorePassword() == null
+ || getLdapKeystorePassword().isEmpty()
+ || getLdapKeystorePath() == null
+ || getLdapKeystorePath().isEmpty()
+ || getFtpBaseDir() == null
+ || getFtpBaseDir().isEmpty()
+ || getFtpKeystoreFile() == null
+ || getFtpKeystoreFile().isEmpty()
+ || getFtpKeystoreAlias() == null
+ || getFtpKeystoreAlias().isEmpty()
+ || getFtpKeystorePassword() == null
+ || getFtpKeystorePassword().isEmpty()
+
+ || getLdapPort() == 0
+ || getSessionTimeoutUser() == 0
+ || getSessionTimeoutServer() == 0
+ || getFtpPort() == 0
+ || getFtpTimeout() == 0 ) {
return false;
}
// check ldap_bind_query
- if ( StringUtils.countMatches( Globals.getPropertyString( PropString.LDAPBINDQUERY ), "%" ) == 0 ) {
+ if ( StringUtils.countMatches( getLdapBindQuery(), "%" ) == 0 ) {
log.error( "ldap_bind_query does not contain '%'" );
return false;
}
// check ldap_search_filter
- if ( StringUtils.countMatches( Globals.getPropertyString( PropString.LDAPSEARCHFILTER ), "%" ) == 0) {
+ if ( StringUtils.countMatches( getLdapSearchFilter(), "%" ) == 0) {
log.error( "ldap_search_filter does not contain '%'" );
return false;
}
// check keystore
- if ( !Globals.getPropertyString( PropString.FTPKEYSTOREFILE ).endsWith( ".jks" )) {
+ if ( !getFtpKeystoreFile().endsWith( ".jks" )) {
log.error( "Keystore is not in jks format." );
return false;
}
// remove "/" at the end of the paths
- String ftp = Globals.getPropertyString( PropString.FTPBASEDIR );
+ String ftp = getFtpBaseDir();
if ( ftp.endsWith( "/" ) ) {
Globals.properties.put( "ftp_base_dir", ftp.substring( 0, ftp.length() - 1 ) );
}
- String image = Globals.getPropertyString( PropString.IMAGEDIR );
+ String image = getImageDir();
if ( image.endsWith( "/" ) ) {
Globals.properties.put( "image_dir", image.substring( 0, image.length() - 1 ) );
}
return true;
}
-
- public static int getPropertyInt( Globals.PropInt props )
- {
- String result = null;
-
- switch ( props ) {
- case LDAPPORT:
- result = properties.getProperty( "ldap_port" );
- break;
- case SESSIONTIMEOUTUSER:
- result = properties.getProperty( "session_timeout_user" );
- break;
- case SESSIONTIMEOUTSERVER:
- result = properties.getProperty( "session_timeout_server" );
- break;
- case FTPPORT:
- result = properties.getProperty( "ftp_port" );
- break;
- case FTPTIMEOUT:
- result = properties.getProperty( "ftp_timeout" );
- break;
- default:
- result = "0";
- break;
- }
-
- if ( result == null )
- return 0;
-
- return Integer.valueOf( result );
+
+ /* INTEGERS */
+
+ public static int getLdapPort() {
+ return Integer.valueOf( properties.getProperty( "ldap_port" ) );
}
-
- public static String getPropertyString( Globals.PropString props )
- {
- String result = null;
-
- switch ( props ) {
- case IMAGEDIR:
- result = properties.getProperty( "image_dir" );
- break;
- case FTPKEYSTOREFILE:
- result = properties.getProperty( "ftp_keystore_file" );
- break;
- case FTPKEYSTOREALIAS:
- result = properties.getProperty( "ftp_keystore_alias" );
- break;
- case FTPKEYSTOREPASSWORD:
- result = properties.getProperty( "ftp_keystore_password" );
- break;
- case LDAPHOST:
- result = properties.getProperty( "ldap_host" );
- break;
- case LDAPBINDQUERY:
- result = properties.getProperty( "ldap_bind_query" );
- break;
- case LDAPSEARCHBASEDN:
- result = properties.getProperty( "ldap_search_base_dn" );
- break;
- case LDAPSEARCHFILTER:
- result = properties.getProperty( "ldap_search_filter" );
- break;
- case LDAPKEYSTOREPASSWORD:
- result = properties.getProperty( "ldap_keystore_password" );
- break;
- case LDAPKEYSTOREPATH:
- result = properties.getProperty( "ldap_keystore_path" );
- break;
- case FTPBASEDIR:
- result = properties.getProperty( "ftp_base_dir" );
- break;
- default:
- result = "";
- break;
- }
-
- return result;
+
+ public static int getSessionTimeoutUser() {
+ return Integer.valueOf( properties.getProperty( "session_timeout_user" ) );
}
-
- public static boolean getPropertyBool( Globals.PropBool props )
- {
- String result = null;
-
- switch ( props ) {
- case LDAPSSL:
- result = properties.getProperty( "ldap_ssl" );
- break;
- default:
- result = "";
- break;
- }
-
- return Boolean.valueOf( result );
+
+ public static int getSessionTimeoutServer() {
+ return Integer.valueOf( properties.getProperty( "session_timeout_user" ) );
+ }
+
+ public static int getFtpPort() {
+ return Integer.valueOf( properties.getProperty( "ftp_port" ) );
+ }
+
+ public static int getFtpTimeout() {
+ return Integer.valueOf( properties.getProperty( "ftp_timeout" ) );
+ }
+
+ /* STRINGS */
+
+ public static String getImageDir() {
+ return properties.getProperty( "image_dir" );
+ }
+
+ public static String getFtpKeystoreFile() {
+ return properties.getProperty( "ftp_keystore_file" );
+ }
+
+ public static String getFtpKeystoreAlias() {
+ return properties.getProperty( "ftp_keystore_alias" );
+ }
+
+ public static String getFtpKeystorePassword() {
+ return properties.getProperty( "ftp_keystore_password" );
+ }
+
+ public static String getLdapHost() {
+ return properties.getProperty( "ldap_host" );
+ }
+
+ public static String getLdapBindQuery() {
+ return properties.getProperty( "ldap_bind_query" );
+ }
+
+ public static String getLdapSearchBaseDn() {
+ return properties.getProperty( "ldap_search_base_dn" );
+ }
+
+ public static String getLdapSearchFilter() {
+ return properties.getProperty( "ldap_search_filter" );
+ }
+
+ public static String getLdapKeystorePassword() {
+ return properties.getProperty( "ldap_keystore_password" );
+ }
+
+ public static String getLdapKeystorePath() {
+ return properties.getProperty( "ldap_keystore_path" );
+ }
+
+ public static String getFtpBaseDir() {
+ return properties.getProperty( "ftp_base_dir" );
+ }
+
+ /* BOOLEANS */
+
+ public static boolean getLdapSsl() {
+ return Boolean.valueOf( properties.getProperty( "ldap_ssl" ) );
}
}
diff --git a/src/main/java/org/openslx/imagemaster/crcchecker/CRCChecker.java b/src/main/java/org/openslx/imagemaster/crcchecker/CRCChecker.java
index 04f6a22..29b7090 100644
--- a/src/main/java/org/openslx/imagemaster/crcchecker/CRCChecker.java
+++ b/src/main/java/org/openslx/imagemaster/crcchecker/CRCChecker.java
@@ -1,14 +1,12 @@
package org.openslx.imagemaster.crcchecker;
-import java.io.DataInputStream;
-import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.zip.CRC32;
import org.apache.log4j.Logger;
+import org.openslx.imagemaster.Globals;
public class CRCChecker
@@ -27,9 +25,7 @@ public class CRCChecker
{
List<Integer> result = new LinkedList<>();
- final int blockSize = 16 * 1024 * 1024;
-
- ImageFile image = new ImageFile( imageFile, blockSize );
+ ImageFile image = new ImageFile( imageFile, Globals.blockSize );
CRCFile crc = new CRCFile( crcFile );
log.debug( "Checking image file: '" + imageFile + "' with crc file: '" + crcFile + "'");
@@ -40,7 +36,7 @@ public class CRCChecker
}
// file is smaller than one block - no need to check crc yet
- if (image.length() < blockSize) {
+ if (image.length() < Globals.blockSize) {
return result;
}
// check all blocks
@@ -60,16 +56,15 @@ public class CRCChecker
CRC32 crcCalc = new CRC32();
crcCalc.update( block );
int crcSum = Integer.reverseBytes( (int) crcCalc.getValue() );
- log.debug( "Got crc for block '" + blockN + "': '" + crcSum + "'" );
int crcSumFromFile;
try {
crcSumFromFile = crc.getCRCSum( blockN );
} catch ( IOException e ) {
throw new IOException( "Could not read CRC file", e );
}
- log.debug( "And read crc from file: '" + crcSumFromFile + "'" );
- if (crcSum == crcSumFromFile) result.add( blockN );
+ if (crcSum == crcSumFromFile) result.add( blockN );
+ else log.debug(blockN + " was invalid");
}
return result;
diff --git a/src/main/java/org/openslx/imagemaster/crcchecker/CRCFile.java b/src/main/java/org/openslx/imagemaster/crcchecker/CRCFile.java
index 3a75b37..b557ada 100644
--- a/src/main/java/org/openslx/imagemaster/crcchecker/CRCFile.java
+++ b/src/main/java/org/openslx/imagemaster/crcchecker/CRCFile.java
@@ -54,7 +54,7 @@ public class CRCFile
*/
public int getCRCSum(int blockNumber) throws IOException {
if (crcSums == null) {
- // the crcSum were not read yet
+ // the crcSums were not read yet
DataInputStream dis = new DataInputStream( new FileInputStream( file ) );
crcSums = new ArrayList<>();
for (int i = 0; i < file.length()/4; i++) {
diff --git a/src/main/java/org/openslx/imagemaster/crcchecker/ImageFile.java b/src/main/java/org/openslx/imagemaster/crcchecker/ImageFile.java
index a6ff8f0..9e77537 100644
--- a/src/main/java/org/openslx/imagemaster/crcchecker/ImageFile.java
+++ b/src/main/java/org/openslx/imagemaster/crcchecker/ImageFile.java
@@ -1,8 +1,8 @@
package org.openslx.imagemaster.crcchecker;
import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
+import java.io.RandomAccessFile;
/**
* Representing an image file.
@@ -12,37 +12,38 @@ import java.io.IOException;
*/
public class ImageFile
{
- private File file;
+ private File f;
+ private RandomAccessFile file = null;
private int blockSize;
public ImageFile(String filename, int blockSize) {
- this.file = new File( filename );
+ this.f = new File( filename );
this.blockSize = blockSize;
}
/**
- * Get a certain block
+ * Get a certain block (uses RandomAccessFile)
* @param block The number of the block you want to get
* @return The specified block
* @throws IOException When file was not found or could not be read
*/
public byte[] getBlock(int block) throws IOException {
if (block < 0) return null;
- if (block > file.length()/blockSize) return null;
+ if (block > f.length()/blockSize) return null;
- FileInputStream fis = new FileInputStream( file );
+ if (file == null) {
+ file = new RandomAccessFile( f, "r" );
+ }
- fis.skip( block * (long) blockSize );
-
- byte[] result = new byte[ ( blockSize > fis.available() )? fis.available() : blockSize ]; // only read availible bytes
-
- fis.read(result);
- fis.close();
+ file.seek( (long)block * blockSize );
+ long remaining = length() - (block * blockSize);
+ byte[] result = new byte[ ( blockSize > remaining )? (int) remaining : blockSize ]; // only read available bytes
+ file.read( result );
return result;
}
public long length() {
- return file.length();
+ return f.length();
}
-}
+} \ No newline at end of file
diff --git a/src/main/java/org/openslx/imagemaster/db/DbImage.java b/src/main/java/org/openslx/imagemaster/db/DbImage.java
index 5d22e33..e3a8888 100644
--- a/src/main/java/org/openslx/imagemaster/db/DbImage.java
+++ b/src/main/java/org/openslx/imagemaster/db/DbImage.java
@@ -3,6 +3,7 @@ package org.openslx.imagemaster.db;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.LinkedList;
import java.util.List;
import org.openslx.imagemaster.thrift.iface.ImageData;
@@ -23,8 +24,10 @@ public class DbImage
public final String shortDescription;
public final String longDescription;
public final Timestamp timestamp;
- public final String ftpUser;
public final long fileSize;
+ public final String token;
+ public final List<Integer> missingBlocks;
+ public final String serverSessionId;
public DbImage(String UUID)
@@ -42,14 +45,16 @@ public class DbImage
this.shortDescription = null;
this.longDescription = null;
this.timestamp = new Timestamp( 0 );
- this.ftpUser = null;
this.fileSize = 0;
+ this.token = null;
+ this.missingBlocks = null;
+ this.serverSessionId = null;
}
public DbImage(String UUID, int imageVersion, String imageName, String imagePath,
Timestamp imageCreateTime, Timestamp imageUpdateTime, String imageOwner, String contentOperatingSystem,
boolean isValid, boolean isDeleted, String shortDescription, String longDescription,
- Timestamp timestamp, String ftpUser, long fileSize)
+ Timestamp timestamp, long fileSize, String token, String missingBlocksList, String serverSessionId)
{
this.UUID = UUID;
this.imageVersion = imageVersion;
@@ -64,8 +69,16 @@ public class DbImage
this.shortDescription = shortDescription;
this.longDescription = longDescription;
this.timestamp = timestamp;
- this.ftpUser = ftpUser;
this.fileSize = fileSize;
+ this.token = token;
+
+ String[] parts = missingBlocksList.split( ";" );
+ this.missingBlocks = new LinkedList<>();
+ for (int i = 0; i < parts.length - 1; i++) { // do not copy the last empty string (1;2;3;) -> "1","2","3",""
+ this.missingBlocks.add( Integer.valueOf( parts[i] ) );
+ }
+
+ this.serverSessionId = serverSessionId;
}
/**
@@ -74,9 +87,9 @@ public class DbImage
* @param imageData
* @return
*/
- public static boolean exists( ImageData imageData )
+ public static boolean exists( String uuid )
{
- if ( MySQL.findUniqueOrNull( DbImage.class, "SELECT images.UUID FROM images WHERE images.UUID = ?", imageData.uuid ) == null ) {
+ if ( MySQL.findUniqueOrNull( DbImage.class, "SELECT images.UUID FROM images WHERE images.UUID = ?", uuid ) == null ) {
return false;
} else {
return true;
@@ -87,23 +100,34 @@ public class DbImage
* Insert a new image into database
* @param imageData The metadata of the image
* @param ts The timestamp of inserting
+ * @param token The token that is able to upload this image
+ * @param missingBlocks The blocks that are missing for this image
+ * @param serverSessionId The server that is uploading this image
* @return Affected rows
*/
- public static int insert( ImageData imageData, long ts, String ftpUser, String ftpPassword )
+ public static int insert( ImageData imageData, long ts, String token, List<Integer> missingBlocks, String serverSessionId)
{
Date createTime = new Date( imageData.imageCreateTime );
Date updateTime = new Date( imageData.imageUpdateTime );
Date timestamp = new Date( ts );
SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
-
+
+ String missingBlocksList = "";
+ if (missingBlocks != null) {
+ for (Integer block : missingBlocks) {
+ missingBlocksList = missingBlocksList + String.valueOf( block ) + ";";
+ }
+ }
+
return MySQL
.update(
- "INSERT INTO images (UUID, image_version, image_name, image_path, image_createTime, image_updateTime, image_owner, content_operatingSystem, status_isValid, status_isDeleted, image_shortDescription, image_longDescription, timestamp, ftpUser, fileSize) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ "INSERT INTO images (UUID, image_version, image_name, image_path, image_createTime, image_updateTime, image_owner, content_operatingSystem, status_isValid, status_isDeleted, image_shortDescription, image_longDescription, timestamp, fileSize, token, missingBlocks, serverSessionId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
imageData.uuid, imageData.imageVersion, imageData.imageName, "!uploading!",
sdf.format( createTime ), sdf.format( updateTime ), imageData.imageOwner,
imageData.conentOperatingSystem, imageData.statusIsValid,
imageData.statusIsDeleted, imageData.imageShortDescription,
- imageData.imageLongDescription, sdf.format( timestamp ), ftpUser, imageData.fileSize );
+ imageData.imageLongDescription, sdf.format( timestamp ), imageData.fileSize,
+ token, missingBlocksList, serverSessionId);
}
public String getUUID()
@@ -111,9 +135,20 @@ public class DbImage
return this.UUID;
}
- public static int update( ImageData imageData, String location )
+ public static int update( String uuid, String location )
{
- return MySQL.update( "UPDATE images SET images.image_path = ? WHERE images.UUID = ?", location, imageData.uuid );
+ return MySQL.update( "UPDATE images SET images.image_path = ? WHERE images.UUID = ?", location, uuid );
+ }
+
+ public static int updateMissingBlocks( String UUID, List<Integer> missingBlocks)
+ {
+ String missingBlocksList = "";
+ if (missingBlocks != null) {
+ for (Integer block : missingBlocks) {
+ missingBlocksList = missingBlocksList + String.valueOf( block ) + ";";
+ }
+ }
+ return MySQL.update( "UPDATE images SET images.missingBlocks = ? WHERE images.UUID = ?", missingBlocksList, UUID );
}
public static int delete( String UUID )
@@ -123,10 +158,20 @@ public class DbImage
public static List<DbImage> getUploadingImages()
{
- return MySQL.findAll( DbImage.class, "SELECT images.UUID, images.image_version, images.image_name, images.image_path, images.image_createTime, images.image_updateTime, images.image_owner, images.content_operatingSystem, images.status_isValid, images.status_isDeleted, images.image_shortDescription, images.image_longDescription, images.timestamp, images.ftpUser, images.fileSize FROM images WHERE image_path = ?", "!uploading!" );
+ return MySQL.findAll( DbImage.class, "SELECT images.UUID, images.image_version, images.image_name, images.image_path, images.image_createTime, images.image_updateTime, images.image_owner, images.content_operatingSystem, images.status_isValid, images.status_isDeleted, images.image_shortDescription, images.image_longDescription, images.timestamp, images.fileSize, images.token, images.missingBlocks, images.serverSessionId FROM images WHERE missingBlocks != ?", "" );
}
public static DbImage getImageByUUID(String uuid) {
- return MySQL.findUniqueOrNull( DbImage.class, "SELECT images.UUID, images.image_version, images.image_name, images.image_path, images.image_createTime, images.image_updateTime, images.image_owner, images.content_operatingSystem, images.status_isValid, images.status_isDeleted, images.image_shortDescription, images.image_longDescription, images.timestamp, images.ftpUser, images.fileSize FROM images WHERE uuid = ?", uuid );
+ return MySQL.findUniqueOrNull( DbImage.class, "SELECT images.UUID, images.image_version, images.image_name, images.image_path, images.image_createTime, images.image_updateTime, images.image_owner, images.content_operatingSystem, images.status_isValid, images.status_isDeleted, images.image_shortDescription, images.image_longDescription, images.timestamp, images.fileSize, images.token, images.missingBlocks, images.serverSessionId FROM images WHERE uuid = ?", uuid );
+ }
+
+ /**
+ * Creates a package of image data of this DbImage object.
+ * @return The corresponding image data
+ */
+ public ImageData getImageData() {
+ return new ImageData(this.UUID, this.imageVersion, this.imageName, this.imageCreateTime.getTime(),
+ this.imageUpdateTime.getTime(), this.imageOwner, this.contentOperatingSystem, this.isValid,
+ this.isDeleted, this.shortDescription, this.longDescription, this.fileSize);
}
}
diff --git a/src/main/java/org/openslx/imagemaster/db/LdapUser.java b/src/main/java/org/openslx/imagemaster/db/LdapUser.java
index 0299829..39bbb69 100644
--- a/src/main/java/org/openslx/imagemaster/db/LdapUser.java
+++ b/src/main/java/org/openslx/imagemaster/db/LdapUser.java
@@ -20,9 +20,6 @@ import org.apache.directory.ldap.client.api.LdapNetworkConnection;
import org.apache.log4j.Logger;
import org.apache.mina.filter.ssl.KeyStoreFactory;
import org.openslx.imagemaster.Globals;
-import org.openslx.imagemaster.Globals.PropBool;
-import org.openslx.imagemaster.Globals.PropInt;
-import org.openslx.imagemaster.Globals.PropString;
import org.openslx.imagemaster.session.User;
import org.openslx.imagemaster.thrift.iface.AuthenticationError;
import org.openslx.imagemaster.thrift.iface.AuthenticationException;
@@ -62,22 +59,22 @@ public class LdapUser extends User
try {
LdapConnectionConfig config = new LdapConnectionConfig();
- String ldapHost = Globals.getPropertyString( PropString.LDAPHOST );
+ String ldapHost = Globals.getLdapHost();
log.debug( "Setting host... " + ldapHost );
config.setLdapHost( ldapHost );
- boolean useSsl = Globals.getPropertyBool( PropBool.LDAPSSL );
+ boolean useSsl = Globals.getLdapSsl();
log.debug( "Setting use ssl... " + useSsl);
config.setUseSsl( useSsl );
- int ldapPort = Globals.getPropertyInt( PropInt.LDAPPORT );
+ int ldapPort = Globals.getLdapPort();
log.debug( "Setting port... " + ldapPort );
config.setLdapPort( ldapPort );
// load keystore ...
KeyStoreFactory ksf = new KeyStoreFactory();
- ksf.setDataFile( new File(Globals.getPropertyString( PropString.LDAPKEYSTOREPATH )) );
- ksf.setPassword( Globals.getPropertyString( PropString.LDAPKEYSTOREPASSWORD ) );
+ ksf.setDataFile( new File(Globals.getLdapKeystorePath()) );
+ ksf.setPassword( Globals.getLdapKeystorePassword());
ksf.setType( "jks" );
// ... and set TrustManager
@@ -89,15 +86,15 @@ public class LdapUser extends User
connection = new LdapNetworkConnection( config );
log.debug( "Trying to bind..." );
- String bind = Globals.getPropertyString( PropString.LDAPBINDQUERY ).replace( "%", login );
+ String bind = Globals.getLdapBindQuery().replace( "%", login );
connection.bind( bind, password );
//connection.bind();
log.debug( "Bind successful" );
// make search query
- EntryCursor cursor = connection.search( Globals.getPropertyString( Globals.PropString.LDAPSEARCHBASEDN ),
- Globals.getPropertyString( Globals.PropString.LDAPSEARCHFILTER ).replace( "%", login ), SearchScope.SUBTREE );
+ EntryCursor cursor = connection.search( Globals.getLdapSearchBaseDn(),
+ Globals.getLdapSearchFilter().replace( "%", login ), SearchScope.SUBTREE );
// only use the first result
cursor.next();
Entry entry = cursor.get();
diff --git a/src/main/java/org/openslx/imagemaster/ftp/FtpCredentialsScheduler.java b/src/main/java/org/openslx/imagemaster/ftp/FtpCredentialsScheduler.java
deleted file mode 100644
index eba3f55..0000000
--- a/src/main/java/org/openslx/imagemaster/ftp/FtpCredentialsScheduler.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package org.openslx.imagemaster.ftp;
-
-import java.io.File;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
-
-import org.apache.log4j.Logger;
-import org.openslx.imagemaster.App;
-import org.openslx.imagemaster.Globals;
-import org.openslx.imagemaster.db.DbImage;
-
-public class FtpCredentialsScheduler extends TimerTask
-{
-
- private static Logger log = Logger.getLogger( FtpCredentialsScheduler.class );
-
- public static final long timeout = Long.valueOf( Globals.getPropertyInt( Globals.PropInt.FTPTIMEOUT ) ) * 60L * 1000L; // timeout in ms
-
- @Override
- public void run()
- {
- synchronized ( App.ftpServer.users ) {
- List<DbImage> uploadingImages = DbImage.getUploadingImages(); // get the uploading images
- // List to save the users that need to be deleted after iterating the map
- List<String> usersToDelete = new LinkedList<>();
- // check all folders
- for ( Map.Entry<String, MasterFtpServer.Infos> entry : App.ftpServer.users.entrySet() ) {
- if ( entry == null )
- continue;
- String username = entry.getKey();
- File dir = new File( Globals.getPropertyString( Globals.PropString.FTPBASEDIR ) + "/" + username );
- if ( !dir.exists() )
- continue;
- File[] list = dir.listFiles();
- if ( list.length == 1 ) {
- // check file size first
- DbImage currentImage = null;
- for (DbImage img : uploadingImages) { // find the image that was uploaded by this user
- if (img.ftpUser == username) currentImage = img;
- }
- if (currentImage != null && list[0].getTotalSpace() == currentImage.fileSize) {
- ImageProcessor.processImageAfterUpload( username, list[0].getName() );
- } else if ( ( new Date().getTime() - list[0].lastModified() ) >= timeout ) { // check timeout
- log.info( username + "'s files are too old. Deleting him and his folder." );
- usersToDelete.add( username );
- }
- } else if ( list.length > 1 ) {
- log.info( "User '" + username + "' uploaded too many files. Deleting his account and his folder." );
- usersToDelete.add( username );
- } else {
- // check the creation time of the user
- if ( ( System.currentTimeMillis() - App.ftpServer.users.get( username ).getCreateTime() ) >= timeout ) {
- log.info( username + " did nothing for too long. Deleting him and his folder" );
- usersToDelete.add( username );
- }
- }
- }
- // now delete users
- for (String u : usersToDelete) {
- App.ftpServer.removeUser( u );
- ImageProcessor.removeImageFromProcessList( u );
- }
-
- }
- }
-
- public static void startScheduling()
- {
- Timer timer = new Timer( "FtpScheduler" );
-
- // start timer now and fire every 60 seconds
- timer.schedule( new FtpCredentialsScheduler(), 0, 60000 );
- }
-
-}
diff --git a/src/main/java/org/openslx/imagemaster/ftp/ImageProcessor.java b/src/main/java/org/openslx/imagemaster/ftp/ImageProcessor.java
deleted file mode 100644
index 2e480dc..0000000
--- a/src/main/java/org/openslx/imagemaster/ftp/ImageProcessor.java
+++ /dev/null
@@ -1,160 +0,0 @@
-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.Globals;
-import org.openslx.imagemaster.Globals.PropInt;
-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 {
- // 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 == null || imageData.imageName == null
- || imageData.imageOwner == null || imageData.conentOperatingSystem == null
- || imageData.imageShortDescription == null
- || imageData.imageLongDescription == null ) {
- throw new ImageDataException(ImageDataError.INVALID_DATA, "Missing arguments.");
- }
-
- 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.length() < 5 || imageData.imageName.length() > 50) {
- throw new ImageDataException(ImageDataError.INVALID_DATA, "ImageName not valid. (Length must be 5 to 50)");
- } else if (!DbUser.exists( imageData.imageOwner )) {
- throw new ImageDataException(ImageDataError.INVALID_DATA, "ImageOwner not known.");
- } else if ( imageData.fileSize <= 0 ) {
- throw new ImageDataException(ImageDataError.INVALID_DATA, "Filesize needs to be greater than 0.");
- }
-
- 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;
- }
-}
diff --git a/src/main/java/org/openslx/imagemaster/ftp/MasterFtpServer.java b/src/main/java/org/openslx/imagemaster/ftp/MasterFtpServer.java
deleted file mode 100644
index c24b318..0000000
--- a/src/main/java/org/openslx/imagemaster/ftp/MasterFtpServer.java
+++ /dev/null
@@ -1,313 +0,0 @@
-package org.openslx.imagemaster.ftp;
-
-import java.io.File;
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.ftpserver.FtpServer;
-import org.apache.ftpserver.FtpServerFactory;
-import org.apache.ftpserver.ftplet.Authority;
-import org.apache.ftpserver.ftplet.FtpException;
-import org.apache.ftpserver.ftplet.Ftplet;
-import org.apache.ftpserver.ftplet.UserManager;
-import org.apache.ftpserver.impl.FtpIoSession;
-import org.apache.ftpserver.listener.Listener;
-import org.apache.ftpserver.listener.ListenerFactory;
-import org.apache.ftpserver.ssl.SslConfigurationFactory;
-import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
-import org.apache.ftpserver.usermanager.SaltedPasswordEncryptor;
-import org.apache.ftpserver.usermanager.impl.BaseUser;
-import org.apache.ftpserver.usermanager.impl.WritePermission;
-import org.apache.log4j.Logger;
-import org.openslx.imagemaster.Globals;
-import org.openslx.imagemaster.Globals.PropString;
-import org.openslx.imagemaster.db.DbFtpUser;
-import org.openslx.imagemaster.thrift.iface.FtpCredentials;
-import org.openslx.imagemaster.util.RandomString;
-import org.openslx.imagemaster.util.Util;
-
-public class MasterFtpServer implements Runnable
-{
-
- private static Logger log = Logger.getLogger( MasterFtpServer.class );
- private FtpServer server;
- private UserManager userManager;
- private Listener listener;
- // key: ftpUsername, value: infos
- public final HashMap<String, Infos> users = new HashMap<>();
- private boolean ini = false;
-
- public enum Mode
- {
- UPLOADING, DOWNLOADING;
-
- @Override
- public String toString() {
- if (this == UPLOADING) {
- return "uploading";
- } else if (this == DOWNLOADING) {
- return "downloading";
- } else {
- return "";
- }
- }
- }
-
- /**
- * Class to hold infos of a ftp user.
- *
- * @author nils
- *
- */
- public class Infos
- {
- private final Long createTime;
- private final Mode mode;
- private final String fileName;
- private final String serverSessionId;
-
- public Infos(Long createTime, Mode mode, String fileName, String serverSessionId)
- {
- this.createTime = createTime;
- this.mode = mode;
- this.fileName = fileName;
- this.serverSessionId = serverSessionId;
- }
-
- public Long getCreateTime()
- {
- return this.createTime;
- }
-
- public Mode getMode()
- {
- return this.mode;
- }
-
- public String getFileName()
- {
- return this.fileName;
- }
-
- public String getServerSessionId() {
- return this.serverSessionId;
- }
- }
-
- public void init( int port )
- {
- if ( ini )
- return;
-
- FtpServerFactory serverFactory = new FtpServerFactory();
- ListenerFactory factory = new ListenerFactory();
-
- // config ssl
- SslConfigurationFactory sslConfigFactory = new SslConfigurationFactory();
- sslConfigFactory.setKeystoreFile( new File( Globals.getPropertyString( PropString.FTPKEYSTOREFILE ) ) );
- sslConfigFactory.setKeyAlias( Globals.getPropertyString( PropString.FTPKEYSTOREALIAS ) );
- sslConfigFactory.setKeystorePassword( Globals.getPropertyString( PropString.FTPKEYSTOREPASSWORD ) );
-
- // set the port of the listener
- factory.setPort( port );
- factory.setSslConfiguration( sslConfigFactory.createSslConfiguration() );
- factory.setImplicitSsl( true );
-
- // replace the default listener
- listener = factory.createListener();
- serverFactory.addListener( "default", listener );
-
- // create user manager
- PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
- File userFile = new File( "ftp.properties" );
- userManagerFactory.setFile( userFile );
- userManagerFactory.setPasswordEncryptor( new SaltedPasswordEncryptor() );
- userManager = userManagerFactory.createUserManager();
- serverFactory.setUserManager( userManager );
-
- // add the Ftplet
- HashMap<String, Ftplet> map = new HashMap<String, Ftplet>();
- map.put( "Ftplet1", new MasterFtplet() );
- serverFactory.setFtplets( map );
-
- // start the server
- server = serverFactory.createServer();
- ini = true;
- }
-
- /**
- * Add a user with username and password.
- * @param username
- * @param password
- * @param mode
- * @param fileName the filename of the file, that is allowed to access (if downloading)
- * @param add user to db
- * @return
- */
- public boolean addUser( String serverSessionId, String username, String password, Mode mode, String fileName, boolean toDb)
- {
- String dir = Globals.getPropertyString( Globals.PropString.FTPBASEDIR ) + "/" + username + "/";
-
- BaseUser user = new BaseUser();
- user.setName( username );
- user.setPassword( password );
- List<Authority> authorities = new ArrayList<Authority>();
-
- String file = "";
-
- if (mode == Mode.UPLOADING) {
- user.setHomeDirectory( dir );
- // uploading satellite is allowed to write
- authorities.add( new WritePermission() );
- } else if (mode == Mode.DOWNLOADING) {
- // the downloading satellite may access the whole dir, but this is restricted in MasterFtplet
- user.setHomeDirectory( Globals.getPropertyString( Globals.PropString.FTPBASEDIR ) );
- // downloading satellite is only allowed to read
- file = fileName;
- }
-
- user.setAuthorities( authorities );
-
- try {
- userManager.save( user );
- synchronized ( users ) {
- users.put( username, new Infos( System.currentTimeMillis(), mode, file, serverSessionId) );
- if (toDb)
- DbFtpUser.addUser( new DbFtpUser( username, password, mode.toString(), fileName, serverSessionId, new Timestamp(System.currentTimeMillis()) ) );
- }
- } catch ( FtpException e ) {
- return false;
- }
-
- return true;
- }
-
- public FtpCredentials addUser( final String serverSessionId, Mode mode, String fileName )
- {
- FtpCredentials ftpCredentials = null;
-
- String generatedUser = RandomString.generate( 10, false );
- String generatedPass = RandomString.generate( 16, true );
-
-
- BaseUser user = new BaseUser();
- user.setName( generatedUser );
- user.setPassword( generatedPass );
- List<Authority> authorities = new ArrayList<Authority>();
-
- String file = "";
- String dir = "";
-
- if (mode == Mode.UPLOADING) {
- // generate the home dir
- dir = Globals.getPropertyString( Globals.PropString.FTPBASEDIR ) + "/" + generatedUser + "/";
- if ( !new File( dir ).mkdir() ) {
- return null;
- }
- // uploading satellite is allowed to write
- authorities.add( new WritePermission() );
- } else if (mode == Mode.DOWNLOADING) {
- // the downloading satellite may access the whole dir, but this is restricted in MasterFtplet
- dir = Globals.getPropertyString( Globals.PropString.IMAGEDIR );
- // downloading satellite is only allowed to read
- file = fileName;
- }
-
- user.setHomeDirectory( dir );
- user.setAuthorities( authorities );
-
- try {
- userManager.save( user );
- ftpCredentials = new FtpCredentials( generatedUser, generatedPass, fileName );
- synchronized ( users ) {
- users.put( ftpCredentials.username, new Infos( System.currentTimeMillis(), mode, file, serverSessionId) );
- DbFtpUser.addUser( new DbFtpUser( generatedUser, generatedPass, mode.toString(), fileName, serverSessionId, new Timestamp(System.currentTimeMillis()) ) );
- }
- } catch ( FtpException e ) {
- // TODO: handle this
- }
-
- log.info( "Generated user/pass: " + generatedUser + "\t"
- + generatedPass + "\n with home dir: " + dir );
-
- return ftpCredentials;
- }
-
- public boolean removeUser( final String username )
- {
- if ( !users.containsKey( username ) )
- return false;
-
- try {
- // first find active session and close it
- Iterator<FtpIoSession> iter = listener.getActiveSessions().iterator();
- while ( iter.hasNext() ) {
- FtpIoSession session = (FtpIoSession)iter.next();
- if ( session.getUser() == null )
- continue;
- if ( session.getUser().getName() == username ) {
- session.close();
- }
- }
- // afterwards delete user
- userManager.delete( username );
- // remove user from map (cache)
- synchronized ( users ) {
- users.remove( username );
- DbFtpUser.removeUserByName( username );
- }
- // remove his home dir
- try {
- File dir = new File( Globals.getPropertyString( Globals.PropString.FTPBASEDIR ) + "/" + username );
- Util.deleteFolder( dir );
- } catch (Exception e) {
- // don't care because it could be a downloading user
- }
- return true;
- } catch ( FtpException e ) {
- return false;
- }
- }
-
- @Override
- public void run()
- {
- try {
- //if (!ini) throw new Exception("FTP server needs to be initalized.");
- log.info( "Starting FTP Sever" );
- server.start();
- } catch ( FtpException e1 ) {
- e1.printStackTrace();
- }
- }
-
- public void addDbFtpUsers()
- {
- List<DbFtpUser> list = DbFtpUser.getAllUsers();
- Iterator<DbFtpUser> iter = list.iterator();
-
- int n = 0;
-
- while (iter.hasNext()) {
- DbFtpUser user = iter.next();
- Mode mode;
- if ( user.mode.equalsIgnoreCase( "downloading" ) ) {
- mode = Mode.DOWNLOADING;
- } else {
- mode = Mode.UPLOADING;
- }
- // don't readd user if it timeouted
- if ( (System.currentTimeMillis() - user.timestamp.getTime()) < FtpCredentialsScheduler.timeout ) {
- this.addUser( user.sessionId, user.username, user.password, mode, user.filename, false );
- n++;
- } else {
- DbFtpUser.removeUserByName( user.username );
- }
- }
-
- log.info( "Added " + n + " FTP users from DB." );
- }
-}
diff --git a/src/main/java/org/openslx/imagemaster/ftp/MasterFtplet.java b/src/main/java/org/openslx/imagemaster/ftp/MasterFtplet.java
deleted file mode 100644
index c514f5e..0000000
--- a/src/main/java/org/openslx/imagemaster/ftp/MasterFtplet.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package org.openslx.imagemaster.ftp;
-
-import java.io.IOException;
-
-import org.apache.ftpserver.ftplet.FtpException;
-import org.apache.ftpserver.ftplet.FtpReply;
-import org.apache.ftpserver.ftplet.FtpRequest;
-import org.apache.ftpserver.ftplet.FtpSession;
-import org.apache.ftpserver.ftplet.Ftplet;
-import org.apache.ftpserver.ftplet.FtpletContext;
-import org.apache.ftpserver.ftplet.FtpletResult;
-import org.apache.log4j.Logger;
-import org.openslx.imagemaster.App;
-import org.openslx.imagemaster.serversession.ServerSessionManager;
-
-public class MasterFtplet implements Ftplet
-{
- private static Logger log = Logger.getLogger( MasterFtplet.class );
-
- @Override
- public void init( FtpletContext ftpletContext ) throws FtpException
- {
- // not used
- }
-
- @Override
- public void destroy()
- {
- // not used
- }
-
- @Override
- public FtpletResult beforeCommand( FtpSession session, FtpRequest request )
- throws FtpException, IOException
- {
- if ( session.getUser() != null ) {
- // check if masterserver is still knowing this user
- if (App.ftpServer.users.containsKey( session.getUser().getName() )) {
- MasterFtpServer.Infos infos = App.ftpServer.users.get( session.getUser().getName() );
- if (infos.getMode() == MasterFtpServer.Mode.DOWNLOADING) { // filter the downloading clients
- if (request.getCommand().equals("RETR")) {
- // check if user is getting the right file
- if (!infos.getFileName().equals(request.getArgument())) {
- // the client tries to retrieve a file, that he is not allowed to get
- String organization = ServerSessionManager.getSession( App.ftpServer.users.get( session.getUser().getName() ).getServerSessionId() ).getOrganization();
- log.info( "A user from organization '" + organization + "' tried to download a file (" + request.getArgument() + "), that he was not allowed to." );
- throw new FtpException( "550 File unavailable." ); // after the exception, the client will be automatically be disconnected
- }
- } else if ( request.getCommand().equals( "MLSD" ) // list dirs
- || request.getCommand().equals( "NSLT" ) // list files
- || request.getCommand().equals( "CWD" ) // change working dir
- ) {
-
- // TODO: block all other commands except login and retrieve
- return FtpletResult.DISCONNECT; // disconnect the client on wrong command
- }
- }
- } else {
- // user is not valid anymore
- throw new FtpException( "430 Invalid username or password." ); // ERROR CODE 430 --> invalid username or password
- // after the exception, the client will be automatically be disconnected
- }
-
- }
-
- return FtpletResult.DEFAULT;
- }
-
- @Override
- public FtpletResult afterCommand( FtpSession session, FtpRequest request,
- FtpReply reply ) throws FtpException, IOException
- {
- // not used
- return FtpletResult.DEFAULT;
- }
-
- @Override
- public FtpletResult onConnect( FtpSession session ) throws FtpException,
- IOException
- {
- if (session.getUser() != null) {
- log.info( session.getUser().getName() + " connected" );
- }
- return FtpletResult.DEFAULT;
- }
-
- @Override
- public FtpletResult onDisconnect( FtpSession session ) throws FtpException,
- IOException
- {
- if (session.getUser() != null) {
- log.info( session.getUser().getName() + " disconnected" );
- }
- return FtpletResult.DEFAULT;
- }
-
-}
diff --git a/src/main/java/org/openslx/imagemaster/server/ApiServer.java b/src/main/java/org/openslx/imagemaster/server/ApiServer.java
index 52783d9..9c3dfb4 100644
--- a/src/main/java/org/openslx/imagemaster/server/ApiServer.java
+++ b/src/main/java/org/openslx/imagemaster/server/ApiServer.java
@@ -1,16 +1,12 @@
package org.openslx.imagemaster.server;
-import java.io.File;
import java.nio.ByteBuffer;
import org.apache.log4j.Logger;
import org.apache.thrift.TException;
-import org.openslx.imagemaster.App;
-import org.openslx.imagemaster.Globals;
import org.openslx.imagemaster.db.DbImage;
import org.openslx.imagemaster.db.DbSatellite;
-import org.openslx.imagemaster.ftp.ImageProcessor;
-import org.openslx.imagemaster.ftp.MasterFtpServer;
+import org.openslx.imagemaster.serverconnection.ImageProcessor;
import org.openslx.imagemaster.serversession.ServerAuthenticator;
import org.openslx.imagemaster.serversession.ServerSession;
import org.openslx.imagemaster.serversession.ServerSessionManager;
@@ -23,7 +19,7 @@ import org.openslx.imagemaster.thrift.iface.AuthenticationError;
import org.openslx.imagemaster.thrift.iface.AuthenticationException;
import org.openslx.imagemaster.thrift.iface.AuthorizationError;
import org.openslx.imagemaster.thrift.iface.AuthorizationException;
-import org.openslx.imagemaster.thrift.iface.FtpCredentials;
+import org.openslx.imagemaster.thrift.iface.DownloadInfos;
import org.openslx.imagemaster.thrift.iface.ImageData;
import org.openslx.imagemaster.thrift.iface.ImageDataError;
import org.openslx.imagemaster.thrift.iface.ImageDataException;
@@ -32,7 +28,10 @@ import org.openslx.imagemaster.thrift.iface.ServerAuthenticationError;
import org.openslx.imagemaster.thrift.iface.ServerAuthenticationException;
import org.openslx.imagemaster.thrift.iface.ServerSessionData;
import org.openslx.imagemaster.thrift.iface.SessionData;
+import org.openslx.imagemaster.thrift.iface.UploadException;
+import org.openslx.imagemaster.thrift.iface.UploadInfos;
import org.openslx.imagemaster.thrift.iface.UserInfo;
+import org.openslx.imagemaster.util.RandomString;
/**
* API Server This is where all the requests from the outside arrive. We don't
@@ -88,40 +87,74 @@ public class ApiServer
session.getLastName(), session.getEMail() );
}
- /**
- * Request ftp credentials to upload a new image to the masterserver.
- *
- * @param imageDescription MetaData of the new image
- * @param serverSessionData the session data of the authenticated uni/hs server
- * @return the genereated ftp credentials
- * @throws AuthorizationException if the uni/hs server has no valid session
- * @throws TException
- */
- public static FtpCredentials submitImage( String serverSessionId,
- ImageData imageDescription ) throws AuthorizationException, ImageDataException
+// /**
+// * Request ftp credentials to upload a new image to the masterserver.
+// *
+// * @param imageDescription MetaData of the new image
+// * @param serverSessionData the session data of the authenticated uni/hs server
+// * @return the genereated ftp credentials
+// * @throws AuthorizationException if the uni/hs server has no valid session
+// * @throws TException
+// */
+// public static FtpCredentials submitImage( String serverSessionId,
+// ImageData imageDescription ) throws AuthorizationException, ImageDataException
+// {
+// if ( ServerSessionManager.getSession( serverSessionId ) == null ) {
+// throw new AuthorizationException( AuthorizationError.NOT_AUTHENTICATED, "No valid serverSessionData" );
+// }
+//
+// // create new user
+// FtpCredentials ftpCredentials = App.ftpServer.addUser( serverSessionId , MasterFtpServer.Mode.UPLOADING, "");
+//
+// if ( ftpCredentials == null ) {
+// log.error( "Could not create ftp credentials" );
+// return null;
+// }
+//
+// try {
+// ImageProcessor.addImageDataToProcess( imageDescription, ftpCredentials.username, ftpCredentials.password );
+// } catch (ImageDataException e) {
+// App.ftpServer.removeUser( serverSessionId );
+// throw new ImageDataException( ImageDataError.INVALID_DATA, e.getMessage() );
+// }
+//
+// return ftpCredentials;
+// }
+
+ public static UploadInfos submitImage( String serverSessionId, ImageData imageDescription ) throws AuthorizationException, ImageDataException, UploadException
{
+ // first check session of server
if ( ServerSessionManager.getSession( serverSessionId ) == null ) {
- throw new AuthorizationException( AuthorizationError.NOT_AUTHENTICATED, "No valid serverSessionData" );
- }
-
- // create new user
- FtpCredentials ftpCredentials = App.ftpServer.addUser( serverSessionId , MasterFtpServer.Mode.UPLOADING, "");
-
- if ( ftpCredentials == null ) {
- log.error( "Could not create ftp credentials" );
- return null;
- }
-
- try {
- ImageProcessor.addImageDataToProcess( imageDescription, ftpCredentials.username, ftpCredentials.password );
- } catch (ImageDataException e) {
- App.ftpServer.removeUser( serverSessionId );
- throw new ImageDataException( ImageDataError.INVALID_DATA, e.getMessage() );
+ throw new AuthorizationException( AuthorizationError.NOT_AUTHENTICATED, "No valid serverSessioId" );
+ }
+ // then let the image processor decide what to do
+ return ImageProcessor.getUploadInfos(serverSessionId, imageDescription);
+ }
+
+ public static DownloadInfos getImage( String uuid, String serverSessionId ) throws AuthorizationException, ImageDataException
+ {
+ /*
+ * TODO: done
+ * Check if server has active session
+ * Check if UUID exists
+ * Create token for downloading
+ */
+
+ // first check session of server
+ if ( ServerSessionManager.getSession( serverSessionId ) == null ) {
+ throw new AuthorizationException( AuthorizationError.NOT_AUTHENTICATED, "No valid serverSessionId" );
+ }
+
+ if (!DbImage.exists( uuid )) {
+ throw new ImageDataException( ImageDataError.UNKNOWN_IMAGE, "UUID is not known by this server." );
}
-
- return ftpCredentials;
+
+ String path = DbImage.getImageByUUID( uuid ).imagePath;
+
+ // TODO: get token form downloader class
+ return new DownloadInfos( RandomString.generate( 100, false ) );
}
-
+
/**
* Start the server authentication of a uni/hs satellite server.
*
@@ -169,78 +202,78 @@ public class ApiServer
return ServerSessionManager.addSession( session );
}
- /**
- * Tell the masterserver that the image upload finished.
- *
- * @param ftpUser the user that was used to upload
- * @param imageDescription the description of the uploaded image
- * @return if nothing went wrong
- * @throws ImageDataException if image was not submitted before
- * @throws AuthorizationException if no valid session exists
- */
- public static boolean finishedUpload( String ftpUser, ImageData imageDescription ) throws ImageDataException
- {
- // check if user is valid
- synchronized ( App.ftpServer.users ) {
- if (!App.ftpServer.users.containsKey( ftpUser )) {
- throw new ImageDataException( ImageDataError.UNKNOWN_IMAGE, "Image with this data was not submitted before." );
- } else {
- if ( App.ftpServer.users.get( ftpUser ).getMode() == MasterFtpServer.Mode.DOWNLOADING ) {
- throw new ImageDataException( ImageDataError.UNKNOWN_IMAGE, "Your were downloading and not uploading." );
- }
- }
- }
-
- // process the image
- File userDirectory = new File( Globals.getPropertyString( Globals.PropString.FTPBASEDIR ) + "/" + ftpUser );
- File[] list = userDirectory.listFiles();
-
- if ( list == null || list.length != 1 ) {
- // user uploaded too many files
- return false;
- }
-
- log.info( ftpUser + " is done with upload" );
-
- ImageProcessor.processImageAfterUpload( ftpUser, list[0].getName() );
-
- // remove user that is not needed anymore
- App.ftpServer.removeUser( ftpUser );
- log.info( "Removed user: " + ftpUser );
+// /**
+// * Tell the masterserver that the image upload finished.
+// *
+// * @param ftpUser the user that was used to upload
+// * @param imageDescription the description of the uploaded image
+// * @return if nothing went wrong
+// * @throws ImageDataException if image was not submitted before
+// * @throws AuthorizationException if no valid session exists
+// */
+// public static boolean finishedUpload( String ftpUser, ImageData imageDescription ) throws ImageDataException
+// {
+// // check if user is valid
+// synchronized ( App.ftpServer.users ) {
+// if (!App.ftpServer.users.containsKey( ftpUser )) {
+// throw new ImageDataException( ImageDataError.UNKNOWN_IMAGE, "Image with this data was not submitted before." );
+// } else {
+// if ( App.ftpServer.users.get( ftpUser ).getMode() == MasterFtpServer.Mode.DOWNLOADING ) {
+// throw new ImageDataException( ImageDataError.UNKNOWN_IMAGE, "Your were downloading and not uploading." );
+// }
+// }
+// }
+//
+// // process the image
+// File userDirectory = new File( Globals.getPropertyString( Globals.PropString.FTPBASEDIR ) + "/" + ftpUser );
+// File[] list = userDirectory.listFiles();
+//
+// if ( list == null || list.length != 1 ) {
+// // user uploaded too many files
+// return false;
+// }
+//
+// log.info( ftpUser + " is done with upload" );
+//
+// ImageProcessor.processImageAfterUpload( ftpUser, list[0].getName() );
+//
+// // remove user that is not needed anymore
+// App.ftpServer.removeUser( ftpUser );
+// log.info( "Removed user: " + ftpUser );
+//
+// return true;
+// }
- return true;
- }
-
- public static FtpCredentials getImage( String uuid, String serverSessionId ) throws AuthorizationException, ImageDataException
- {
- if ( ServerSessionManager.getSession( serverSessionId ) == null ) {
- throw new AuthorizationException( AuthorizationError.NOT_AUTHENTICATED, "No valid serverSessionData" );
- }
-
- // check if image exists
- DbImage image = DbImage.getImageByUUID( uuid );
-
- if (image == null) throw new ImageDataException( ImageDataError.UNKNOWN_IMAGE, "No image found with uuid '" + uuid + "'");
-
- FtpCredentials ftpCredentials = App.ftpServer.addUser( serverSessionId, MasterFtpServer.Mode.DOWNLOADING, new File(image.imagePath).getName() );
-
- // TODO: what is happening here?
- if (ftpCredentials == null) return null;
-
- return ftpCredentials;
- }
+// public static FtpCredentials getImage( String uuid, String serverSessionId ) throws AuthorizationException, ImageDataException
+// {
+// if ( ServerSessionManager.getSession( serverSessionId ) == null ) {
+// throw new AuthorizationException( AuthorizationError.NOT_AUTHENTICATED, "No valid serverSessionData" );
+// }
+//
+// // check if image exists
+// DbImage image = DbImage.getImageByUUID( uuid );
+//
+// if (image == null) throw new ImageDataException( ImageDataError.UNKNOWN_IMAGE, "No image found with uuid '" + uuid + "'");
+//
+// FtpCredentials ftpCredentials = App.ftpServer.addUser( serverSessionId, MasterFtpServer.Mode.DOWNLOADING, new File(image.imagePath).getName() );
+//
+// // TODO: what is happening here?
+// if (ftpCredentials == null) return null;
+//
+// return ftpCredentials;
+// }
- public static boolean finishedDownload( String ftpUser )
- {
- if ( !App.ftpServer.users.containsKey( ftpUser ))
- return false;
-
- log.info( "User: '" + ftpUser + "' finished download and gets deleted." );
-
- // download is done, user can be removed now
- App.ftpServer.removeUser( ftpUser );
-
- return true;
- }
+// public static boolean finishedDownload( String ftpUser )
+// {
+// if ( !App.ftpServer.users.containsKey( ftpUser ))
+// return false;
+//
+// log.info( "User: '" + ftpUser + "' finished download and gets deleted." );
+//
+// // download is done, user can be removed now
+// App.ftpServer.removeUser( ftpUser );
+//
+// return true;
+// }
}
diff --git a/src/main/java/org/openslx/imagemaster/serverconnection/ImageInfos.java b/src/main/java/org/openslx/imagemaster/serverconnection/ImageInfos.java
new file mode 100644
index 0000000..1e84978
--- /dev/null
+++ b/src/main/java/org/openslx/imagemaster/serverconnection/ImageInfos.java
@@ -0,0 +1,73 @@
+package org.openslx.imagemaster.serverconnection;
+
+import java.sql.Timestamp;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Helper class for ImageProcessor to save some infos about the images in the process list.
+ */
+public class ImageInfos
+{
+ /**
+ * Token for the satellite.
+ */
+ private String token;
+ /**
+ * The missing blocks that need to be uploaded by the satellite.
+ */
+ private List<Integer> missingBlocks;
+ /**
+ * The list of blocks that the satellite received last.
+ * (This could be used to tell the CRCChecker to check these blocks.
+ */
+ private List<Integer> lastSentBlocks = new LinkedList<>();
+ private String serverSessionId;
+ private Timestamp ts; // when did the server something for the last time
+
+ protected ImageInfos(String token, List<Integer> missingBlocks, String serverSessionId, Timestamp ts)
+ {
+ this.token = token;
+ this.missingBlocks = missingBlocks;
+ this.serverSessionId = serverSessionId;
+ this.ts = ts;
+ }
+
+ protected void removeBlock( int number )
+ {
+ this.missingBlocks.remove( number );
+ }
+
+ protected void removeBlocks( Collection<Integer> list )
+ {
+ this.missingBlocks.removeAll( list );
+ }
+
+ protected void setLastSentBlocks(List<Integer> list) {
+ this.lastSentBlocks = list;
+ }
+
+ protected List<Integer> getLastSentBlocks() {
+ return this.lastSentBlocks;
+ }
+
+ protected String getToken()
+ {
+ return this.token;
+ }
+
+ protected List<Integer> getMissingBlocks()
+ {
+ return this.missingBlocks;
+ }
+
+ protected String getServerSessionId()
+ {
+ return this.serverSessionId;
+ }
+
+ protected Timestamp getTimestamp() {
+ return this.ts;
+ }
+}
diff --git a/src/main/java/org/openslx/imagemaster/serverconnection/ImageProcessor.java b/src/main/java/org/openslx/imagemaster/serverconnection/ImageProcessor.java
new file mode 100644
index 0000000..d4ae717
--- /dev/null
+++ b/src/main/java/org/openslx/imagemaster/serverconnection/ImageProcessor.java
@@ -0,0 +1,123 @@
+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.");
+ }
+}
diff --git a/src/main/java/org/openslx/imagemaster/serversession/ServerSession.java b/src/main/java/org/openslx/imagemaster/serversession/ServerSession.java
index 355fc0b..d5e86f2 100644
--- a/src/main/java/org/openslx/imagemaster/serversession/ServerSession.java
+++ b/src/main/java/org/openslx/imagemaster/serversession/ServerSession.java
@@ -1,7 +1,6 @@
package org.openslx.imagemaster.serversession;
import org.openslx.imagemaster.Globals;
-import org.openslx.imagemaster.Globals.PropInt;
/**
* Holds the session id of the server and manages the timeout.
@@ -9,7 +8,7 @@ import org.openslx.imagemaster.Globals.PropInt;
*/
public class ServerSession
{
- private static final long TIMEOUT = Long.valueOf( Globals.getPropertyInt( PropInt.SESSIONTIMEOUTSERVER ) ) * 1000L;
+ private static final long TIMEOUT = Long.valueOf( Globals.getSessionTimeoutServer() ) * 1000L;
private long timeOut = 0;
private final ServerUser serverUser;
diff --git a/src/main/java/org/openslx/imagemaster/session/Session.java b/src/main/java/org/openslx/imagemaster/session/Session.java
index 39861a1..727045a 100644
--- a/src/main/java/org/openslx/imagemaster/session/Session.java
+++ b/src/main/java/org/openslx/imagemaster/session/Session.java
@@ -1,7 +1,6 @@
package org.openslx.imagemaster.session;
import org.openslx.imagemaster.Globals;
-import org.openslx.imagemaster.Globals.PropInt;
/**
* Simple representation of a user session. Contains user-related data and
@@ -10,7 +9,7 @@ import org.openslx.imagemaster.Globals.PropInt;
*/
public class Session
{
- private static final long TIMEOUT = Long.valueOf( Globals.getPropertyInt( PropInt.SESSIONTIMEOUTUSER ) ) * 1000L;
+ private static final long TIMEOUT = Long.valueOf( Globals.getSessionTimeoutUser() ) * 1000L;
private long timeOut = 0;
private final User user;
diff --git a/src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java b/src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java
index b32589c..458788d 100644
--- a/src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java
+++ b/src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java
@@ -7,6 +7,7 @@ import org.apache.thrift.TException;
import org.openslx.imagemaster.server.ApiServer;
import org.openslx.imagemaster.thrift.iface.AuthenticationException;
import org.openslx.imagemaster.thrift.iface.AuthorizationException;
+import org.openslx.imagemaster.thrift.iface.DownloadInfos;
import org.openslx.imagemaster.thrift.iface.FtpCredentials;
import org.openslx.imagemaster.thrift.iface.ImageData;
import org.openslx.imagemaster.thrift.iface.ImageDataException;
@@ -15,6 +16,8 @@ import org.openslx.imagemaster.thrift.iface.InvalidTokenException;
import org.openslx.imagemaster.thrift.iface.ServerAuthenticationException;
import org.openslx.imagemaster.thrift.iface.ServerSessionData;
import org.openslx.imagemaster.thrift.iface.SessionData;
+import org.openslx.imagemaster.thrift.iface.UploadException;
+import org.openslx.imagemaster.thrift.iface.UploadInfos;
import org.openslx.imagemaster.thrift.iface.UserInfo;
public class ImageServerHandler implements ImageServer.Iface
@@ -60,27 +63,16 @@ public class ImageServerHandler implements ImageServer.Iface
}
@Override
- public FtpCredentials submitImage( String serverSessionId, ImageData imageDescription ) throws AuthorizationException, ImageDataException
+ public UploadInfos submitImage( String serverSessionId, ImageData imageDescription ) throws AuthorizationException, ImageDataException, UploadException, TException
{
return ApiServer.submitImage( serverSessionId, imageDescription );
}
@Override
- public boolean finishedUpload( String ftpUser, ImageData imageDescription ) throws ImageDataException
+ public DownloadInfos getImage( String uuid, String serverSessionId ) throws AuthorizationException, ImageDataException, TException
{
- return ApiServer.finishedUpload( ftpUser, imageDescription );
- }
-
- @Override
- public FtpCredentials getImage( String uuid, String serverSessionId ) throws AuthorizationException, ImageDataException
- {
- return ApiServer.getImage( uuid, serverSessionId );
- }
-
- @Override
- public boolean finishedDownload( String ftpUser ) throws TException
- {
- return ApiServer.finishedDownload( ftpUser );
+ // TODO Auto-generated method stub
+ return null;
}
}
diff --git a/src/main/thrift/imagemaster.thrift b/src/main/thrift/imagemaster.thrift
deleted file mode 100644
index 7986d4c..0000000
--- a/src/main/thrift/imagemaster.thrift
+++ /dev/null
@@ -1,119 +0,0 @@
-/**
- * Define some namespace/package name for our stuff
- */
-
-namespace java org.openslx.imagemaster.thrift.iface
-namespace php testing
-
-typedef string ID
-typedef string Token
-typedef string UUID
-typedef i64 Date
-
-enum AuthorizationError {
- GENERIC_ERROR,
- NOT_AUTHENTICATED,
- NO_PERMISSION
-}
-
-enum AuthenticationError {
- GENERIC_ERROR,
- INVALID_CREDENTIALS,
- ACCOUNT_SUSPENDED,
- BANNED_NETWORK
-}
-
-enum ServerAuthenticationError {
- GENERIC_ERROR,
- INVALID_ORGANIZATION,
- BANNED_NETWORK
-}
-
-enum ImageDataError {
- INVALID_DATA,
- UNKNOWN_IMAGE
-}
-
-exception AuthorizationException {
- 1: AuthorizationError number,
- 2: string message
-}
-
-exception AuthenticationException {
- 1: AuthenticationError number,
- 2: string message
-}
-
-exception InvalidTokenException {
-}
-
-exception ServerAuthenticationException {
- 1: ServerAuthenticationError number,
- 2: string message
-}
-
-exception ImageDataException {
- 1: ImageDataError number,
- 2: string message
-}
-
-struct UserInfo {
- 1: string userId,
- 2: string firstName,
- 3: string lastName,
- 4: string eMail
-}
-
-struct SessionData {
- 1: ID sessionId,
- 2: Token authToken,
- 3: string serverAddress
-}
-
-struct FtpCredentials {
- 1: string username,
- 2: string password,
- 3: string filename
-}
-
-struct ServerSessionData {
- 1: ID sessionId
-}
-
-struct ImageData {
- 1: UUID uuid,
- 2: i32 imageVersion,
- 3: string imageName,
- 4: Date imageCreateTime,
- 5: Date imageUpdateTime,
- 6: string imageOwner,
- 7: string conentOperatingSystem,
- 8: bool statusIsValid,
- 9: bool statusIsDeleted,
- 10: string imageShortDescription,
- 11: string imageLongDescription,
- 12: i64 fileSize
-}
-
-service ImageServer {
-
- bool ping(),
-
- SessionData authenticate(1:string username, 2:string password) throws (1:AuthenticationException failure),
-
- UserInfo getUserFromToken(1:Token token) throws (1:InvalidTokenException failure),
-
- string startServerAuthentication(1:string organization) throws (1: ServerAuthenticationException failure),
-
- ServerSessionData serverAuthenticate(1:string organization, 2:binary challengeResponse) throws (1:ServerAuthenticationException failure),
-
- FtpCredentials submitImage(1:string serverSessionId, 2:ImageData imageDescription) throws (1:AuthorizationException failure, 2: ImageDataException failure2),
-
- bool finishedUpload(1:string ftpUser, 2:ImageData imageDescription) throws (1: ImageDataException failure),
-
- FtpCredentials getImage(1:UUID uuid, 2:string serverSessionId) throws (1:AuthorizationException failure, 2: ImageDataException failure2),
-
- bool finishedDownload(1:string ftpUser)
-
-}
-
diff --git a/src/test/java/org/openslx/imagemaster/AppTest.java b/src/test/java/org/openslx/imagemaster/AppTest.java
index 00be484..7904efc 100644
--- a/src/test/java/org/openslx/imagemaster/AppTest.java
+++ b/src/test/java/org/openslx/imagemaster/AppTest.java
@@ -1,19 +1,14 @@
package org.openslx.imagemaster;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.security.InvalidKeyException;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SignatureException;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
+import java.util.UUID;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
-import org.openslx.imagemaster.util.AsymMessageVerifier;
+import org.openslx.imagemaster.serverconnection.ImageProcessor;
+import org.openslx.imagemaster.thrift.iface.ImageData;
+import org.openslx.imagemaster.thrift.iface.UploadInfos;
import org.openslx.imagemaster.util.Sha512Crypt;
/**
@@ -52,4 +47,26 @@ public class AppTest extends TestCase
{
Sha512Crypt.selfTest();
}
+
+ public void testImageProcessor() {
+ ImageData imageData = new ImageData(UUID.randomUUID().toString(), 1, "windows7.vmdk",
+ System.currentTimeMillis(), System.currentTimeMillis(), "ns202@uni-freiburg.de", "win7",
+ true, false, "Windows 7", "Das ist ein tolles Windows 7", 40*16*1024*1024L); // exactly 40 blocks
+
+ UploadInfos uploadInfos = ImageProcessor.getUploadInfos( "asdfasdfasdf", imageData );
+ assertEquals( "Not the right number of blocks", 20, uploadInfos.missingBlocks.size() );
+ for (int i = 0; i < uploadInfos.missingBlocks.size(); i++) {
+ assertEquals(i, uploadInfos.missingBlocks.remove( 0 ).intValue());
+ }
+
+ String token = uploadInfos.getToken();
+
+ uploadInfos = ImageProcessor.getUploadInfos( "asdfasdfasdf", imageData );
+ assertEquals( "Not the right number of blocks", 20, uploadInfos.missingBlocks.size() );
+ for (int i = 0; i < uploadInfos.missingBlocks.size(); i++) {
+ assertEquals(i, uploadInfos.missingBlocks.remove( 0 ).intValue());
+ }
+
+ assertEquals("Wrong token was sent back.", token, uploadInfos.getToken());
+ }
}
diff --git a/src/test/java/org/openslx/imagemaster/ServerTest.java b/src/test/java/org/openslx/imagemaster/ServerTest.java
deleted file mode 100644
index 946b33f..0000000
--- a/src/test/java/org/openslx/imagemaster/ServerTest.java
+++ /dev/null
@@ -1,223 +0,0 @@
-package org.openslx.imagemaster;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.ConnectException;
-import java.net.SocketException;
-import java.nio.ByteBuffer;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SignatureException;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
-import java.util.UUID;
-
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-
-import junit.framework.TestCase;
-
-import org.apache.commons.net.ftp.FTP;
-import org.apache.commons.net.ftp.FTPReply;
-import org.apache.commons.net.ftp.FTPSClient;
-import org.apache.log4j.Logger;
-import org.apache.thrift.TException;
-import org.apache.thrift.protocol.TBinaryProtocol;
-import org.apache.thrift.protocol.TProtocol;
-import org.apache.thrift.transport.TSocket;
-import org.apache.thrift.transport.TTransport;
-import org.openslx.imagemaster.thrift.iface.FtpCredentials;
-import org.openslx.imagemaster.thrift.iface.ImageData;
-import org.openslx.imagemaster.thrift.iface.ImageServer.Client;
-import org.openslx.imagemaster.thrift.iface.ServerSessionData;
-import org.openslx.imagemaster.thrift.iface.SessionData;
-import org.openslx.imagemaster.thrift.iface.UserInfo;
-import org.openslx.imagemaster.util.AsymMessageVerifier;
-
-
-public class ServerTest extends TestCase
-{
- private static Logger log = Logger.getLogger( ServerTest.class );
-
- @Override
- public void setUp() throws Exception {
- // start the server
-// Thread t = new Thread(new Runnable() {
-//
-// @Override
-// public void run()
-// {
-// App.main( null );
-// }
-// }, "App");
-// t.start();
-// Thread.sleep( 2000 );
- }
-
- public void test() {
- assertTrue(true);
- }
-
-// public void testSomething() throws TException {
-// TTransport transport = new TSocket("localhost", 9090);
-// transport.open();
-//
-// TProtocol protocol = new TBinaryProtocol(transport);
-// Client client = new Client(protocol);
-//
-// assertTrue( "Could not ping server", client.ping() );
-//
-// client.getImage( "8fbaf5cb-ebf6-11e3-996b-f5a55bd7273c", "" );
-// }
-
- /**
- * Test the authentication
- *
- * @throws TException
- * @throws IOException
- */
-// public void testAuthentication() throws TException, IOException
-// {
-// TTransport transport = new TSocket( "localhost", 9090 );
-// transport.open();
-//
-// TProtocol protocol = new TBinaryProtocol( transport );
-// Client client = new Client( protocol );
-//
-// assertTrue( "Could not ping server", client.ping() );
-//
-// BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
-// System.out.print("Enter username: ");
-// String username = reader.readLine();
-// System.out.print("Enter password: ");
-// String password = reader.readLine();
-//
-// SessionData sessionData = client.authenticate( username, password );
-// UserInfo userInfo = client.getUserFromToken( sessionData.getAuthToken() );
-// System.out.println( "User info: " + userInfo );
-// System.out.println( "Server address from MySQL: " + sessionData.serverAddress );
-// }
-
- /**
- * Test the server authentication and FTP Upload.
- *
- * @throws TException
- * @throws IOException
- * @throws SocketException
- * @throws KeyStoreException
- * @throws CertificateException
- * @throws NoSuchAlgorithmException
- * @throws UnrecoverableKeyException
- * @throws SignatureException
- * @throws InvalidKeyException
- * @throws InvalidAlgorithmParameterException
- */
-// public void testServerAuthAndFtpUpload() throws TException, SocketException, IOException, UnrecoverableKeyException, NoSuchAlgorithmException, CertificateException, KeyStoreException, InvalidKeyException, SignatureException, InvalidAlgorithmParameterException
-// {
-// if (true) return;
-//
-// @SuppressWarnings( "unused" )
-// TTransport transport = new TSocket( "localhost", 9090 );
-// transport.open();
-//
-// TProtocol protocol = new TBinaryProtocol( transport );
-// Client client = new Client( protocol );
-//
-// assertTrue( "Could not ping server", client.ping() );
-//
-// String stringToEncrypt = client.startServerAuthentication( "Test Organization" );
-// System.out.println( "Authentication started. Got string: " + stringToEncrypt );
-//
-// AsymMessageSign messageSigner = new AsymMessageSign( "ftp", "password", "./config/keystore.jks" );
-// byte[] response = messageSigner.signMessage( stringToEncrypt );
-//
-// System.out.println( "Signed string: " + response );
-// ByteBuffer bBuffer = ByteBuffer.wrap( response );
-//
-// ServerSessionData data = client.serverAuthenticate( "Test Organization", bBuffer );
-// System.out.println( "Authenticated and got sid: '" + data.getSessionId() + "'" );
-//
-// // Create ImageData
-// int version = 1;
-// String imageName = "maschine.vmkd";
-// UUID uuid = UUID.randomUUID();
-// long imageCreateTime = System.currentTimeMillis();
-// long imageUpdateTime = imageCreateTime;
-// String imageOwner = "ns202";
-// String contentOperatingSystem = "win7";
-// boolean statusIsValid = true;
-// boolean statusIsDeleted = false;
-// String imageShortDescrption = "EIN SUPER TOLLES IMAGE!";
-// String imageLongDescription = "Lorem ipsum dolor sit amet.";
-//
-// String fileName = "/home/nils/file_to_upload.bin";
-//
-// ImageData imageData = new ImageData( uuid.toString(), version, imageName,
-// imageCreateTime, imageUpdateTime, imageOwner, contentOperatingSystem,
-// statusIsValid, statusIsDeleted, imageShortDescrption, imageLongDescription, new File(fileName).getTotalSpace() );
-//
-// System.out.println( "Created imageData..." );
-//
-// FtpCredentials ftpCredentials = client.submitImage( data.sessionId, imageData );
-// System.out.println( "Got FTP credentials. User: " + ftpCredentials.username + ", password: " + ftpCredentials.password );
-//
-// FTPSClient FtpClient = new FTPSClient( "SSL", true );
-// System.out.println("Created new ftpsclient...");
-// TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance( KeyManagerFactory.getDefaultAlgorithm() );
-// KeyStore keystore = KeyStore.getInstance( "JKS" );
-// keystore.load( new FileInputStream( new File( "./config/keystore.jks" ) ), "password".toCharArray() );
-// System.out.println("Loaded keystore..");
-// trustManagerFactory.init( keystore );
-// TrustManager trustManager = trustManagerFactory.getTrustManagers()[0];
-// FtpClient.setTrustManager(trustManager);
-//
-// System.out.println("Trying to connect...");
-//
-// String host = "localhost";
-// int port = 2221;
-// String user = ftpCredentials.username;
-// String password = ftpCredentials.password;
-//
-// try {
-// FtpClient.connect( host, port );
-// System.out.println( "Connected to " + host + ":" + port + ". Reply code: " + FtpClient.getReplyCode() );
-// if ( !FTPReply.isPositiveCompletion( FtpClient.getReplyCode() ) ) {
-// throw new ConnectException( "No positive reply code." );
-// }
-// if ( !FtpClient.login( user, password ) ) {
-// throw new ConnectException( "Could not login." );
-// }
-// System.out.println( "Logged in with user: " + user );
-// FtpClient.setFileType( FTP.BINARY_FILE_TYPE );
-// FtpClient.enterLocalPassiveMode();
-// System.out.println( "Entered PASSIVE MODE" );
-// InputStream input = new FileInputStream( fileName );
-// System.out.print( "Starting file upload ... " );
-// FtpClient.storeFile( "xcvb.vmdk", input );
-// System.out.println( "done." );
-// FtpClient.noop();
-// } catch (Exception e) {
-// e.printStackTrace();
-// } finally {
-// if ( FtpClient.isConnected() ) {
-// try {
-// FtpClient.logout();
-// FtpClient.disconnect();
-// boolean result = client.finshedUpload( ftpCredentials.username, imageData );
-// System.out.println("Telling server that upload finished: " + result);
-// } catch ( IOException e ) {
-// e.printStackTrace();
-// }
-// }
-// }
-//
-// }
-}