diff --git a/AsbCloudApp/Data/ReportPropertiesDto.cs b/AsbCloudApp/Data/ReportPropertiesDto.cs
deleted file mode 100644
index 0da8a6bf..00000000
--- a/AsbCloudApp/Data/ReportPropertiesDto.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System.IO;
-
-namespace AsbCloudApp.Data
-{
- public class ReportPropertiesDto
- {
- public FileStream Filestream { get; set; }
- public string ContentType { get; set; }
- public string FileName { get; set; }
- }
-}
diff --git a/AsbCloudApp/Services/IBackgroundQueue.cs b/AsbCloudApp/Services/IBackgroundQueue.cs
new file mode 100644
index 00000000..ae99317b
--- /dev/null
+++ b/AsbCloudApp/Services/IBackgroundQueue.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace AsbCloudApp.Services
+{
+ public interface IBackgroundQueue
+ {
+ int EnqueueTask(Action action);
+
+ bool TryDequeue(out (Action action, int id) item);
+ }
+}
diff --git a/AsbCloudApp/Services/IReportService.cs b/AsbCloudApp/Services/IReportService.cs
index 916f7d89..ee759b8d 100644
--- a/AsbCloudApp/Services/IReportService.cs
+++ b/AsbCloudApp/Services/IReportService.cs
@@ -5,8 +5,9 @@ namespace AsbCloudApp.Services
{
public interface IReportService
{
+ string RootPath { get; }
+ int CreateReport(int wellId, int stepSeconds, int format, DateTime begin, DateTime end);
int GetReportPagesCount(int wellId, DateTime begin, DateTime end, int stepSeconds, int format);
- ReportPropertiesDto GetReportFileProperties(string reportName, string rootPath);
DatesRangeDto GetReportsDatesRange(int wellId);
}
}
diff --git a/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj b/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj
index ab446ac9..a934217c 100644
--- a/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj
+++ b/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj
@@ -7,6 +7,7 @@
+
@@ -21,4 +22,19 @@
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+
diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs
index a7a1fd65..b7b4ef6f 100644
--- a/AsbCloudInfrastructure/DependencyInjection.cs
+++ b/AsbCloudInfrastructure/DependencyInjection.cs
@@ -19,9 +19,12 @@ namespace AsbCloudInfrastructure
services.AddScoped(provider => provider.GetService());
+ services.AddHostedService();
+
services.AddSingleton(new MapperConfiguration(AutoMapperConfig));
services.AddSingleton(new CacheDb());
services.AddSingleton();
+ services.AddSingleton();
services.AddTransient();
services.AddTransient();
diff --git a/AsbCloudInfrastructure/Services/BackgroundQueue.cs b/AsbCloudInfrastructure/Services/BackgroundQueue.cs
new file mode 100644
index 00000000..a182bdcd
--- /dev/null
+++ b/AsbCloudInfrastructure/Services/BackgroundQueue.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Concurrent;
+using AsbCloudApp.Services;
+
+namespace AsbCloudInfrastructure.Services
+{
+ class BackgroundQueue : IBackgroundQueue
+ {
+ private ConcurrentQueue<(Action action, int id)> tasks =
+ new ConcurrentQueue<(Action action, int id)>();
+
+ private int id = 0;
+
+ public int EnqueueTask(Action action)
+ {
+ if (action == null)
+ throw new ArgumentNullException(nameof(action));
+
+ tasks.Enqueue(new(action, id++));
+ return id;
+ }
+
+ public bool TryDequeue(out (Action action, int id) item)
+ => tasks.TryDequeue(out item);
+ }
+}
diff --git a/AsbCloudInfrastructure/Services/BackgroundWorkerService.cs b/AsbCloudInfrastructure/Services/BackgroundWorkerService.cs
new file mode 100644
index 00000000..7510cbb8
--- /dev/null
+++ b/AsbCloudInfrastructure/Services/BackgroundWorkerService.cs
@@ -0,0 +1,40 @@
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Hosting;
+using AsbCloudApp.Services;
+
+namespace AsbCloudInfrastructure.Services
+{
+ public class BackgroundWorkerService : BackgroundService
+ {
+ private readonly IBackgroundQueue tasksQueue;
+
+ public BackgroundWorkerService(IBackgroundQueue tasksQueue)
+ {
+ this.tasksQueue = tasksQueue;
+ }
+
+ protected override async Task ExecuteAsync(CancellationToken token)
+ {
+ try
+ {
+ while (!token.IsCancellationRequested)
+ {
+ if (tasksQueue.TryDequeue(out var item))
+ await Task.Run(item.action);
+ else
+ await Task.Delay(100, token);
+ }
+ }
+ catch
+ {
+ //logger ?
+ }
+ }
+
+ public override async Task StopAsync(CancellationToken token)
+ {
+ await base.StopAsync(token);
+ }
+ }
+}
diff --git a/AsbCloudInfrastructure/Services/ReportService.cs b/AsbCloudInfrastructure/Services/ReportService.cs
index c0e26168..bd4cc08c 100644
--- a/AsbCloudInfrastructure/Services/ReportService.cs
+++ b/AsbCloudInfrastructure/Services/ReportService.cs
@@ -3,6 +3,8 @@ using AsbCloudApp.Data;
using AsbCloudDb.Model;
using System;
using System.IO;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
using AsbSaubReport;
namespace AsbCloudInfrastructure.Services
@@ -10,35 +12,46 @@ namespace AsbCloudInfrastructure.Services
public class ReportService : IReportService
{
private readonly IAsbCloudDbContext db;
+ private readonly IConfiguration configuration;
private readonly ITelemetryService telemetryService;
+ private readonly IServiceProvider serviceProvider;
+ private readonly IBackgroundQueue queue;
- public ReportService(IAsbCloudDbContext db, ITelemetryService telemetryService)
+ public ReportService(IAsbCloudDbContext db, IConfiguration configuration, ITelemetryService telemetryService, IServiceProvider serviceProvider, IBackgroundQueue queue)
{
this.db = db;
+ this.configuration = configuration;
this.telemetryService = telemetryService;
+ this.queue = queue;
+ this.serviceProvider = serviceProvider;
+ RootPath = "reports";
+ }
+
+ public string RootPath { get ; private set; }
+
+ public int CreateReport(int wellId, int stepSeconds, int format, DateTime begin, DateTime end)
+ {
+ var newReportId = queue.EnqueueTask(() =>
+ {
+ var optionsBuilder = new DbContextOptionsBuilder();
+ optionsBuilder.UseNpgsql(configuration.GetConnectionString("DefaultConnection"));
+
+ using (var context = new AsbCloudDbContext(optionsBuilder.Options))
+ {
+ var generator = GetReportGenerator(wellId, begin, end, stepSeconds, format, context);
+ generator.Make();
+ }
+ });
+ return newReportId;
}
public int GetReportPagesCount(int wellId, DateTime begin, DateTime end, int stepSeconds, int format)
{
- var generator = GetReportGenerator(wellId, begin, end, stepSeconds, format);
+ var generator = GetReportGenerator(wellId, begin, end, stepSeconds, format, (AsbCloudDbContext)db);
return generator.GetPagesCount();
}
- public ReportPropertiesDto GetReportFileProperties(string reportName, string rootPath)
- {
- string path = Path.Combine(rootPath, reportName);
- FileStream fs = new FileStream(path, FileMode.Open);
- string contentType = Path.GetExtension(path);
- string fileName = Path.GetFileName(path);
-
- return new ReportPropertiesDto {
- Filestream = fs,
- ContentType = contentType,
- FileName = fileName
- };
- }
-
public DatesRangeDto GetReportsDatesRange(int wellId)
{
var telemetry = telemetryService.GetTelemetryByWellId(wellId);
@@ -51,11 +64,11 @@ namespace AsbCloudInfrastructure.Services
return new DatesRangeDto { From = result.From, To = result.To };
}
- private IReportGenerator GetReportGenerator(int wellId,DateTime begin, DateTime end, int stepSeconds, int format)
+ private IReportGenerator GetReportGenerator(int wellId, DateTime begin, DateTime end, int stepSeconds, int format, AsbCloudDbContext context)
{
- var dataSource = new ReportDataSourcePgCloud((AsbCloudDbContext)db, wellId);
+ var dataSource = new ReportDataSourcePgCloud(context, wellId);
var generator = new PdfGenerator(dataSource);
-
+ generator.ReportDirectory = Path.Combine(RootPath, $"{wellId}");
generator.Begin = begin;
generator.End = end;
generator.Step = TimeSpan.FromSeconds(stepSeconds);
diff --git a/AsbCloudWebApi/Controllers/ReportController.cs b/AsbCloudWebApi/Controllers/ReportController.cs
index 4f24c98e..118f136e 100644
--- a/AsbCloudWebApi/Controllers/ReportController.cs
+++ b/AsbCloudWebApi/Controllers/ReportController.cs
@@ -1,5 +1,4 @@
using System;
-using System.Threading.Tasks;
using System.IO;
using Microsoft.AspNetCore.Mvc;
using AsbCloudApp.Data;
@@ -35,15 +34,13 @@ namespace AsbCloudWebApi.Controllers
/// id скважины
/// дата начала интервала
/// дата окончания интервала
- /// шаг интервала
+ /// шаг интервала
/// формат отчета (0-PDF, 1-LASS)
/// id фоновой задачи формирования отчета
[HttpPost]
[Route("{wellId}/report")]
[ProducesResponseType(typeof(string), (int)System.Net.HttpStatusCode.OK)]
-
- // ЭТОТ МЕТОД ПОКА НЕ РЕАЛИЗОВАН
- public async Task CreateReportAsync(int wellId, int stepSeconds, int format, DateTime begin = default, DateTime end = default)
+ public IActionResult CreateReport(int wellId, int stepSeconds, int format, DateTime begin = default, DateTime end = default)
{
int? idCustomer = User.GetCustomerId();
@@ -53,17 +50,9 @@ namespace AsbCloudWebApi.Controllers
if (!wellService.CheckWellOwnership((int)idCustomer, wellId))
return Forbid();
- return await Task.Run(() =>
- {
- // создаем отчет. Это заготовка, пока еще не перенесена в сервис.
+ var id = reportService.CreateReport(wellId, stepSeconds, format, begin, end);
- var taskId = Task.CurrentId;
-
- if (taskId is null)
- throw new NullReferenceException("Не удалось получить id задачи");
-
- return Ok(taskId.ToString());
- });
+ return Ok(id);
}
///
@@ -86,14 +75,12 @@ namespace AsbCloudWebApi.Controllers
if (!wellService.CheckWellOwnership((int)idCustomer, wellId))
return Forbid();
-
- var options = reportService.GetReportFileProperties(reportName, appEnvironment.ContentRootPath);
-
- return File(options.Filestream, options.ContentType, options.FileName);
+ // TODO: словарь content typoв
+ return PhysicalFile(Path.Combine(reportService.RootPath, $"{wellId}", reportName), "application/pdf", reportName);
}
catch (FileNotFoundException ex)
{
- return NotFound("Файл не найден");
+ return NotFound($"Файл не найден. Текст ошибки: {ex.Message}");
}
}
@@ -103,7 +90,7 @@ namespace AsbCloudWebApi.Controllers
/// id скважины
/// дата начала интервала
/// дата окончания интервала
- /// шаг интервала
+ /// шаг интервала
/// формат отчета (0-PDF, 1-LASS)
/// прогнозируемое кол-во страниц отчета
[HttpGet]