diff options
Diffstat (limited to 'src/main/java/org/openslx/satellitedaemon/filetransfer')
3 files changed, 404 insertions, 0 deletions
diff --git a/src/main/java/org/openslx/satellitedaemon/filetransfer/FileDownloadWorker.java b/src/main/java/org/openslx/satellitedaemon/filetransfer/FileDownloadWorker.java new file mode 100644 index 0000000..e1ba7e9 --- /dev/null +++ b/src/main/java/org/openslx/satellitedaemon/filetransfer/FileDownloadWorker.java @@ -0,0 +1,51 @@ +package org.openslx.satellitedaemon.filetransfer; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; +import org.openslx.filetransfer.Downloader; +import org.openslx.imagemaster.thrift.iface.DownloadInfos; +import org.openslx.satellitedaemon.Globals; +import org.openslx.satellitedaemon.Globals.PropInt; +import org.openslx.satellitedaemon.Globals.PropString; +import org.openslx.satellitedaemon.db.DbImage; + + +public class FileDownloadWorker implements Runnable +{ + private static Logger log = Logger.getLogger( FileUploadWorker.class ); + + @Override + public void run() + { + while ( true ) { + List<DbImage> imageList = DbImage.getAllMarkedForDownload(); + log.info( "FILTRANSFERDownloadWorker: imageList Contains " + imageList.size() + " items." ); + for ( DbImage image : imageList ) { + + List<Integer> range = new ArrayList<Integer>(); + for (long i = 0; i < (image.fileSize / Globals.getPropertyInt( PropInt.BLOCKSIZE )); i++) { + range.add( (int) i ); + } + DownloadInfos downInfos = ThriftConnection.getDownloadInfos( image, range ); + if ( downInfos == null ) { + log.error( "The DownloadInfos returned by ThriftConnection class are null" ); + } + + Downloader d = new Downloader( Globals.getPropertyString( PropString.FILETRANSFERSERVERIP ), downInfos.port, Globals.getMasterServerSslContext() ); + d.sendToken( downInfos.token ); + d.setOutputFilename( "/home/michael/Downloads/tescht.whatever" ); + while ( d.readMetaData() ) + d.readBinary(); + } + try { + Thread.sleep( 5 * 60 * 1000 ); + } catch ( InterruptedException e ) { + Thread.currentThread().interrupt(); + return; + } + } + + } +} diff --git a/src/main/java/org/openslx/satellitedaemon/filetransfer/FileUploadWorker.java b/src/main/java/org/openslx/satellitedaemon/filetransfer/FileUploadWorker.java new file mode 100644 index 0000000..8e66ea9 --- /dev/null +++ b/src/main/java/org/openslx/satellitedaemon/filetransfer/FileUploadWorker.java @@ -0,0 +1,85 @@ +package org.openslx.satellitedaemon.filetransfer; + +import java.util.List; +import java.util.UUID; + +import org.apache.log4j.Logger; +import org.openslx.filetransfer.Uploader; +import org.openslx.imagemaster.thrift.iface.ImageData; +import org.openslx.imagemaster.thrift.iface.UploadInfos; +import org.openslx.satellitedaemon.Globals; +import org.openslx.satellitedaemon.Globals.PropInt; +import org.openslx.satellitedaemon.Globals.PropString; +import org.openslx.satellitedaemon.db.DbImage; + +public class FileUploadWorker implements Runnable +{ + private static Logger log = Logger.getLogger( FileUploadWorker.class ); + + @Override + public void run() + { + while ( true ) { + // This List contains all Images in the Database that should be uploaded. + List<DbImage> imageList = DbImage.getAllMarkedForUpload(); + log.info( "FILTRANSFERUploadWorker: imageList Contains " + imageList.size() + " items." ); + + // Upload one Image after the other. + for ( DbImage image : imageList ) { + // TODO: still some fields for ImageData, which i can't fill with info from DbImage. + // ImageData imDat = new ImageData( image.guid, image.rid, + // image.name, System.currentTimeMillis(), System.currentTimeMillis(), image.creator, "anyThing", + // true, false, "best", "theVeryBest", image.fileSize ); + + ImageData imDat = new ImageData( UUID.randomUUID().toString(), image.rid, + image.name, System.currentTimeMillis(), System.currentTimeMillis(), image.creator, "anyThing", + true, false, "best", "theVeryBest", image.fileSize ); + + // uploadInfo and ThriftAuthentication + String crcPath = image.path.concat( ".crc" ); + UploadInfos upInfos = ThriftConnection.getUploadInfos( imDat, crcPath ); + if ( upInfos == null ) { + log.error( "The UploadInfos returned by ThriftConnection Class are null" ); + + return; + + // FIXME: And then..? If you just continue, you'll run into a null pointer exception + + } + log.info( "Got upInfos. Trying to create Uploader with token: " + upInfos.token ); + + // creating the uploader with the "context"-item. + Uploader u = new Uploader( Globals.getPropertyString( PropString.FILETRANSFERSERVERIP ), upInfos.port, Globals.getMasterServerSslContext() ); + u.sendToken( upInfos.token ); + + // continue sending Blocks until getMissingBlocks is empty. + while ( !upInfos.getMissingBlocks().isEmpty() ) { + // Send all Blocks from upInfos.getMissingBlocks() in ranges. + List<Integer> blocks = upInfos.getMissingBlocks(); + int start = 0; + for ( int i = 0; i < blocks.size() - 1; i++ ) { + if ( blocks.get( i ) != ( blocks.get( i + 1 ) - 1 ) ) { + u.sendRange( start * Globals.getPropertyInt( PropInt.BLOCKSIZE ), i * Globals.getPropertyInt( PropInt.BLOCKSIZE ) ); + u.sendFile( image.path ); + start = i + 1; + } + if ( i == blocks.size() - 2 ) { + u.sendRange( start * Globals.getPropertyInt( PropInt.BLOCKSIZE ), ( blocks.size() - 1 ) * Globals.getPropertyInt( PropInt.BLOCKSIZE ) ); + u.sendFile( image.path ); + } + } + upInfos = ThriftConnection.getUploadInfos( imDat ); + } + u.close(); + } + try { + Thread.sleep( 5 * 60 * 1000 ); + // Thread.sleep( 1000 ); + } catch ( InterruptedException e ) { + Thread.currentThread().interrupt(); + return; + } + } + + } +} diff --git a/src/main/java/org/openslx/satellitedaemon/filetransfer/ThriftConnection.java b/src/main/java/org/openslx/satellitedaemon/filetransfer/ThriftConnection.java new file mode 100644 index 0000000..b656a84 --- /dev/null +++ b/src/main/java/org/openslx/satellitedaemon/filetransfer/ThriftConnection.java @@ -0,0 +1,268 @@ +package org.openslx.satellitedaemon.filetransfer; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.ByteBuffer; +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.List; + +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.crcchecker.CRCFile; +import org.openslx.imagemaster.thrift.iface.DownloadInfos; +import org.openslx.imagemaster.thrift.iface.ImageData; +import org.openslx.imagemaster.thrift.iface.ImageServer; +import org.openslx.imagemaster.thrift.iface.ServerAuthenticationException; +import org.openslx.imagemaster.thrift.iface.ServerSessionData; +import org.openslx.imagemaster.thrift.iface.UploadInfos; +import org.openslx.satellitedaemon.Globals; +import org.openslx.satellitedaemon.Globals.PropInt; +import org.openslx.satellitedaemon.Globals.PropString; +import org.openslx.satellitedaemon.db.DbImage; +import org.openslx.satellitedaemon.util.EncryptWithServerIdPublicKey; + +// TODO: Handle all the auto-generated catch blocks in a meaningful way + +/***********************************************************************************************/ +/** + * Handles the authentication with the Satellite Server and sends the FILTRANSFERCredentials, which + * are necessary for the upload of the image. + */ +public class ThriftConnection +{ + private static ImageServer.Client client = null; + private static ServerSessionData sSD = null; + private static Logger log = Logger.getLogger( ThriftConnection.class ); + private static CRCFile crc = null; + + /***********************************************************************************************/ + /** + * Method for getting UploadeInfos + * + * !! on the first Call !! + * + * when the CRCsum need to be transfered. + * The method calls getConnection() to check if the connection is ok + * and to get the ServerSessionData. If connection is ok, it calls + * submitImage with CRCsum in List<Integer>. + * + * @return returns 'null' if there is a problem. + */ + public static UploadInfos getUploadInfos( ImageData imDat, String filename ) + { + ImageServer.Client theClient = null; + try { + theClient = getConnection(); + if ( theClient == null ) { + log.error( "Client was null!" ); + return null; + } + // .submitImage needs the List<Integer> from CRCFile.getCRCs() only + // on the first time called. null afterwards. + log.info( "First call of submitImage following..." ); + crc = new CRCFile( filename ); + log.info( "Made CRCFile from " + filename ); + return theClient.submitImage( sSD.sessionId, imDat, crc.getCrcSums() ); + } catch ( TException e ) { + log.error("TException"); + } catch ( UnrecoverableKeyException e ) { + log.error("UnrecoverableKeyException"); + } catch ( InvalidKeyException e ) { + log.error("InvalidKeyException"); + } catch ( NoSuchAlgorithmException e ) { + log.error("NoSuchAlgorithmException"); + } catch ( CertificateException e ) { + log.error("CertificateException"); + } catch ( FileNotFoundException e ) { + log.error("FileNotFoundException"); + } catch ( KeyStoreException e ) { + log.error("KeyStoreException"); + } catch ( SignatureException e ) { + log.error("SignatureException"); + } catch ( IOException e ) { + log.error("IOException"); + } + return null; + } + + /***********************************************************************************************/ + /** + * Method for getting UploadeInfos when CRCsum was already transfered on first call. + * The method calls getConnection() to check if the connection is ok + * and to get the ServerSessionData. If connection is ok, it calls + * submitImage with sSD.sessionId, imDat and !!null!! + * + * @return returns 'null' if there is a problem. + */ + public static UploadInfos getUploadInfos( ImageData imDat ) + { + ImageServer.Client theClient = null; + try { + theClient = getConnection(); + if ( theClient == null ) { + log.error( "Client was null!" ); + return null; + } + // .submitImage needs the List<Integer> from CRCFile.getCRCs() only + // on the first time called. null afterwards. + return theClient.submitImage( sSD.sessionId, imDat, crc.getCrcSums() ); + } catch ( TException e ) { + log.error("TException"); + } catch ( UnrecoverableKeyException e ) { + log.error("UnrecoverableKeyException"); + } catch ( InvalidKeyException e ) { + log.error("InvalidKeyException"); + } catch ( NoSuchAlgorithmException e ) { + log.error("NoSuchAlgorithmException"); + } catch ( CertificateException e ) { + log.error("CertificateException"); + } catch ( FileNotFoundException e ) { + log.error("FileNotFoundException"); + } catch ( KeyStoreException e ) { + log.error("KeyStoreException"); + } catch ( SignatureException e ) { + log.error("SignatureException"); + } catch ( IOException e ) { + log.error("IOException"); + } + return null; + } + + /***********************************************************************************************/ + /** + * Method for getting DonwloadInfos. Calls getConnection if client was null. + * You need to spezifie all Blocks you want to have in an List. + * + * @return returns 'null' if there is a problem. + */ + public static DownloadInfos getDownloadInfos( DbImage imDat, List<Integer> range ) + { + ImageServer.Client theClient = null; + try { + theClient = getConnection(); + if ( theClient == null ) { + log.error( "Client was null!" ); + return null; + } + + return theClient.getImage( imDat.guid, sSD.sessionId, range ); + } catch ( TException e ) { + log.error("TException"); + } catch ( UnrecoverableKeyException e ) { + log.error("UnrecoverableKeyException"); + } catch ( InvalidKeyException e ) { + log.error("InvalidKeyException"); + } catch ( NoSuchAlgorithmException e ) { + log.error("NoSuchAlgorithmException"); + } catch ( CertificateException e ) { + log.error("CertificateException"); + } catch ( FileNotFoundException e ) { + log.error("FileNotFoundException"); + } catch ( KeyStoreException e ) { + log.error("KeyStoreException"); + } catch ( SignatureException e ) { + log.error("SignatureException"); + } catch ( IOException e ) { + log.error("IOException"); + } + return null; + } + + /***********************************************************************************************/ + /** + * This method checks if there is already a working connection. If not, + * newClient() establishes one. Also it does the Authentication if not done + * yet. + * + * @return returns the client if successful. + */ + private static ImageServer.Client getConnection() + throws UnrecoverableKeyException, NoSuchAlgorithmException, CertificateException, + FileNotFoundException, KeyStoreException, IOException, InvalidKeyException, SignatureException + { + ImageServer.Client theClient = null; + boolean isAuthenticated = false; + if ( client == null ) { + log.info( "The global client was null. Making a new client ..." ); + theClient = newClient(); + if ( theClient == null ) { + log.debug( "ThriftConnection: The client was null after newClient()" ); + return null; + } + } else { + log.info( "The global Client was already used. Setting isAuthenticated = true." ); + theClient = client; + isAuthenticated = true; + } + // try { + // isAuthenticated = theClient.ping(); + // } catch ( TException x ) { + // theClient = newClient(); + // if ( theClient == null ) { + // return null; + // } + // } + if ( !isAuthenticated ) { + log.info( "ThriftConnection: Client not yet Authenticated. Trying..." ); + String toEncrypt; + if ( theClient == null ) { + log.debug( "The client was null" ); + return null; + } + try { + toEncrypt = theClient.startServerAuthentication( Globals.getPropertyString( PropString.THRIFTORGANIZATIONNAME ) ); + log.info( "The random String we want to encrypt: " + toEncrypt ); + EncryptWithServerIdPublicKey rse = new EncryptWithServerIdPublicKey( Globals.getPropertyString( PropString.RNDSTRINGENCRYPTALIAS ), + Globals.getPropertyString( PropString.RNDSTRINGENCRYPTPASSWORD ), + Globals.getPropertyString( PropString.RNDSTRINGENCRYPTPATH ) ); + byte[] byteArray = rse.encryptString( toEncrypt ); + sSD = theClient.serverAuthenticate( + Globals.getPropertyString( PropString.THRIFTORGANIZATIONNAME ), ByteBuffer.wrap( byteArray ) ); + } catch ( ServerAuthenticationException e ) { + log.error( "ThriftConnection: ServerAuthenticationException: Server Authetication was not sucessful." ); + e.printStackTrace(); + return null; + } catch ( TException e ) { + log.error( "ThriftConnection: TException: Server Authetication was not sucessful." ); + e.printStackTrace(); + return null; + } + log.info( "is Authenticated." ); + + } + client = theClient; + return theClient; + } + + /***********************************************************************************************/ + /** + * + * @return + */ + private static ImageServer.Client newClient() + { + ImageServer.Client newClient = null; + try { + TTransport transport; + transport = new TSocket( Globals.getPropertyString( PropString.FILETRANSFERSERVERIP ), Globals.getPropertyInt( PropInt.THRIFTPORT ) ); + transport.open(); + TProtocol protocol = new TBinaryProtocol( transport ); + newClient = new ImageServer.Client( protocol ); + log.debug( "ThriftConnection: Made a new Client" ); + } catch ( TException x ) { + log.error( "ThriftConnection coudn't create new client." ); + x.printStackTrace(); + return null; + } + return newClient; + } +} |