Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
cab61ee
Add migration overview documentation for RavenDB to SQL transition
warwickschroeder Sep 4, 2026
7f1a100
Refine migration overview documentation for RavenDB to SQL transition
warwickschroeder Sep 10, 2026
9173ec2
Clarify documentation on RavenDB source requirements for containerize…
warwickschroeder Sep 10, 2026
82ea176
Enhance migration overview documentation for RavenDB to SQL transitio…
warwickschroeder Sep 11, 2026
6028d94
Implement the foundation for migration engine
warwickschroeder Sep 11, 2026
3a0263a
Add unit tests for migration engine functionality and improve migrati…
warwickschroeder Sep 15, 2026
259cb82
Clarify migration overview by detailing additional skip conditions fo…
warwickschroeder Sep 15, 2026
818b0e7
PR review fixes
warwickschroeder Sep 15, 2026
fa6c14e
PR review
warwickschroeder Sep 16, 2026
4bc951e
Enhance migration engine to handle benign skips and update related tests
warwickschroeder Sep 17, 2026
0dcf9c8
Enhance Migration Engine and Unit Tests
warwickschroeder Sep 17, 2026
94c8cab
Refactor migration settings and update documentation to remove RavenD…
warwickschroeder Sep 30, 2026
8482252
Clarify event log handling and data retention during migration from R…
warwickschroeder Sep 30, 2026
bbdbcb7
Update migration documentation to clarify integration events and erro…
warwickschroeder Sep 30, 2026
e9f6da8
Refine migration documentation for clarity on data retention and copy…
warwickschroeder Sep 30, 2026
13eb6b7
[Migration Engine Part 2] Add a migration checkpoint table to SQL Ser…
warwickschroeder Oct 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
# Categories are declared by the <TestCategory> property in each test project. A category can
# span several projects that share infrastructure, so that the container is provisioned once
# and the union of their build closures is compiled once.
test-category: [ DefaultCore, DefaultMonitoring, Raven, SqlServer, PostgreSql, RabbitMQ, AzureServiceBus, AzureStorageQueues, MSMQ, SQS, IBMMQ ]
test-category: [ DefaultCore, DefaultMonitoring, Migration, Raven, SqlServer, PostgreSql, RabbitMQ, AzureServiceBus, AzureStorageQueues, MSMQ, SQS, IBMMQ ]
include:
- os: windows-latest
os-name: Windows
Expand Down Expand Up @@ -87,7 +87,7 @@ jobs:
id: select
run: ./tools/select-test-projects.ps1 -Category ${{ matrix.test-category }}
- name: Download RavenDB Server
if: matrix.test-category == 'DefaultCore'
if: contains(fromJSON('["DefaultCore", "Migration"]'), matrix.test-category)
run: ./tools/download-ravendb-server.ps1
- name: Build
id: build
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ It's also possible to [locally test containers built from PRs in GitHub Containe
If the instance is executed for the first time, it must set up the required infrastructure. To do so, once the instance is configured to use the selected transport and persister, run it in setup mode. This can be done by using the `Setup {instance name}` launch profile that is defined in
the `launchSettings.json` file of each instance. When started in setup mode, the instance will start as usual, execute the setup process, and exit. At this point the instance can be run normally by using the non-setup launch profile.

## Migrating from RavenDB to SQL Server or PostgreSQL

- [Migrate from RavenDB to SQL Server or PostgreSQL](docs/migration/ravendb-to-sql-migration-instructions.md): what an operator can run today, and what is not built yet.

## Secrets

Testing using the [CI workflow](/.github/workflows/ci.yml) depends on the following secrets. The Particular values for these secrets are stored in the secure note named **ServiceControl Repo Secrets**.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
234 changes: 234 additions & 0 deletions docs/migration/ravendb-to-sql-migration-instructions.md

Large diffs are not rendered by default.

496 changes: 496 additions & 0 deletions docs/migration/ravendb-to-sql-migration-overview.md

Large diffs are not rendered by default.

289 changes: 289 additions & 0 deletions docs/migration/ravendb-to-sql-migration-system-design.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
<ItemGroup>
<ProjectReference Include="..\ServiceControl.AcceptanceTesting\ServiceControl.AcceptanceTesting.csproj" />
<ProjectReference Include="..\ServiceControl.Persistence.EFCore.PostgreSql\ServiceControl.Persistence.EFCore.PostgreSql.csproj" />
<!-- Built so its manifest is where DevelopmentPersistenceLocations looks; not copied, or its persistence.manifest would collide with this project's own. -->
<ProjectReference Include="..\ServiceControl.Persistence.RavenDB\ServiceControl.Persistence.RavenDB.csproj" ReferenceOutputAssembly="false" Private="false" />
<ProjectReference Include="..\ServiceControl.RavenDB\ServiceControl.RavenDB.csproj" />
<ProjectReference Include="..\ServiceControl.Transports.Learning\ServiceControl.Transports.Learning.csproj" />
<ProjectReference Include="..\ServiceControl\ServiceControl.csproj" />
<ProjectReference Include="..\TestHelper\TestHelper.csproj" />
Expand All @@ -20,6 +23,7 @@
<ItemGroup>
<PackageReference Include="GitHubActionsTestLogger" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" />
<PackageReference Include="Microsoft.Extensions.TimeProvider.Testing" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="NServiceBus.Heartbeat" />
<PackageReference Include="NServiceBus.SagaAudit" />
Expand All @@ -31,6 +35,9 @@

<ItemGroup>
<Compile Include="..\ServiceControl.AcceptanceTests\**\*.cs" LinkBase="Shared" />
<Compile Include="..\ServiceControl.Migration.AcceptanceTests\**\*.cs" LinkBase="Migration" />
<Compile Include="..\ServiceControl.Persistence.Tests\IngestedFailure.cs" />
<Compile Include="..\ServiceControl.Persistence.Tests\EFCore\InMemoryBodyStoragePersistence.cs" />
<Compile Include="..\ServiceControl.Persistence.Tests.PostgreSql\PostgreSqlSharedContainer.cs" />
<Compile Include="..\ServiceControl.Persistence.Tests.PostgreSql\TestSchema.cs" />
<Compile Include="..\ServiceControl.Persistence.Tests.PostgreSql\StopSharedPostgreSql.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
<ItemGroup>
<ProjectReference Include="..\ServiceControl.AcceptanceTesting\ServiceControl.AcceptanceTesting.csproj" />
<ProjectReference Include="..\ServiceControl.Persistence.EFCore.SqlServer\ServiceControl.Persistence.EFCore.SqlServer.csproj" />
<!-- Built so its manifest is where DevelopmentPersistenceLocations looks; not copied, or its persistence.manifest would collide with this project's own. -->
<ProjectReference Include="..\ServiceControl.Persistence.RavenDB\ServiceControl.Persistence.RavenDB.csproj" ReferenceOutputAssembly="false" Private="false" />
<ProjectReference Include="..\ServiceControl.RavenDB\ServiceControl.RavenDB.csproj" />
<ProjectReference Include="..\ServiceControl.Transports.Learning\ServiceControl.Transports.Learning.csproj" />
<ProjectReference Include="..\ServiceControl\ServiceControl.csproj" />
<ProjectReference Include="..\TestHelper\TestHelper.csproj" />
Expand All @@ -20,6 +23,7 @@
<ItemGroup>
<PackageReference Include="GitHubActionsTestLogger" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" />
<PackageReference Include="Microsoft.Extensions.TimeProvider.Testing" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="NServiceBus.Heartbeat" />
<PackageReference Include="NServiceBus.SagaAudit" />
Expand All @@ -31,6 +35,9 @@

<ItemGroup>
<Compile Include="..\ServiceControl.AcceptanceTests\**\*.cs" LinkBase="Shared" />
<Compile Include="..\ServiceControl.Migration.AcceptanceTests\**\*.cs" LinkBase="Migration" />
<Compile Include="..\ServiceControl.Persistence.Tests\IngestedFailure.cs" />
<Compile Include="..\ServiceControl.Persistence.Tests\EFCore\InMemoryBodyStoragePersistence.cs" />
<Compile Include="..\ServiceControl.Persistence.Tests.SqlServer\SqlServerSharedContainer.cs" />
<Compile Include="..\ServiceControl.Persistence.Tests.SqlServer\TestSchema.cs" />
<Compile Include="..\ServiceControl.Persistence.Tests.SqlServer\StopSharedSqlServer.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,9 @@ namespace ServiceControl.AcceptanceTests.Recoverability
using ServiceControl.Infrastructure;
using ServiceControl.MessageFailures;
using ServiceControl.Operations;
using ServiceControl.Persistence.DataMigration;
using ServiceControl.Persistence.EFCore.DbContexts;
using ServiceControl.Persistence.EFCore.Entities;
using ServiceControl.Persistence.EFCore.Infrastructure;
using ServiceControl.Recoverability;
using ServiceControl.Transports;

class When_hosting_error_ingestion_only : AcceptanceTest
Expand Down Expand Up @@ -97,9 +96,36 @@ public async Task Should_default_the_concurrency_to_10_when_none_is_configured()
"InternalCustomChecksHostedService", // reports this node's ingestion health to the database
"MetricsReporterHostedService",
"HealthCheckPublisherHostedService", // inert, no IHealthCheckPublisher is registered
"ExternalIntegrationRequestsDataStore" // its drain is inert here, nothing calls Subscribe
"ExternalIntegrationRequestsDataStore", // its drain is inert here, nothing calls Subscribe
"FinishedCopyBeforeAnIngestionNodeOpens" // keeps this node out of a database a copy has not finished filling
];

[Test]
public async Task Should_refuse_to_start_while_a_copy_into_the_database_is_unfinished()
{
var settings = await CreateSettings();

await new SetupCommand().Execute(new HostArguments([]), settings);

var host = ErrorIngestionOnlyCommand.BuildHost(settings);

try
{
await host.Services.GetRequiredService<IMigrationCheckpointStore>().Upsert(
new MigrationCheckpoint(MigrationCategoryIds.KnownEndpoints, MigrationCategoryState.Halted, null, 0, 0, null, null, null, null, null, "The source stopped responding."));

var exception = Assert.ThrowsAsync<Exception>(() => host.StartAsync());

Assert.That(exception.Message, Does.Contain("has not finished")
.And.Contain(MigrationCategoryIds.KnownEndpoints)
.And.Contain("--migration-abandon KnownEndpoints"));
}
finally
{
await host.DisposeAsync();
}
}

[Test]
public void Should_refuse_to_start_against_unsupported_storage()
{
Expand Down Expand Up @@ -204,6 +230,7 @@ public async Task Should_serve_health_over_https_with_the_configured_certificate
await new SetupCommand().Execute(new HostArguments([]), settings);

host = ErrorIngestionOnlyCommand.BuildHost(settings);
host.Urls.Clear();
host.Urls.Add("https://127.0.0.1:0");

await host.StartAsync();
Expand Down
6 changes: 6 additions & 0 deletions src/ServiceControl.Migration.AcceptanceTests/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[*.cs]

# Justification: Test project
dotnet_diagnostic.CA2007.severity = none
dotnet_diagnostic.PS0013.severity = none
dotnet_diagnostic.PS0018.severity = none
Loading
Loading