feat: include data connections and SMTP in artifact deployment

This commit is contained in:
Joseph Doherty
2026-03-17 13:48:52 -04:00
parent e313eda9fd
commit 2f3e0ceecb
17 changed files with 151 additions and 29 deletions

View File

@@ -0,0 +1,6 @@
namespace ScadaLink.Commons.Messages.Artifacts;
public record DataConnectionArtifact(
string Name,
string Protocol,
string? ConfigurationJson);

View File

@@ -6,4 +6,6 @@ public record DeployArtifactsCommand(
IReadOnlyList<ExternalSystemArtifact>? ExternalSystems,
IReadOnlyList<DatabaseConnectionArtifact>? DatabaseConnections,
IReadOnlyList<NotificationListArtifact>? NotificationLists,
IReadOnlyList<DataConnectionArtifact>? DataConnections,
IReadOnlyList<SmtpConfigurationArtifact>? SmtpConfigurations,
DateTimeOffset Timestamp);

View File

@@ -0,0 +1,11 @@
namespace ScadaLink.Commons.Messages.Artifacts;
public record SmtpConfigurationArtifact(
string Name,
string Server,
int Port,
string AuthMode,
string FromAddress,
string? Username,
string? Password,
string? OAuthConfig);

View File

@@ -479,6 +479,27 @@ public class DeploymentManagerActor : ReceiveActor, IWithTimers
}
}
// Store data connection definitions (OPC UA endpoints, etc.)
if (command.DataConnections != null)
{
foreach (var dc in command.DataConnections)
{
await _storage.StoreDataConnectionDefinitionAsync(
dc.Name, dc.Protocol, dc.ConfigurationJson);
}
}
// Store SMTP configurations
if (command.SmtpConfigurations != null)
{
foreach (var smtp in command.SmtpConfigurations)
{
await _storage.StoreSmtpConfigurationAsync(
smtp.Name, smtp.Server, smtp.Port, smtp.AuthMode,
smtp.FromAddress, smtp.Username, smtp.Password, smtp.OAuthConfig);
}
}
return new ArtifactDeploymentResponse(
command.DeploymentId, "", true, null, DateTimeOffset.UtcNow);
}

View File

@@ -78,6 +78,13 @@ public class SiteStorageService
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS data_connection_definitions (
name TEXT PRIMARY KEY,
protocol TEXT NOT NULL,
configuration TEXT,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS smtp_configurations (
name TEXT PRIMARY KEY,
server TEXT NOT NULL,
@@ -467,6 +474,60 @@ public class SiteStorageService
await command.ExecuteNonQueryAsync();
}
// ── Data Connection Definition CRUD ──
/// <summary>
/// Stores or updates a data connection definition (OPC UA endpoint, etc.).
/// </summary>
public async Task StoreDataConnectionDefinitionAsync(string name, string protocol, string? configJson)
{
await using var connection = new SqliteConnection(_connectionString);
await connection.OpenAsync();
await using var command = connection.CreateCommand();
command.CommandText = @"
INSERT INTO data_connection_definitions (name, protocol, configuration, updated_at)
VALUES (@name, @protocol, @config, @updatedAt)
ON CONFLICT(name) DO UPDATE SET
protocol = excluded.protocol,
configuration = excluded.configuration,
updated_at = excluded.updated_at";
command.Parameters.AddWithValue("@name", name);
command.Parameters.AddWithValue("@protocol", protocol);
command.Parameters.AddWithValue("@config", (object?)configJson ?? DBNull.Value);
command.Parameters.AddWithValue("@updatedAt", DateTimeOffset.UtcNow.ToString("O"));
await command.ExecuteNonQueryAsync();
_logger.LogDebug("Stored data connection definition '{Name}' (protocol={Protocol})", name, protocol);
}
/// <summary>
/// Returns all stored data connection definitions.
/// </summary>
public async Task<List<StoredDataConnectionDefinition>> GetAllDataConnectionDefinitionsAsync()
{
await using var connection = new SqliteConnection(_connectionString);
await connection.OpenAsync();
await using var command = connection.CreateCommand();
command.CommandText = "SELECT name, protocol, configuration FROM data_connection_definitions";
var results = new List<StoredDataConnectionDefinition>();
await using var reader = await command.ExecuteReaderAsync();
while (await reader.ReadAsync())
{
results.Add(new StoredDataConnectionDefinition
{
Name = reader.GetString(0),
Protocol = reader.GetString(1),
ConfigurationJson = reader.IsDBNull(2) ? null : reader.GetString(2)
});
}
return results;
}
}
/// <summary>
@@ -492,3 +553,13 @@ public class StoredSharedScript
public string? ParameterDefinitions { get; init; }
public string? ReturnDefinition { get; init; }
}
/// <summary>
/// Represents a data connection definition stored locally in SQLite.
/// </summary>
public class StoredDataConnectionDefinition
{
public string Name { get; init; } = string.Empty;
public string Protocol { get; init; } = string.Empty;
public string? ConfigurationJson { get; init; }
}