<PackageReference Include="Relativity.Transfer.Client" Version="7.2.7" />

AsperaFaspService

using Aspera.Transfer; using Relativity.Transfer.Aspera.Resources; using Relativity.Transfer.Resources; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; namespace Relativity.Transfer.Aspera { internal class AsperaFaspService { private static readonly object SyncRoot = new object(); private readonly ITransferLog log; private readonly AsperaClientConfiguration configuration; private readonly IAsperaFaspProxy faspProxy; private readonly IFileSystemService fileSystemService; private int retryCount; public int RetryCount { get { lock (SyncRoot) { return retryCount; } } set { lock (SyncRoot) { retryCount = value; } } } public AsperaFaspService(ITransferLog log, AsperaClientConfiguration configuration, IAsperaFaspProxy proxy, IFileSystemService fileSystemService) { if (log == null) throw new ArgumentNullException("log"); if (configuration == null) throw new ArgumentNullException("configuration"); if (proxy == null) throw new ArgumentNullException("proxy"); if (fileSystemService == null) throw new ArgumentNullException("fileSystemService"); this.log = log; this.configuration = configuration; faspProxy = proxy; this.fileSystemService = fileSystemService; } public static string EncodeCookieString(string name, Guid cookie) { return (!string.IsNullOrWhiteSpace(name)) ? $"""{cookie}""{name}" : cookie.ToString(); } public static string EncodeCookieString(string name, Guid jobId, Guid cookie) { return $"{EncodeCookieString(name, cookie)}""{jobId}"; } public Guid CreateAsperaJob(ITransferRequest request, FileTransferListener listener) { if (request == null) throw new ArgumentNullException("request"); if (listener == null) throw new ArgumentNullException("listener"); faspProxy.SetupRuntime(); if (!request.ClientRequestId.HasValue) request.ClientRequestId = Guid.NewGuid(); if (!request.JobId.HasValue) request.JobId = Guid.NewGuid(); FileLocation source; FileLocation destination; if (request.Direction == TransferDirection.Upload) { source = new LocalFileLocation(); destination = CreateRemoteFileLocation(new TransferPath[0]); } else { source = CreateRemoteFileLocation(new TransferPath[0]); destination = new LocalFileLocation(); } XferParams xferParams = CreateTransferParameters(request.Name, request.JobId.Value, request.ClientRequestId.Value); JobOrder order = new JobOrder(source, destination, xferParams); return faspProxy.StartTransfer(order, request.JobId.Value, RetryCount, listener); } public void LockSession(Guid sessionId) { if (sessionId == Guid.Empty) throw new ArgumentException(AsperaStrings.SessionIdArgumentExceptionMessage, "sessionId"); faspProxy.LockPersistentSession(sessionId); } public void AddFile(Guid sessionId, TransferPath path) { if (sessionId == Guid.Empty) throw new ArgumentException(AsperaStrings.SessionIdArgumentExceptionMessage, "sessionId"); if (path == (TransferPath)null) throw new ArgumentNullException("path"); if (string.IsNullOrEmpty(path.SourcePath)) throw new ArgumentException(CoreStrings.SourcePathArgumentExceptionMessage, "path"); if (string.IsNullOrEmpty(path.TargetPath)) throw new ArgumentException(CoreStrings.TargetPathArgumentExceptionMessage, "path"); try { faspProxy.AddPersistentPath(sessionId, path); } catch (FaspManagerException innerException) { throw new TransferException(AsperaStrings.AddSourceExcpetionMessage, innerException); } } public bool JobExists(Guid sessionId) { if (sessionId == Guid.Empty) throw new ArgumentException(AsperaStrings.SessionIdArgumentExceptionMessage, "sessionId"); IEnumerable<Guid> sessionIds = faspProxy.GetSessionIds(); return sessionIds.Any((Guid x) => x == sessionId); } public void CancelJob(Guid sessionId, bool persist, FileTransferListener listener) { if (sessionId == Guid.Empty) throw new ArgumentException(AsperaStrings.SessionIdArgumentExceptionMessage, "sessionId"); IEnumerable<Guid> sessionIds = faspProxy.GetSessionIds(); if (!sessionIds.Any((Guid x) => x == sessionId)) log.LogInformation("The Aspera '{SessionId}' session cannot be cancelled because the job does not exist.", sessionId); else { log.LogInformation("Preparing to cancel the '{SessionId}' Aspera session.", sessionId); faspProxy.RemoveJobListener(sessionId, listener); faspProxy.CancelTransfer(sessionId, persist); faspProxy.RemoveSession(sessionId); log.LogInformation("Successfully cancelled the '{SessionId}' Aspera session.", sessionId); } } public void RemoveJob(Guid sessionId, FileTransferListener listener) { if (sessionId == Guid.Empty) throw new ArgumentException(AsperaStrings.SessionIdArgumentExceptionMessage, "sessionId"); IEnumerable<Guid> sessionIds = faspProxy.GetSessionIds(); if (!sessionIds.Any((Guid x) => x == sessionId)) log.LogInformation("The Aspera '{SessionId}' job cannot be removed because the job does not exist.", sessionId); else try { faspProxy.RemoveJobListener(sessionId, listener); } finally { faspProxy.RemoveSession(sessionId); } } private RemoteFileLocation CreateRemoteFileLocation(IEnumerable<TransferPath> paths) { RemoteFileLocation remoteFileLocation; try { AsperaCredential asperaCredential = new AsperaCredential(configuration.Credential); if (!string.IsNullOrEmpty(configuration.SshPrivateKeyFile)) { if (!fileSystemService.FileExists(configuration.SshPrivateKeyFile)) { string message = string.Format(CultureInfo.CurrentCulture, AsperaStrings.AsperaSshPrivateKeyFileNotFoundArgumentExceptionMessage, configuration.SshPrivateKeyFile); throw new TransferException(message, true); } if (string.IsNullOrEmpty(configuration.SecurityToken)) { string message2 = string.Format(CultureInfo.CurrentCulture, AsperaStrings.AsperaSecurityTokenArgumentExceptionMessage, Array.Empty<object>()); throw new TransferException(message2, true); } remoteFileLocation = new RemoteFileLocation(asperaCredential.Host.ToString(), asperaCredential.AccountUserName.UnprotectData(), configuration.SshPrivateKeyFile, configuration.SshPassphrase); } else remoteFileLocation = new RemoteFileLocation(asperaCredential.Host.ToString(), asperaCredential.AccountUserName.UnprotectData(), asperaCredential.AccountPassword.UnprotectData()); } catch (Exception ex) { throw new TransferException(ex.Message, true); } foreach (TransferPath path in paths) { if (string.IsNullOrEmpty(path.SourcePath)) throw new ArgumentException(AsperaStrings.AsperaTargetPathArgumentExceptionMessage, "paths"); if (string.IsNullOrEmpty(path.TargetFileName)) remoteFileLocation.addPath(path.SourcePath); else remoteFileLocation.addPath(path.SourcePath, path.TargetFileName); } return remoteFileLocation; } private XferParams CreateTransferParameters(string name, Guid jobId, Guid cookie) { string localLogDir = TransferHelper.CreateTransferLogDirectory(log, fileSystemService, configuration.TransferLogDirectory, "Aspera-Transfers"); string token = string.Empty; if (!string.IsNullOrEmpty(configuration.SecurityToken)) token = "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(configuration.SecurityToken)); XferParams xferParams = new XferParams { reportSkippedFiles = configuration.ReportNotOverriddenFiles, cookie = EncodeCookieString(name, jobId, cookie), createDirs = configuration.CreateDirectories, cipher = new Cipher?(TypeHelper.ParseEnum(configuration.EncryptionCipher, Cipher.AES_256, log)), httpFallback = null, localLogDir = localLogDir, minimumRateKbps = configuration.MinDataRateMbps * 1000, overwritePolicy = TypeHelper.ParseEnum(configuration.OverwritePolicy, OverwritePolicy.ALWAYS, log), partialFileSuffix = null, persist = true, policy = TypeHelper.ParseEnum(configuration.Policy, Policy.FAIR, log), preserveDates = configuration.PreserveDates, resumeCheck = new Resume?(TypeHelper.ParseEnum(configuration.ResumeCheck, Resume.OFF, log)), retryTimeoutS = Convert.ToInt32(configuration.HttpTimeoutSeconds), saveBeforeOverwriteEnabled = configuration.SaveBeforeOverwriteEnabled, targetRateKbps = configuration.TargetDataRateMbps * 1000, token = token, tcpPort = configuration.TcpPort, udpPort = configuration.UdpPortStartRange, datagramSize = configuration.DatagramSize }; log.LogInformation(xferParams.Dump(), Array.Empty<object>()); return xferParams; } } }