summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/java/org/openslx/imagemaster/App.java2
-rw-r--r--src/main/java/org/openslx/imagemaster/db/DbImage.java88
-rw-r--r--src/main/java/org/openslx/imagemaster/db/DbUser.java63
-rw-r--r--src/main/java/org/openslx/imagemaster/server/ApiServer.java14
-rw-r--r--src/main/java/org/openslx/imagemaster/serverconnection/Connection.java36
-rw-r--r--src/main/java/org/openslx/imagemaster/serverconnection/ConnectionHandler.java194
-rw-r--r--src/main/java/org/openslx/imagemaster/serverconnection/CrcScheduler.java2
-rw-r--r--src/main/java/org/openslx/imagemaster/serverconnection/DownloadingClient.java71
-rw-r--r--src/main/java/org/openslx/imagemaster/serverconnection/ImageProcessor.java297
-rw-r--r--src/main/java/org/openslx/imagemaster/serverconnection/UploadingImage.java172
-rw-r--r--src/main/java/org/openslx/imagemaster/session/Authenticator.java6
-rw-r--r--src/main/java/org/openslx/imagemaster/session/User.java9
-rw-r--r--src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java8
-rw-r--r--src/main/java/org/openslx/imagemaster/util/Util.java22
-rw-r--r--src/test/java/org/openslx/imagemaster/AppTest.java5
15 files changed, 356 insertions, 633 deletions
diff --git a/src/main/java/org/openslx/imagemaster/App.java b/src/main/java/org/openslx/imagemaster/App.java
index 34b50f8..5a325ba 100644
--- a/src/main/java/org/openslx/imagemaster/App.java
+++ b/src/main/java/org/openslx/imagemaster/App.java
@@ -5,7 +5,6 @@ import java.util.List;
import org.apache.log4j.Logger;
import org.openslx.imagemaster.serverconnection.CrcScheduler;
-import org.openslx.imagemaster.serverconnection.ImageProcessor;
import org.openslx.imagemaster.thrift.server.BinaryListener;
import org.slf4j.LoggerFactory;
@@ -32,7 +31,6 @@ public class App
// Init the properties and load uploading images from database
Globals.init();
- ImageProcessor.init();
// Create binary listener
Thread t;
diff --git a/src/main/java/org/openslx/imagemaster/db/DbImage.java b/src/main/java/org/openslx/imagemaster/db/DbImage.java
index dc2ab34..a7a2adb 100644
--- a/src/main/java/org/openslx/imagemaster/db/DbImage.java
+++ b/src/main/java/org/openslx/imagemaster/db/DbImage.java
@@ -1,8 +1,6 @@
package org.openslx.imagemaster.db;
import java.sql.Timestamp;
-import java.text.SimpleDateFormat;
-import java.util.Date;
import java.util.List;
import org.openslx.imagemaster.Globals;
@@ -20,22 +18,22 @@ public class DbImage
public final String uuid;
public final int imageVersion;
public final String imageName;
+ /**
+ * Relative path of image file (relative to Globals.getImageDir())
+ */
public final String imagePath;
public final Timestamp imageCreateTime;
public final Timestamp imageUpdateTime;
- public final String imageOwner;
+ public final int imageOwnerId;
public final String contentOperatingSystem;
public final boolean isValid;
public final boolean isDeleted;
public final String shortDescription;
public final String longDescription;
- public final Timestamp timestamp;
public final long fileSize;
- public final String token;
public final int[] blockStatus;
- public final String serverSessionId;
- public DbImage(String uuid)
+ public DbImage( String uuid )
{
this.uuid = uuid;
this.imageVersion = 0;
@@ -43,23 +41,20 @@ public class DbImage
this.imagePath = null;
this.imageCreateTime = null;
this.imageUpdateTime = null;
- this.imageOwner = null;
+ this.imageOwnerId = 0;
this.contentOperatingSystem = null;
this.isValid = false;
this.isDeleted = false;
this.shortDescription = null;
this.longDescription = null;
- this.timestamp = new Timestamp( 0 );
this.fileSize = 0;
- this.token = null;
this.blockStatus = null;
- this.serverSessionId = null;
}
- public DbImage(String uuid, int imageVersion, String imageName, String imagePath,
- Timestamp imageCreateTime, Timestamp imageUpdateTime, String imageOwner, String contentOperatingSystem,
+ public DbImage( String uuid, int imageVersion, String imageName, String imagePath,
+ Timestamp imageCreateTime, Timestamp imageUpdateTime, int imageOwnerId, String contentOperatingSystem,
boolean isValid, boolean isDeleted, String shortDescription, String longDescription,
- Timestamp timestamp, long fileSize, String token, String missingBlocksList, String serverSessionId)
+ long fileSize, String missingBlocksList )
{
this.uuid = uuid;
this.imageVersion = imageVersion;
@@ -67,26 +62,24 @@ public class DbImage
this.imagePath = imagePath;
this.imageCreateTime = imageCreateTime;
this.imageUpdateTime = imageUpdateTime;
- this.imageOwner = imageOwner;
+ this.imageOwnerId = imageOwnerId;
this.contentOperatingSystem = contentOperatingSystem;
this.isValid = isValid;
this.isDeleted = isDeleted;
this.shortDescription = shortDescription;
this.longDescription = longDescription;
- this.timestamp = timestamp;
this.fileSize = fileSize;
- this.token = token;
String[] parts = missingBlocksList.split( ";" );
blockStatus = new int[ Util.getNumberOfBlocks( fileSize, Globals.blockSize ) ]; // initialize array to ones
- for ( int i : blockStatus ) {
- blockStatus[i] = UploadingImage.valid;
+ for ( int i = 0; i < blockStatus.length; ++i ) {
+ blockStatus[i] = UploadingImage.VALID;
}
- for ( int i = 0; i < parts.length; i++ ) {
- blockStatus[i] = UploadingImage.missing;
+ for ( String block : parts ) { // Now mark missing blocks (if any)
+ int i = Util.tryToParseInt( block, -1 );
+ if ( i >= 0 && i < blockStatus.length )
+ blockStatus[i] = UploadingImage.MISSING;
}
-
- this.serverSessionId = serverSessionId;
}
/**
@@ -104,38 +97,30 @@ 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 amountBlocks The blocks that are missing for this image
- * @param serverSessionId The server that is uploading this image
+ * @param filepath Local storage path of image
* @return Affected rows
*/
- public static int insert( ImageData imageData, long ts, String token, int amountBlocks, String serverSessionId, String filepath )
+ public static int insert( ImageData imageData, String filepath )
{
- 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" );
-
+ int numBlocks = Util.getNumberOfBlocks( imageData.fileSize, Globals.blockSize );
String missingBlocksList = "";
- for ( int i = 0; i < amountBlocks; i++ ) {
+ for ( int i = 0; i < numBlocks; i++ ) {
missingBlocksList = missingBlocksList + String.valueOf( i ) + ";";
}
+ DbUser user = DbUser.forLogin( imageData.imageOwner );
+ int owner = 0;
+ if (user != null)
+ owner = user.userId;
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, fileSize, token, missingBlocks, serverSessionId) 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, fileSize, missingBlocks) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
imageData.uuid, imageData.imageVersion, imageData.imageName, filepath,
- sdf.format( createTime ), sdf.format( updateTime ), imageData.imageOwner,
+ imageData.imageCreateTime, imageData.imageUpdateTime, owner,
imageData.contentOperatingSystem, imageData.statusIsValid,
imageData.statusIsDeleted, imageData.imageShortDescription,
- imageData.imageLongDescription, sdf.format( timestamp ), imageData.fileSize,
- token, missingBlocksList, serverSessionId );
- }
-
- public String getUuid()
- {
- return this.uuid;
+ imageData.imageLongDescription, imageData.fileSize,
+ missingBlocksList );
}
/**
@@ -218,8 +203,23 @@ public class DbImage
*/
public ImageData getImageData()
{
+ String owner = "unknown";
+ DbUser user = DbUser.forLogin( this.imageOwnerId );
+ if (user != null)
+ owner = user.getLogin();
return new ImageData( this.uuid, this.imageVersion, this.imageName, this.imageCreateTime.getTime(),
- this.imageUpdateTime.getTime(), this.imageOwner, this.contentOperatingSystem, this.isValid,
+ this.imageUpdateTime.getTime(), owner, this.contentOperatingSystem, this.isValid,
this.isDeleted, this.shortDescription, this.longDescription, this.fileSize );
}
+
+ /**
+ * Get absolute path of this image
+ *
+ * @return absolute path
+ */
+ public String getAbsolutePath()
+ {
+ return Globals.getImageDir() + "/" + this.imagePath;
+ }
+
}
diff --git a/src/main/java/org/openslx/imagemaster/db/DbUser.java b/src/main/java/org/openslx/imagemaster/db/DbUser.java
index 91e0615..c486da3 100644
--- a/src/main/java/org/openslx/imagemaster/db/DbUser.java
+++ b/src/main/java/org/openslx/imagemaster/db/DbUser.java
@@ -2,6 +2,7 @@ package org.openslx.imagemaster.db;
import org.apache.log4j.Logger;
import org.openslx.imagemaster.session.User;
+import org.openslx.imagemaster.util.Sha512Crypt;
/**
* Represents a user that can login against the masterserver.
@@ -11,9 +12,9 @@ public class DbUser extends User
private static Logger log = Logger.getLogger( DbUser.class );
- public DbUser(int userId, String username, String password, String organization,
+ public DbUser( int userId, String username, String password, String organization,
String firstName, String lastName, String eMail,
- String satelliteAddress)
+ String satelliteAddress )
{
super( userId, username, password, organization, firstName, lastName, eMail,
satelliteAddress );
@@ -41,6 +42,37 @@ public class DbUser extends User
parts[0], parts[1] );
}
+ /**
+ * Query database for user with given userId
+ *
+ * @param userid
+ * @return instance of DbUser for matching entry from DB, or null if not
+ * found
+ */
+ public static DbUser forLogin( final int userid )
+ {
+ return MySQL
+ .findUniqueOrNull(
+ DbUser.class,
+ "SELECT user.userid, user.username, user.password, user.organization, user.firstname, user.lastname, user.email, satellite.address FROM user"
+ + " LEFT JOIN satellite USING (organization)"
+ + " WHERE user.userid = ? LIMIT 1",
+ userid );
+ }
+
+ public static boolean exists( final String login )
+ {
+ return forLogin( login ) != null;
+ }
+
+ public static DbUser forLogin( String login, String password )
+ {
+ DbUser user = forLogin( login );
+ if ( user == null || !Sha512Crypt.verifyPassword( password, user.password ) )
+ return null;
+ return user;
+ }
+
public static boolean insertOrUpdate( User user )
{
log.debug( "Inserted user '" + user.username + "' into db." );
@@ -58,7 +90,8 @@ public class DbUser extends User
"SELECT user.userid, user.username, user.password, user.organization, user.firstname, user.lastname, user.email, satellite.address FROM user"
+ " LEFT JOIN satellite USING (organization)"
+ " WHERE user.username = ? LIMIT 1", username );
- if ( user == null ) return 0;
+ if ( user == null )
+ return 0;
return user.userId;
}
@@ -70,29 +103,9 @@ public class DbUser extends User
"SELECT user.userid, user.username, user.password, user.organization, user.firstname, user.lastname, user.email, satellite.address FROM user"
+ " LEFT JOIN satellite USING (organization)"
+ " WHERE user.userid = ? LIMIT 1", id );
- if (user == null) return "";
+ if ( user == null )
+ return "";
return user.username;
}
- /**
- * Checks if a user with id (userid@organization) exists
- * @param id
- * @return Whether the user exists
- */
- public static boolean exists( String id )
- {
- String[] parts = id.split( "@" );
- String user = parts[0];
- String organization = parts[1];
-
- DbUser dbUser = MySQL.findUniqueOrNull( DbUser.class,
- "SELECT user.userid, user.username, user.password, user.organization, user.firstname, user.lastname, user.email, satellite.address FROM user"
- + " LEFT JOIN satellite USING (organization)"
- + " WHERE user.username = ? AND user.organization = ? LIMIT 1", user, organization);
-
- if ( dbUser == null ) return false;
-
- return true;
- }
-
}
diff --git a/src/main/java/org/openslx/imagemaster/server/ApiServer.java b/src/main/java/org/openslx/imagemaster/server/ApiServer.java
index ee22493..ce20020 100644
--- a/src/main/java/org/openslx/imagemaster/server/ApiServer.java
+++ b/src/main/java/org/openslx/imagemaster/server/ApiServer.java
@@ -19,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.DownloadInfos;
+import org.openslx.imagemaster.thrift.iface.DownloadData;
import org.openslx.imagemaster.thrift.iface.ImageData;
import org.openslx.imagemaster.thrift.iface.ImageDataError;
import org.openslx.imagemaster.thrift.iface.ImageDataException;
@@ -28,8 +28,8 @@ 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.UploadData;
import org.openslx.imagemaster.thrift.iface.UploadException;
-import org.openslx.imagemaster.thrift.iface.UploadInfos;
import org.openslx.imagemaster.thrift.iface.UserInfo;
/**
@@ -85,18 +85,18 @@ public class ApiServer
session.getLastName(), session.getEMail() );
}
- public static UploadInfos submitImage( String serverSessionId, ImageData imageDescription, List<Integer> crcSums )
+ public static UploadData submitImage( String serverSessionId, ImageData imageDescription, List<Integer> crcSums )
throws AuthorizationException, ImageDataException, UploadException
{
// first check session of server
if ( ServerSessionManager.getSession( serverSessionId ) == null ) {
- throw new AuthorizationException( AuthorizationError.NOT_AUTHENTICATED, "No valid serverSessioId" );
+ throw new AuthorizationException( AuthorizationError.NOT_AUTHENTICATED, "No valid serverSessionId" );
}
// then let the image processor decide what to do
- return ImageProcessor.getUploadInfos( serverSessionId, imageDescription, crcSums );
+ return ImageProcessor.getUploadInfos( imageDescription, crcSums );
}
- public static DownloadInfos getImage( String uuid, String serverSessionId ) throws AuthorizationException, ImageDataException
+ public static DownloadData getImage( String uuid, String serverSessionId ) throws AuthorizationException, ImageDataException
{
// first check session of server
if ( ServerSessionManager.getSession( serverSessionId ) == null ) {
@@ -108,7 +108,7 @@ public class ApiServer
}
// then let the image processor decide what to do
- return ImageProcessor.getDownloadInfos( serverSessionId, uuid, null );
+ return ImageProcessor.getDownloadInfos( uuid );
}
/**
diff --git a/src/main/java/org/openslx/imagemaster/serverconnection/Connection.java b/src/main/java/org/openslx/imagemaster/serverconnection/Connection.java
deleted file mode 100644
index bfdb1bb..0000000
--- a/src/main/java/org/openslx/imagemaster/serverconnection/Connection.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.openslx.imagemaster.serverconnection;
-
-/**
- * This represents a connection.
- * (When a satellite is up- or downloading an image from/to masterserver).
- * It is used to help the ConnectionHandler and is storing infos.
- */
-public class Connection
-{
- /**
- * Where the file is stored locally.
- */
- protected final String filepath;
-
- /**
- * Type of this connection.
- * True if uploading, false if downloading
- */
- protected final boolean type;
- public UploadingImage image = null;
- public DownloadingClient client = null;
- public final static boolean UPLOADING = true;
- public final static boolean DOWNLOADING = false;
-
- /**
- * Create a new connection data
- * @param filepath Where the file is stored locally
- * @param type True if uploading, false if downloading
- * @param listenerThread The active listener thread that listens for incoming connections
- */
- protected Connection(String filepath, boolean type)
- {
- this.filepath = filepath;
- this.type = type;
- }
-}
diff --git a/src/main/java/org/openslx/imagemaster/serverconnection/ConnectionHandler.java b/src/main/java/org/openslx/imagemaster/serverconnection/ConnectionHandler.java
index 0fb52f5..e6319c9 100644
--- a/src/main/java/org/openslx/imagemaster/serverconnection/ConnectionHandler.java
+++ b/src/main/java/org/openslx/imagemaster/serverconnection/ConnectionHandler.java
@@ -1,6 +1,5 @@
package org.openslx.imagemaster.serverconnection;
-import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -10,14 +9,18 @@ import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
-import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
+import org.apache.commons.lang.mutable.MutableInt;
import org.apache.log4j.Logger;
import org.openslx.filetransfer.Downloader;
import org.openslx.filetransfer.FileRange;
@@ -26,6 +29,7 @@ import org.openslx.filetransfer.Listener;
import org.openslx.filetransfer.Uploader;
import org.openslx.filetransfer.WantRangeCallback;
import org.openslx.imagemaster.Globals;
+import org.openslx.imagemaster.db.DbImage;
/**
* Class to handle all incoming and outgoing connections.
@@ -37,8 +41,11 @@ public class ConnectionHandler implements IncomingEvent
private static Logger log = Logger.getLogger( ConnectionHandler.class );
private static SSLContext sslContext;
- private static Map<String, Connection> connections = new ConcurrentHashMap<>();
+ private static Map<String, UploadingImage> pendingIncomingUploads = new ConcurrentHashMap<>();
+ private static Map<String, DbImage> pendingIncomingDownloads = new ConcurrentHashMap<>();
private static IncomingEvent eventHandler = new ConnectionHandler();
+ private static ThreadPoolExecutor uploadPool = new ThreadPoolExecutor( 0, 5, 6, TimeUnit.MINUTES, new SynchronousQueue<Runnable>() );
+ private static ThreadPoolExecutor downloadPool = new ThreadPoolExecutor( 0, 5, 6, TimeUnit.MINUTES, new SynchronousQueue<Runnable>() );
private static Listener listener;
@@ -81,153 +88,120 @@ public class ConnectionHandler implements IncomingEvent
}
/**
- * Add a new connection with a unique token.
- * To up- or download the file in file path.
+ * Add a new allowed incoming upload connection
+ * for the given token and image.
*
* @param token The unique token
- * @param filepath The file to up- or download
- * @param type True if upload or false if download
- * @return The created connection
+ * @param image Image being uploaded
*/
- public static Connection addConnection( String token, String filepath, boolean type )
+ public static void addUpload( String token, UploadingImage image )
{
- log.debug( "Added connection (" + ( ( type ) ? "uploading" : "downloading" ) + ") with token: '" + token + "'" );
-
- Connection connection = new Connection( filepath, type );
- synchronized ( connections ) {
- connections.put( token, connection );
- }
- return connection;
- }
-
- public static boolean hasConnection( String token )
- {
- return connections.containsKey( token );
+ pendingIncomingUploads.put( token, image );
+ log.debug( "Added upload" );
}
- public static void removeConnection( String token )
+ /**
+ * Add a new allowed incoming download connection
+ * for the given token and image.
+ *
+ * @param token The unique token
+ * @param image Image being uploaded
+ */
+ public static void addDownload( String token, DbImage image )
{
- synchronized ( connections ) {
- connections.remove( token ); // token is remove, so connections are rejected
- }
+ pendingIncomingDownloads.put( token, image );
+ log.debug( "Added download" );
}
/**
* Server is uploading - client is downloading!
*/
@Override
- public void incomingUploader( Uploader uploader ) throws IOException
+ public void incomingUploader( final Uploader uploader )
{
String token = uploader.getToken();
- log.debug( "Got token :'" + token + "'" );
// check token to identify the client
- if (token == null)
- {
+ if ( token == null ) {
uploader.sendErrorCode( "No token available." );
- uploader.close(null);
+ uploader.close( null );
return;
}
- if ( !connections.containsKey( token ) ) {
+
+ final DbImage image = pendingIncomingDownloads.remove( token );
+ if ( image == null ) {
uploader.sendErrorCode( "Token not accepted." );
- uploader.close(null);
+ uploader.close( null );
return;
}
- // check if he was a downloading client
- if ( connections.get( token ).type == Connection.UPLOADING ) {
- uploader.sendErrorCode( "You can not download, if you are uploading." );
- uploader.close(null);
- return;
+ try {
+ uploadPool.execute( new Runnable() {
+ @Override
+ public void run()
+ {
+ uploader.upload( image.getAbsolutePath() );
+ }
+ } );
+ } catch ( RejectedExecutionException e ) {
+ uploader.sendErrorCode( "Too many concurrent uploads." );
+ uploader.close( null );
}
-
- String fileName = connections.get( token ).filepath;
- uploader.upload(fileName);
}
/**
* Server is downloading - client is uploading!
*/
@Override
- public void incomingDownloader( Downloader downloader ) throws IOException
+ public void incomingDownloader( final Downloader downloader ) throws IOException
{
log.debug( "Client wants to upload" );
String token = downloader.getToken();
- if (token == null)
+ if ( token == null )
{
downloader.sendErrorCode( "No token available." );
- downloader.close(null);
+ downloader.close( null );
return;
}
- // Check token to identify the client.
- if ( !connections.containsKey( token ) ) {
+
+ final UploadingImage image = pendingIncomingUploads.remove( token );
+ if ( image == null ) {
downloader.sendErrorCode( "Token not accepted." );
- downloader.close(null);
+ downloader.close( null );
return;
}
-
- // check if he was a uploading client
- if ( connections.get( token ).type == Connection.DOWNLOADING ) {
- downloader.sendErrorCode( "You can not upload, if you are downloading." );
- downloader.close(null);
- return;
+ final MutableInt lastBlock = new MutableInt( -1 );
+
+ try {
+ downloadPool.execute( new Runnable() {
+ @Override
+ public void run()
+ {
+ downloader.download( image.getAbsolutePath(), new WantRangeCallback() {
+ @Override
+ public FileRange get()
+ {
+ if ( lastBlock.intValue() != -1 ) {
+ image.setNeedsCheck( lastBlock.intValue() );
+ image.increaseTransmittedTimes( lastBlock.intValue() );
+ }
+ // get start of range.
+ int blockNumber = image.getNextMissingBlock();
+ if ( blockNumber == -1 )
+ return null;
+ lastBlock.setValue( blockNumber );
+ log.debug( "Block " + blockNumber + " was transmitted " + image.getTimesTransmitted( blockNumber ) + " time(s)." );
+
+ long startOfRange = image.getNextMissingBlock() * Globals.blockSize;
+ long endOfRange = Math.min( startOfRange + Globals.blockSize, image.getFileSize() );
+ FileRange range = new FileRange( startOfRange, endOfRange );
+ return range;
+ }
+ } );
+ }
+ } );
+ } catch ( RejectedExecutionException e ) {
+ downloader.sendErrorCode( "Too many concurrent downloads." );
+ downloader.close( null );
}
-
- String destinationFileName = connections.get( token ).filepath;
- final UploadingImage image = connections.get( token ).image;
- downloader.download( destinationFileName, new WantRangeCallback() {
-
- @Override
- public FileRange get() {
- // get start of range.
- int blockNumber = image.getNextMissingBlock();
- if (blockNumber == -1)
- return null;
-
- image.setNeedsCheck( blockNumber );
- image.increaseTransmittedTimes( blockNumber );
- log.debug( "Block " + blockNumber + " was transmitted " + image.getTimesTransmitted( blockNumber ) + " time(s)." );
-
- long startOfRange = image.getNextMissingBlock() * Globals.blockSize;
- long endOfRange = Math.min(startOfRange + Globals.blockSize, image.getImageFile().length());
- FileRange range = new FileRange(startOfRange, endOfRange);
- return range;
- }
- });
-// long startOfRange = 0;
-// String token = "";
-// // try to read meta data
-// while ( downloader.readMetaData() ) {
-// // check token to identify the client
-// token = downloader.getToken();
-// if ( !connections.containsKey( token ) ) {
-// downloader.sendErrorCode( "Token not accepted." );
-// downloader.close(null);
-// return;
-// }
-//
-// startOfRange = downloader.getStartOfRange();
-//
-// if ( downloader.getDiffOfRange() <= 0 ) {
-// return;
-// }
-//
-// // check if he was a uploading client
-// if ( connections.get( token ).type == Connection.DOWNLOADING ) {
-// downloader.sendErrorCode( "You can not upload, if you are downloading." );
-// downloader.close(null);
-// return;
-// }
-//
-//
-// int blockNumber = (int) ( startOfRange / Globals.blockSize );
-// UploadingImage image = connections.get( token ).image;
-// image.setNeedsCheck( blockNumber );
-// image.increaseTransmittedTimes( blockNumber );
-// log.debug( "Block " + blockNumber + " was transmitted " + image.getTimesTransmitted( blockNumber ) + " time(s)." );
-//
-// downloader.setOutputFilename( connections.get( token ).filepath );
-// downloader.receiveBinary();
-// }
- downloader.close(null);
}
}
diff --git a/src/main/java/org/openslx/imagemaster/serverconnection/CrcScheduler.java b/src/main/java/org/openslx/imagemaster/serverconnection/CrcScheduler.java
index 1ad921b..ff1374c 100644
--- a/src/main/java/org/openslx/imagemaster/serverconnection/CrcScheduler.java
+++ b/src/main/java/org/openslx/imagemaster/serverconnection/CrcScheduler.java
@@ -29,7 +29,7 @@ public class CrcScheduler extends TimerTask
// iterate over the uploading images that need to be checked
while ( iter.hasNext() ) {
UploadingImage image = iter.next();
- log.debug( "Checking blocks of " + image.getDbImage().imageName );
+ log.debug( "Checking blocks of " + image.getUuid() );
CrcChecker crcChecker = new CrcChecker( image.getImageFile(), image.getCrcFile() );
log.debug( "CRCFile is valid: " + crcChecker.hasValidCrcFile() );
if ( !crcChecker.hasValidCrcFile() ) {
diff --git a/src/main/java/org/openslx/imagemaster/serverconnection/DownloadingClient.java b/src/main/java/org/openslx/imagemaster/serverconnection/DownloadingClient.java
deleted file mode 100644
index 630096f..0000000
--- a/src/main/java/org/openslx/imagemaster/serverconnection/DownloadingClient.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package org.openslx.imagemaster.serverconnection;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Helper class for the ImageProcessor and ConnectionHandler to know some things about the downloading client
- */
-public class DownloadingClient
-{
-
- private final HashMap<String, ImageInfos> downloadingImages = new HashMap<>();
-
- public void addDownload( String uuid, List<Integer> list, String token )
- {
- downloadingImages.put( uuid, new ImageInfos( uuid, list, token ) );
- }
-
- public void removeDownload( String uuid )
- {
- downloadingImages.remove( uuid );
- }
-
- public boolean isDownloading( String uuid )
- {
- return downloadingImages.containsKey( uuid );
- }
-
- public boolean hasDownloads()
- {
- return (downloadingImages.size() > 0);
- }
-
- public List<Integer> getLastRequestedBlocks( String token )
- {
- for (Map.Entry<String, ImageInfos> entry : downloadingImages.entrySet() ) {
- if (entry.getValue().token.equals( token )) return entry.getValue().lastRequestedBlocks;
- }
- return null;
- }
-
- public void requestBlocks( String uuid, List<Integer> list )
- {
- if ( !downloadingImages.containsKey( uuid ) )
- return;
- downloadingImages.get( uuid ).lastRequestedBlocks = list;
- }
-
- public String getToken( String uuid )
- {
- if ( !downloadingImages.containsKey( uuid ) )
- return null;
- return downloadingImages.get( uuid ).token;
- }
-
- class ImageInfos
- {
- public final String uuid;
- public final String token;
- private List<Integer> lastRequestedBlocks;
-
- ImageInfos(String uuid, List<Integer> list, String token)
- {
- this.uuid = uuid;
- this.lastRequestedBlocks = list;
- this.token = token;
- }
- }
-
-}
diff --git a/src/main/java/org/openslx/imagemaster/serverconnection/ImageProcessor.java b/src/main/java/org/openslx/imagemaster/serverconnection/ImageProcessor.java
index d5e253c..739bc62 100644
--- a/src/main/java/org/openslx/imagemaster/serverconnection/ImageProcessor.java
+++ b/src/main/java/org/openslx/imagemaster/serverconnection/ImageProcessor.java
@@ -1,9 +1,7 @@
package org.openslx.imagemaster.serverconnection;
import java.io.File;
-import java.io.IOException;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@@ -15,13 +13,13 @@ import org.openslx.imagemaster.Globals;
import org.openslx.imagemaster.crcchecker.CrcFile;
import org.openslx.imagemaster.db.DbImage;
import org.openslx.imagemaster.db.DbUser;
-import org.openslx.imagemaster.thrift.iface.DownloadInfos;
+import org.openslx.imagemaster.thrift.iface.DownloadData;
import org.openslx.imagemaster.thrift.iface.ImageData;
import org.openslx.imagemaster.thrift.iface.ImageDataError;
import org.openslx.imagemaster.thrift.iface.ImageDataException;
+import org.openslx.imagemaster.thrift.iface.UploadData;
import org.openslx.imagemaster.thrift.iface.UploadError;
import org.openslx.imagemaster.thrift.iface.UploadException;
-import org.openslx.imagemaster.thrift.iface.UploadInfos;
import org.openslx.imagemaster.util.RandomString;
import org.openslx.imagemaster.util.Util;
@@ -35,10 +33,6 @@ public class ImageProcessor
private static final 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: uploadingImageInfos
@@ -48,14 +42,7 @@ public class ImageProcessor
/**
* The UUIDs of the images that need to be checked by the crc checker.
*/
- private static List<String> imagesToCheck = new LinkedList<>();
-
- /**
- * The downloading clients.
- * Key: serverSessionId
- * Value: downloadingClientInfos
- */
- private static HashMap<String, DownloadingClient> downloadingClients = new HashMap<>();
+ private static List<String> imagesToCheck = new ArrayList<>();
/**
* Checks if this image is already uploading and returns a new list with missing blocks if so.
@@ -66,218 +53,81 @@ public class ImageProcessor
* @return
* @throws UploadException If some error occurred during the process
*/
- public static UploadInfos getUploadInfos( String serverSessionId, ImageData imageData, List<Integer> crcSums )
+ public static UploadData getUploadInfos( ImageData imageData, List<Integer> crcSums )
throws UploadException, ImageDataException
{
// check image data
- if ( imageData.imageName == null || imageData.imageName.isEmpty() ) {
+ if ( imageData.imageName == null || imageData.imageName.isEmpty() )
throw new ImageDataException( ImageDataError.INVALID_DATA, "Image name not set." );
- } else if ( imageData.imageOwner == null || imageData.imageOwner.isEmpty() ) {
- throw new ImageDataException( ImageDataError.INVALID_DATA, "Image owner not set." );
- } else if ( imageData.contentOperatingSystem == null || imageData.contentOperatingSystem.isEmpty() ) {
+ if ( imageData.imageOwner == null || !DbUser.exists( imageData.imageOwner ) )
+ throw new ImageDataException( ImageDataError.INVALID_DATA, "Invalid image owner." );
+ if ( imageData.contentOperatingSystem == null || imageData.contentOperatingSystem.isEmpty() )
throw new ImageDataException( ImageDataError.INVALID_DATA, "Content operating system not set." );
- } else if ( imageData.fileSize <= 0 ) {
+ if ( imageData.fileSize <= 0 )
throw new ImageDataException( ImageDataError.INVALID_DATA, "File size is too small." );
- } else if ( !DbUser.exists( imageData.imageOwner ) ) {
- throw new ImageDataException( ImageDataError.INVALID_DATA, "User is not known." );
- }
-
- //TODO: this is not working like this:
- DbImage i = DbImage.getImageByUuid( imageData.uuid );
-// boolean isUpdate = false;
-// if ( i != null ) {
-// // image is already available
-// // is the client updating??
-// if ( imageData.imageVersion <= i.imageVersion ) {
-// throw new ImageDataException( ImageDataError.INVALID_DATA, "This image with the same or a newer version is already available." );
-// } else {
-// // TODO: update db and prepare for new image file
-// isUpdate = true;
-// }
-// }
- log.debug( serverSessionId + " is submitting " + imageData.uuid );
+ log.debug( "Satellite is submitting " + imageData.uuid );
- String uuid = imageData.uuid;
- String token;
- String filepath;
- int nBlocks;
- int[] allBlocks;
+ final String uuid = imageData.uuid;
+ final String filepathRelative;
+ final CrcFile crcFile = new CrcFile( crcSums );
UploadingImage image;
synchronized ( uploadingImages ) {
// check if image is already uploading
- if ( ( image = uploadingImages.get( uuid ) ) != null ) {
- if ( image.getCrcFile() == null ) {
- CrcFile crcFile;
- try {
- // try to write crc file ...
- crcFile = CrcFile.writeCrcFile( crcSums, generateFilepathOfCrcFile( imageData ) );
- } catch ( IOException e ) {
- // ... and keep it in ram if it fails
- crcFile = new CrcFile( crcSums );
- }
- image.setCrcFile( crcFile );
+ if ( ( image = uploadingImages.get( uuid ) ) == null ) {
+ // insert new image
+ if ( crcSums != null && !crcFile.isValid() )
+ throw new UploadException( UploadError.INVALID_CRC, "CRC sums were invalid." );
+ filepathRelative = generateFilepathOfImage( imageData );
+ DbImage.insert( imageData, filepathRelative ); // Make sure it exists in DB
+ try {
+ image = new UploadingImage( uuid );
+ } catch ( Exception e ) {
+ throw new UploadException( UploadError.GENERIC_ERROR, "Internal error" );
}
- List<Integer> missing = getNMissingBlocks( image, AMOUNT );
- if ( missing.isEmpty() && image.allBlocksValid() ) {
- uploadDone( uuid );
- return new UploadInfos( image.getToken(), Globals.getSslSocketPort(), missing, image.allBlocksValid() );
- }
- return new UploadInfos( image.getToken(), Globals.getSslSocketPort(), missing, false );
- }
-
- // insert new image
- if ( !CrcFile.sumsAreValid( crcSums ) )
- throw new UploadException( UploadError.INVALID_CRC, "CRC sums were invalid." );
- filepath = generateFilepathOfImage( imageData );
- token = RandomString.generate( 100, false );
- nBlocks = Util.getNumberOfBlocks( imageData.fileSize, Globals.blockSize );
- allBlocks = new int[ nBlocks ]; // initialize array with all zeros which mean that this block is missing
- image = new UploadingImage( token, allBlocks, System.currentTimeMillis(), uuid, filepath );
- image.setDbImage( i ); // set the dbImage (it doesn't matter if the image is null because the uploadingImage is creating it then
- uploadingImages.put( uuid, image );
- }
-
- CrcFile crcFile;
- try {
- // try to write crc file ...
- crcFile = CrcFile.writeCrcFile( crcSums, generateFilepathOfCrcFile( imageData ) );
- } catch ( IOException e ) {
- // ... and keep it in ram if it fails
- crcFile = new CrcFile( crcSums );
- }
- image.setCrcFile( crcFile );
-
- ConnectionHandler.addConnection( token, filepath, Connection.UPLOADING ).image = image;
-// if ( isUpdate ) {
-// i.updateVersion( i.imageVersion, Util.getNumberOfBlocks( i.fileSize, Globals.blockSize ) );
-// } else {
- DbImage.insert( imageData, System.currentTimeMillis(), token, nBlocks, serverSessionId, filepath );
-// }
- imagesToCheck.add( uuid );
- log.debug( imagesToCheck );
-
- log.debug( image.toString() );
- return new UploadInfos( token, Globals.getSslSocketPort(), getNMissingBlocks( image, AMOUNT ), false );
- }
-
- public static DownloadInfos getDownloadInfos( String serverSessionId, String uuid, List<Integer> requestedBlocks )
- {
- // check if server is already downloading
- if ( downloadingClients.containsKey( serverSessionId ) ) {
- DownloadingClient client = downloadingClients.get( serverSessionId );
-
- // remove download if done
- if ( requestedBlocks.isEmpty() )
- {
- downloadDone( serverSessionId, uuid );
- return new DownloadInfos();
- }
-
- if ( client.isDownloading( uuid ) )
- {
- // client was downloading this image
- // update the requested blocks
- client.requestBlocks( uuid, requestedBlocks );
- return new DownloadInfos( client.getToken( uuid ), Globals.getSslSocketPort() );
+ uploadingImages.put( uuid, image );
}
-
- // server was downloading another image and now gets a new connection for this new download
- String token = RandomString.generate( 100, false );
- String filepath = DbImage.getImageByUuid( uuid ).imagePath;
- ConnectionHandler.addConnection( token, filepath, Connection.DOWNLOADING );
-
- client.addDownload( uuid, requestedBlocks, token );
- downloadingClients.put( serverSessionId, client );
- return new DownloadInfos( token, Globals.getSslSocketPort() );
}
- // insert new client and start listener
- synchronized ( downloadingClients ) {
- String token = RandomString.generate( 100, false );
- String filepath = DbImage.getImageByUuid( uuid ).imagePath;
-
- DownloadingClient client = new DownloadingClient();
- client.addDownload( uuid, requestedBlocks, token );
- downloadingClients.put( serverSessionId, client );
+ final String token = RandomString.generate( 50, false );
- ConnectionHandler.addConnection( token, filepath, Connection.DOWNLOADING ).client = client;
- return new DownloadInfos( token, Globals.getSslSocketPort() );
- }
+ ConnectionHandler.addUpload( token, image );
+ // Set crc file on image - if there is already a crc file assigned, this does nothing
+ image.setCrcFile( crcFile );
+ if ( image.allBlocksValid() )
+ removeFinishedUploads();
+ return new UploadData( token, Globals.getSslSocketPort() );
}
- private static void downloadDone( String serverSessionId, String uuid )
+ public static DownloadData getDownloadInfos( String uuid ) throws ImageDataException
{
- synchronized ( downloadingClients ) {
- DownloadingClient client = downloadingClients.get( serverSessionId );
- client.removeDownload( uuid );
- ConnectionHandler.removeConnection( client.getToken( uuid ) );
- if ( !client.hasDownloads() ) {
- downloadingClients.remove( serverSessionId );
- }
- }
+ DbImage image = DbImage.getImageByUuid( uuid );
+ if ( image == null )
+ throw new ImageDataException( ImageDataError.UNKNOWN_IMAGE, "UUID '" + uuid + "' does not map to a known image." );
+ // server was downloading another image and now gets a new connection for this new download
+ String token = RandomString.generate( 50, false );
+ ConnectionHandler.addDownload( token, image );
+ return new DownloadData( token, Globals.getSslSocketPort(), null ); // TODO: Return crc list
}
/**
- * 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 blocks
- * @throws UploadException If a block was transmitted to many times.
+ * Go though list of active uploading images and remove
+ * those that are finished.
*/
- private static List<Integer> getNMissingBlocks( UploadingImage image, int amount ) throws UploadException
+ public static void removeFinishedUploads()
{
- int missing = image.getAmountOfBlocksNeedingRequest();
- log.debug( "The number of missing blocks: " + missing );
- if ( amount > missing )
- amount = missing;
- List<Integer> result = new ArrayList<>( amount );
-
- int got = 0;
- for ( int i = 0; i < image.getNumberOfBlocks(); i++ ) {
- if ( image.needsRequest( i ) ) {
- int times = image.getTimesTransmitted( i );
- if ( times > Globals.getSslTransmitTimes() ) {
- log.debug( "Block " + i + " is probably broken." );
- throw new UploadException( UploadError.BROKEN_BLOCK, "Block " + i + " was transmitted "
- + times + " and is still not valid." );
- }
- result.add( i );
- got++;
+ for (Iterator<UploadingImage> it = uploadingImages.values().iterator(); it.hasNext(); ) {
+ UploadingImage image = it.next();
+ if (image.allBlocksValid()) {
+ synchronized ( imagesToCheck ) {
+ imagesToCheck.remove( image.getUuid() );
+ image.updateMissingBlocks( null );
+ }
+ it.remove();
}
- if ( got == amount )
- break;
- }
-
- log.debug( "Returned " + got + " missing blocks." );
-
- 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 ( imagesToCheck ) {
- imagesToCheck.remove( uuid );
- log.debug( "Removing " + uuid );
- }
-
- UploadingImage image;
- synchronized ( uploadingImages ) {
- image = uploadingImages.remove( uuid );
}
- image.getDbImage().updateMissingBlocks( null );
- // file was already downloaded in the right location by the updownloader class.
- // remove the connection so that it can be used by a new client
- ConnectionHandler.removeConnection( image.getToken() );
}
public static List<UploadingImage> getImagesToCheck()
@@ -297,28 +147,28 @@ public class ImageProcessor
// TODO
return null;
}
-
+
/**
* Generates the filePath of an image.
* And creates the folder if wanted.
* The crc file is found under filePath + ".crc"
*
* @param imageData The data of the image
- * @param createFolder If you want the folder to be created
* @return The filePath of the given image
*/
public static String generateFilepathOfImage( ImageData imageData )
{
return generateFilePathOfImage( imageData.uuid, imageData.imageName, imageData.imageVersion );
}
-
- public static String generateFilePathOfImage( String uuid, String imageName, int imageVersion) {
- String result = Globals.getImageDir() + "/" + uuid + "/";
- File dir = new File(result);
+
+ public static String generateFilePathOfImage( String uuid, String imageName, int imageVersion )
+ {
+ String result = Util.sanitizeFileName( uuid ) + "/";
+ File dir = new File( Globals.getImageDir() + "/" + result );
if ( !dir.exists() ) {
dir.mkdirs();
}
- result += imageName + "-v" + String.valueOf( imageVersion ) + ".vmdk";
+ result += imageName + "-rev" + String.valueOf( imageVersion );
return result;
}
@@ -326,41 +176,10 @@ public class ImageProcessor
{
return generateFilepathOfImage( imageData ) + ".crc";
}
-
+
public static String generateFilepathOfCrcFile( String uuid, String imageName, int imageVersion )
{
return generateFilePathOfImage( uuid, imageName, imageVersion ) + ".crc";
}
- /**
- * Checks pending uploads in database and adds them to process list again.
- */
- static
- {
- List<DbImage> list = DbImage.getUploadingImages();
- for ( DbImage image : list ) {
- UploadingImage infos = new UploadingImage( image.token, image.blockStatus, image.timestamp.getTime(), image.uuid, image.imagePath );
- ConnectionHandler.addConnection( image.token, image.imagePath, Connection.UPLOADING ).image = infos;
- CrcFile crcFile = new CrcFile( generateFilepathOfCrcFile( image.uuid, image.imageName, image.imageVersion ) ); // TODO: has to be adjusted with the corresponding value above
- try {
- if ( !crcFile.isValid() ) {
- continue;
- // UploadingImage object will contain a CRCFile = null which invokes the ImageProcessor to retry to save it
- }
- } catch ( IOException e ) {
- continue;
- // same thing here
- }
- infos.setCrcFile( crcFile );
- uploadingImages.put( image.uuid, infos );
- imagesToCheck.add( image.uuid );
- }
- log.info( "Added " + list.size() + " pending upload(s) to process list again." );
- }
-
-
-
- public static void init()
- {
- }
}
diff --git a/src/main/java/org/openslx/imagemaster/serverconnection/UploadingImage.java b/src/main/java/org/openslx/imagemaster/serverconnection/UploadingImage.java
index 169877c..78d5f2b 100644
--- a/src/main/java/org/openslx/imagemaster/serverconnection/UploadingImage.java
+++ b/src/main/java/org/openslx/imagemaster/serverconnection/UploadingImage.java
@@ -1,5 +1,6 @@
package org.openslx.imagemaster.serverconnection;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -10,16 +11,14 @@ import org.openslx.imagemaster.crcchecker.ImageFile;
import org.openslx.imagemaster.db.DbImage;
/**
- * Helper class for ImageProcessor and ConnectionHandler to save some infos about the images in the process list.
+ * Helper class for ImageProcessor and ConnectionHandler to save some infos about the images in the
+ * process list.
*/
public class UploadingImage
{
public static final Logger log = Logger.getLogger( UploadingImage.class );
- /**
- * Token for the satellite.
- */
- private String token;
+
/**
* The status list of the blocks.
* x = 0 block is missing
@@ -27,177 +26,164 @@ public class UploadingImage
* x > 0 block is invalid and was transmitted x times (needs request)
* x < 0 block is invalid and was transmitted x times (needs check)
*/
- private int[] blockStatus = null;
- public static final int valid = 200;
- public static final int missing = 0;
- private long timestamp; // when did the server something for the last time
+ private final int[] blockStatus;
+ /**
+ * Remember last position in blockStatus array that was returned, so we don't always
+ * iterate from the beginning.
+ */
+ private int lastStatusPos = 0;
+
+ public static final int VALID = 200;
+ public static final int MISSING = 0;
+
private DbImage dbImage = null; // the DB representation of this image
- private String uuid;
- private String filename;
+ /**
+ * Class for accessing the file (read blocks from it)
+ */
private ImageFile imageFile = null;
private CrcFile crcFile = null;
- protected UploadingImage(String token, int[] initialBlockStatus, long timestamp, String uuid, String filename)
+ protected UploadingImage( String uuid )
{
- this.token = token;
- this.timestamp = timestamp;
- this.uuid = uuid;
- this.blockStatus = initialBlockStatus;
- this.filename = filename;
+ this.dbImage = DbImage.getImageByUuid( uuid );
+ if ( this.dbImage == null )
+ throw new RuntimeException( "Unknown image " + uuid + " on UploadingImage creation" );
+ this.blockStatus = this.dbImage.blockStatus;
}
protected void setValid( int index )
{
- if ( blockStatus == null )
- return;
synchronized ( blockStatus ) {
- blockStatus[index] = valid;
+ blockStatus[index] = VALID;
}
}
protected void updateDb()
{
- if ( blockStatus == null )
- return;
-
List<Integer> missingBlocks = new ArrayList<>();
-
synchronized ( blockStatus ) {
for ( int block = 0; block < blockStatus.length; block++ ) {
- if ( blockStatus[block] != valid ) {
+ if ( blockStatus[block] != VALID ) {
missingBlocks.add( block );
}
}
}
- getDbImage().updateMissingBlocks( missingBlocks );
+ dbImage.updateMissingBlocks( missingBlocks );
}
protected void setMissing( int index )
{
- if ( blockStatus == null )
- return;
synchronized ( blockStatus ) {
- blockStatus[index] = missing;
+ blockStatus[index] = MISSING;
}
}
protected void setNeedsRequest( int index )
{
- if ( blockStatus == null )
- return;
synchronized ( blockStatus ) {
- blockStatus[index] *= ( blockStatus[index] < missing ) ? -1 : 1; // switch to positive value if needed
+ blockStatus[index] = Math.abs( blockStatus[index] ); // switch to positive value if needed
}
}
protected void setNeedsCheck( int index )
{
- if ( blockStatus == null )
- return;
synchronized ( blockStatus ) {
- blockStatus[index] *= ( blockStatus[index] > missing ) ? -1 : 1; // switch to negative value if needed
+ blockStatus[index] = -Math.abs( blockStatus[index] ); // switch to negative value if needed
}
}
protected void increaseTransmittedTimes( int index )
{
- if ( blockStatus == null || blockStatus[index] == 200 )
- return;
synchronized ( blockStatus ) {
- blockStatus[index] += ( blockStatus[index] <= missing ) ? -1 : 1; // increase in both directions
+ if ( blockStatus[index] == 200 )
+ return;
+ blockStatus[index] += ( blockStatus[index] <= MISSING ) ? -1 : 1; // increase in both directions
}
}
protected int getTimesTransmitted( int index )
{
synchronized ( blockStatus ) {
- return ( blockStatus[index] > 0 ) ? blockStatus[index] : ( -1 ) * blockStatus[index];
+ return Math.abs( blockStatus[index] );
}
}
- protected String getToken()
- {
- return this.token;
- }
-
protected boolean needsRequest( int index )
{
- if ( blockStatus == null )
- return false;
synchronized ( blockStatus ) {
- return ( ( blockStatus[index] >= missing ) && ( blockStatus[index] != valid ) );
+ return ( ( blockStatus[index] >= MISSING ) && ( blockStatus[index] != VALID ) );
}
}
protected boolean needsCheck( int index )
{
- if ( blockStatus == null )
- return false;
synchronized ( blockStatus ) {
- return ( blockStatus[index] < missing );
+ return ( blockStatus[index] < MISSING );
}
}
protected int getNumberOfBlocks()
{
- ///////////////////////////////////////////////////////////////////
-// ArrayList<Integer> l = new ArrayList<Integer>( blockStatus.length );
-// for ( int i : blockStatus ) {
-// l.add( i );
-// }
-// log.debug( l );
- ///////////////////////////////////////////////////////////////////
return blockStatus.length;
}
-
+
protected int getNextMissingBlock()
{
- // TODO: handle intern status of current uploading block.
- for (int i = 0; i < blockStatus.length; i++) {
- if (blockStatus[i] == 0)
- return i;
+ synchronized ( blockStatus ) {
+ for ( int i = 0; i < blockStatus.length; i++ ) {
+ int index = ( i + lastStatusPos ) % blockStatus.length;
+ if ( blockStatus[index] == MISSING )
+ return lastStatusPos = index;
+ }
+ for ( int index = 0; index < blockStatus.length; index++ ) {
+ if ( blockStatus[index] > MISSING && blockStatus[index] < VALID )
+ return lastStatusPos = index;
+ }
+ for ( int index = 0; index < blockStatus.length; index++ ) {
+ if ( blockStatus[index] < MISSING )
+ return lastStatusPos = index;
+ }
}
return -1;
}
+ /*
protected long getTimestamp()
{
return this.timestamp;
}
-
- protected DbImage getDbImage()
- {
- if ( dbImage == null ) {
- dbImage = DbImage.getImageByUuid( this.uuid );
- }
- return this.dbImage;
- }
-
- protected void setDbImage( DbImage dbImage )
- {
- if ( dbImage != null ) {
- return;
- } else {
- this.dbImage = dbImage;
- }
- }
+ */
protected ImageFile getImageFile()
{
if ( imageFile == null ) {
- imageFile = new ImageFile( filename, Globals.blockSize );
+ imageFile = new ImageFile( dbImage.getAbsolutePath(), Globals.blockSize );
}
return imageFile;
}
protected CrcFile getCrcFile()
{
+ if ( crcFile == null ) {
+ try {
+ crcFile = new CrcFile( dbImage.getAbsolutePath() + ".crc" );
+ } catch ( IOException e ) {
+ // Not found... return null
+ }
+ }
return crcFile;
}
protected void setCrcFile( CrcFile crcFile )
{
- this.crcFile = crcFile;
+ if ( getCrcFile() == null ) {
+ this.crcFile = crcFile;
+ try {
+ crcFile.writeCrcFile( dbImage.getAbsolutePath() + ".crc" );
+ } catch ( IOException e ) {
+ log.error( "Could not write crc list to file", e );
+ }
+ }
}
public int getAmountOfBlocksNeedingRequest()
@@ -228,8 +214,28 @@ public class UploadingImage
@Override
public String toString()
{
- return "UUID: " + uuid + ", filename " + filename + "\nmissing blocks " + getAmountOfBlocksNeedingRequest() +
- ", number of blocks " + getNumberOfBlocks() + ", token " + getToken();
+ return "UUID: " + dbImage.uuid + ", filename " + dbImage.imagePath + "\nmissing blocks " + getAmountOfBlocksNeedingRequest() +
+ ", number of blocks " + getNumberOfBlocks();
+
+ }
+ public String getAbsolutePath()
+ {
+ return dbImage.getAbsolutePath();
+ }
+
+ public long getFileSize()
+ {
+ return dbImage.fileSize;
+ }
+
+ public String getUuid()
+ {
+ return dbImage.uuid;
+ }
+
+ public void updateMissingBlocks( List<Integer> missingBlocks )
+ {
+ dbImage.updateMissingBlocks( missingBlocks );
}
}
diff --git a/src/main/java/org/openslx/imagemaster/session/Authenticator.java b/src/main/java/org/openslx/imagemaster/session/Authenticator.java
index 5d1b728..19891b9 100644
--- a/src/main/java/org/openslx/imagemaster/session/Authenticator.java
+++ b/src/main/java/org/openslx/imagemaster/session/Authenticator.java
@@ -1,9 +1,7 @@
package org.openslx.imagemaster.session;
import org.apache.log4j.Logger;
-import org.openslx.imagemaster.db.DbSatellite;
import org.openslx.imagemaster.db.DbUser;
-import org.openslx.imagemaster.db.LdapUser;
import org.openslx.imagemaster.thrift.iface.AuthenticationError;
import org.openslx.imagemaster.thrift.iface.AuthenticationException;
@@ -26,6 +24,7 @@ public class Authenticator
public static User authenticate( String username, String password ) throws AuthenticationException
{
String login = username;
+ /*
if ( username.split( "@" ).length == 2 ) {
log.info( "username is in username@organization format" );
// we are in username@organization format
@@ -37,10 +36,11 @@ public class Authenticator
log.info( "username is not in a valid format." );
throw new AuthenticationException( AuthenticationError.INVALID_CREDENTIALS, "Credentials must be in (username@organization) or (prefix@username)" );
}
+ */
log.info( "Logging in with: " + login );
- LdapUser user = LdapUser.forLogin( login, password ); // throws exception if credentials are invalid
+ User user = DbUser.forLogin( login, password ); // throws exception if credentials are invalid
if ( user == null ) {
log.debug( "Login failed: " + username );
throw new AuthenticationException( AuthenticationError.GENERIC_ERROR, "Something went wrong." );
diff --git a/src/main/java/org/openslx/imagemaster/session/User.java b/src/main/java/org/openslx/imagemaster/session/User.java
index 82ba8ca..264c17f 100644
--- a/src/main/java/org/openslx/imagemaster/session/User.java
+++ b/src/main/java/org/openslx/imagemaster/session/User.java
@@ -14,8 +14,8 @@ public abstract class User
public final String satelliteAddress;
public final int userId;
- protected User(int userId, String username, String password, String organization, String firstName, String lastName, String eMail,
- String satelliteAddress)
+ protected User( int userId, String username, String password, String organization, String firstName, String lastName, String eMail,
+ String satelliteAddress )
{
this.userId = userId;
this.username = username;
@@ -46,4 +46,9 @@ public abstract class User
return sb.toString();
}
+ public String getLogin()
+ {
+ return username + "@" + organization;
+ }
+
}
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 6ca2384..84e3ede 100644
--- a/src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java
+++ b/src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java
@@ -8,7 +8,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.DownloadData;
import org.openslx.imagemaster.thrift.iface.ImageData;
import org.openslx.imagemaster.thrift.iface.ImageDataException;
import org.openslx.imagemaster.thrift.iface.ImageServer;
@@ -16,8 +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.UploadData;
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
@@ -63,13 +63,13 @@ public class ImageServerHandler implements ImageServer.Iface
}
@Override
- public UploadInfos submitImage( String serverSessionId, ImageData imageDescription, List<Integer> crcSums ) throws AuthorizationException, ImageDataException, UploadException, TException
+ public UploadData submitImage( String serverSessionId, ImageData imageDescription, List<Integer> crcSums ) throws AuthorizationException, ImageDataException, UploadException, TException
{
return ApiServer.submitImage( serverSessionId, imageDescription, crcSums );
}
@Override
- public DownloadInfos getImage( String uuid, String serverSessionId ) throws AuthorizationException, ImageDataException, TException
+ public DownloadData getImage( String serverSessionId, String uuid ) throws AuthorizationException, ImageDataException, TException
{
return ApiServer.getImage( uuid, serverSessionId );
}
diff --git a/src/main/java/org/openslx/imagemaster/util/Util.java b/src/main/java/org/openslx/imagemaster/util/Util.java
index 595c059..ffd3106 100644
--- a/src/main/java/org/openslx/imagemaster/util/Util.java
+++ b/src/main/java/org/openslx/imagemaster/util/Util.java
@@ -101,10 +101,22 @@ public class Util
*/
public static int tryToParseInt( String s )
{
+ return tryToParseInt( s, 0 );
+ }
+
+ /**
+ * Tries to parse an int. Returns defaultValue on error.
+ *
+ * @param s The strig to parse
+ * @param defaultValue value to be returned if s is not parsable
+ * @return The parsed int
+ */
+ public static int tryToParseInt( String s, int defaultValue )
+ {
try {
return Integer.parseInt( s );
} catch ( NumberFormatException e ) {
- return 0;
+ return defaultValue;
}
}
@@ -116,4 +128,12 @@ public class Util
return blocks;
}
+ public static String sanitizeFileName( String fileName )
+ {
+ fileName = fileName.replaceAll( "[^a-zA-Z0-9_\\-]+", "_" );
+ if ( fileName.length() > 40 )
+ fileName = fileName.substring( 0, 40 );
+ return fileName;
+ }
+
}
diff --git a/src/test/java/org/openslx/imagemaster/AppTest.java b/src/test/java/org/openslx/imagemaster/AppTest.java
index de18faa..079d0c2 100644
--- a/src/test/java/org/openslx/imagemaster/AppTest.java
+++ b/src/test/java/org/openslx/imagemaster/AppTest.java
@@ -1,14 +1,9 @@
package org.openslx.imagemaster;
-import java.util.UUID;
-
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
-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;
/**