private async Task <Unit> HandleError(PowershellFailure failure, IOperationTaskMessage command)
        {
            await _bus.Publish(OperationTaskStatusEvent.Failed(command.OperationId, command.TaskId,
                                                               new ErrorData {
                ErrorMessage = failure.Message
            })).ConfigureAwait(false);

            return(Unit.Default);
        }
示例#2
0
        public Task FailOrRun <T>(OperationTaskStatusEvent <T> message, Func <Task> completedFunc) where T : OperationTaskCommand
        {
            if (message.OperationFailed)
            {
                return(Fail(message.GetMessage()));
            }

            return(completedFunc());
        }
示例#3
0
        public Task FailOrRun <T, TOpMessage>(OperationTaskStatusEvent <T> message, Func <TOpMessage, Task> completedFunc)
            where T : OperationTaskCommand
            where TOpMessage : class
        {
            if (message.OperationFailed)
            {
                return(Fail(message.GetMessage()));
            }

            return(completedFunc(message.GetMessage() as TOpMessage));
        }
示例#4
0
        public Task Handle(OperationTaskStatusEvent <PlaceVirtualMachineCommand> message)
        {
            return(FailOrRun <PlaceVirtualMachineCommand, PlaceVirtualMachineResult>(message, (r) =>
            {
                var convergeMessage = new ConvergeVirtualMachineCommand
                {
                    Config = Data.Config, AgentName = r.AgentName, OperationId = message.OperationId, TaskId = Guid.NewGuid()
                };

                return _taskDispatcher.Send(convergeMessage);
            }));
        }
示例#5
0
        public async Task Handle(OperationTaskStatusEvent message)
        {
            var op = await _dbContext.Operations.FindAsync(message.OperationId).ConfigureAwait(false);

            var task = await _dbContext.OperationTasks.FindAsync(message.TaskId).ConfigureAwait(false);

            if (op == null || task == null)
            {
                return;
            }

            if (task.Status == OperationTaskStatus.Queued || task.Status == OperationTaskStatus.Running)
            {
                var taskCommandTypeName = Data.Tasks[message.TaskId];

                var genericType        = typeof(OperationTaskStatusEvent <>);
                var wrappedCommandType = genericType.MakeGenericType(Type.GetType(taskCommandTypeName));
                var commandInstance    = Activator.CreateInstance(wrappedCommandType, message);
                await _bus.SendLocal(commandInstance);
            }

            task.Status = message.OperationFailed ? OperationTaskStatus.Failed : OperationTaskStatus.Completed;

            if (message.TaskId == Data.PrimaryTaskId)
            {
                op.Status = message.OperationFailed ? OperationStatus.Failed : OperationStatus.Completed;
                string errorMessage = null;
                if (message.GetMessage() is ErrorData errorData)
                {
                    errorMessage = errorData.ErrorMessage;
                }

                op.StatusMessage = string.IsNullOrWhiteSpace(errorMessage) ? op.Status.ToString() : errorMessage;
                MarkAsComplete();
            }


            await _dbContext.SaveChangesAsync();
        }
        public async Task Handle(AcceptedOperationTask <T> message)
        {
            var command = message.Command;

            var result = await GetVmInfo(command.MachineId, _engine)
                         .BindAsync(optVmInfo =>
            {
                return(optVmInfo.MatchAsync(
                           Some: s => HandleCommand(s, command, _engine),
                           None: () => Unit.Default));
            }).ConfigureAwait(false);

            await result.MatchAsync(
                LeftAsync : f => HandleError(f, command),
                RightAsync : async _ =>
            {
                await _bus.Publish(OperationTaskStatusEvent.Completed(command.OperationId, command.TaskId))
                .ConfigureAwait(false);

                return(Unit.Default);
            }).ConfigureAwait(false);
        }
        public Task Handle(AcceptedOperationTask <ConvergeVirtualMachineCommand> message)
        {
            var command = message.Command;
            var config  = command.Config;

            _operationId = command.OperationId;
            _taskId      = command.TaskId;

            var hostSettings = GetHostSettings();

            var chain =

                from normalizedVMConfig in Converge.NormalizeMachineConfig(config, _engine, ProgressMessage)
                from vmList in GetVmInfo(normalizedVMConfig.Id, _engine)
                from optionalVmInfo in EnsureUnique(vmList, normalizedVMConfig.Id)

                from currentStorageSettings in Storage.DetectVMStorageSettings(optionalVmInfo, hostSettings, ProgressMessage)
                from plannedStorageSettings in Storage.PlanVMStorageSettings(normalizedVMConfig, currentStorageSettings, hostSettings, GenerateId)

                from vmInfoCreated in EnsureCreated(optionalVmInfo, config, plannedStorageSettings, _engine)
                from _ in AttachToOperation(vmInfoCreated, _bus, command.OperationId)
                from vmInfo in EnsureNameConsistent(vmInfoCreated, config, _engine)

                from vmInfoConverged in ConvergeVm(vmInfo, config, plannedStorageSettings, hostSettings, _engine)
                select vmInfoConverged;

            return(chain.ToAsync().MatchAsync(
                       LeftAsync: HandleError,
                       RightAsync: async vmInfo2 =>
            {
                await ProgressMessage($"Virtual machine '{vmInfo2.Value.Name}' has been converged.").ConfigureAwait(false);

                return await _bus.Publish(OperationTaskStatusEvent.Completed(_operationId, _taskId))
                .ToUnit().ConfigureAwait(false);
            }));
        }
示例#8
0
        public async Task Handle(CreateNewOperationTaskCommand message)
        {
            var command = JsonConvert.DeserializeObject(message.CommandData, Type.GetType(message.CommandType));

            var op = await _dbContext.Operations.FindAsync(message.OperationId).ConfigureAwait(false);

            if (op == null)
            {
                MarkAsComplete();
                return;
            }

            var task = await _dbContext.OperationTasks.FindAsync(message.TaskId).ConfigureAwait(false);

            if (task == null)
            {
                task = new OperationTask
                {
                    Id        = message.TaskId,
                    Operation = op,
                };

                _dbContext.Add(task);
            }

            task.Name = command.GetType().Name;
            Data.Tasks.Add(message.TaskId, command.GetType().AssemblyQualifiedName);

            await _dbContext.SaveChangesAsync().ConfigureAwait(false);

            var sendCommandAttribute = command.GetType().GetCustomAttribute <SendMessageToAttribute>();

            switch (sendCommandAttribute.Recipient)
            {
            case MessageRecipient.VMHostAgent:
            {
                switch (command)
                {
                case IMachineCommand machineCommand:
                {
                    var machine = await _dbContext.Machines.FindAsync(machineCommand.MachineId).ConfigureAwait(false);

                    if (machine == null)
                    {
                        if (command.GetType().GetCustomAttribute(typeof(MachineMayNotExistsAttribute)) != null)
                        {
                            await Handle(OperationTaskStatusEvent.Completed(message.OperationId, message.TaskId));
                        }
                        else
                        {
                            await Handle(OperationTaskStatusEvent.Failed(message.OperationId, message.TaskId,
                                                                         new ErrorData {
                                        ErrorMessage = "Machine not found"
                                    }));
                        }

                        return;
                    }

                    await _bus.Advanced.Routing.Send($"{QueueNames.VMHostAgent}.{machine.AgentName}", command)
                    .ConfigureAwait(false);

                    return;
                }

                case IHostAgentCommand agentCommand:
                    await _bus.Advanced.Routing.Send($"{QueueNames.VMHostAgent}.{agentCommand.AgentName}", command)
                    .ConfigureAwait(false);

                    return;

                default:
                    throw new InvalidDataException($"Don't know how to route operation task command of type {command.GetType()}");
                }
            }

            case MessageRecipient.Controllers:
                await _bus.Send(command);

                return;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
示例#9
0
 public Task Handle(OperationTaskStatusEvent <ConvergeVirtualMachineCommand> message)
 {
     return(FailOrRun(message, () => Complete()));
 }
示例#10
0
 public Task Complete(object message = null)
 {
     return(Bus.SendLocal(OperationTaskStatusEvent.Completed(Data.OperationId, Data.InitiatingTaskId, message)));
 }
示例#11
0
 public Task Handle(OperationTaskStatusEvent <TMessage> message)
 {
     return(message.OperationFailed ? InitiatingTaskFailed() : InitiatingTaskCompleted());
 }