Beispiel #1
0
 private string GetDirectory(TaskReference task)
 {
     ArgUtil.NotEmpty(task.Id, nameof(task.Id));
     ArgUtil.NotNull(task.Name, nameof(task.Name));
     ArgUtil.NotNullOrEmpty(task.Version, nameof(task.Version));
     return Path.Combine(
         IOUtil.GetTasksPath(HostContext),
         $"{task.Name}_{task.Id}",
         task.Version);
 }
Beispiel #2
0
        private async Task DownloadAsync(IExecutionContext executionContext, TaskReference task)
        {
            Trace.Entering();
            ArgUtil.NotNull(executionContext, nameof(executionContext));
            ArgUtil.NotNull(task, nameof(task));
            ArgUtil.NotNullOrEmpty(task.Version, nameof(task.Version));
            var taskServer = HostContext.GetService<ITaskServer>();

            // first check to see if we already have the task
            string destDirectory = GetDirectory(task);
            Trace.Info($"Ensuring task exists: ID '{task.Id}', version '{task.Version}', name '{task.Name}', directory '{destDirectory}'.");
            if (Directory.Exists(destDirectory))
            {
                Trace.Info("Task already downloaded.");
                return;
            }

            Trace.Info("Getting task.");
            string zipFile;
            var version = new TaskVersion(task.Version);

            //download and extract task in a temp folder and rename it on success
            string tempDirectory = Path.Combine(IOUtil.GetTasksPath(HostContext), "_temp_" + Guid.NewGuid());
            try
            {
                Directory.CreateDirectory(tempDirectory);
                zipFile = Path.Combine(tempDirectory, string.Format("{0}.zip", Guid.NewGuid()));
                //open zip stream in async mode
                using (FileStream fs = new FileStream(zipFile, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true))
                {
                    using (Stream result = await taskServer.GetTaskContentZipAsync(task.Id, version, executionContext.CancellationToken))
                    {
                        //81920 is the default used by System.IO.Stream.CopyTo and is under the large object heap threshold (85k). 
                        await result.CopyToAsync(fs, 81920, executionContext.CancellationToken);
                        await fs.FlushAsync(executionContext.CancellationToken);
                    }
                }

                ZipFile.ExtractToDirectory(zipFile, tempDirectory);
                File.Delete(zipFile);
                Directory.CreateDirectory(Path.GetDirectoryName(destDirectory));
                Directory.Move(tempDirectory, destDirectory);
                Trace.Info("Finished getting task.");
            }
            finally
            {
                try
                {
                    //if the temp folder wasn't moved -> wipe it
                    if (Directory.Exists(tempDirectory))
                    {
                        Trace.Verbose("Deleting task temp folder: {0}", tempDirectory);
                        IOUtil.DeleteDirectory(tempDirectory, CancellationToken.None); // Don't cancel this cleanup and should be pretty fast.
                    }
                }
                catch (Exception ex)
                {
                    //it is not critical if we fail to delete the temp folder
                    Trace.Warning("Failed to delete temp folder '{0}'. Exception: {1}", tempDirectory, ex);
                    executionContext.Warning(StringUtil.Loc("FailedDeletingTempDirectory0Message1", tempDirectory, ex.Message));
                }
            }
        }
        public async Task <HttpResponseMessage> TerminateRequest([FromBody] Guid id)
        {
            var request = await DataContext.Requests.FindAsync(id);

            request.CancelledByID = Identity.ID;
            request.CancelledOn   = DateTime.UtcNow;

            var newStatus = (int)request.Status < 400 ? RequestStatuses.TerminatedPriorToDistribution : DTO.Enums.RequestStatuses.Cancelled;


            var completedRoutingStatuses = new[] { RoutingStatus.RequestRejected, RoutingStatus.Canceled, RoutingStatus.ResponseRejectedAfterUpload, RoutingStatus.ResponseRejectedBeforeUpload, RoutingStatus.Failed, RoutingStatus.Completed };
            var rdms = DataContext.RequestDataMarts.Where(s => s.RequestID == id);

            foreach (var rdm in rdms)
            {
                if (completedRoutingStatuses.Contains(rdm.Status) == false)
                {
                    rdm.Status = DTO.Enums.RoutingStatus.Canceled;
                }
            }

            try
            {
                await DataContext.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message, ex);
                return(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex));
            }

            await DataContext.Entry(request).ReloadAsync();

            request.Status = newStatus;
            await DataContext.SaveChangesAsync();

            //have to explicitly change the request status since the property is marked as computed for EF.
            await DataContext.Database.ExecuteSqlCommandAsync("UPDATE Requests SET Status = @status WHERE ID = @ID", new System.Data.SqlClient.SqlParameter("@status", (int)newStatus), new System.Data.SqlClient.SqlParameter("@ID", request.ID));

            //cancel any outstanding tasks associated with the request.
            var incompleteTaskStatuses            = new[] { TaskStatuses.Complete, TaskStatuses.Cancelled };
            IEnumerable <PmnTask> incompleteTasks = await DataContext.Actions.Where(t => t.References.Any(r => r.ItemID == id) && t.Status != TaskStatuses.Complete && t.Status != TaskStatuses.Cancelled).ToArrayAsync();

            foreach (var incompleteTask in incompleteTasks)
            {
                incompleteTask.Status          = DTO.Enums.TaskStatuses.Cancelled;
                incompleteTask.EndOn           = DateTime.UtcNow;
                incompleteTask.PercentComplete = 100d;
            }
            await DataContext.SaveChangesAsync();

            await DataContext.Entry(request).ReloadAsync();

            //This has to be down here or the task can't be found to update.
            request.WorkFlowActivityID = Guid.Parse("CC2E0001-9B99-4C67-8DED-A3B600E1C696");

            var ta = new PmnTask
            {
                CreatedOn          = DateTime.UtcNow,
                PercentComplete    = 100,
                Priority           = DTO.Enums.Priorities.High,
                StartOn            = DateTime.UtcNow,
                EndOn              = DateTime.UtcNow,
                Status             = DTO.Enums.TaskStatuses.Complete,
                Subject            = "Request Terminated",
                Type               = DTO.Enums.TaskTypes.Task,
                WorkflowActivityID = request.WorkFlowActivityID
            };

            DataContext.Actions.Add(ta);

            var reference = new TaskReference
            {
                ItemID = request.ID,
                TaskID = ta.ID,
                Type   = DTO.Enums.TaskItemTypes.Request
            };

            DataContext.ActionReferences.Add(reference);

            await DataContext.SaveChangesAsync();

            try
            {
                await DataContext.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message, ex);
                return(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex));
            }


            return(Request.CreateResponse(HttpStatusCode.OK));
        }
Beispiel #4
0
        public Definition Load(TaskReference task)
        {
            // Validate args.
            Trace.Entering();
            ArgUtil.NotNull(task, nameof(task));

            // Initialize the definition wrapper object.
            var definition = new Definition() { Directory = GetDirectory(task) };

            // Deserialize the JSON.
            string file = Path.Combine(definition.Directory, Constants.Path.TaskJsonFile);
            Trace.Info($"Loading task definition '{file}'.");
            string json = File.ReadAllText(file);
            definition.Data = JsonConvert.DeserializeObject<DefinitionData>(json);

            // Replace the macros within the handler data sections.
            foreach (HandlerData handlerData in (definition.Data?.Execution?.All as IEnumerable<HandlerData> ?? new HandlerData[0]))
            {
                handlerData?.ReplaceMacros(HostContext, definition);
            }

            return definition;
        }
Beispiel #5
0
        private async Task DownloadAsync(IExecutionContext executionContext, TaskReference task)
        {
            Trace.Entering();
            ArgUtil.NotNull(executionContext, nameof(executionContext));
            ArgUtil.NotNull(task, nameof(task));
            ArgUtil.NotNullOrEmpty(task.Version, nameof(task.Version));
            var taskServer = HostContext.GetService <ITaskServer>();

            // first check to see if we already have the task
            string destDirectory = GetDirectory(task);

            Trace.Info($"Ensuring task exists: ID '{task.Id}', version '{task.Version}', name '{task.Name}', directory '{destDirectory}'.");
            if (Directory.Exists(destDirectory))
            {
                Trace.Info("Task already downloaded.");
                return;
            }

            Trace.Info("Getting task.");
            string zipFile;
            var    version = new TaskVersion(task.Version);

            //download and extract task in a temp folder and rename it on success
            string tempDirectory = Path.Combine(IOUtil.GetTasksPath(HostContext), "_temp_" + Guid.NewGuid());

            try
            {
                Directory.CreateDirectory(tempDirectory);
                zipFile = Path.Combine(tempDirectory, string.Format("{0}.zip", Guid.NewGuid()));
                //open zip stream in async mode
                using (FileStream fs = new FileStream(zipFile, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true))
                {
                    using (Stream result = await taskServer.GetTaskContentZipAsync(task.Id, version, executionContext.CancellationToken))
                    {
                        //81920 is the default used by System.IO.Stream.CopyTo and is under the large object heap threshold (85k).
                        await result.CopyToAsync(fs, 81920, executionContext.CancellationToken);

                        await fs.FlushAsync(executionContext.CancellationToken);
                    }
                }

                ZipFile.ExtractToDirectory(zipFile, tempDirectory);
                File.Delete(zipFile);
                Directory.CreateDirectory(Path.GetDirectoryName(destDirectory));
                Directory.Move(tempDirectory, destDirectory);
                Trace.Info("Finished getting task.");
            }
            finally
            {
                try
                {
                    //if the temp folder wasn't moved -> wipe it
                    if (Directory.Exists(tempDirectory))
                    {
                        Trace.Verbose("Deleting task temp folder: {0}", tempDirectory);
                        IOUtil.DeleteDirectory(tempDirectory, CancellationToken.None); // Don't cancel this cleanup and should be pretty fast.
                    }
                }
                catch (Exception ex)
                {
                    //it is not critical if we fail to delete the temp folder
                    Trace.Warning("Failed to delete temp folder '{0}'. Exception: {1}", tempDirectory, ex);
                    executionContext.Warning(StringUtil.Loc("FailedDeletingTempDirectory0Message1", tempDirectory, ex.Message));
                }
            }
        }