/// <summary>
 /// Updates the <see cref="ReceivingBuffer"/> with the data
 /// of a given block, and performs a few simple tests.
 /// </summary>
 /// <param name="block"></param>
 private void ReceiveBlock(BufferedDataBlock block)
 {
   using (var stream = File.Open(TargetFilePath, FileMode.Append))
   {
     stream.Write(block.Data, 0, block.Data.Length);
   }
 }
    public void Init()
    {
      RootDir = FileUtil.CreateTempFolder("_" + GetType().Name);

      var provider = new LocalFileSystemProvider(RootDir, true);
      //prepare test dir and paths
      DownloadService = (LocalFileSystemDownloadService) provider.DownloadTransfers;
      
      
      SourceFilePath = FileUtil.CreateTempFilePath(RootDir.FullName, "source", "bin");

      //create file
      SourceFileContents = new byte[5 * 1024 * 1024];
      new Random(DateTime.Now.Millisecond).NextBytes(SourceFileContents);
      File.WriteAllBytes(SourceFilePath, SourceFileContents);
      SourceFile = new FileInfo(SourceFilePath);

      //prepare target buffer
      ReceivingBuffer = new List<byte>();
      LastBlock = null;

      //get token
      Token = DownloadService.RequestDownloadToken(SourceFilePath, false);

      InitInternal();
    }
    private void WriteBlock(BufferedDataBlock block)
    {
      Assert.AreEqual(block.BlockLength, block.Data.Length);
      Assert.AreEqual(token.TransferId, block.TransferTokenId);

      receivedBlocks.Add(block);
      target.AddRange(block.Data);
    }
Exemple #4
0
        /// <summary>
        /// Reads a data block's buffer and writes it to a given <paramref name="targetStream"/>.
        /// </summary>
        /// <param name="dataBlock">The data block that provides a chunk of data that should
        /// be written to the <paramref name="targetStream"/>.</param>
        /// <param name="targetStream">The target stream that receives the block's
        /// <see cref="BufferedDataBlock.Data"/>.</param>
        public static void WriteTo(this BufferedDataBlock dataBlock, Stream targetStream)
        {
            //TODO support variable block length that differs from buffer length:
            //targetStream.Write(dataBlock.Data, 0, dataBlock.BlockLength ?? dataBlock.Data.Length);
            //-> means we also have to change block validation

            targetStream.Position = dataBlock.Offset;
            targetStream.Write(dataBlock.Data, 0, dataBlock.Data.Length);
        }
Exemple #5
0
    private void FlushInternal(bool isAutoFlush)
    {
      //on autoflush, do not send blocks smaller than the threshold
      long minBufferSize = 0;
      if (isAutoFlush)
      {
        //if auto-flushing, flush as long as we can create full-sized blocks,
        //OR are above the flushing threshold
        minBufferSize = Math.Min(AutoFlushThreshold, Token.MaxBlockSize ?? 0);
        
        //make sure we don't have a negative value
        minBufferSize = Math.Max(minBufferSize, 0);
      }
      
      lock (syncRoot)
      {
        if (transmissionBuffer.Count == 0) return;


        while (transmissionBuffer.Count > 0 && transmissionBuffer.Count >= minBufferSize)
        {
          //the blockSize is an int - the buffer can't be bigger anyway
          int blockSize = (int)(Math.Min(transmissionBuffer.Count, Token.MaxBlockSize ?? transmissionBuffer.Count));
          byte[] data = new byte[blockSize];
          transmissionBuffer.CopyTo(0, data, 0, blockSize);

          long blockNumber = LastTransmittedBlockNumber.HasValue
                               ? LastTransmittedBlockNumber.Value + 1
                               : Token.TransmittedBlockCount;

          BufferedDataBlock block = new BufferedDataBlock
                              {
                                TransferTokenId = Token.TransferId,
                                BlockNumber = blockNumber,
                                BlockLength = blockSize,
                                Data = data,
                                Offset = InitialOffset + WrittenBytes
                              };

          //write block
          OutputAction(block);

          //if not exception occurred, update state, remove data from buffer and continue
          transmissionBuffer.RemoveRange(0, blockSize);
          WrittenBytes += blockSize;
          LastTransmittedBlockNumber = blockNumber;
        }
      }
    }
Exemple #6
0
        public void WriteBlock(BufferedDataBlock block)
        {
            lock (this)
            {
                if (block.BlockNumber != LastProcessedBlockNumber + 1)
                {
                    throw new NotImplementedException(""); //TODO provide implementation
                }

                WriteDataImpl(block);

                if (block.IsLastBlock)
                {
                    FinalizeTransfer();
                }
            }
        }
    public void WriteBlock(BufferedDataBlock block)
    {
      lock(this)
      {
        if (block.BlockNumber != LastProcessedBlockNumber + 1)
        {
          throw new NotImplementedException(""); //TODO provide implementation
        }

        WriteDataImpl(block);

        if (block.IsLastBlock)
        {
          FinalizeTransfer();
        }
      }
    }
        public void StartDownload()
        {
            if (Token == null)
            {
                Token = TransferService.RequestDownloadToken(ResourceId, false);
            }

            while (true)
            {
                IDataBlockInfo blockInfo;
                string         transferId = Token.TransferId;

                long nextBlock = 0;
                if (Token.LastTransmittedBlockInfo != null)
                {
                    nextBlock = Token.LastTransmittedBlockInfo.BlockNumber + 1;
                }

                if (UseStreamingTransfer)
                {
                    StreamedDataBlock block = TransferService.ReadBlockStreamed(transferId, nextBlock);
                    block.Data.WriteTo(OutputStream);
                    blockInfo = block;
                }
                else
                {
                    BufferedDataBlock block = TransferService.ReadBlock(transferId, nextBlock);
                    OutputStream.Write(block.Data, 0, block.Data.Length);
                    blockInfo = block;
                }

                //update the token, get independent file info without data or stream
                Token.LastTransmittedBlockInfo  = DataBlockInfo.FromDataBlock(blockInfo);
                Token.LastBlockTransmissionTime = SystemTime.Now();

                if (blockInfo.IsLastBlock)
                {
                    //we're done - update token data
                    Token.CompletionTime = Token.LastBlockTransmissionTime;
                    TransferService.CompleteTransfer(transferId);
                    Token.Status = TransferStatus.Completed;

                    break;
                }
            }
        }
    protected override void InitInternal()
    {
      SourceFileContents = new byte[12345678];
      new Random(DateTime.Now.Millisecond).NextBytes(SourceFileContents);

      //create parent folder
      ParentDirectory = rootDirectory.CreateSubdirectory("Dwnld_Parent");

      //create file
      SourceFilePath = FileUtil.CreateTempFilePath(ParentDirectory.FullName, "_dwlndsource", "bin");
      File.WriteAllBytes(SourceFilePath, SourceFileContents);
      SourceFile = new FileInfo(SourceFilePath);
      SourceFileInfo = provider.GetFileInfo(SourceFilePath);


      //prepare target buffer
      ReceivingBuffer = new List<byte>();
      LastBlock = null;
    }
    protected override void InitInternal()
    {
      base.InitInternal();
      InitToken();

      byte[] buffer = new byte[10000];
      Array.Copy(SourceFileContents, buffer, 10000);

      BufferedBlock = new BufferedDataBlock
                        {
                          TransferTokenId = Token.TransferId,
                          BlockLength = 10000,
                          Data = buffer
                        };

      StreamedBlock = new StreamedDataBlock
                        {
                          TransferTokenId = Token.TransferId,
                          BlockLength = 10000,
                          Data = new ChunkStream(new MemoryStream(SourceFileContents), 10000, 0, false)
                        };
    }
    protected override void InitInternal()
    {
      base.InitInternal();
      InitToken();

      //read first 10000 bytes
      byte[] buffer = GetBuffer(10000);


      BufferedBlock = new BufferedDataBlock
                        {
                          TransferTokenId = Token.TransferId,
                          BlockLength = 10000,
                          Data = buffer
                        };

      StreamedBlock = new StreamedDataBlock
                        {
                          TransferTokenId = Token.TransferId,
                          BlockLength = 10000,
                          Data = new ChunkStream(new MemoryStream(buffer), 10000, 0, false)
                        };
    }
    public void Init()
    {
      Input = new List<BufferedDataBlock>();
      for(int i=0; i<10; i++)
      {
        byte[] data = new byte[200000];
        new Random().NextBytes(data);

        BufferedDataBlock db = new BufferedDataBlock
                         {
                           BlockLength = 200000,
                           BlockNumber = i,
                           Data = data,
                           IsLastBlock = i == 9,
                           Offset = i*200000,
                           TransferTokenId = "xxx"
                         };
        Input.Add(db);
      }

      ReceivedData = new List<byte>();
      InputStream = new BufferedBlockInputStream((i) => Input[(int)i], 200000*10);
    }
    public void Writing_Last_Buffered_Block_Should_Complete_Transfer()
    {
      BufferedBlockOutputStream os = new BufferedBlockOutputStream(Token, 15000, b => UploadHandler.WriteBlock(b));
      MemoryStream ms = new MemoryStream(SourceFileContents);
      ms.WriteTo(os);

      Assert.AreEqual(TransferStatus.Running, UploadHandler.GetTransferStatus(Token.TransferId));

      //write an empty last block
      BufferedDataBlock db = new BufferedDataBlock
                               {
                                 TransferTokenId = Token.TransferId,
                                 BlockLength = 0,
                                 Offset = SourceFile.Length,
                                 Data = new byte[0],
                                 BlockNumber = 0,
                                 IsLastBlock = true
                               };
      UploadHandler.WriteBlock(db);

      Assert.AreEqual(TransferStatus.Completed, UploadHandler.GetTransferStatus(Token.TransferId));
      FileAssert.AreEqual(SourceFilePath, TargetFilePath);
    }
 /// <summary>
 /// Uploads a given data block that contains a chunk of data for an uploaded file.
 /// </summary>
 /// <param name="block">The block to be written.</param>
 /// <exception cref="DataBlockException">If the data block's contents cannot be stored,
 /// either because it's an invalid number, or because only sequential downloads
 /// are possible, and the block does not refer to the current download
 /// position.
 /// </exception>
 /// <exception cref="TransferStatusException">If the transfer has already expired.</exception>
 public void WriteBlock(BufferedDataBlock block)
 {
   throw new NotImplementedException();
 }
 /// <summary>
 /// Uploads a given data block that contains a chunk of data for an uploaded file.
 /// </summary>
 /// <param name="block">The block to be written.</param>
 /// <exception cref="DataBlockException">If the data block's contents cannot be stored,
 /// either because it's an invalid number, or because only sequential downloads
 /// are possible, and the block does not refer to the current download
 /// position.
 /// </exception>
 /// <exception cref="TransferStatusException">If the transfer has already expired.</exception>
 void IFSDataUploadService.WriteDataBlock(BufferedDataBlock block)
 {
   throw new NotImplementedException();
 }
    public void WriteDataBlock(string transferId, int blockNumber, int blockLength, long offset, byte[] data)
    {
      Action action = () =>
      {
        BufferedDataBlock block = new BufferedDataBlock
        {
          TransferTokenId = transferId,
          BlockNumber = blockNumber,
          BlockLength = blockLength,
          Offset = offset,
          Data = data
        };

        Decorated.UploadTransfers.WriteBlock(block);
      };

      FaultUtil.SecureAction(FileSystemTask.DataBlockUploadRequest, action);
    }
    public void Writing_A_Single_Empty_Block_Should_Create_File()
    {
      UploadHandler.CancelTransfer(Token.TransferId, AbortReason.ClientAbort);

      //get token for empty file
      Token = UploadHandler.RequestUploadToken(TargetFilePath, false, 0, "");

      TargetFile.Refresh();
      Assert.IsFalse(TargetFile.Exists);

      var block = new BufferedDataBlock { TransferTokenId = Token.TransferId, BlockLength = 0, BlockNumber = 0, Data = new byte[0], IsLastBlock = true};
      UploadHandler.WriteBlock(block);

      TargetFile.Refresh();
      Assert.IsTrue(TargetFile.Exists);
    }
    /// <summary>
    /// Creates a list of data blocks based on the source file, which
    /// can be uploaded to the target.
    /// </summary>
    protected List<BufferedDataBlock> CreateBufferedBlocks()
    {
      var list = new List<BufferedDataBlock>();


      long offset = 0;
      int blockCount = 0;
      byte[] buffer = new byte[Token.MaxBlockSize ?? 2048];
      
      using (var fs = SourceFile.OpenRead())
      {
        while (true)
        {
          //long offset = fs.Position;
          var read = fs.Read(buffer, 0, buffer.Length);

          //we're done
          if (read == 0) break;

          BufferedDataBlock block = new BufferedDataBlock
          {
            TransferTokenId = Token.TransferId,
            BlockLength = read,
            BlockNumber = blockCount++,
            Offset = offset,
            Data = buffer.CreateCopy(read)
          };

          offset += read;
          list.Add(block);
        }
      }

      var bytesCount = list.Select(b => b.BlockLength).Sum();
      Assert.AreEqual(bytesCount.Value, SourceFile.Length);

      return list;
    }
    public void Writing_Last_Buffered_Block_Should_Complete_Transfer()
    {
      using (var fs = SourceFile.OpenRead())
      {
        fs.WriteTo(Token, SourceFile.Length, 2048, b =>
                                                     {
                                                       b.IsLastBlock = false;
                                                       Uploads.WriteBlockStreamed(b);
                                                     });
      }

      Assert.AreEqual(TransferStatus.Running, Uploads.GetTransferStatus(Token.TransferId));

      //write an empty last block
      BufferedDataBlock db = new BufferedDataBlock
                               {
                                 TransferTokenId = Token.TransferId,
                                 BlockLength = 0,
                                 Offset = SourceFile.Length,
                                 Data = new byte[0],
                                 BlockNumber = 0,
                                 IsLastBlock = true
                               };
      Uploads.WriteBlock(db);

      CompareUploadToSourceFile();

      TransferStatus status = Uploads.GetTransferStatus(Token.TransferId);
      Assert.IsTrue(status.Is(TransferStatus.Completed, TransferStatus.UnknownTransfer));
    }
    public void Writing_An_Empty_Block_Should_Be_Supported()
    {
      //write an empty last block
      BufferedDataBlock db = new BufferedDataBlock
      {
        TransferTokenId = Token.TransferId,
        BlockLength = 0,
        Offset = 0,
        Data = new byte[0],
        BlockNumber = 0,
        IsLastBlock = false
      };

      Uploads.WriteBlock(db);
    }
Exemple #21
0
 protected override void WriteDataImpl(BufferedDataBlock block)
 {
     DestinationStream.Seek(block.Offset, SeekOrigin.Begin);
     DestinationStream.Write(block.Data, 0, block.Data.Length);
     DestinationStream.Flush();
 }
 protected override void WriteDataImpl(BufferedDataBlock block)
 {
   DestinationStream.Seek(block.Offset, SeekOrigin.Begin);
   DestinationStream.Write(block.Data, 0, block.Data.Length);
   DestinationStream.Flush();
 }
 protected override void InitInternal()
 {
   base.InitInternal();
   InitToken();
   recentBlock = null;
 }
Exemple #24
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="block"></param>
 protected abstract void WriteDataImpl(BufferedDataBlock block);
    /// <summary>
    /// Updates the <see cref="ReceivingBuffer"/> with the data
    /// of a given block, and performs a few simple tests.
    /// </summary>
    /// <param name="block"></param>
    protected virtual void ReceiveBlock(BufferedDataBlock block)
    {
      Assert.AreEqual(Token.TransferId, block.TransferTokenId);
      Assert.AreEqual(ReceivingBuffer.Count, block.Offset);

      Assert.AreEqual(block.BlockLength, block.Data.Length);
      ReceivingBuffer.AddRange(block.Data);
      LastBlock = block;
    }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="block"></param>
 protected abstract void WriteDataImpl(BufferedDataBlock block);