feat: wire SQLite replication between site nodes and fix ConfigurationDatabase tests
Add SiteReplicationActor (runs on every site node) to replicate deployed configs and store-and-forward buffer operations to the standby peer via cluster member discovery and fire-and-forget Tell. Wire ReplicationService handler and pass replication actor to DeploymentManagerActor singleton. Fix 5 pre-existing ConfigurationDatabase test failures: RowVersion NOT NULL on SQLite, stale migration name assertion, and seed data count mismatch.
This commit is contained in:
@@ -15,6 +15,7 @@ public static class ExternalSystemCommands
|
||||
command.Add(BuildCreate(contactPointsOption, formatOption));
|
||||
command.Add(BuildUpdate(contactPointsOption, formatOption));
|
||||
command.Add(BuildDelete(contactPointsOption, formatOption));
|
||||
command.Add(BuildMethodGroup(contactPointsOption, formatOption));
|
||||
|
||||
return command;
|
||||
}
|
||||
@@ -110,4 +111,121 @@ public static class ExternalSystemCommands
|
||||
});
|
||||
return cmd;
|
||||
}
|
||||
|
||||
// ── Method subcommands ──
|
||||
|
||||
private static Command BuildMethodGroup(Option<string> contactPointsOption, Option<string> formatOption)
|
||||
{
|
||||
var group = new Command("method") { Description = "Manage external system methods" };
|
||||
group.Add(BuildMethodList(contactPointsOption, formatOption));
|
||||
group.Add(BuildMethodGet(contactPointsOption, formatOption));
|
||||
group.Add(BuildMethodCreate(contactPointsOption, formatOption));
|
||||
group.Add(BuildMethodUpdate(contactPointsOption, formatOption));
|
||||
group.Add(BuildMethodDelete(contactPointsOption, formatOption));
|
||||
return group;
|
||||
}
|
||||
|
||||
private static Command BuildMethodList(Option<string> contactPointsOption, Option<string> formatOption)
|
||||
{
|
||||
var sysIdOption = new Option<int>("--external-system-id") { Description = "External system ID", Required = true };
|
||||
var cmd = new Command("list") { Description = "List methods for an external system" };
|
||||
cmd.Add(sysIdOption);
|
||||
cmd.SetAction(async (ParseResult result) =>
|
||||
{
|
||||
return await CommandHelpers.ExecuteCommandAsync(
|
||||
result, contactPointsOption, formatOption,
|
||||
new ListExternalSystemMethodsCommand(result.GetValue(sysIdOption)));
|
||||
});
|
||||
return cmd;
|
||||
}
|
||||
|
||||
private static Command BuildMethodGet(Option<string> contactPointsOption, Option<string> formatOption)
|
||||
{
|
||||
var idOption = new Option<int>("--id") { Description = "Method ID", Required = true };
|
||||
var cmd = new Command("get") { Description = "Get an external system method by ID" };
|
||||
cmd.Add(idOption);
|
||||
cmd.SetAction(async (ParseResult result) =>
|
||||
{
|
||||
return await CommandHelpers.ExecuteCommandAsync(
|
||||
result, contactPointsOption, formatOption,
|
||||
new GetExternalSystemMethodCommand(result.GetValue(idOption)));
|
||||
});
|
||||
return cmd;
|
||||
}
|
||||
|
||||
private static Command BuildMethodCreate(Option<string> contactPointsOption, Option<string> formatOption)
|
||||
{
|
||||
var sysIdOption = new Option<int>("--external-system-id") { Description = "External system ID", Required = true };
|
||||
var nameOption = new Option<string>("--name") { Description = "Method name", Required = true };
|
||||
var httpMethodOption = new Option<string>("--http-method") { Description = "HTTP method (GET, POST, PUT, DELETE)", Required = true };
|
||||
var pathOption = new Option<string>("--path") { Description = "URL path (e.g. /api/Add)", Required = true };
|
||||
var paramsOption = new Option<string?>("--params") { Description = "Parameter definitions JSON" };
|
||||
var returnOption = new Option<string?>("--return") { Description = "Return definition JSON" };
|
||||
|
||||
var cmd = new Command("create") { Description = "Create an external system method" };
|
||||
cmd.Add(sysIdOption);
|
||||
cmd.Add(nameOption);
|
||||
cmd.Add(httpMethodOption);
|
||||
cmd.Add(pathOption);
|
||||
cmd.Add(paramsOption);
|
||||
cmd.Add(returnOption);
|
||||
cmd.SetAction(async (ParseResult result) =>
|
||||
{
|
||||
return await CommandHelpers.ExecuteCommandAsync(
|
||||
result, contactPointsOption, formatOption,
|
||||
new CreateExternalSystemMethodCommand(
|
||||
result.GetValue(sysIdOption),
|
||||
result.GetValue(nameOption)!,
|
||||
result.GetValue(httpMethodOption)!,
|
||||
result.GetValue(pathOption)!,
|
||||
result.GetValue(paramsOption),
|
||||
result.GetValue(returnOption)));
|
||||
});
|
||||
return cmd;
|
||||
}
|
||||
|
||||
private static Command BuildMethodUpdate(Option<string> contactPointsOption, Option<string> formatOption)
|
||||
{
|
||||
var idOption = new Option<int>("--id") { Description = "Method ID", Required = true };
|
||||
var nameOption = new Option<string?>("--name") { Description = "Method name" };
|
||||
var httpMethodOption = new Option<string?>("--http-method") { Description = "HTTP method" };
|
||||
var pathOption = new Option<string?>("--path") { Description = "URL path" };
|
||||
var paramsOption = new Option<string?>("--params") { Description = "Parameter definitions JSON" };
|
||||
var returnOption = new Option<string?>("--return") { Description = "Return definition JSON" };
|
||||
|
||||
var cmd = new Command("update") { Description = "Update an external system method" };
|
||||
cmd.Add(idOption);
|
||||
cmd.Add(nameOption);
|
||||
cmd.Add(httpMethodOption);
|
||||
cmd.Add(pathOption);
|
||||
cmd.Add(paramsOption);
|
||||
cmd.Add(returnOption);
|
||||
cmd.SetAction(async (ParseResult result) =>
|
||||
{
|
||||
return await CommandHelpers.ExecuteCommandAsync(
|
||||
result, contactPointsOption, formatOption,
|
||||
new UpdateExternalSystemMethodCommand(
|
||||
result.GetValue(idOption),
|
||||
result.GetValue(nameOption),
|
||||
result.GetValue(httpMethodOption),
|
||||
result.GetValue(pathOption),
|
||||
result.GetValue(paramsOption),
|
||||
result.GetValue(returnOption)));
|
||||
});
|
||||
return cmd;
|
||||
}
|
||||
|
||||
private static Command BuildMethodDelete(Option<string> contactPointsOption, Option<string> formatOption)
|
||||
{
|
||||
var idOption = new Option<int>("--id") { Description = "Method ID", Required = true };
|
||||
var cmd = new Command("delete") { Description = "Delete an external system method" };
|
||||
cmd.Add(idOption);
|
||||
cmd.SetAction(async (ParseResult result) =>
|
||||
{
|
||||
return await CommandHelpers.ExecuteCommandAsync(
|
||||
result, contactPointsOption, formatOption,
|
||||
new DeleteExternalSystemMethodCommand(result.GetValue(idOption)));
|
||||
});
|
||||
return cmd;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,6 +300,9 @@ public static class TemplateCommands
|
||||
var lockedOption = new Option<bool>("--locked") { Description = "Lock status" };
|
||||
lockedOption.DefaultValueFactory = _ => false;
|
||||
|
||||
var paramsOption = new Option<string?>("--parameters") { Description = "Parameter definitions JSON" };
|
||||
var returnOption = new Option<string?>("--return-def") { Description = "Return definition JSON" };
|
||||
|
||||
var addCmd = new Command("add") { Description = "Add a script to a template" };
|
||||
addCmd.Add(templateIdOption);
|
||||
addCmd.Add(nameOption);
|
||||
@@ -307,6 +310,8 @@ public static class TemplateCommands
|
||||
addCmd.Add(triggerTypeOption);
|
||||
addCmd.Add(triggerConfigOption);
|
||||
addCmd.Add(lockedOption);
|
||||
addCmd.Add(paramsOption);
|
||||
addCmd.Add(returnOption);
|
||||
addCmd.SetAction(async (ParseResult result) =>
|
||||
{
|
||||
return await CommandHelpers.ExecuteCommandAsync(
|
||||
@@ -317,7 +322,9 @@ public static class TemplateCommands
|
||||
result.GetValue(codeOption)!,
|
||||
result.GetValue(triggerTypeOption)!,
|
||||
result.GetValue(triggerConfigOption),
|
||||
result.GetValue(lockedOption)));
|
||||
result.GetValue(lockedOption),
|
||||
result.GetValue(paramsOption),
|
||||
result.GetValue(returnOption)));
|
||||
});
|
||||
group.Add(addCmd);
|
||||
|
||||
@@ -329,6 +336,9 @@ public static class TemplateCommands
|
||||
var updateLockedOption = new Option<bool>("--locked") { Description = "Lock status" };
|
||||
updateLockedOption.DefaultValueFactory = _ => false;
|
||||
|
||||
var updateParamsOption = new Option<string?>("--parameters") { Description = "Parameter definitions JSON" };
|
||||
var updateReturnOption = new Option<string?>("--return-def") { Description = "Return definition JSON" };
|
||||
|
||||
var updateCmd = new Command("update") { Description = "Update a template script" };
|
||||
updateCmd.Add(updateIdOption);
|
||||
updateCmd.Add(updateNameOption);
|
||||
@@ -336,6 +346,8 @@ public static class TemplateCommands
|
||||
updateCmd.Add(updateTriggerTypeOption);
|
||||
updateCmd.Add(updateTriggerConfigOption);
|
||||
updateCmd.Add(updateLockedOption);
|
||||
updateCmd.Add(updateParamsOption);
|
||||
updateCmd.Add(updateReturnOption);
|
||||
updateCmd.SetAction(async (ParseResult result) =>
|
||||
{
|
||||
return await CommandHelpers.ExecuteCommandAsync(
|
||||
@@ -346,7 +358,9 @@ public static class TemplateCommands
|
||||
result.GetValue(updateCodeOption)!,
|
||||
result.GetValue(updateTriggerTypeOption)!,
|
||||
result.GetValue(updateTriggerConfigOption),
|
||||
result.GetValue(updateLockedOption)));
|
||||
result.GetValue(updateLockedOption),
|
||||
result.GetValue(updateParamsOption),
|
||||
result.GetValue(updateReturnOption)));
|
||||
});
|
||||
group.Add(updateCmd);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user