package org.openslx.imagemaster.serverconnection; import java.io.File; import java.io.FileNotFoundException; import java.nio.ByteBuffer; import java.sql.SQLException; import java.util.List; import java.util.UUID; import org.apache.log4j.Logger; import org.openslx.bwlp.thrift.iface.ImagePublishData; import org.openslx.bwlp.thrift.iface.TInvocationException; import org.openslx.bwlp.thrift.iface.TransferInformation; import org.openslx.filetransfer.util.ChunkStatus; import org.openslx.filetransfer.util.FileChunk; import org.openslx.filetransfer.util.IncomingTransferBase; import org.openslx.imagemaster.Globals; import org.openslx.imagemaster.db.mappers.DbImage; import org.openslx.imagemaster.db.mappers.DbImageBlock; import org.openslx.imagemaster.util.Util; import org.openslx.util.ThriftUtil; public class IncomingTransfer extends IncomingTransferBase { private static final Logger LOGGER = Logger.getLogger( IncomingTransfer.class ); private static final long MIN_FREE_SPACE_BYTES = FileChunk.CHUNK_SIZE * 10; private final String imageVersionId; private final TransferInformation transferInfo; public IncomingTransfer( ImagePublishData img, List blockHashes, File absDestination, int plainPort, int sslPort ) throws TInvocationException, FileNotFoundException { super( UUID.randomUUID().toString(), absDestination, img.fileSize, ThriftUtil.unwrapByteBufferList( blockHashes ) ); this.imageVersionId = img.imageVersionId; this.transferInfo = new TransferInformation( getId(), plainPort, sslPort ); // If the file already exists, see if any chunks are already complete if ( absDestination.exists() && absDestination.length() > 0 ) { try { List statusList = DbImageBlock.getMissingStatusList( img.imageVersionId ); if ( !statusList.isEmpty() ) { getChunks().resumeFromStatusList( statusList, absDestination.length() ); for ( int i = 0; i < 3; ++i ) { queueUnhashedChunk( false ); } } } catch ( SQLException e ) { } } } @Override public String getRelativePath() { return Util.getRelativePath( getTmpFileName(), new File( Globals.getImageDir() ) ); } @Override public synchronized void cancel() { super.cancel(); getTmpFileName().delete(); } @Override protected boolean hasEnoughFreeSpace() { long space = Globals.getImagePath().getUsableSpace(); return space > MIN_FREE_SPACE_BYTES; } @Override protected boolean finishIncomingTransfer() { potentialFinishTime.set( System.currentTimeMillis() ); try { DbImage.markValid( this.imageVersionId, true ); } catch ( SQLException e ) { // Nothing to do } return true; } @Override public TransferInformation getTransferInfo() { return transferInfo; } @Override protected void chunkStatusChanged( FileChunk chunk ) { if ( chunk.getFailCount() > 6 ) { cancel(); LOGGER.warn( "Server is cancelling upload of Version " + imageVersionId + ": Hash check for block " + chunk.getChunkIndex() + " failed " + chunk.getFailCount() + " times." ); } ChunkStatus status = chunk.getStatus(); if ( status == ChunkStatus.MISSING || status == ChunkStatus.COMPLETE ) { try { DbImageBlock.asyncUpdate( imageVersionId, chunk ); } catch ( InterruptedException e ) { e.printStackTrace(); } } } public Object getImageVersionId() { return imageVersionId; } }