Exemple #1
0
        public override async Task StartAsync(ManagedTaskProgress progress, CancellationToken cancellationToken = default)
        {
            progress.Report(50, 1, "Running data extract...");
            var downloadStream = await _downloadData.GetStream(cancellationToken);

            var filename = downloadStream.FileName;
            var stream   = downloadStream.Stream;

            progress.Report(100, 2, "Download ready...");

            await _sharedSettings.StartDataStream(_reference, stream, _downloadUrl, "file", filename, false, cancellationToken);

            var url = $"{_downloadUrl.Url}/download/{_reference}";

            var downloadMessage = new DownloadReadyMessage()
            {
                InstanceId    = _sharedSettings.InstanceId,
                SecurityToken = _sharedSettings.SecurityToken,
                ConnectionId  = _connectionId,
                Reference     = _reference,
                HubKey        = _hubKey,
                Url           = url
            };

            var returnValue = await _sharedSettings.PostAsync <DownloadReadyMessage, ReturnValue>("Remote/DownloadReady", downloadMessage, cancellationToken);

            if (!returnValue.Success)
            {
                throw new RemoteOperationException($"The data download did not completed.  {returnValue.Message}", returnValue.Exception);
            }
        }
Exemple #2
0
        public override async Task StartAsync(ManagedTaskProgress progress, CancellationToken cancellationToken = default)
        {
            progress.Report(50, 1, "Preparing files...");

            var downloadStream = await _connectionFlatFile.DownloadFiles(_flatFile, _path, _files, _files.Length > 1, cancellationToken);

            var filename = _files.Length == 1 ? _files[0] : _flatFile.Name + "_files.zip";

            progress.Report(100, 2, "Files ready for download...");

            await _sharedSettings.StartDataStream(_messageId, downloadStream, _downloadUrl, "file", filename, false, cancellationToken);

            var url = $"{_sharedSettings.RemoteSettings.Network.ProxyUrl}/download/{_messageId}";

            var downloadMessage = new DownloadReadyMessage()
            {
                InstanceId    = _sharedSettings.InstanceId,
                SecurityToken = _sharedSettings.SecurityToken,
                ConnectionId  = _connectionId,
                Reference     = _reference,
                HubKey        = _hubKey,
                Url           = url
            };

            var returnValue = await _sharedSettings.PostAsync <DownloadReadyMessage, ReturnValue>("Remote/DownloadReady", downloadMessage, cancellationToken);

            if (!returnValue.Success)
            {
                throw new RemoteOperationException($"The file download did not completed.  {returnValue.Message}", returnValue.Exception);
            }
        }
Exemple #3
0
        /// <summary>
        /// Processes a message from the webserver, and redirects to the appropriate method.
        /// </summary>
        /// <param name="remoteMessage"></param>
        /// <returns></returns>
        private async Task ProcessMessage(RemoteMessage remoteMessage)
        {
            var cancellationTokenSource = new CancellationTokenSource();
            var commandCancel           = cancellationTokenSource.Token;

            try
            {
                // var remoteMessage = Json.DeserializeObject<RemoteMessage>(message, TemporaryEncryptionKey);

                //if the success is false, then it is a dummy message returned through a long polling timeout, so just ignore.
                if (!remoteMessage.Success)
                {
                    return;
                }

                _logger.LogDebug($"Message received is command: {remoteMessage.Method}, messageId: {remoteMessage.MessageId}.");

                //JObject values = (JObject)command.Value;
                // if (!string.IsNullOrEmpty((string)command.Value))
                //     values = JObject.Parse((string)command.Value);

                var method = typeof(RemoteOperations).GetMethod(remoteMessage.Method);

                if (method == null)
                {
                    _logger.LogError(100, "Unknown method : " + remoteMessage.Method);
                    var error = new ReturnValue <object>(false, $"Unknown method: {remoteMessage.Method}.", null);
                    AddResponseMessage(remoteMessage.MessageId, error);
                    return;
                }

                if (remoteMessage.SecurityToken == _sharedSettings.SecurityToken)
                {
                    Stream stream;

                    // if method is a task, execute async
                    if (method.ReturnType == typeof(Task))
                    {
                        var task = (Task)method.Invoke(_remoteOperations, new object[] { remoteMessage, commandCancel });
                        if (task.IsFaulted)
                        {
                            throw task.Exception;
                        }
                        await task.ConfigureAwait(false);

                        return;

                        // if method is a void, execute sync
                    }
                    else if (method.ReturnType == typeof(void))
                    {
                        method.Invoke(_remoteOperations, new object[] { remoteMessage, commandCancel });
                        return;
                    }

                    // if method is a task with a return type, create a call back stream to execute
                    else if (method.ReturnType.BaseType == typeof(Task))
                    {
                        var args = method.ReturnType.GetGenericArguments();
                        if (args.Length > 0 && args[0].IsAssignableFrom(typeof(Stream)))
                        {
                            var task = (Task)method.Invoke(_remoteOperations, new object[] { remoteMessage, commandCancel });
                            if (task.IsFaulted)
                            {
                                throw task.Exception;
                            }
                            await task.ConfigureAwait(false);

                            var resultProperty = task.GetType().GetProperty("Result");
                            stream = (Stream)resultProperty.GetValue(task);
                        }
                        else
                        {
                            stream = new StreamAsyncAction <object>(async() =>
                            {
                                var task = (Task)method.Invoke(_remoteOperations, new object[] { remoteMessage, commandCancel });
                                if (task.IsFaulted)
                                {
                                    throw task.Exception;
                                }
                                await task.ConfigureAwait(false);
                                var property = task.GetType().GetProperty("Result");

                                if (property == null)
                                {
                                    throw new RemoteOperationException($"The method {method.Name} does not return a result.");
                                }

                                return(property.GetValue(task));
                            });
                        }

                        // if method is a stream, then start the stream.
                    }
                    else if (method.ReturnType.IsAssignableFrom(typeof(Stream)))
                    {
                        try
                        {
                            stream = (Stream)method.Invoke(_remoteOperations,
                                                           new object[] { remoteMessage, commandCancel });
                        }
                        catch (TargetInvocationException ex)
                        {
                            throw ex.InnerException ?? ex;
                        }
                    }

                    // other return types, execute sync.
                    else
                    {
                        try
                        {
                            stream = new StreamAction <object>(() =>
                                                               method.Invoke(_remoteOperations, new object[] { remoteMessage, commandCancel }));
                        }
                        catch (TargetInvocationException ex)
                        {
                            throw ex.InnerException ?? ex;
                        }
                    }

                    await _sharedSettings.StartDataStream(remoteMessage.MessageId, stream, remoteMessage.DownloadUrl, "json", "", false, commandCancel);
                }
                else
                {
                    throw new RemoteException($"The command {remoteMessage.Method} failed due to mismatching security tokens.");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(100, ex, "Unknown error processing incoming message: " + ex.Message);
                var error = new ReturnValue <object>(false, $"{ex.Message}", ex);

                // when error occurs, set local cache or send to proxy so message gets to client.
                if (remoteMessage.DownloadUrl.DownloadUrlType != EDownloadUrlType.Proxy)
                {
                    var stream = new StreamAction <ReturnValue>(() => error);
                    await _sharedSettings.StartDataStream(remoteMessage.MessageId, stream, remoteMessage.DownloadUrl, "json", "", true, commandCancel);

//
//                    _memoryCache.Set(remoteMessage.MessageId, stream, TimeSpan.FromSeconds(5));
                }
                else
                {
                    var result = new ReturnValue(false, ex.Message, ex);
                    await _sharedSettings.PostDirect($"{remoteMessage.DownloadUrl.Url}/error/{remoteMessage.MessageId}", result.Serialize(), commandCancel);
                }
            }
        }