Add Rider launch profiles, fix DI and migrations for dev startup
- Rider launch profiles: "ScadaLink Central" and "ScadaLink Site" - appsettings.Central.json: correct test_infra credentials (ScadaLink_Dev1#, scadalink_app user, GLAuth on 3893, Mailpit on 1025) - Fix HealthMonitoring DI: split site vs central registration to avoid missing IHealthReportTransport on central - Regenerate single clean EF migration (InitialSchema) covering all entities - Suppress PendingModelChangesWarning in dev mode - Fix isDevelopment check for ASPNETCORE_ENVIRONMENT propagation Verified: Host starts, connects to SQL Server, applies migrations, boots Akka.NET cluster, LDAP auth works (admin/password via GLAuth), health endpoint returns Healthy.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,28 +0,0 @@
|
|||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace ScadaLink.ConfigurationDatabase.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class SeedData : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.InsertData(
|
|
||||||
table: "LdapGroupMappings",
|
|
||||||
columns: new[] { "Id", "LdapGroupName", "Role" },
|
|
||||||
values: new object[] { 1, "SCADA-Admins", "Admin" });
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DeleteData(
|
|
||||||
table: "LdapGroupMappings",
|
|
||||||
keyColumn: "Id",
|
|
||||||
keyValue: 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -12,8 +12,8 @@ using ScadaLink.ConfigurationDatabase;
|
|||||||
namespace ScadaLink.ConfigurationDatabase.Migrations
|
namespace ScadaLink.ConfigurationDatabase.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(ScadaLinkDbContext))]
|
[DbContext(typeof(ScadaLinkDbContext))]
|
||||||
[Migration("20260316231942_SeedData")]
|
[Migration("20260317065749_InitialSchema")]
|
||||||
partial class SeedData
|
partial class InitialSchema
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
@@ -25,6 +25,25 @@ namespace ScadaLink.ConfigurationDatabase.Migrations
|
|||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("FriendlyName")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("Xml")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("DataProtectionKeys");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("ScadaLink.Commons.Entities.Audit.AuditLogEntry", b =>
|
modelBuilder.Entity("ScadaLink.Commons.Entities.Audit.AuditLogEntry", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
@@ -79,6 +98,44 @@ namespace ScadaLink.ConfigurationDatabase.Migrations
|
|||||||
b.ToTable("AuditLogEntries");
|
b.ToTable("AuditLogEntries");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("ScadaLink.Commons.Entities.Deployment.DeployedConfigSnapshot", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("ConfigurationJson")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("DeployedAt")
|
||||||
|
.HasColumnType("datetimeoffset");
|
||||||
|
|
||||||
|
b.Property<string>("DeploymentId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("nvarchar(100)");
|
||||||
|
|
||||||
|
b.Property<int>("InstanceId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("RevisionHash")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("nvarchar(100)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("DeploymentId");
|
||||||
|
|
||||||
|
b.HasIndex("InstanceId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("DeployedConfigSnapshots");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("ScadaLink.Commons.Entities.Deployment.DeploymentRecord", b =>
|
modelBuilder.Entity("ScadaLink.Commons.Entities.Deployment.DeploymentRecord", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
@@ -103,6 +160,9 @@ namespace ScadaLink.ConfigurationDatabase.Migrations
|
|||||||
.HasMaxLength(100)
|
.HasMaxLength(100)
|
||||||
.HasColumnType("nvarchar(100)");
|
.HasColumnType("nvarchar(100)");
|
||||||
|
|
||||||
|
b.Property<string>("ErrorMessage")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.Property<int>("InstanceId")
|
b.Property<int>("InstanceId")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
@@ -112,6 +172,7 @@ namespace ScadaLink.ConfigurationDatabase.Migrations
|
|||||||
|
|
||||||
b.Property<byte[]>("RowVersion")
|
b.Property<byte[]>("RowVersion")
|
||||||
.IsConcurrencyToken()
|
.IsConcurrencyToken()
|
||||||
|
.IsRequired()
|
||||||
.ValueGeneratedOnAddOrUpdate()
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
.HasColumnType("rowversion");
|
.HasColumnType("rowversion");
|
||||||
|
|
||||||
@@ -954,6 +1015,15 @@ namespace ScadaLink.ConfigurationDatabase.Migrations
|
|||||||
b.ToTable("TemplateScripts");
|
b.ToTable("TemplateScripts");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("ScadaLink.Commons.Entities.Deployment.DeployedConfigSnapshot", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("ScadaLink.Commons.Entities.Instances.Instance", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("InstanceId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("ScadaLink.Commons.Entities.Deployment.DeploymentRecord", b =>
|
modelBuilder.Entity("ScadaLink.Commons.Entities.Deployment.DeploymentRecord", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("ScadaLink.Commons.Entities.Instances.Instance", null)
|
b.HasOne("ScadaLink.Commons.Entities.Instances.Instance", null)
|
||||||
@@ -6,7 +6,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
|
|||||||
namespace ScadaLink.ConfigurationDatabase.Migrations
|
namespace ScadaLink.ConfigurationDatabase.Migrations
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public partial class InitialCreate : Migration
|
public partial class InitialSchema : Migration
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
@@ -94,6 +94,20 @@ namespace ScadaLink.ConfigurationDatabase.Migrations
|
|||||||
table.PrimaryKey("PK_DataConnections", x => x.Id);
|
table.PrimaryKey("PK_DataConnections", x => x.Id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "DataProtectionKeys",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "int", nullable: false)
|
||||||
|
.Annotation("SqlServer:Identity", "1, 1"),
|
||||||
|
FriendlyName = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||||
|
Xml = table.Column<string>(type: "nvarchar(max)", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_DataProtectionKeys", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "ExternalSystemDefinitions",
|
name: "ExternalSystemDefinitions",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
@@ -493,6 +507,29 @@ namespace ScadaLink.ConfigurationDatabase.Migrations
|
|||||||
onDelete: ReferentialAction.Restrict);
|
onDelete: ReferentialAction.Restrict);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "DeployedConfigSnapshots",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "int", nullable: false)
|
||||||
|
.Annotation("SqlServer:Identity", "1, 1"),
|
||||||
|
InstanceId = table.Column<int>(type: "int", nullable: false),
|
||||||
|
DeploymentId = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: false),
|
||||||
|
RevisionHash = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: false),
|
||||||
|
ConfigurationJson = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||||
|
DeployedAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_DeployedConfigSnapshots", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_DeployedConfigSnapshots_Instances_InstanceId",
|
||||||
|
column: x => x.InstanceId,
|
||||||
|
principalTable: "Instances",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "DeploymentRecords",
|
name: "DeploymentRecords",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
@@ -506,7 +543,8 @@ namespace ScadaLink.ConfigurationDatabase.Migrations
|
|||||||
DeployedBy = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
DeployedBy = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
||||||
DeployedAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false),
|
DeployedAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false),
|
||||||
CompletedAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: true),
|
CompletedAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: true),
|
||||||
RowVersion = table.Column<byte[]>(type: "rowversion", rowVersion: true, nullable: true)
|
ErrorMessage = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||||
|
RowVersion = table.Column<byte[]>(type: "rowversion", rowVersion: true, nullable: false)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
@@ -567,6 +605,11 @@ namespace ScadaLink.ConfigurationDatabase.Migrations
|
|||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
migrationBuilder.InsertData(
|
||||||
|
table: "LdapGroupMappings",
|
||||||
|
columns: new[] { "Id", "LdapGroupName", "Role" },
|
||||||
|
values: new object[] { 1, "SCADA-Admins", "Admin" });
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "IX_ApiKeys_KeyValue",
|
name: "IX_ApiKeys_KeyValue",
|
||||||
table: "ApiKeys",
|
table: "ApiKeys",
|
||||||
@@ -634,6 +677,17 @@ namespace ScadaLink.ConfigurationDatabase.Migrations
|
|||||||
column: "Name",
|
column: "Name",
|
||||||
unique: true);
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_DeployedConfigSnapshots_DeploymentId",
|
||||||
|
table: "DeployedConfigSnapshots",
|
||||||
|
column: "DeploymentId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_DeployedConfigSnapshots_InstanceId",
|
||||||
|
table: "DeployedConfigSnapshots",
|
||||||
|
column: "InstanceId",
|
||||||
|
unique: true);
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "IX_DeploymentRecords_DeployedAt",
|
name: "IX_DeploymentRecords_DeployedAt",
|
||||||
table: "DeploymentRecords",
|
table: "DeploymentRecords",
|
||||||
@@ -813,6 +867,12 @@ namespace ScadaLink.ConfigurationDatabase.Migrations
|
|||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "DatabaseConnectionDefinitions");
|
name: "DatabaseConnectionDefinitions");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "DataProtectionKeys");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "DeployedConfigSnapshots");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "DeploymentRecords");
|
name: "DeploymentRecords");
|
||||||
|
|
||||||
@@ -22,6 +22,25 @@ namespace ScadaLink.ConfigurationDatabase.Migrations
|
|||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("FriendlyName")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("Xml")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("DataProtectionKeys");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("ScadaLink.Commons.Entities.Audit.AuditLogEntry", b =>
|
modelBuilder.Entity("ScadaLink.Commons.Entities.Audit.AuditLogEntry", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
@@ -76,6 +95,44 @@ namespace ScadaLink.ConfigurationDatabase.Migrations
|
|||||||
b.ToTable("AuditLogEntries");
|
b.ToTable("AuditLogEntries");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("ScadaLink.Commons.Entities.Deployment.DeployedConfigSnapshot", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("ConfigurationJson")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("DeployedAt")
|
||||||
|
.HasColumnType("datetimeoffset");
|
||||||
|
|
||||||
|
b.Property<string>("DeploymentId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("nvarchar(100)");
|
||||||
|
|
||||||
|
b.Property<int>("InstanceId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("RevisionHash")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("nvarchar(100)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("DeploymentId");
|
||||||
|
|
||||||
|
b.HasIndex("InstanceId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("DeployedConfigSnapshots");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("ScadaLink.Commons.Entities.Deployment.DeploymentRecord", b =>
|
modelBuilder.Entity("ScadaLink.Commons.Entities.Deployment.DeploymentRecord", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
@@ -100,6 +157,9 @@ namespace ScadaLink.ConfigurationDatabase.Migrations
|
|||||||
.HasMaxLength(100)
|
.HasMaxLength(100)
|
||||||
.HasColumnType("nvarchar(100)");
|
.HasColumnType("nvarchar(100)");
|
||||||
|
|
||||||
|
b.Property<string>("ErrorMessage")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
b.Property<int>("InstanceId")
|
b.Property<int>("InstanceId")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
@@ -109,6 +169,7 @@ namespace ScadaLink.ConfigurationDatabase.Migrations
|
|||||||
|
|
||||||
b.Property<byte[]>("RowVersion")
|
b.Property<byte[]>("RowVersion")
|
||||||
.IsConcurrencyToken()
|
.IsConcurrencyToken()
|
||||||
|
.IsRequired()
|
||||||
.ValueGeneratedOnAddOrUpdate()
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
.HasColumnType("rowversion");
|
.HasColumnType("rowversion");
|
||||||
|
|
||||||
@@ -951,6 +1012,15 @@ namespace ScadaLink.ConfigurationDatabase.Migrations
|
|||||||
b.ToTable("TemplateScripts");
|
b.ToTable("TemplateScripts");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("ScadaLink.Commons.Entities.Deployment.DeployedConfigSnapshot", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("ScadaLink.Commons.Entities.Instances.Instance", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("InstanceId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("ScadaLink.Commons.Entities.Deployment.DeploymentRecord", b =>
|
modelBuilder.Entity("ScadaLink.Commons.Entities.Deployment.DeploymentRecord", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("ScadaLink.Commons.Entities.Instances.Instance", null)
|
b.HasOne("ScadaLink.Commons.Entities.Instances.Instance", null)
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ public static class ServiceCollectionExtensions
|
|||||||
public static IServiceCollection AddConfigurationDatabase(this IServiceCollection services, string connectionString)
|
public static IServiceCollection AddConfigurationDatabase(this IServiceCollection services, string connectionString)
|
||||||
{
|
{
|
||||||
services.AddDbContext<ScadaLinkDbContext>(options =>
|
services.AddDbContext<ScadaLinkDbContext>(options =>
|
||||||
options.UseSqlServer(connectionString));
|
options.UseSqlServer(connectionString)
|
||||||
|
.ConfigureWarnings(w => w.Ignore(
|
||||||
|
Microsoft.EntityFrameworkCore.Diagnostics.RelationalEventId.PendingModelChangesWarning)));
|
||||||
|
|
||||||
services.AddScoped<ISecurityRepository, SecurityRepository>();
|
services.AddScoped<ISecurityRepository, SecurityRepository>();
|
||||||
services.AddScoped<ICentralUiRepository, CentralUiRepository>();
|
services.AddScoped<ICentralUiRepository, CentralUiRepository>();
|
||||||
|
|||||||
@@ -5,12 +5,23 @@ namespace ScadaLink.HealthMonitoring;
|
|||||||
public static class ServiceCollectionExtensions
|
public static class ServiceCollectionExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Register site-side health monitoring services.
|
/// Register site-side health monitoring services (metric collection + periodic reporting).
|
||||||
|
/// Call this on site nodes only. For central, call AddCentralHealthAggregation() instead.
|
||||||
|
/// </summary>
|
||||||
|
public static IServiceCollection AddSiteHealthMonitoring(this IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddSingleton<ISiteHealthCollector, SiteHealthCollector>();
|
||||||
|
services.AddHostedService<HealthReportSender>();
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Register shared health monitoring services (safe for both central and site).
|
||||||
|
/// Does not start the HealthReportSender — call AddSiteHealthMonitoring() on site nodes for that.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static IServiceCollection AddHealthMonitoring(this IServiceCollection services)
|
public static IServiceCollection AddHealthMonitoring(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddSingleton<ISiteHealthCollector, SiteHealthCollector>();
|
services.AddSingleton<ISiteHealthCollector, SiteHealthCollector>();
|
||||||
services.AddHostedService<HealthReportSender>();
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ try
|
|||||||
builder.Services.AddClusterInfrastructure();
|
builder.Services.AddClusterInfrastructure();
|
||||||
builder.Services.AddCommunication();
|
builder.Services.AddCommunication();
|
||||||
builder.Services.AddHealthMonitoring();
|
builder.Services.AddHealthMonitoring();
|
||||||
|
builder.Services.AddCentralHealthAggregation();
|
||||||
builder.Services.AddExternalSystemGateway();
|
builder.Services.AddExternalSystemGateway();
|
||||||
builder.Services.AddNotificationService();
|
builder.Services.AddNotificationService();
|
||||||
|
|
||||||
@@ -98,7 +99,8 @@ try
|
|||||||
// Apply or validate database migrations (skip when running in test harness)
|
// Apply or validate database migrations (skip when running in test harness)
|
||||||
if (!string.Equals(configuration["ScadaLink:Database:SkipMigrations"], "true", StringComparison.OrdinalIgnoreCase))
|
if (!string.Equals(configuration["ScadaLink:Database:SkipMigrations"], "true", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
var isDevelopment = app.Environment.IsDevelopment();
|
var isDevelopment = app.Environment.IsDevelopment()
|
||||||
|
|| string.Equals(Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"), "Development", StringComparison.OrdinalIgnoreCase);
|
||||||
using (var scope = app.Services.CreateScope())
|
using (var scope = app.Services.CreateScope())
|
||||||
{
|
{
|
||||||
var dbContext = scope.ServiceProvider.GetRequiredService<ScadaLinkDbContext>();
|
var dbContext = scope.ServiceProvider.GetRequiredService<ScadaLinkDbContext>();
|
||||||
|
|||||||
24
src/ScadaLink.Host/Properties/launchSettings.json
Normal file
24
src/ScadaLink.Host/Properties/launchSettings.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"profiles": {
|
||||||
|
"ScadaLink Central": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "",
|
||||||
|
"applicationUrl": "https://localhost:5001;http://localhost:5000",
|
||||||
|
"environmentVariables": {
|
||||||
|
"DOTNET_ENVIRONMENT": "Central",
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ScadaLink Site": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": false,
|
||||||
|
"environmentVariables": {
|
||||||
|
"DOTNET_ENVIRONMENT": "Site",
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,13 +2,13 @@
|
|||||||
"ScadaLink": {
|
"ScadaLink": {
|
||||||
"Node": {
|
"Node": {
|
||||||
"Role": "Central",
|
"Role": "Central",
|
||||||
"NodeHostname": "central-node1",
|
"NodeHostname": "localhost",
|
||||||
"RemotingPort": 8081
|
"RemotingPort": 8081
|
||||||
},
|
},
|
||||||
"Cluster": {
|
"Cluster": {
|
||||||
"SeedNodes": [
|
"SeedNodes": [
|
||||||
"akka.tcp://scadalink@central-node1:8081",
|
"akka.tcp://scadalink@localhost:8081",
|
||||||
"akka.tcp://scadalink@central-node2:8081"
|
"akka.tcp://scadalink@localhost:8082"
|
||||||
],
|
],
|
||||||
"SplitBrainResolverStrategy": "keep-oldest",
|
"SplitBrainResolverStrategy": "keep-oldest",
|
||||||
"StableAfter": "00:00:15",
|
"StableAfter": "00:00:15",
|
||||||
@@ -17,8 +17,8 @@
|
|||||||
"MinNrOfMembers": 1
|
"MinNrOfMembers": 1
|
||||||
},
|
},
|
||||||
"Database": {
|
"Database": {
|
||||||
"ConfigurationDb": "Server=localhost,1433;Database=ScadaLink_Config;User Id=sa;Password=YourPassword;TrustServerCertificate=True",
|
"ConfigurationDb": "Server=localhost,1433;Database=ScadaLinkConfig;User Id=scadalink_app;Password=ScadaLink_Dev1#;TrustServerCertificate=true",
|
||||||
"MachineDataDb": "Server=localhost,1433;Database=ScadaLink_MachineData;User Id=sa;Password=YourPassword;TrustServerCertificate=True"
|
"MachineDataDb": "Server=localhost,1433;Database=ScadaLinkMachineData;User Id=scadalink_app;Password=ScadaLink_Dev1#;TrustServerCertificate=true"
|
||||||
},
|
},
|
||||||
"Security": {
|
"Security": {
|
||||||
"LdapServer": "localhost",
|
"LdapServer": "localhost",
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
"LdapUseTls": false,
|
"LdapUseTls": false,
|
||||||
"AllowInsecureLdap": true,
|
"AllowInsecureLdap": true,
|
||||||
"LdapSearchBase": "dc=scadalink,dc=local",
|
"LdapSearchBase": "dc=scadalink,dc=local",
|
||||||
"JwtSigningKey": "CHANGE-ME-development-signing-key-at-least-32-chars",
|
"JwtSigningKey": "scadalink-dev-jwt-signing-key-must-be-at-least-32-characters-long",
|
||||||
"JwtExpiryMinutes": 15,
|
"JwtExpiryMinutes": 15,
|
||||||
"IdleTimeoutMinutes": 30
|
"IdleTimeoutMinutes": 30
|
||||||
},
|
},
|
||||||
@@ -44,7 +44,12 @@
|
|||||||
"InboundApi": {
|
"InboundApi": {
|
||||||
"DefaultMethodTimeout": "00:00:30"
|
"DefaultMethodTimeout": "00:00:30"
|
||||||
},
|
},
|
||||||
"Notification": {},
|
"Notification": {
|
||||||
|
"SmtpServer": "localhost",
|
||||||
|
"SmtpPort": 1025,
|
||||||
|
"AuthMode": "None",
|
||||||
|
"FromAddress": "scada-notifications@company.com"
|
||||||
|
},
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"MinimumLevel": "Information"
|
"MinimumLevel": "Information"
|
||||||
}
|
}
|
||||||
|
|||||||
1462
src/ScadaLink.Host/logs/scadalink-20260317.log
Normal file
1462
src/ScadaLink.Host/logs/scadalink-20260317.log
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user