Skip to content

Commit 9f6a58b

Browse files
committed
rebuild storing logic #23
1 parent 339ee5b commit 9f6a58b

File tree

14 files changed

+207
-36
lines changed

14 files changed

+207
-36
lines changed

src/NTorSpectator.Database/DatabaseInjector.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ public static IServiceCollection AddDatabase(this IServiceCollection services, I
2222
services.AddDbContextPool<DataContext>(opts => opts.UseNpgsql(configuration.GetConnectionString("SpectatorDatabase")));
2323
services
2424
.AddTransient<ISitesRepository, SitesRepository>()
25-
.AddTransient<IObservesRepository, ObservesRepository>();
25+
.AddTransient<IObservesRepository, ObservesRepository>()
26+
.AddTransient<IReportsRepository, ReportsRepository>();
2627

2728
return services;
2829
}

src/NTorSpectator.Database/Repositories/ObservesRepository.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ public ObservesRepository(DataContext context)
1414

1515
public async Task<Observation?> GetLastObservationForSite(string siteUri)
1616
{
17-
var siteId = await _context.Sites
18-
.Where(x => x.SiteUri == siteUri)
19-
.Select(x => x.Id)
20-
.SingleAsync();
21-
var observation = await _context.Observations.Where(x => x.SiteId == siteId).OrderByDescending(x => x.ObservedAt).FirstOrDefaultAsync();
17+
var observation = await _context.Observations
18+
.Include(x => x.Site)
19+
.Where(x => x.Site.SiteUri == siteUri)
20+
.OrderByDescending(x => x.ObservedAt)
21+
.FirstOrDefaultAsync();
2222

2323
return observation is null ?
2424
null :
25-
new Observation { ObservedAt = observation.ObservedAt, IsAvailable = observation.IsAvailable };
25+
new Observation { ObservedAt = observation.ObservedAt, IsAvailable = observation.IsAvailable, SiteUri = observation.Site.SiteUri};
2626
}
2727

2828
public async Task AddNewObservation(string siteUri, bool isAvailable, DateTime timestamp)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using Microsoft.EntityFrameworkCore;
2+
using Microsoft.Extensions.Logging;
3+
using NTorSpectator.Database.Models;
4+
using NTorSpectator.Services.Models;
5+
using NTorSpectator.Services.Persistent;
6+
7+
namespace NTorSpectator.Database.Repositories;
8+
9+
internal class ReportsRepository : IReportsRepository
10+
{
11+
private readonly DataContext _context;
12+
private readonly ILogger<ReportsRepository> _logger;
13+
14+
public ReportsRepository(DataContext context, ILogger<ReportsRepository> logger)
15+
{
16+
_context = context;
17+
_logger = logger;
18+
}
19+
20+
public async Task SaveReport(Report report)
21+
{
22+
var siteList = await _context.Sites.ToListAsync();
23+
var reportDal = new ObservationReport();
24+
foreach (var observation in report.Observations)
25+
{
26+
var site = siteList.SingleOrDefault(x => x.SiteUri == observation.SiteUri);
27+
if (site is null)
28+
{
29+
_logger.LogWarning("Site is not found in database, won't save observation for uri {SiteUri}", observation.SiteUri);
30+
continue;
31+
}
32+
reportDal.Observations.Add(new(){Site = site, ObservedAt = observation.ObservedAt, IsAvailable = observation.IsAvailable});
33+
}
34+
35+
foreach (var siteEvent in report.Events)
36+
{
37+
var site = siteList.SingleOrDefault(x => x.SiteUri == siteEvent.SiteUri);
38+
if (site is null)
39+
{
40+
_logger.LogWarning("Site is not found in database, won't save event for uri {SiteUri}", siteEvent.SiteUri);
41+
continue;
42+
}
43+
reportDal.Events.Add(new(){Site = site, OccuredAt = siteEvent.OccuredAt, EventType = (int)siteEvent.Kind});
44+
}
45+
46+
_context.Reports.Add(reportDal);
47+
await _context.SaveChangesAsync();
48+
}
49+
}

src/NTorSpectator.Services/BizlogicInjector.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,16 @@
44

55
namespace NTorSpectator.Services;
66

7+
/// <summary>
8+
/// Injects business logic into application
9+
/// </summary>
710
public static class BizlogicInjector
811
{
12+
/// <summary>
13+
/// Inject bizlogic services into DI
14+
/// </summary>
15+
/// <param name="services">DI containEr</param>
16+
/// <returns></returns>
917
public static IServiceCollection AddBizLogic(this IServiceCollection services)
1018
{
1119
services.AddTransient<ISitesCatalogue, SitesCatalogue>()
Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1+
using NTorSpectator.Services.Models;
2+
13
namespace NTorSpectator.Services;
24

5+
/// <summary>
6+
/// Mastodon toots sender
7+
/// </summary>
38
public interface IReporter
49
{
5-
Task ReportWentDown(string siteUri, DateTime lastSeen);
6-
Task ReportCameUp(string siteUri);
10+
/// <summary>
11+
/// Publish toot with report data
12+
/// </summary>
13+
/// <param name="report">Report to publish</param>
14+
Task PublishReportData(Report report);
715
}
Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
1+
using NTorSpectator.Services.Models;
2+
13
namespace NTorSpectator.Services;
24

5+
/// <summary>
6+
/// Service which deals with sites observations
7+
/// </summary>
38
public interface ISiteObserver
49
{
5-
Task AddNewObservation(string siteUri, bool isAvailable);
10+
/// <summary>
11+
/// Saves report into database
12+
/// </summary>
13+
/// <param name="report">Report to save</param>
14+
Task SaveReport(Report report);
15+
16+
/// <summary>
17+
/// Generate event for this observation
18+
/// </summary>
19+
/// <param name="observation">Observation to generate event based on it</param>
20+
/// <returns>Event if site availability changed. Null - otherwise</returns>
21+
Task<AvailabilityEvent?> GenerateEvent(Observation observation);
622
}

src/NTorSpectator.Services/ISitesCatalogue.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,9 @@ public interface ISitesCatalogue
1414
/// <returns>true if the site was added, otherwise - false</returns>
1515
Task<bool> AddIfNotExists(string siteUri);
1616

17+
/// <summary>
18+
/// Get all sites from the persistent site catalogue
19+
/// </summary>
20+
/// <returns></returns>
1721
Task<IReadOnlyCollection<Site>> GetAllSites();
1822
}
Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,47 @@
11
using Microsoft.Extensions.Logging;
2+
using NTorSpectator.Services.Models;
23
using NTorSpectator.Services.Persistent;
34

45
namespace NTorSpectator.Services.Logic;
56

6-
public class SiteObserver : ISiteObserver
7+
internal class SiteObserver : ISiteObserver
78
{
8-
private readonly IReporter _reporter;
9-
private readonly IObservesRepository _repo;
9+
private readonly IObservesRepository _observationsRepository;
1010
private readonly ILogger<SiteObserver> _logger;
11+
private readonly IReportsRepository _reportsRepository;
1112

12-
public SiteObserver(IReporter reporter, IObservesRepository repo, ILogger<SiteObserver> logger)
13+
public SiteObserver(IReporter reporter, IObservesRepository observationsRepository, ILogger<SiteObserver> logger, IReportsRepository reportsRepository)
1314
{
14-
_reporter = reporter;
15-
_repo = repo;
15+
_observationsRepository = observationsRepository;
1616
_logger = logger;
17+
_reportsRepository = reportsRepository;
1718
}
1819

19-
public async Task AddNewObservation(string siteUri, bool isAvailable)
20+
public async Task<AvailabilityEvent?> GenerateEvent(Observation observation)
2021
{
21-
using var _ = _logger.BeginScope(new Dictionary<string, object> { { "SiteUri", siteUri }, { "IsAvailable", isAvailable } });
22+
using var _ = _logger.BeginScope(new Dictionary<string, object> { { "SiteUri", observation.SiteUri }, { "IsAvailable", observation.IsAvailable } });
2223
_logger.LogDebug("Got new observation to save");
23-
var previousObservation = await _repo.GetLastObservationForSite(siteUri);
24-
await _repo.AddNewObservation(siteUri, isAvailable, DateTime.UtcNow);
25-
_logger.LogInformation("Saved new observation");
24+
var previousObservation = await _observationsRepository.GetLastObservationForSite(observation.SiteUri);
2625
if (previousObservation is null)
2726
{
2827
_logger.LogDebug("This is first observation for site. Won't compare with previous");
29-
return;
28+
return null;
3029
}
3130

32-
if (previousObservation.IsAvailable == isAvailable)
31+
if (previousObservation.IsAvailable == observation.IsAvailable)
3332
{
34-
_logger.LogDebug("Site availability has not changed, nothing to report");
35-
return;
33+
_logger.LogDebug("Site availability has not changed, won't create event");
34+
return null;
3635
}
3736

38-
if (isAvailable)
37+
_logger.LogDebug("Site availability changed! Will create new event");
38+
return new()
3939
{
40-
await _reporter.ReportCameUp(siteUri);
41-
_logger.LogInformation("Reported site came up");
42-
}
43-
else
44-
{
45-
await _reporter.ReportWentDown(siteUri, previousObservation.ObservedAt);
46-
_logger.LogInformation("Reported site went down");
47-
}
48-
40+
SiteUri = observation.SiteUri,
41+
OccuredAt = observation.ObservedAt,
42+
Kind = observation.IsAvailable ? AvailabilityEvent.EventType.Up : AvailabilityEvent.EventType.Down
43+
};
4944
}
45+
46+
public Task SaveReport(Report report) => _reportsRepository.SaveReport(report);
5047
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
namespace NTorSpectator.Services.Models;
2+
3+
/// <summary>
4+
/// One event for the site: came up or gone down
5+
/// </summary>
6+
public class AvailabilityEvent
7+
{
8+
/// <summary>
9+
/// Site url
10+
/// </summary>
11+
public required string SiteUri { get; init; }
12+
13+
/// <summary>
14+
/// Site came up or gone down
15+
/// </summary>
16+
public EventType Kind { get; set; }
17+
18+
/// <summary>
19+
/// When the event has occured
20+
/// </summary>
21+
public DateTime OccuredAt { get; set; }
22+
23+
/// <summary>
24+
/// Event types - down or up
25+
/// </summary>
26+
public enum EventType
27+
{
28+
/// <summary>
29+
/// No value
30+
/// </summary>
31+
None = 0,
32+
33+
/// <summary>
34+
/// Site gone down
35+
/// </summary>
36+
Down = -1,
37+
38+
/// <summary>
39+
/// Site came up
40+
/// </summary>
41+
Up = 1
42+
}
43+
}

src/NTorSpectator.Services/Models/Observation.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,9 @@ public class Observation
1414
/// Is available
1515
/// </summary>
1616
public bool IsAvailable { get; set; }
17+
18+
/// <summary>
19+
/// Site uri, which was observed
20+
/// </summary>
21+
public required string SiteUri { get; init; }
1722
}

0 commit comments

Comments
 (0)