public async Task <LabelModel> UpdateLabelAsync(LabelModel updatingLabel)
        {
            LabelModel currentLabel = await _labelsRepository.GetLabelByIdAsync(updatingLabel.Id);

            if (currentLabel == null)
            {
                throw new NotFoundException($"Label with id = {updatingLabel.Id} not found");
            }

            if (currentLabel.Version != updatingLabel.Version)
            {
                throw new VersionsNotMatchException();
            }

            var outboxMessage = OutboxMessageModel.Create(
                new LabelCreatedUpdatedMessage
            {
                LabelId  = updatingLabel.Id,
                OldTitle = currentLabel.Title,
                Title    = updatingLabel.Title,
                Color    = updatingLabel.Color
            }, Topics.Labels, MessageActions.Updated);

            return(await _labelsRepository.UpdateLabelAsync(updatingLabel, outboxMessage));
        }
Example #2
0
        protected override async Task RollbackTransactionInternalAsync(TransactionBase transaction)
        {
            Console.WriteLine("Rollback started");

            var moveTransaction = MoveTaskTransaction.CreateFromBase(transaction);

            if (moveTransaction.MovedMembers.IsNullOrEmpty())
            {
                Console.WriteLine("Nothing to rollback");
                return;
            }

            string projectId = moveTransaction.ProjectId;

            var projectMembersById = (await _projectMembersRepository.GetProjectsMembersAsync(projectId: projectId)).ToDictionary(m => m.UserId);

            foreach (var movedMember in moveTransaction.MovedMembers)
            {
                var member = projectMembersById[movedMember];

                var outboxMessage = OutboxMessageModel.Create(
                    new ProjectMemberDeletedMessage
                {
                    Username     = member.Username,
                    UserId       = member.UserId,
                    ProjectId    = projectId,
                    ProjectTitle = member.ProjectTitle
                }, Topics.ProjectMembers, MessageActions.Deleted);

                await _projectMembersRepository.DeleteMemberFromProjectAsync(projectId, movedMember, outboxMessage);
            }

            Console.WriteLine("Rollback completed");
        }
        private Task HandleMembersMovedAsync(TransactionBase transaction, BaseTransactionMessage message, TransactionsRepository repository)
        {
            var membersMovedMesasge = message as MoveTaskMembersMovedMessage;

            if (transaction == null)
            {
                Console.WriteLine($"Transaction for moved task members not found");
                return(Task.CompletedTask);
            }

            var moveTaskTransaction = MoveTaskTransaction.CreateFromBase(transaction);

            moveTaskTransaction.AreMembersPrepared = true;
            moveTaskTransaction.Message            = "Handle task hours with new project";

            var outboxMessage = OutboxMessageModel.Create(
                new MoveTaskHandleHoursMessage()
            {
                TransactionId = transaction.Id,
                ProjectId     = moveTaskTransaction.ProjectId,
                TaskId        = moveTaskTransaction.ObjectId
            }, Topics.Tasks, TransactionMessageActions.MoveTask_HandleHoursRequested);

            return(repository.CreateOrUpdateTransactionAsync(moveTaskTransaction, outboxMessage));
        }
Example #4
0
        public async Task <ProjectModel> CreateProjectAsync(ProjectModel newProject, string requestId)
        {
            if (!(await CheckAndSaveRequestIdAsync(requestId)))
            {
                throw new AlreadyHandledException();
            }

            try
            {
                newProject.Init();

                var outboxMessage = OutboxMessageModel.Create(
                    new ProjectCreatedUpdatedMessage
                {
                    ProjectId = newProject.Id,
                    Title     = newProject.Title
                }, Topics.Projects, MessageActions.Created);

                return(await _projectsRepository.CreateProjectAsync(newProject, outboxMessage));
            }
            catch (Exception)
            {
                //rollback request id
                await _requestsRepository.DeleteRequestIdAsync(requestId);

                throw;
            }
        }
        public async Task <LabelModel> CreateLabelAsync(LabelModel newLabel, string requestId)
        {
            if (!(await CheckAndSaveRequestIdAsync(requestId)))
            {
                throw new AlreadyHandledException();
            }

            try
            {
                newLabel.Init();

                var outboxMessage = OutboxMessageModel.Create(
                    new LabelCreatedUpdatedMessage
                {
                    LabelId = newLabel.Id,
                    Title   = newLabel.Title,
                    Color   = newLabel.Color
                }, Topics.Labels, MessageActions.Created);

                return(await _labelsRepository.CreateLabelAsync(newLabel, outboxMessage));
            }
            catch (Exception)
            {
                //rollback request id
                await _requestsRepository.DeleteRequestIdAsync(requestId);

                throw;
            }
        }
        internal async Task <UserModel> UpdateUserAsync(UserModel updatingUser)
        {
            var curentUser = await _repository.GetUserAsync(updatingUser.Id);

            if (curentUser == null)
            {
                throw new NotFoundException($"User with id {updatingUser.Id} not found");
            }

            if (curentUser.Version != updatingUser.Version)
            {
                throw new VersionsNotMatchException();
            }

            updatingUser.Version = curentUser.Version + 1;

            var message = OutboxMessageModel.Create(
                new UserCreatedUpdatedMessage
            {
                UserId   = updatingUser.Id,
                Username = updatingUser.Username
            }, Topics.Users, MessageActions.Updated
                );

            var updatedUser = await _repository.UpdateUserAsync(updatingUser, message);

            return(updatedUser);
        }
        public async Task UpdateProjectMebmerRoleAsync(ProjectMemberModel updatingMember)
        {
            ProjectMemberModel currentMember = await _projectMembersRepository
                                               .GetProjectMemberAsync(updatingMember.ProjectId, updatingMember.UserId);

            if (currentMember == null)
            {
                throw new NotFoundException($"User with id = {updatingMember.UserId} not found in project with id {updatingMember.ProjectId}");
            }

            (string projectTitle, string username) = await EnsureProjectAndUserExistAsync(updatingMember.ProjectId, updatingMember.UserId);

            var outboxMessage = OutboxMessageModel.Create(
                new ProjectMemberCreatedUpdatedMessage
            {
                ProjectId    = updatingMember.ProjectId,
                ProjectTitle = projectTitle,
                UserId       = updatingMember.UserId,
                Username     = username,
                Role         = updatingMember.Role
            }, Topics.ProjectMembers, MessageActions.Updated
                );

            await _projectMembersRepository.UpdateProjectMemberAsync(updatingMember, outboxMessage);
        }
        private async Task <string> UpdateHoursWithNewProjectAsync(string messageString)
        {
            Console.WriteLine("Prepare hours stage started");
            MoveTaskHandleHoursMessage message = JsonConvert.DeserializeObject <MoveTaskHandleHoursMessage>(messageString);

            string transactionId = message.TransactionId;
            var    transaction   = await _transactionsRepository.GetTransactionAsync(transactionId);

            if (transaction != null && transaction.State == TransactionStates.Denied)
            {
                return($"Transaction {transactionId} already denied");
            }

            var moveTaskTransaction = transaction == null
                ? MoveTaskTransaction.Create(transactionId, message.TaskId, message.ProjectId)
                : MoveTaskTransaction.CreateFromBase(transaction);

            moveTaskTransaction.State = TransactionStates.Processing;

            string projectTitle = "undefined";
            string taskId       = message.TaskId;
            var    task         = await _tasksRepository.GetTaskAsync(taskId);

            if (task != null)
            {
                string projectId = task.ProjectId;
                var    project   = await _projectsRepository.GetProjectAsync(projectId);

                projectTitle = project?.Title;
            }

            string postfix = $"(from {projectTitle})";

            moveTaskTransaction.AppliedPostfix = postfix;

            var taskWorkingHours = (await _workingHoursRepository.GetProjectTaskMemberWorkingHoursAsync(taskId: moveTaskTransaction.TaskId)).ToList();

            List <string> affectedRecordsIds = new List <string>();

            foreach (var workingHoursRecord in taskWorkingHours)
            {
                workingHoursRecord.Description += postfix;
                await _workingHoursRepository.UpdateWorkingHoursRecordAsync(workingHoursRecord);

                affectedRecordsIds.Add(workingHoursRecord.Id);
            }

            moveTaskTransaction.AffectedRecordsIds = affectedRecordsIds;
            moveTaskTransaction.UpdateData();

            var outboxMessage = OutboxMessageModel.Create(
                new MoveTaskHoursHandledMessage
            {
                TransactionId = moveTaskTransaction.Id,
            }, Topics.WorkingHours, TransactionMessageActions.MoveTask_HandleHoursCompleted);

            await _transactionsRepository.CreateOrUpdateTransactionAsync(moveTaskTransaction, outboxMessage);

            return($"Working hours updated successful");
        }
        public async Task <TaskAggregate> CreateTaskAsync(TaskModel newTask,
                                                          IEnumerable <string> usersIds, IEnumerable <string> labelsIds, string requestId)
        {
            if (!(await CheckAndSaveRequestIdAsync(requestId)))
            {
                throw new AlreadyHandledException();
            }

            try
            {
                newTask.Init();

                TaskRelatedData taskData = await GetAndCheckTaskRelatedDataAsync(newTask, usersIds, labelsIds);

                var list = taskData.List;

                var taskCollections = new TaskCollections
                {
                    Members = usersIds,
                    Labels  = labelsIds
                };

                var membersRecords = _mapper.Map <IEnumerable <UserModel>, IEnumerable <TaskUserRecord> >(taskData.Users);
                var labelsRecords  = _mapper.Map <IEnumerable <LabelModel>, IEnumerable <TaskLabelRecord> >(taskData.Labels);

                var outboxMessage = OutboxMessageModel.Create(
                    new TaskCreatedMessage
                {
                    TaskId       = newTask.Id,
                    Title        = newTask.Title,
                    ProjectId    = list.ProjectId,
                    ProjectTitle = list.ProjectTitle,
                    ListId       = list.Id,
                    ListTitle    = list.Title,
                    Members      = membersRecords,
                    Labels       = labelsRecords
                }, Topics.Tasks, MessageActions.Created);

                var createdTask = await _tasksRepository.CreateTaskAsync(newTask, taskCollections, outboxMessage);

                List <Task> cacheInvalidationTasks = new List <Task>();
                foreach (var user in usersIds)
                {
                    string userCacheKey = string.Format(CacheSettings.UserTasksCacheKeyPattern, user);
                    cacheInvalidationTasks.Add(_cache.RemoveAsync(userCacheKey));
                }

                await Task.WhenAll(cacheInvalidationTasks);

                return(createdTask);
            }
            catch (Exception)
            {
                //rollback request id
                await _requestsRepository.DeleteRequestIdAsync(requestId);

                throw;
            }
        }
        private async Task HandleListPreparedAsync(TransactionBase transaction, BaseTransactionMessage message, TransactionsRepository repository,
                                                   TasksRepository tasksRepository)
        {
            var listPreparedMessage = message as MoveTaskListPreparedMessage;

            if (transaction == null)
            {
                Console.WriteLine($"Transaction for prepared list {listPreparedMessage.ListId} not found");
                return;
            }

            var moveTaskTransaction = MoveTaskTransaction.CreateFromBase(transaction);

            string newListId = listPreparedMessage.ListId;

            moveTaskTransaction.ListId         = newListId;
            moveTaskTransaction.IsListPrepared = true;
            moveTaskTransaction.UpdateData();

            string taskId = moveTaskTransaction.ObjectId;

            IEnumerable <string> taskMembersIds = await tasksRepository.GetTaskMembersIdsAsync(taskId);

            OutboxMessageModel nextMessage = default(OutboxMessageModel);

            if (!taskMembersIds.IsNullOrEmpty())
            {
                var task = await tasksRepository.GetTaskAsync(taskId);

                moveTaskTransaction.Message = "Move members to project";

                nextMessage = OutboxMessageModel.Create(
                    new MoveTaskMoveMembersMessage()
                {
                    TransactionId   = transaction.Id,
                    TargetProjectId = moveTaskTransaction.ProjectId,
                    SourceProjectId = task.ProjectId,
                    TaskMembers     = taskMembersIds
                }, Topics.Tasks, TransactionMessageActions.MoveTask_MoveMembersRequested);
            }
            else
            {
                moveTaskTransaction.AreMembersPrepared = true;
                moveTaskTransaction.Message            = "Handle task hours with new project";

                nextMessage = OutboxMessageModel.Create(
                    new MoveTaskHandleHoursMessage()
                {
                    TransactionId = transaction.Id,
                    ProjectId     = moveTaskTransaction.ProjectId,
                    TaskId        = taskId
                }, Topics.Tasks, TransactionMessageActions.MoveTask_HandleHoursRequested);
            }

            await repository.CreateOrUpdateTransactionAsync(moveTaskTransaction, nextMessage);
        }
        public Task DeleteListAsync(string listId)
        {
            var outboxMessage = OutboxMessageModel.Create(
                new ListDeletedMessage
            {
                ListId = listId,
            }, Topics.Lists, MessageActions.Deleted);

            return(_listsRepository.DeleteListAsync(listId, outboxMessage));
        }
Example #12
0
        private Task HandleNoMembersToMoveAsync(MoveTaskTransaction moveTaskTransaction)
        {
            moveTaskTransaction.UpdateData();

            var outboxMessage = OutboxMessageModel.Create(
                new MoveTaskMembersMovedMessage
            {
                TransactionId = moveTaskTransaction.Id,
            }, Topics.ProjectMembers, TransactionMessageActions.MoveTask_MoveMembersCompleted);

            return(_transactionsRepository.CreateOrUpdateTransactionAsync(moveTaskTransaction, outboxMessage));
        }
        internal async Task <(bool isSuccess, string error)> DeleteUserAsync(string userId)
        {
            var message = OutboxMessageModel.Create(
                new UserDeletedMessage
            {
                UserId = userId
            }, Topics.Users, MessageActions.Deleted
                );

            await _repository.DeleteUserAsync(userId, message);

            return(true, string.Empty);
        }
        public async Task <TaskAggregate> CreateTaskAsync(TaskModel newTask,
                                                          IEnumerable <string> usersIds, IEnumerable <string> labelsIds, string requestId)
        {
            if (!(await CheckAndSaveRequestIdAsync(requestId)))
            {
                throw new AlreadyHandledException();
            }

            try
            {
                newTask.Init();

                TaskRelatedData taskData = await GetAndCheckTaskRelatedDataAsync(newTask, usersIds, labelsIds);

                var list = taskData.List;

                var taskCollections = new TaskCollections
                {
                    Members = usersIds,
                    Labels  = labelsIds
                };

                var membersRecords = _mapper.Map <IEnumerable <UserModel>, IEnumerable <TaskUserRecord> >(taskData.Users);
                var labelsRecords  = _mapper.Map <IEnumerable <LabelModel>, IEnumerable <TaskLabelRecord> >(taskData.Labels);

                var outboxMessage = OutboxMessageModel.Create(
                    new TaskCreatedMessage
                {
                    TaskId       = newTask.Id,
                    Title        = newTask.Title,
                    ProjectId    = list.ProjectId,
                    ProjectTitle = list.ProjectTitle,
                    ListId       = list.Id,
                    ListTitle    = list.Title,
                    Members      = membersRecords,
                    Labels       = labelsRecords
                }, Topics.Tasks, MessageActions.Created);

                return(await _tasksRepository.CreateTaskAsync(newTask, taskCollections, outboxMessage));
            }
            catch (Exception)
            {
                //rollback request id
                await _requestsRepository.DeleteRequestIdAsync(requestId);

                throw;
            }
        }
        public async Task <UserModel> CreateUserAsync(UserModel user)
        {
            user.Init();

            var message = OutboxMessageModel.Create(
                new UserCreatedUpdatedMessage
            {
                UserId   = user.Id,
                Username = user.Username
            }, Topics.Users, MessageActions.Created
                );

            var createdUser = await _repository.CreateUserAsync(user, message);

            return(createdUser);
        }
        public async Task RemoveMemberFromProjectAsync(string projectId, string userId)
        {
            (ProjectModel project, UserModel user) = await GetProjectAndUserAsync(projectId, userId);

            var outboxMessage = OutboxMessageModel.Create(
                new ProjectMemberDeletedMessage
            {
                ProjectId    = projectId,
                ProjectTitle = project?.Title,
                UserId       = userId,
                Username     = user?.Username
            }, Topics.ProjectMembers, MessageActions.Deleted
                );

            await _projectMembersRepository.DeleteMemberFromProjectAsync(projectId, userId, outboxMessage);
        }
Example #17
0
        protected override Task RollbackTransactionInternalAsync(TransactionBase transaction)
        {
            var moveTransaction = MoveTaskTransaction.CreateFromBase(transaction);

            if (!moveTransaction.IsListCreated || moveTransaction.ListId == null)
            {
                return(Task.CompletedTask); //nothing to do here
            }
            var outboxMessage = OutboxMessageModel.Create(
                new ListDeletedMessage
            {
                ListId = moveTransaction.ListId,
            }, Topics.Lists, MessageActions.Deleted);

            return(_listsRepository.DeleteListAsync(moveTransaction.ListId, outboxMessage));
        }
        public async Task <TaskAggregate> UpdateTaskAsync(TaskModel updatingTask, IEnumerable <string> usersIds,
                                                          IEnumerable <string> labelsIds)
        {
            TaskAggregate currentTask = await _tasksRepository.GetTaskAsync(updatingTask.Id);

            if (currentTask == null)
            {
                throw new NotFoundException($"Task with id = {updatingTask.Id} not found");
            }

            if (currentTask.Version != updatingTask.Version)
            {
                throw new VersionsNotMatchException();
            }

            TaskRelatedData taskData = await GetAndCheckTaskRelatedDataAsync(updatingTask, usersIds, labelsIds);

            EnsureProjectNotChanged(currentTask, taskData);

            var(removingCollections, addingCollections) = DetermineAddedAndRemovedItems(currentTask, taskData);
            var list = taskData.List;

            var addedMembersRecords   = _mapper.Map <IEnumerable <UserModel>, IEnumerable <TaskUserRecord> >(addingCollections.Users);
            var removedMembersRecords = _mapper.Map <IEnumerable <UserModel>, IEnumerable <TaskUserRecord> >(removingCollections.Users);
            var addedLabelsRecords    = _mapper.Map <IEnumerable <LabelModel>, IEnumerable <TaskLabelRecord> >(addingCollections.Labels);
            var removedLabelsRecords  = _mapper.Map <IEnumerable <LabelModel>, IEnumerable <TaskLabelRecord> >(removingCollections.Labels);

            var outboxMessage = OutboxMessageModel.Create(
                new TaskUpdatedMessage
            {
                TaskId         = updatingTask.Id,
                Title          = updatingTask.Title,
                ProjectId      = list.ProjectId,
                ProjectTitle   = list.ProjectTitle,
                ListId         = list.Id,
                ListTitle      = list.Title,
                RemovedMembers = removedMembersRecords,
                AddedMembers   = addedMembersRecords,
                RemovedLabels  = removedLabelsRecords,
                AddedLabels    = addedLabelsRecords
            }, Topics.Tasks, MessageActions.Updated);


            return(await _tasksRepository.UpdateTaskAsync(updatingTask, addingCollections.ToTaskCollections(),
                                                          removingCollections.ToTaskCollections(), outboxMessage));
        }
Example #19
0
        public async Task DeleteProjectAsync(string projectId)
        {
            var project = await _projectsRepository.GetProjectByIdAsync(projectId);

            if (project == null)
            {
                return;
            }

            var outboxMessage = OutboxMessageModel.Create(
                new ProjectDeletedMessage
            {
                ProjectId = projectId,
                Title     = project.Title
            }, Topics.Projects, MessageActions.Deleted);

            await _projectsRepository.DeleteProjectAsync(projectId, outboxMessage);
        }
        public async Task DeleteLabelAsync(string labelId)
        {
            var label = await _labelsRepository.GetLabelByIdAsync(labelId);

            if (label == null)
            {
                return;
            }

            var outboxMessage = OutboxMessageModel.Create(
                new LabelDeletedMessage
            {
                LabelId = labelId,
                Title   = label.Title
            }, Topics.Labels, MessageActions.Deleted);

            await _labelsRepository.DeleteLabelAsync(labelId, outboxMessage);
        }
        public async Task DeleteTaskAsync(string taskId)
        {
            var task = await _tasksRepository.GetTaskAsync(taskId);

            if (task == null)
            {
                return;
            }

            var outboxMessage = OutboxMessageModel.Create(
                new TaskDeletedMessage
            {
                TaskId    = taskId,
                Title     = task.Title,
                ProjectId = task.ProjectId
            }, Topics.Tasks, MessageActions.Deleted);

            await _tasksRepository.DeleteTaskAsync(taskId, outboxMessage);
        }
        public async Task DeleteTaskAsync(string taskId)
        {
            var task = await _tasksRepository.GetTaskAsync(taskId);

            if (task == null)
            {
                return;
            }

            var outboxMessage = OutboxMessageModel.Create(
                new TaskDeletedMessage
            {
                TaskId    = taskId,
                Title     = task.Title,
                ProjectId = task.ProjectId
            }, Topics.Tasks, MessageActions.Deleted);

            await _cache.RemoveAsync(string.Format(CacheSettings.TaskIdCacheKeyPattern, taskId));

            await _tasksRepository.DeleteTaskAsync(taskId, outboxMessage);
        }
        public async Task <TaskAggregate> MoveTaskToProjectAsync(string taskId, string targetProjectId, string targetListTitle, string requestId)
        {
            if (!(await CheckAndSaveRequestIdAsync(requestId)))
            {
                throw new AlreadyHandledException();
            }

            var task = await _tasksRepository.GetTaskAsync(taskId);

            if (!string.IsNullOrWhiteSpace(task.TransactionId))
            {
                throw new AlreadyInTransactionException();
            }

            if (task.ProjectId == targetProjectId)
            {
                throw new EntityExistsException("Task already in target project");
            }

            List <string> taskMembers = task.Members?.Select(m => m.Id).ToList() ?? new List <string>();

            MoveTaskTransaction moveTransaction = MoveTaskTransaction.Create(taskId, targetProjectId, targetListTitle);

            moveTransaction.State = TransactionStates.Processing;

            var moveMessage = OutboxMessageModel.Create(
                new MoveTaskPrepareListMessage
            {
                TransactionId = moveTransaction.Id,
                ListTitle     = targetListTitle,
                ProjectId     = targetProjectId
            }, Topics.Tasks, TransactionMessageActions.MoveTask_PrepareListRequested);

            await _transactionsRepository.CreateTransactionRecordAsync(moveTransaction, moveMessage);

            await _tasksRepository.SetTransactionAsync(taskId, moveTransaction.Id);

            return(await _tasksRepository.GetTaskAsync(taskId));
        }
        public async Task AddMemberToProjectAsync(ProjectMemberModel newProjectMember, string requestId)
        {
            if (!(await CheckAndSaveRequestIdAsync(requestId)))
            {
                throw new AlreadyHandledException();
            }

            (string projectTitle, string username) = await EnsureProjectAndUserExistAsync(newProjectMember.ProjectId, newProjectMember.UserId);

            try
            {
                var existingMember = await _projectMembersRepository.GetProjectMemberAsync(newProjectMember.ProjectId, newProjectMember.UserId);

                if (existingMember != null)
                {
                    throw new EntityExistsException("This member already in project");
                }

                var outboxMessage = OutboxMessageModel.Create(
                    new ProjectMemberCreatedUpdatedMessage
                {
                    ProjectId    = newProjectMember.ProjectId,
                    ProjectTitle = projectTitle,
                    UserId       = newProjectMember.UserId,
                    Username     = username,
                    Role         = newProjectMember.Role
                }, Topics.ProjectMembers, MessageActions.Created
                    );

                await _projectMembersRepository.AddMemberToProjectAsync(newProjectMember, outboxMessage);
            }
            catch (Exception)
            {
                //rollback request id
                await _requestsRepository.DeleteRequestIdAsync(requestId);

                throw;
            }
        }
        public async Task <ListProjectAggregate> UpdateListAsync(ListModel updatingList)
        {
            ListModel currentList = await _listsRepository.GetListByIdAsync(updatingList.Id);

            if (currentList == null)
            {
                throw new NotFoundException($"List with id = {updatingList.Id} not found");
            }

            if (currentList.Version != updatingList.Version)
            {
                throw new VersionsNotMatchException();
            }

            var outboxMessage = OutboxMessageModel.Create(
                new ListUpdatedMessage
            {
                ListId = updatingList.Id,
                Title  = updatingList.Title
            }, Topics.Lists, MessageActions.Updated);

            return(await _listsRepository.UpdateListAsync(updatingList, outboxMessage));
        }
        public async Task <UserModel> CreateUserAsync(UserModel user)
        {
            bool isUsernameBusy = await _repository.IsAnyUserByPredicateAsync(usr => usr.Username == user.Username);

            if (isUsernameBusy)
            {
                throw new EntityExistsException("This username already in use");
            }

            user.Init();

            var message = OutboxMessageModel.Create(
                new UserCreatedUpdatedMessage
            {
                UserId   = user.Id,
                Username = user.Username
            }, Topics.Users, MessageActions.Created
                );

            var createdUser = await _repository.CreateUserAsync(user, message);

            return(createdUser);
        }
        public async Task <ListProjectAggregate> CreateListAsync(ListModel newList, string requestId)
        {
            if (!(await CheckAndSaveRequestIdAsync(requestId)))
            {
                throw new AlreadyHandledException();
            }

            try
            {
                var project = await _projectsRepository.GetProjectAsync(newList.ProjectId);

                if (project == null)
                {
                    throw new NotFoundException($"Project with id {newList.ProjectId} not found");
                }

                newList.Init();

                var outboxMessage = OutboxMessageModel.Create(
                    new ListCreatedMessage
                {
                    ListId    = newList.Id,
                    ProjectId = newList.ProjectId,
                    Title     = newList.Title
                }, Topics.Lists, MessageActions.Created);

                return(await _listsRepository.CreateListAsync(newList, outboxMessage));
            }
            catch (Exception)
            {
                //rollback request id
                await _requestsRepository.DeleteRequestIdAsync(requestId);

                throw;
            }
        }
Example #28
0
        public async Task <ProjectModel> UpdateProjectAsync(ProjectModel updatingProject)
        {
            ProjectModel currentProject = await _projectsRepository.GetProjectByIdAsync(updatingProject.Id);

            if (currentProject == null)
            {
                throw new NotFoundException($"Project with id = {updatingProject.Id} not found");
            }

            if (currentProject.Version != updatingProject.Version)
            {
                throw new VersionsNotMatchException();
            }

            var outboxMessage = OutboxMessageModel.Create(
                new ProjectCreatedUpdatedMessage
            {
                ProjectId = updatingProject.Id,
                Title     = updatingProject.Title,
                OldTitle  = currentProject.Title
            }, Topics.Projects, MessageActions.Updated);

            return(await _projectsRepository.UpdateProjectAsync(updatingProject, outboxMessage));
        }
        public async Task <TaskAggregate> UpdateTaskAsync(TaskModel updatingTask, IEnumerable <string> usersIds,
                                                          IEnumerable <string> labelsIds)
        {
            TaskAggregate currentTask = await _tasksRepository.GetTaskAsync(updatingTask.Id);

            if (currentTask == null)
            {
                throw new NotFoundException($"Task with id = {updatingTask.Id} not found");
            }

            if (currentTask.Version != updatingTask.Version)
            {
                throw new VersionsNotMatchException();
            }

            TaskRelatedData taskData = await GetAndCheckTaskRelatedDataAsync(updatingTask, usersIds, labelsIds);

            EnsureProjectNotChanged(currentTask, taskData);

            var(removingCollections, addingCollections) = DetermineAddedAndRemovedItems(currentTask, taskData);
            var list = taskData.List;

            var addedMembersRecords   = _mapper.Map <IEnumerable <UserModel>, IEnumerable <TaskUserRecord> >(addingCollections.Users);
            var removedMembersRecords = _mapper.Map <IEnumerable <UserModel>, IEnumerable <TaskUserRecord> >(removingCollections.Users);
            var addedLabelsRecords    = _mapper.Map <IEnumerable <LabelModel>, IEnumerable <TaskLabelRecord> >(addingCollections.Labels);
            var removedLabelsRecords  = _mapper.Map <IEnumerable <LabelModel>, IEnumerable <TaskLabelRecord> >(removingCollections.Labels);

            var outboxMessage = OutboxMessageModel.Create(
                new TaskUpdatedMessage
            {
                TaskId         = updatingTask.Id,
                Title          = updatingTask.Title,
                ProjectId      = list.ProjectId,
                ProjectTitle   = list.ProjectTitle,
                ListId         = list.Id,
                ListTitle      = list.Title,
                RemovedMembers = removedMembersRecords,
                AddedMembers   = addedMembersRecords,
                RemovedLabels  = removedLabelsRecords,
                AddedLabels    = addedLabelsRecords
            }, Topics.Tasks, MessageActions.Updated);

            updatingTask.Version += 1;

            var updatedTask = await _tasksRepository.UpdateTaskAsync(updatingTask, addingCollections.ToTaskCollections(),
                                                                     removingCollections.ToTaskCollections(), outboxMessage);


            string cacheKey = string.Format(CacheSettings.TaskIdCacheKeyPattern, updatedTask.Id);

            List <Task> cacheInvalidationTasks = new List <Task>();

            cacheInvalidationTasks.Add(_cache.SetCacheValueAsync(cacheKey, updatedTask, CacheSettings.TaskIdCacheLifetime));

            foreach (var user in usersIds)
            {
                string userCacheKey = string.Format(CacheSettings.UserTasksCacheKeyPattern, user);
                cacheInvalidationTasks.Add(_cache.RemoveAsync(userCacheKey));
            }

            foreach (var user in removingCollections.Users)
            {
                string userCacheKey = string.Format(CacheSettings.UserTasksCacheKeyPattern, user.Id);
                cacheInvalidationTasks.Add(_cache.RemoveAsync(userCacheKey));
            }

            await Task.WhenAll(cacheInvalidationTasks);

            return(updatedTask);
        }
Example #30
0
        private async Task <string> PrepareListStageInternalAsync(MoveTaskPrepareListMessage message)
        {
            string transactionId = message.TransactionId;
            var    transaction   = await _transactionsRepository.GetTransactionAsync(transactionId);

            if (transaction != null && transaction.State == TransactionStates.Denied)
            {
                return($"Transaction {transactionId} already denied");
            }

            var moveTransaction = transaction == null
                ? MoveTaskTransaction.Create(transactionId, message.ProjectId, message.ListTitle)
                : MoveTaskTransaction.CreateFromBase(transaction);

            moveTransaction.State = TransactionStates.Processing;

            string projectId = message.ProjectId;
            var    project   = await _projectsRepository.GetProjectAsync(projectId);

            if (project == null)
            {
                string reason = $"Project {projectId} not found";

                var rollbackOutboxMessage = OutboxMessageModel.Create(
                    new RollbackTransactionMessage
                {
                    TransactionId = transactionId,
                    Reason        = reason
                }, Topics.Lists, TransactionMessageActions.MoveTask_Rollback);

                moveTransaction.State   = TransactionStates.Denied;
                moveTransaction.Message = reason;
                moveTransaction.UpdateData();

                await _transactionsRepository.CreateOrUpdateTransactionAsync(moveTransaction, rollbackOutboxMessage);

                return(reason);
            }

            try
            {
                var projectLists  = (await _listsRepository.GetProjectListsAsyn(projectId)).ToList();
                var sameTitleList = projectLists.FirstOrDefault(list => list.Title == message.ListTitle);

                if (sameTitleList == null)
                {
                    var newList = new ListModel
                    {
                        Title     = message.ListTitle,
                        ProjectId = projectId
                    };

                    newList.Init();

                    moveTransaction.ListId        = newList.Id;
                    moveTransaction.IsListCreated = true;

                    var completedOutboxMessage = OutboxMessageModel.Create(
                        new ListCreatedMessage
                    {
                        ListId    = newList.Id,
                        ProjectId = newList.ProjectId,
                        Title     = newList.Title
                    }, Topics.Lists, MessageActions.Created);

                    await _listsRepository.CreateListAsync(newList, completedOutboxMessage);
                }
                else
                {
                    moveTransaction.ListId        = sameTitleList.Id;
                    moveTransaction.IsListCreated = false;
                }

                moveTransaction.UpdateData();

                var outboxMessage = OutboxMessageModel.Create(
                    new MoveTaskListPreparedMessage
                {
                    TransactionId = transactionId,
                    ListId        = moveTransaction.ListId
                }, Topics.Lists, TransactionMessageActions.MoveTask_PrepareListCompleted);

                await _transactionsRepository.CreateOrUpdateTransactionAsync(moveTransaction, outboxMessage);

                return("Prepare list stage completed successful");
            }
            catch (Exception e)
            {
                string errorReason = $"Unknonw exception occured:\n{e.Message}\n{e.StackTrace}";
                moveTransaction.Message = errorReason;
                moveTransaction.State   = TransactionStates.Denied;

                var failedOutboxMessage = OutboxMessageModel.Create(
                    new RollbackTransactionMessage
                {
                    TransactionId = transactionId,
                    Reason        = moveTransaction.Message
                }, Topics.Lists, TransactionMessageActions.MoveTask_Rollback);

                await _transactionsRepository.CreateOrUpdateTransactionAsync(moveTransaction, failedOutboxMessage);

                throw;
            }
        }