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); }
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)); }
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; }
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)); } } }