/// <inheritdoc/> protected override async Task <TaskModel> ProtectedHandleAsync(CreateTaskCommand request, CancellationToken cancellationToken) { var principal = PrincipalProvider.GetPrincipal(); if (principal == null) { throw new ForbiddenException("Not authenticated"); } if (request.Command.CommandType != CommandType.ProcessObjectCommand || request.Command.GetType() != typeof(ProcessObjectCommand)) { throw new NotSupportedException("The provided command type is not supported."); } var command = request.Command as ProcessObjectCommand; Guid objectId = Guid.Parse(command.Id); var objectOwnerId = Context.ObjectRepository.GetQuery(e => e.Id == objectId).Select(e => e.UserId).FirstOrDefault(); if (!AuthService.IsAuthorized(objectOwnerId)) { throw new ForbiddenException("Not authorized"); } processMutex = new Mutex(false, this.GetMethodName()); return(await processMutex.Execute(new TimeSpan(0, 0, 2), async() => { var activeCount = await Context.TaskRepository.CountAsync(e => e.ObjectId == objectId && (e.Status == (int)Domain.Enums.TaskStatus.Created || e.Status == (int)Domain.Enums.TaskStatus.Queued || e.Status == (int)Domain.Enums.TaskStatus.Processing)); if (activeCount > 0) { throw new AmiException("The specified object is already actively being processed."); } var position = await Context.TaskRepository.CountAsync(e => e.Status == (int)Domain.Enums.TaskStatus.Queued); var entity = new TaskEntity() { Id = idGenerator.GenerateId(), CreatedDate = DateTime.UtcNow, ModifiedDate = DateTime.UtcNow, QueuedDate = DateTime.UtcNow, Status = (int)Domain.Enums.TaskStatus.Queued, Progress = 0, Position = position, CommandType = (int)CommandType.ProcessObjectCommand, CommandSerialized = serializer.Serialize(command), UserId = principal.Identity.Name, ObjectId = objectId }; Context.TaskRepository.Add(entity); await Context.SaveChangesAsync(cancellationToken); var result = await mediator.Send(new GetByIdQuery() { Id = entity.Id.ToString() }); if (result == null) { throw new UnexpectedNullException($"The task '{entity.Id.ToString()}' could not be retrieved after creating it."); } if (entity.Object != null) { await Events.CreateAsync(entity.Object.UserId, EventType.TaskCreated, result, cancellationToken); await Gateway.NotifyGroupsAsync(entity.Object.UserId, EventType.TaskCreated, result, cancellationToken); } backgroundService.EnqueueTask(result.Id); return result; })); }