public ActionResult <List <AvailabilityResult> > GetProjectAvailability(string projectId, [BindRequired][JsonSchemaDate] DateTime begin, [BindRequired][JsonSchemaDate] DateTime end, [BindRequired] AvailabilityGranularity granularity) { if (_databaseManager.Database == null) { return(this.StatusCode(503, "The database has not been loaded yet.")); } projectId = WebUtility.UrlDecode(projectId); // log var message = $"User '{_userIdService.GetUserId()}' requests availability of project '{projectId}' ..."; _logger.LogInformation(message); try { return(this.ProcessProjectId <List <AvailabilityResult> >(projectId, message, (project, projectMeta) => { _logger.LogInformation($"{message} Done."); return this.CreateAvailabilityResponse(project, begin, end, granularity); })); } catch (Exception ex) { _logger.LogError($"{message} {ex.GetFullMessage()}"); throw; } }
public async Task <List <AvailabilityResult> > GetAvailabilityAsync(AvailabilityGranularity granularity) { // security check if (!Utilities.IsProjectAccessible(_userIdService.User, this.ProjectContainer.Id, _databaseManager.Database)) { throw new UnauthorizedAccessException($"The current user is not authorized to access project '{this.ProjectContainer.Id}'."); } return(await _dataService.GetAvailabilityAsync(this.ProjectContainer.Id, this.DateTimeBegin, this.DateTimeEnd, granularity)); }
public Task <List <AvailabilityResult> > GetAvailabilityAsync(string projectId, DateTime begin, DateTime end, AvailabilityGranularity granularity) { return(Task.Run(() => { var dataReaders = _databaseManager.GetDataReaders(_userIdService.User, projectId); return dataReaders.Select(dataReaderForUsing => { using var dataReader = dataReaderForUsing; return dataReader.GetAvailability(projectId, begin, end, granularity); }).ToList(); })); }
public AvailabilityResult GetAvailability(string projectId, DateTime begin, DateTime end, AvailabilityGranularity granularity) { var dateBegin = begin.Date; var dateEnd = end.Date; ConcurrentDictionary <DateTime, double> aggregatedData = default; var totalDays = (int)(dateEnd - dateBegin).TotalDays; switch (granularity) { case AvailabilityGranularity.Day: aggregatedData = new ConcurrentDictionary <DateTime, double>(); Parallel.For(0, totalDays, day => { var date = dateBegin.AddDays(day); var availability = this.GetAvailability(projectId, date); aggregatedData.TryAdd(date, availability); }); break; case AvailabilityGranularity.Month: granularity = AvailabilityGranularity.Month; var months = new DateTime[totalDays]; var datasets = new double[totalDays]; Parallel.For(0, totalDays, day => { var date = dateBegin.AddDays(day); var month = new DateTime(date.Year, date.Month, 1); months[day] = month; datasets[day] = this.GetAvailability(projectId, date); }); var uniqueMonths = months .Distinct() .OrderBy(month => month) .ToList(); var zipData = months .Zip(datasets, (month, dataset) => (month, dataset)) .ToList(); aggregatedData = new ConcurrentDictionary <DateTime, double>(); for (int i = 0; i < uniqueMonths.Count; i++) { var currentMonth = uniqueMonths[i]; var availability = (int)zipData .Where(current => current.month == currentMonth) .Average(current => current.dataset); aggregatedData.TryAdd(currentMonth, availability); } break; default: throw new NotSupportedException($"Availability granularity value '{granularity}' is not supported."); } return(new AvailabilityResult() { DataReaderRegistration = this.Registration, Data = aggregatedData .ToDictionary(entry => entry.Key, entry => entry.Value) }); }
private List <AvailabilityResult> CreateAvailabilityResponse(ProjectInfo project, DateTime begin, DateTime end, AvailabilityGranularity granularity) { var dataReaders = _databaseManager.GetDataReaders(_userIdService.User, project.Id); return(dataReaders.Select(dataReaderForUsing => { using var dataReader = dataReaderForUsing; var availability = dataReader.GetAvailability(project.Id, begin, end, granularity); var registration = new DataReaderRegistration() { RootPath = availability.DataReaderRegistration.RootPath, DataReaderId = availability.DataReaderRegistration.DataReaderId, }; return new AvailabilityResult() { DataReaderRegistration = registration, Data = availability.Data }; }).ToList()); }