SoapFileTransferService
using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Relativity.Transfer.Http
{
internal sealed class SoapFileTransferService : ISoapFileTransferService, IDisposable
{
private readonly IFileSystemService fileSystemService;
private readonly RelativityConnectionInfo connectionInfo;
private readonly IUserManagerService userManagerService;
private readonly IFileIoService fileIoService;
private readonly int chunkSize;
private readonly bool createDirectories;
private bool disposed;
public SoapFileTransferService(RelativityConnectionInfo connectionInfo, Workspace workspace, HttpClientConfiguration configuration, IFileSystemService fileSystemService, ITransferLog log)
{
if (connectionInfo == null)
throw new ArgumentNullException("connectionInfo");
if (configuration == null)
throw new ArgumentNullException("configuration");
if (fileSystemService == null)
throw new ArgumentNullException("fileSystemService");
if (log == null)
throw new ArgumentNullException("log");
this.connectionInfo = connectionInfo;
this.fileSystemService = fileSystemService;
userManagerService = new UserManagerService(this.connectionInfo, configuration, log);
fileIoService = new FileIoService(this.connectionInfo, workspace, configuration, userManagerService, log);
chunkSize = ((configuration.HttpChunkSize > 0) ? configuration.HttpChunkSize : 102400);
createDirectories = configuration.CreateDirectories;
}
~SoapFileTransferService()
{
Dispose(false);
}
public void Login()
{
userManagerService.Login();
}
public Task RemoveTempFile(int workspaceId, string fileGuid, CancellationToken token)
{
return fileIoService.RemoveTempFile(workspaceId, fileGuid, token);
}
public async Task<TransferPathResult> UploadAsync(TransferPath path, Action<long, long, int, int> progress, CancellationToken token)
{
if (path == (TransferPath)null)
throw new ArgumentNullException("path");
if (string.IsNullOrEmpty(path.TargetPath))
throw new ArgumentNullException("TargetPath");
if (!path.TargetPath.EndsWith("\\"))
path.TargetPath += "\\";
TransferPathResult result = new TransferPathResult {
Path = path,
Status = TransferPathStatus.Started,
StartTime = new DateTime?(DateTime.Now)
};
if (token.IsCancellationRequested) {
result.Status = TransferPathStatus.Canceled;
result.EndTime = DateTime.Now;
return result;
}
using (FileStream sourceStream = new FileStream(path.SourcePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
int readLength = chunkSize;
if (sourceStream.Length < chunkSize)
readLength = Convert.ToInt32(sourceStream.Length);
string fileName = (!string.IsNullOrEmpty(path.TargetFileName)) ? path.TargetFileName : (string.IsNullOrEmpty(fileSystemService.GetFileName(path.TargetPath)) ? Guid.NewGuid().ToString() : fileSystemService.GetFileName(path.TargetPath));
long totalBytes = sourceStream.Length;
int totalChunks = (totalBytes <= 0 || totalBytes <= 0) ? 1 : Convert.ToInt32(Math.Ceiling((double)totalBytes / (double)chunkSize));
for (int i = 0; i < totalChunks; i++) {
if (token.IsCancellationRequested) {
result.Status = TransferPathStatus.Canceled;
result.EndTime = DateTime.Now;
break;
}
byte[] fileData = new byte[readLength + 1];
sourceStream.Read(fileData, 0, readLength);
if (i == 0) {
IoResponse ioResponse = await fileIoService.BeginFillAsync(connectionInfo.WorkspaceId, fileData, path.TargetPath, fileName, token).ConfigureAwait(false);
if (!ioResponse.Success)
throw new IOException(ioResponse.ErrorMessage);
fileName = ioResponse.Filename;
} else {
IoResponse response = await fileIoService.FileFillAsync(connectionInfo.WorkspaceId, fileData, path.TargetPath, fileName, token).ConfigureAwait(false);
if (!response.Success) {
await fileIoService.RemoveFillAsync(connectionInfo.WorkspaceId, path.TargetPath, fileName, token).ConfigureAwait(false);
throw new IOException(response.ErrorMessage);
}
}
result.BytesTransferred += readLength;
result.Checksum = string.Empty;
if (progress != null && i > 0)
progress(result.BytesTransferred, totalBytes, i + 1, totalChunks);
readLength = ((sourceStream.Position + chunkSize > sourceStream.Length) ? Convert.ToInt32(sourceStream.Length - sourceStream.Position) : chunkSize);
}
result.EndTime = DateTime.Now;
result.Status = (token.IsCancellationRequested ? TransferPathStatus.Canceled : TransferPathStatus.Successful);
return result;
}
}
public async Task<TransferPathResult> DownloadAsync(TransferPath path, CancellationToken token)
{
if (path == (TransferPath)null)
throw new ArgumentNullException("path");
if (string.IsNullOrEmpty(path.TargetPath))
throw new ArgumentNullException("TargetPath");
TransferPathResult result = new TransferPathResult {
Path = path,
Status = TransferPathStatus.Started,
StartTime = new DateTime?(DateTime.Now)
};
if (token.IsCancellationRequested) {
result.Status = TransferPathStatus.Canceled;
result.EndTime = DateTime.Now;
return result;
}
string path2 = path.TargetFileName ?? path.SourcePath;
string targetFile = Path.Combine(path.TargetPath, path2);
if (createDirectories && !Directory.Exists(path.TargetPath))
Directory.CreateDirectory(path.TargetPath);
HttpTransferPathData data = HttpTransferPathData.GetData(path);
await fileIoService.DownloadFileAsync(targetFile, data, token).ConfigureAwait(false);
FileItem fileItem = fileSystemService.GetFileItem(targetFile);
result.BytesTransferred = fileItem.Length;
result.EndTime = DateTime.Now;
result.Status = (token.IsCancellationRequested ? TransferPathStatus.Canceled : TransferPathStatus.Successful);
return result;
}
public async Task<string> GetDiskSpaceReportAsync(int workspaceId, CancellationToken token)
{
StringBuilder report = new StringBuilder();
string[][] array = await fileIoService.GetDefaultRepositorySpaceReportAsync(workspaceId, token).ConfigureAwait(false);
if (array != null) {
string[][] array2 = array;
foreach (string[] array3 in array2) {
if (report.Length > 0)
report.AppendLine();
if (array3.Length > 1)
report.AppendFormat("{0}: {1}", array3[0], array3[1]);
}
}
return report.ToString();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!disposed) {
if (disposing) {
if (userManagerService != null)
userManagerService.Dispose();
if (fileIoService != null)
fileIoService.Dispose();
}
disposed = true;
}
}
}
}