private async STT.Task <Data.TaskStatus> ProcessTaskAsync(TaskEntity taskToExecute, List <ResultEntity> resultEntityList, SteamfitterContext steamfitterContext, CancellationToken ct) { var overallStatus = Data.TaskStatus.succeeded; var tasks = new List <STT.Task <string> >(); var xref = new Dictionary <int, ResultEntity>(); foreach (var resultEntity in resultEntityList) { resultEntity.InputString = resultEntity.InputString.Replace("{moid}", resultEntity.VmId.ToString()); resultEntity.InputString = resultEntity.InputString.Replace("{VmName}", resultEntity.VmName); if (resultEntity.VmId != null && resultEntity.VmName == "") { resultEntity.VmName = _stackStormService.GetVmName((Guid)resultEntity.VmId); } resultEntity.Status = TaskStatus.pending; resultEntity.StatusDate = DateTime.UtcNow; // if no expiration is set, us the maximum allowed by the TaskProcessMaxWaitSeconds setting resultEntity.ExpirationSeconds = resultEntity.ExpirationSeconds <= 0 ? _vmTaskProcessingOptions.CurrentValue.TaskProcessMaxWaitSeconds : resultEntity.ExpirationSeconds; var task = await RunTask(taskToExecute, resultEntity, ct); tasks.Add(task); xref[task.Id] = resultEntity; await steamfitterContext.SaveChangesAsync(); _engineHub.Clients.Group(EngineGroups.SystemGroup).SendAsync(EngineMethods.ResultUpdated, _mapper.Map <ViewModels.Result>(resultEntity)); } foreach (var bucket in AsCompletedBuckets(tasks)) { try { var task = await bucket; var resultEntity = xref[task.Id]; resultEntity.ActualOutput = task.Result == null ? "" : task.Result.ToString(); resultEntity.Status = ProcessResult(resultEntity, ct); resultEntity.StatusDate = DateTime.UtcNow; if (resultEntity.Status != Data.TaskStatus.succeeded) { if (overallStatus != Data.TaskStatus.failed) { overallStatus = resultEntity.Status; } } await steamfitterContext.SaveChangesAsync(); _engineHub.Clients.Group(EngineGroups.SystemGroup).SendAsync(EngineMethods.ResultUpdated, _mapper.Map <ViewModels.Result>(resultEntity)); } catch (OperationCanceledException) { _logger.LogInformation("the executing task was cancelled"); } catch (Exception ex) { _logger.LogInformation(ex, "the executing task caused an exception"); } } return(overallStatus); }
private async Task <Data.TaskStatus> ExecuteStackstormTaskAsync(DispatchTaskEntity dispatchTaskToExecute, List <DispatchTaskResultEntity> resultEntityList, CancellationToken ct) { var overallStatus = Data.TaskStatus.succeeded; foreach (var resultEntity in resultEntityList) { Task <string> task = null; resultEntity.InputString = resultEntity.InputString.Replace("VmGuid", "Moid").Replace("{moid}", resultEntity.VmId.ToString()); resultEntity.VmName = _stackStormService.GetVmName((Guid)resultEntity.VmId); switch (dispatchTaskToExecute.Action) { case TaskAction.guest_file_read: { task = Task.Run(() => _stackStormService.GuestReadFile(resultEntity.InputString)); break; } case TaskAction.guest_process_run: { task = Task.Run(() => _stackStormService.GuestCommand(resultEntity.InputString)); break; } case TaskAction.vm_hw_power_on: { task = Task.Run(() => _stackStormService.VmPowerOn(resultEntity.InputString)); break; } case TaskAction.vm_hw_power_off: { task = Task.Run(() => _stackStormService.VmPowerOff(resultEntity.InputString)); break; } case TaskAction.vm_create_from_template: { task = Task.Run(() => _stackStormService.CreateVmFromTemplate(resultEntity.InputString)); break; } case TaskAction.vm_hw_remove: { task = Task.Run(() => _stackStormService.VmRemove(resultEntity.InputString)); break; } default: { var message = $"Task Action {dispatchTaskToExecute.Action} has not been implemented."; _logger.LogError(message); resultEntity.Status = Data.TaskStatus.failed; resultEntity.StatusDate = DateTime.UtcNow; break; } } if (task.Wait(TimeSpan.FromSeconds(resultEntity.ExpirationSeconds))) { resultEntity.ActualOutput = task.Result.ToString(); resultEntity.Status = ProcessDispatchTaskResult(resultEntity, ct); } else { resultEntity.ActualOutput = task.Result.ToString(); resultEntity.Status = Data.TaskStatus.expired; } resultEntity.StatusDate = DateTime.UtcNow; if (resultEntity.Status != Data.TaskStatus.succeeded) { if (overallStatus != Data.TaskStatus.failed) { overallStatus = resultEntity.Status; } } } await _context.SaveChangesAsync(); return(overallStatus); }