diff --git a/DeepTrace/Data/DataSourceDefinition.cs b/DeepTrace/Data/DataSourceDefinition.cs
index 0002a21..a5ff797 100644
--- a/DeepTrace/Data/DataSourceDefinition.cs
+++ b/DeepTrace/Data/DataSourceDefinition.cs
@@ -10,7 +10,7 @@ public class DataSourceQuery
}
public string Query { get; set; }
- public MudBlazor.Utilities.MudColor Color { get; set; }
+ public string Color { get; set; }
}
diff --git a/DeepTrace/DeepTrace.csproj b/DeepTrace/DeepTrace.csproj
index 064fd66..eec8e4b 100644
--- a/DeepTrace/DeepTrace.csproj
+++ b/DeepTrace/DeepTrace.csproj
@@ -10,13 +10,10 @@
+
-
-
-
-
diff --git a/DeepTrace/Pages/DataSources.razor b/DeepTrace/Pages/DataSources.razor
index 4392b80..9a3926b 100644
--- a/DeepTrace/Pages/DataSources.razor
+++ b/DeepTrace/Pages/DataSources.razor
@@ -1,6 +1,7 @@
@page "/datasources"
@using DeepTrace.Controls
@using DeepTrace.Data;
+@using DeepTrace.Services;
@using Microsoft.ML;
@using System.Data;
@using MudBlazor;
@@ -11,6 +12,7 @@
@inject PrometheusClient Prometheus
@inject IDialogService DialogService
+@inject IDataSourceStorageService StorageService
DataSources
@@ -28,7 +30,7 @@
-
+
@foreach (var source in _dataSources)
{
@source.Name
@@ -67,7 +69,7 @@
}
-
+
}
@@ -113,7 +115,7 @@
private class PrometheusForm
{
[Required]
- public DataSourceDefinition Source { get; set; } = new();
+ public DataSourceStorage Source { get; set; } = new();
public DateRange Dates { get; set; } = new DateRange(DateTime.UtcNow.Date - TimeSpan.FromDays(14), DateTime.UtcNow.Date);
@@ -129,7 +131,7 @@
}
private PrometheusForm _queryForm = new();
- private List _dataSources = new()
+ private List _dataSources = new()
{
new()
{
@@ -194,9 +196,12 @@
};
- protected override void OnInitialized()
+ protected override async Task OnInitializedAsync()
{
base.OnInitialized();
+ var res = await StorageService.Load();
+ if (res.Count > 0)
+ _dataSources = res;
_queryForm.Source = _dataSources[0];
}
@@ -225,7 +230,7 @@
StateHasChanged();
}
- private void HandleDeleteSource()
+ private async Task HandleDeleteSource()
{
if (_dataSources.Count < 2)
{
@@ -238,8 +243,16 @@
ShowError("Not found");
return;
}
+
+ var toDelete = _dataSources[pos];
_dataSources.RemoveAt(pos);
_queryForm.Source = _dataSources[pos<_dataSources.Count ? pos: _dataSources.Count-1];
+
+ if ( toDelete.Id == null )
+ {
+ await StorageService.Delete(toDelete);
+ }
+
StateHasChanged();
}
@@ -267,19 +280,24 @@
var startDate = _queryForm.Dates.Start.Value.Date + startTime;
var endDate = _queryForm.Dates.End.Value.Date + endTime;
- if (!await FormatQueries())
- return;
-
- TimeSpan step;
-
//step = _queryForm.Step;
//var n = (endDate - startDate).TotalSeconds / step.TotalSeconds;
//if (n > 1000)
+
+ // use automatic step value to always request 500 elements
var seconds = (endDate - startDate).TotalSeconds / 500.0;
if (seconds < 1.0)
seconds = 1.0;
- step = TimeSpan.FromSeconds(seconds);
+ var step = TimeSpan.FromSeconds(seconds);
+ // -------------------------------------------------- check syntax and format all queries
+ if (!await FormatQueries())
+ return;
+
+ // -------------------------------------------------- persist data source!
+ await StorageService.Store(_queryForm.Source);
+
+ // -------------------------------------------------- execute queries
var tasks = _queryForm.Source.Queries
.Select(x => Prometheus.RangeQuery(x.Query, startDate, endDate, step, TimeSpan.FromSeconds(2)))
.ToArray();
@@ -321,7 +339,7 @@
new()
{
Name = def.Query,
- Color = def.Color.Value,
+ Color = def.Color,
Data = m[0].Values!.ToList()
}
);
diff --git a/DeepTrace/Program.cs b/DeepTrace/Program.cs
index 6a61884..fd27dba 100644
--- a/DeepTrace/Program.cs
+++ b/DeepTrace/Program.cs
@@ -1,8 +1,7 @@
-using Microsoft.AspNetCore.Components;
-using Microsoft.AspNetCore.Components.Web;
-using DeepTrace.Data;
using MudBlazor.Services;
using PrometheusAPI;
+using MongoDB.Driver;
+using DeepTrace.Services;
var builder = WebApplication.CreateBuilder(args);
@@ -11,7 +10,12 @@ builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddMudServices();
-builder.Services.AddHttpClient(c => c.BaseAddress = new UriBuilder("http://localhost:9090").Uri);
+builder.Services.AddHttpClient(c => c.BaseAddress = new UriBuilder(builder.Configuration.GetValue("Connections:Prometheus")!).Uri);
+
+builder.Services
+ .AddSingleton( s => new MongoClient(builder.Configuration.GetValue("Connections:MongoDb") ))
+ .AddSingleton()
+ ;
var app = builder.Build();
@@ -21,7 +25,6 @@ if (!app.Environment.IsDevelopment())
app.UseExceptionHandler("/Error");
}
-
app.UseStaticFiles();
app.UseRouting();
diff --git a/DeepTrace/Services/DataSourceStorageService.cs b/DeepTrace/Services/DataSourceStorageService.cs
new file mode 100644
index 0000000..e565807
--- /dev/null
+++ b/DeepTrace/Services/DataSourceStorageService.cs
@@ -0,0 +1,58 @@
+using MongoDB.Bson;
+using MongoDB.Driver;
+
+namespace DeepTrace.Services
+{
+ public class DataSourceStorageService : IDataSourceStorageService
+ {
+
+ private const string MongoDBDatabaseName = "DeepTrace";
+ private const string MongoDBCollection = "Sources";
+
+ private readonly IMongoClient _client;
+
+ public DataSourceStorageService(IMongoClient client)
+ {
+ _client = client;
+ }
+
+ public async Task> Load()
+ {
+ var db = _client.GetDatabase(MongoDBDatabaseName);
+ var collection = db.GetCollection(MongoDBCollection);
+
+ var res = await (await collection.FindAsync("{}")).ToListAsync();
+ return res;
+ }
+ public async Task Store(DataSourceStorage source)
+ {
+ var db = _client.GetDatabase(MongoDBDatabaseName);
+ var collection = db.GetCollection(MongoDBCollection);
+
+ if ( source.Id == null )
+ source.Id = ObjectId.GenerateNewId();
+
+ // use upsert (insert or update) to automatically handle subsequent updates
+ await collection.ReplaceOneAsync(
+ filter: new BsonDocument("_id", source.Id),
+ options: new ReplaceOptions { IsUpsert = true },
+ replacement: source
+ );
+ }
+
+ public async Task Delete(DataSourceStorage source, bool ignoreNotStored = false)
+ {
+ if ( source.Id == null )
+ {
+ if (!ignoreNotStored)
+ throw new InvalidDataException("Source was not stored yet. There is nothing to delete");
+ return;
+ }
+
+ var db = _client.GetDatabase(MongoDBDatabaseName);
+ var collection = db.GetCollection(MongoDBCollection);
+
+ await collection.DeleteOneAsync($"_id = {source.Id}");
+ }
+ }
+}
diff --git a/DeepTrace/Services/IDataSourceStorageService.cs b/DeepTrace/Services/IDataSourceStorageService.cs
new file mode 100644
index 0000000..60b952a
--- /dev/null
+++ b/DeepTrace/Services/IDataSourceStorageService.cs
@@ -0,0 +1,19 @@
+using DeepTrace.Data;
+using MongoDB.Bson.Serialization.Attributes;
+using MongoDB.Bson;
+
+namespace DeepTrace.Services
+{
+ public class DataSourceStorage : DataSourceDefinition
+ {
+ [BsonId]
+ public ObjectId? Id { get; set; }
+ }
+
+ public interface IDataSourceStorageService
+ {
+ Task Delete(DataSourceStorage source, bool ignoreNotStored = false);
+ Task> Load();
+ Task Store(DataSourceStorage source);
+ }
+}
\ No newline at end of file
diff --git a/DeepTrace/appsettings.json b/DeepTrace/appsettings.json
index 10f68b8..6b73d63 100644
--- a/DeepTrace/appsettings.json
+++ b/DeepTrace/appsettings.json
@@ -5,5 +5,10 @@
"Microsoft.AspNetCore": "Warning"
}
},
- "AllowedHosts": "*"
+ "AllowedHosts": "*",
+
+ "Connections": {
+ "Prometheus": "http://localhost:9090",
+ "MongoDb": "mongodb://localhost:27017"
+ }
}