using AsbCloudApp.Data; using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudWebApi.SignalR; using AsbCloudWebApi.SignalR.Clients; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace AsbCloudWebApi.Controllers.SAUB; [ApiController] [Authorize] [Route("api/[controller]")] public abstract class TelemetryDataBaseController : ControllerBase where TDto : ITelemetryData { protected readonly IWellService wellService; private readonly ITelemetryService telemetryService; private readonly ITelemetryDataService telemetryDataService; protected readonly IHubContext telemetryHubContext; public TelemetryDataBaseController( ITelemetryService telemetryService, ITelemetryDataService telemetryDataService, IWellService wellService, IHubContext telemetryHubContext) { this.telemetryService = telemetryService; this.telemetryDataService = telemetryDataService; this.wellService = wellService; this.telemetryHubContext = telemetryHubContext; } protected abstract Task SignalRNotifyAsync(int idWell, IEnumerable dtos, CancellationToken token); /// /// Принимает данные от разных систем по скважине /// /// Уникальный идентификатор отправителя /// Данные /// Токен для отмены задачи /// [HttpPost("{uid}")] [AllowAnonymous] public virtual async Task PostDataAsync(string uid, [FromBody] IEnumerable dtos, CancellationToken token) { await telemetryDataService.UpdateDataAsync(uid, dtos, token).ConfigureAwait(false); var idWell = telemetryService.GetIdWellByTelemetryUid(uid); if (idWell is not null && dtos.Any()) _ = Task.Run(() => SignalRNotifyAsync(idWell.Value, dtos, CancellationToken.None)); return Ok(); } /// /// Возвращает данные САУБ по скважине. /// По умолчанию за последние 10 минут. /// /// id скважины /// дата начала выборки. По умолчанию: текущее время - intervalSec /// интервал времени даты начала выборки, секунды /// желаемое количество точек. Если в выборке точек будет больше, то выборка будет прорежена. /// Токен завершения задачи /// [HttpGet("{idWell}")] [Permission] public virtual async Task>> GetDataAsync(int idWell, DateTime begin = default, int intervalSec = 600, int approxPointsCount = 1024, //TODO: сделать cancellationToken обязательным CancellationToken token = default) { int? idCompany = User.GetCompanyId(); if (idCompany is null) return Forbid(); bool isCompanyOwnsWell = await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token).ConfigureAwait(false); if (!isCompanyOwnsWell) return Forbid(); var content = await telemetryDataService.GetByWellAsync(idWell, begin, intervalSec, approxPointsCount, token).ConfigureAwait(false); return Ok(content); } /// /// Новая версия. Возвращает данные САУБ по скважине. /// По умолчанию за последние 10 минут. /// /// id скважины /// /// Токен завершения задачи /// [HttpGet("{idWell}/data")] [Permission] public virtual async Task>> GetData2Async(int idWell, [FromQuery]TelemetryDataRequest request, CancellationToken token) { int? idCompany = User.GetCompanyId(); if (idCompany is null) return Forbid(); bool isCompanyOwnsWell = await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token).ConfigureAwait(false); if (!isCompanyOwnsWell) return Forbid(); var content = await telemetryDataService.GetByWellAsync(idWell, request, token); return Ok(content); } /// /// Возвращает диапазон дат за которые есть телеметрия за период времени /// /// /// /// /// /// [HttpGet("{idWell}/dateRange")] [ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)] [ProducesResponseType((int)System.Net.HttpStatusCode.NotFound)] [ProducesResponseType((int)System.Net.HttpStatusCode.NoContent)] public virtual async Task> GetRangeAsync( [FromRoute] int idWell, [Required] DateTimeOffset geDate, DateTimeOffset? leDate, CancellationToken token) { int? idCompany = User.GetCompanyId(); if (idCompany is null) return Forbid(); bool isCompanyOwnsWell = await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token).ConfigureAwait(false); if (!isCompanyOwnsWell) return Forbid(); var content = await telemetryDataService.GetRangeAsync(idWell, geDate, leDate, token); if (content is null) return NoContent(); return Ok(content); } /// /// Возвращает диапазон дат сохраненных данных. /// /// id скважины /// Токен завершения задачи /// [HttpGet("{idWell}/datesRange")] [Permission] [ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)] [ProducesResponseType((int)System.Net.HttpStatusCode.NotFound)] [ProducesResponseType((int)System.Net.HttpStatusCode.NoContent)] public virtual async Task> GetDataDatesRangeAsync(int idWell, CancellationToken token) { int? idCompany = User.GetCompanyId(); if (idCompany is null) return Forbid(); bool isCompanyOwnsWell = await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token).ConfigureAwait(false); if (!isCompanyOwnsWell) return Forbid(); try { var dataDatesRange = wellService.GetDatesRange(idWell); return Ok(dataDatesRange); } catch(KeyNotFoundException) { return NoContent(); } } }