private IMongoQueryable <DbGeoTask> ApplyPagination(
     IMongoQueryable <DbGeoTask> query, DbGetGeoTaskListRequest request)
 {
     if (request.Offset > 0)
     {
         query = query.Skip(request.Offset);
     }
     if (request.Limit > 0)
     {
         query = query.Take(request.Limit);
     }
     return(query);
 }
Example #2
0
 public static Dictionary <string, object> ToDictionary
     (this DbGetGeoTaskListRequest from)
 {
     return(new Dictionary <string, object>
     {
         { nameof(from.Archived), from.Archived },
         { nameof(from.Contains), from.Contains },
         { nameof(from.Limit), from.Limit },
         { nameof(from.MaxTimeToDeadLine), from.MaxTimeToDeadLine },
         { nameof(from.Offset), from.Offset },
         { nameof(from.TaskStatusMask), from.TaskStatusMask },
         { nameof(from.Actors), String.Join(',',
                                            from.Actors.Select(x => $"{x.Key}: {x.Value}")) },
         { nameof(from.ProjectIds), String.Join(',', from.ProjectIds) },
         { nameof(from.GeoIds), String.Join(',', from.GeoIds) },
     });
 }
        public DbGetGeoTaskListRequestSecurityBuilder
            (DbGetGeoTaskListRequest filter, Actor currentActor,
            ActorRole projectActorRole = null)
        {
            if (filter is null)
            {
                throw new System.ArgumentNullException(nameof(filter));
            }

            if (currentActor is null)
            {
                throw new System.ArgumentNullException(nameof(currentActor));
            }

            Filter           = filter;
            Actor            = currentActor;
            ProjectActorRole = projectActorRole;
        }
        public async Task <ListResponse <GeoTask> > Handle
            (DbGetGeoTaskListRequest request,
            CancellationToken cancellationToken)
        {
            try
            {
                Logger.LogInformation(LogEvent.DatabaseRequest,
                                      "Request={Request}.", request.ToDictionary());

                var validation = new DbGetGeoTaskListRequestValidator()
                                 .Validate(request);
                if (!validation.IsValid)
                {
                    Logger.LogWarning
                        (LogEvent.DatabaseRequestArgumentError,
                        "Database request validation" +
                        " error. Error={Error}.", validation.Errors);
                    return(ErrorResult("Database request validation error"));
                }

                var db         = DbContext.Db;
                var query      = BuildQuery(request);
                var totalCount = await query.CountAsync()
                                 .ConfigureAwait(false);

                if (totalCount == 0)
                {
                    return(new ListResponse <GeoTask>(new List <GeoTask>(),
                                                      totalCount));
                }

                query = ApplyPagination(query, request);
                var dbGeoTaskList = await query
                                    .ToListAsync()
                                    .ConfigureAwait(false);

                if (dbGeoTaskList is null)
                {
                    Logger.LogWarning
                        (LogEvent.DatabaseEmptyResponse,
                        "Database GeoTasks null response.");
                    return(ErrorResult("Database GeoTasks null response."));
                }

                var actorIdsSet = new HashSet <string>();
                dbGeoTaskList.ForEach
                    (x =>
                {
                    x.AssistentActorsIds
                    .ForEach(x => actorIdsSet.Add(x));
                    actorIdsSet.Add(x.CreatedById);
                    actorIdsSet.Add(x.ResponsibleActorId);
                    x.ObserverActorsIds
                    .ForEach(x => actorIdsSet.Add(x));
                }
                    );

                var actorListResponse = await Mediator
                                        .Send(new DbListRequest <Actor>(actorIdsSet))
                                        .ConfigureAwait(false);

                if (!actorListResponse.Success)
                {
                    Logger.LogWarning
                        (LogEvent.DatabaseEmptyResponse,
                        "Database Actors null response.");
                    return(ErrorResult("Database Actors null response."));
                }
                var actors = actorListResponse.Entities.ToDictionary(x => x.Id);

                var result = new ListResponse <GeoTask>
                {
                    Success    = true,
                    TotalCount = totalCount
                };
                dbGeoTaskList.ForEach(x =>
                                      result.Entities.Add(x.ToGeoTask(actors)));

                return(result);
            }
            catch (Exception e)
            {
                Logger.LogWarning(LogEvent.DatabaseExceptionError, e,
                                  "Database exception error. Error={Error}.", e.Message);
                return(ErrorResult("Database exception error"));
            }
        }
        private IMongoQueryable <DbGeoTask> BuildQuery
        (
            DbGetGeoTaskListRequest request
        )
        {
            var query = DbContext.Db.GetCollection <DbGeoTask>
                            (Defaults.TaskCollectionName)
                        .AsQueryable();

            if (!string.IsNullOrWhiteSpace(request.Contains))
            {
                query = query.WhereText(request.Contains);
            }

            if (request.Archived.HasValue)
            {
                query = query.Where(x => x.IsArchived == request.Archived);
            }

            if (request.ProjectIds.Count > 0)
            {
                query = query.Where(x =>
                                    request.ProjectIds.Contains(x.ProjectId));
            }

            if (request.Actors.Count > 0)
            {
                foreach (var actorPair in request.Actors)
                {
                    if (actorPair.Value == 0 ||
                        actorPair.Value
                        .Contains(ActorGeoTaskRole.Assistant))
                    {
                        query = query.Where(x =>
                                            x.AssistentActorsIds.Any(x => x == actorPair.Key));
                    }

                    if (actorPair.Value == 0 ||
                        actorPair.Value.Contains(ActorGeoTaskRole.Creator))
                    {
                        query = query.Where(x =>
                                            x.CreatedById == actorPair.Key);
                    }

                    if (actorPair.Value == 0 ||
                        actorPair.Value.Contains(ActorGeoTaskRole.Observer))
                    {
                        query = query.Where(x =>
                                            x.ObserverActorsIds.Any(x => x == actorPair.Key));
                    }

                    if (actorPair.Value == 0 ||
                        actorPair.Value
                        .Contains(ActorGeoTaskRole.Responsible))
                    {
                        query = query.Where(x =>
                                            x.ResponsibleActorId == actorPair.Key);
                    }
                }
            }

            if (request.TaskStatusMask != 0)
            {
                var statuses  = new HashSet <GeoTaskStatus>();
                var checkList = EnumerationClass.GetAll <GeoTaskStatus>();
                foreach (var item in checkList)
                {
                    if (request.TaskStatusMask.Contains(item))
                    {
                        statuses.Add(item);
                    }
                }

                query = query.Where(x => statuses.Contains(x.Status));
            }

            if (request.MaxTimeToDeadLine.HasValue)
            {
                var deadlineTime = DateTime.UtcNow
                                   + request.MaxTimeToDeadLine.Value;
                query = query.Where(x =>
                                    x.PlanFinishAt.HasValue &&
                                    deadlineTime >= x.PlanFinishAt);
            }

            if (request.GeoIds.Count > 0)
            {
                query = query.Where(x =>
                                    x.GeosIds.Any(z => request.GeoIds.Contains(z)));
            }

            return(query);
        }
Example #6
0
        public async Task <ListResponse <GeoTask> > Handle
            (GeoTaskListQuery request, CancellationToken cancellationToken)
        {
            Logger.LogInformation(AppLogEvent.HandleRequest,
                                  "Handle get task collection {request}",
                                  request.ToDictionary());

            if (request is null)
            {
                Logger.LogWarning(AppLogEvent.HandleArgumentError,
                                  "Handle get task collection request with empty request");
                return(ErrorResponse("Request empty argument"));
            }

            try
            {
                // Validate request
                var validator        = new GeoTaskListQueryValidator();
                var validationResult = await validator.ValidateAsync(request)
                                       .ConfigureAwait(false);

                if (!validationResult.IsValid)
                {
                    Logger.LogError("Query validation error. " +
                                    "Request={Request}. Error={Error}.",
                                    request.ToDictionary(),
                                    validationResult.Errors.Select(x => x.ErrorMessage));
                    return(ErrorResponse
                               (validationResult.Errors.Select(x => x.ErrorMessage)));
                }

                // Build filter
                var defaultLimit = Configuration.GetValue
                                       (Defaults.ConfigurationApiDefaultLimitParameterName,
                                       Defaults.ConfigurationApiDefaultLimitDefaultValue);
                var maxLimit = Configuration.GetValue
                                   (Defaults.ConfigurationApiMaxLimitParameterName,
                                   Defaults.ConfigurationApiMaxLimitDefaultValue);
                var filter = new DbGetGeoTaskListRequest
                {
                    Offset = request.Offset,
                    Limit  = request.Limit == 0
                        ? defaultLimit
                        : Math.Min(request.Limit, maxLimit),
                    Archived          = request.Archived,
                    Contains          = request.СontainsKeyWords,
                    MaxTimeToDeadLine = request.MaxTimeToDeadLine,
                    TaskStatusMask    = request.TaskStatusMask,
                };
                if (!String.IsNullOrWhiteSpace(request.ActorId))
                {
                    filter.Actors[request.ActorId] = request.ActorRoleMask;
                }
                if (!string.IsNullOrWhiteSpace(request.ProjectId))
                {
                    filter.ProjectIds.Add(request.ProjectId);
                }
                filter.GeoIds.AddRange(request.GeoIds);

                // Get Actor for current user by user name
                var currentActorResponse = await Mediator
                                           .Send(new DbGetActorByNameRequest
                                                 (request.CurrentPrincipal?.Identity?.Name))
                                           .ConfigureAwait(false);

                Actor currentActor = null;
                if (currentActorResponse.Success)
                {
                    currentActor = currentActorResponse.Entity;
                }
                else
                {
                    Logger.LogWarning(AppLogEvent.HandleArgumentError,
                                      "Not found current actor");
                    return(ErrorResponse("Not found current actor"));
                }

                ActorRole projectActorRole = null;
                if (!string.IsNullOrWhiteSpace(request.ProjectId))
                {
                    projectActorRole = await GetProjectRoleAsync
                                           (request.ProjectId, currentActor?.Id)
                                       .ConfigureAwait(false);
                }

                // Apply security filter
                var securizator = new DbGetGeoTaskListRequestSecurityBuilder
                                      (filter, currentActor, projectActorRole);
                var securedFilter = securizator.Build();

                return(await Mediator.Send(securedFilter)
                       .ConfigureAwait(false));
            }
            catch (Exception e)
            {
                Logger.LogError(AppLogEvent.HandleErrorResponse, e,
                                "Call repository exception");
                return(ErrorResponse("Not found"));
            }
        }