using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.Core; using Tango.Core.DI; using Tango.Core.IO; using Tango.Integration.ExternalBridge; using Tango.PPC.Common.ExternalBridge; using Tango.PPC.Shared.RemoteJobUpload; using Tango.Settings; namespace Tango.PPC.Common.RemoteJobUpload { [TangoCreateWhenRegistered] public class DefaultRemoteJobUploadService : ExtendedObject, IRemoteJobUploadService, IExternalBridgeRequestHandler { private class PendingJobUpload { public String ID { get; set; } public String Name { get; set; } public TemporaryFile File { get; set; } public RemoteJobUploadType Type { get; set; } } private PPCSettings _settings; private TemporaryFolder _jobsFolder; private List _jobs; public event EventHandler JobReceived; public bool Enabled { get { return _settings.EnableRemoteJobUpload; } set { _settings.EnableRemoteJobUpload = value; } } public DefaultRemoteJobUploadService(IPPCExternalBridgeService externalBridge) { try { _jobs = new List(); externalBridge.RegisterRequestHandler(this); _settings = SettingsManager.Default.GetOrCreate(); _jobsFolder = TemporaryManager.CreateFolder(); } catch (Exception ex) { LogManager.Log(ex, "Error initializing the remote job upload service."); Enabled = false; } } [ExternalBridgeRequestHandlerMethod(typeof(RemoteJobUploadRequest), RequestHandlerLoggingMode.LogRequestNameAndContent)] public async Task OnRemoteJobUploadRequest(RemoteJobUploadRequest request, String token, ExternalBridgeReceiver receiver) { this.ThrowIfDisabled(); PendingJobUpload job = new PendingJobUpload(); job.ID = Guid.NewGuid().ToString(); job.Name = request.Name; job.File = _jobsFolder.CreateImaginaryFile(); job.Type = request.Type; _jobs.Add(job); await receiver.SendGenericResponse(new RemoteJobUploadResponse() { TargetFilePath = job.File.Path, ID = job.ID }, token); } [ExternalBridgeRequestHandlerMethod(typeof(RemoteJobUploadCompletedRequest), RequestHandlerLoggingMode.LogRequestNameAndContent)] public async Task OnRemoteJobUploadCompletedRequest(RemoteJobUploadCompletedRequest request, String token, ExternalBridgeReceiver receiver) { var completion = new TaskCompletionSource(); var job = _jobs.SingleOrDefault(x => x.ID == request.ID); if (job == null) { throw new FileNotFoundException("The specified job id could not be found."); } _jobs.Remove(job); JobReceived?.Invoke(this, new RemoteJobReceivedEventArgs(async () => { job.File.Delete(); await receiver.SendGenericResponse(new RemoteJobUploadCompletedResponse(), token); completion.SetResult(true); }, async (error) => { job.File.Delete(); await receiver.SendGenericResponse(new RemoteJobUploadCompletedResponse() { Error = error }, token); completion.SetResult(true); }) { Type = job.Type, FilePath = job.File.Path, Name = job.Name }); await completion.Task; } public void OnReceiverDisconnected(ExternalBridgeReceiver receiver) { } } }