public async Task AbleToMigrate_delayed_delivery_does_not_exist_should_indicate_problems() { var sut = new SqlTTimeoutsTarget(new TestLoggingAdapter(), connectionString, schema); await using var connection = new SqlConnection(connectionString); await connection.OpenAsync(); await using var command = connection.CreateCommand(); command.CommandText = string.Format(@" IF OBJECT_ID('{0}.{1}', 'u') IS NOT NULL DROP TABLE {0}.{1}; ", $"{ExistingEndpointName}.Delayed", schema); await command.ExecuteNonQueryAsync(); var info = new EndpointInfo { EndpointName = ExistingEndpointName, ShortestTimeout = DateTime.UtcNow.AddDays(3), LongestTimeout = DateTime.UtcNow.AddDays(5), Destinations = new List <string> { ExistingDestination } }; var result = await sut.AbleToMigrate(info); Assert.IsFalse(result.CanMigrate); }
public async Task AbleToMigrate_delayed_delivery_does_exist_should_indicate_no_problems() { var sut = new SqlTTimeoutsTarget(new TestLoggingAdapter(), connectionString, schema); await using var connection = new SqlConnection(connectionString); await connection.OpenAsync(); await using var command = connection.CreateCommand(); command.CommandText = string.Format(@" CREATE TABLE [{1}].[{0}] ( RowVersion bigint IDENTITY(1,1) NOT NULL ); ", $"{ExistingEndpointName}.Delayed", schema); await command.ExecuteNonQueryAsync(); var info = new EndpointInfo { EndpointName = ExistingEndpointName, ShortestTimeout = DateTime.UtcNow.AddDays(3), LongestTimeout = DateTime.UtcNow.AddDays(5), Destinations = new List <string> { ExistingDestination } }; var result = await sut.AbleToMigrate(info); Assert.IsTrue(result.CanMigrate); }
public async Task Can_migrate_timeouts() { var sourceEndpoint = NServiceBus.AcceptanceTesting.Customization.Conventions.EndpointNamingConvention(typeof(AspSource)); var targetEndpoint = NServiceBus.AcceptanceTesting.Customization.Conventions.EndpointNamingConvention(typeof(SqlTTarget)); await Scenario.Define <SourceContext>() .WithEndpoint <AspSource>(b => b.CustomConfig(ec => { SetupPersistence(ec); }) .When(async(session, c) => { var delayedMessage = new DelayedMessage(); var options = new SendOptions(); options.DelayDeliveryWith(TimeSpan.FromSeconds(15)); options.SetDestination(targetEndpoint); await session.Send(delayedMessage, options); await WaitUntilTheTimeoutsAreSavedInAsp(sourceEndpoint, 2); c.TimeoutSet = true; })) .Done(c => c.TimeoutSet) .Run(TimeSpan.FromSeconds(30)); var setupContext = await Scenario.Define <TargetContext>() .WithEndpoint <SqlTTarget>(b => b.CustomConfig(ec => { ec.OverrideLocalAddress(sourceEndpoint); ec.UseTransport <SqlServerTransport>() .ConnectionString(sqlConnectionString); })) .Done(c => c.EndpointsStarted) .Run(TimeSpan.FromSeconds(30)); var logger = new TestLoggingAdapter(setupContext); var timeoutStorage = CreateTimeoutStorage(sourceEndpoint); var timeoutTarget = new SqlTTimeoutsTarget(logger, sqlConnectionString, "dbo"); var migrationRunner = new MigrationRunner(logger, timeoutStorage, timeoutTarget); await migrationRunner.Run(DateTime.Now.AddDays(-10), EndpointFilter.SpecificEndpoint(sourceEndpoint), new Dictionary <string, string>()); var context = await Scenario.Define <TargetContext>() .WithEndpoint <SqlTTarget>(b => b.CustomConfig(ec => { ec.OverrideLocalAddress(sourceEndpoint); ec.UseTransport <SqlServerTransport>() .ConnectionString(sqlConnectionString); })) .Done(c => c.GotTheDelayedMessage) .Run(TimeSpan.FromSeconds(30)); Assert.True(context.GotTheDelayedMessage); }
public async Task Can_migrate_timeouts() { var sourceEndpoint = NServiceBus.AcceptanceTesting.Customization.Conventions.EndpointNamingConvention(typeof(NHibernateSource)); var targetEndpoint = NServiceBus.AcceptanceTesting.Customization.Conventions.EndpointNamingConvention(typeof(SqlTTarget)); using (var testSession = CreateSessionFactory().OpenSession()) { // Explicit using scope to ensure dispose before SUT connects using (var testTx = testSession.BeginTransaction()) { await testSession.SaveAsync(new TimeoutEntity { Endpoint = sourceEndpoint, Destination = targetEndpoint, SagaId = Guid.NewGuid(), Headers = "{\"NServiceBus.EnclosedMessageTypes\": \"TimeoutMigrationTool.NHibernate.AcceptanceTests.NHibernateToSqlTEndToEnd+DelayedMessage\"}", State = Encoding.UTF8.GetBytes("{}"), Time = DateTime.UtcNow.AddSeconds(15) }); await testTx.CommitAsync(); } } var context = await Scenario.Define <TargetContext>() .WithEndpoint <SqlTTarget>(b => b.CustomConfig(ec => { ec.OverrideLocalAddress(sourceEndpoint); var transportConfig = ec.UseTransport <SqlServerTransport>(); transportConfig.ConnectionString(connectionString); ec.UseSerialization <NewtonsoftSerializer>(); }) .When(async(_, c) => { var logger = new TestLoggingAdapter(c); var timeoutsSource = new NHibernateTimeoutsSource(connectionString, 1024, DatabaseDialect); var timeoutTarget = new SqlTTimeoutsTarget(logger, connectionString, "dbo"); var migrationRunner = new MigrationRunner(logger, timeoutsSource, timeoutTarget); await migrationRunner.Run(DateTime.Now.AddDays(-10), EndpointFilter.SpecificEndpoint(sourceEndpoint), new Dictionary <string, string>()); })) .Done(c => c.GotTheDelayedMessage) .Run(TimeSpan.FromSeconds(90)); Assert.True(context.GotTheDelayedMessage); }
public async Task Should_delete_staging_table_when_empty() { var sut = new SqlTTimeoutsTarget(new TestLoggingAdapter(), connectionString, schema); await using var connection = new SqlConnection(connectionString); await connection.OpenAsync(); await SqlTQueueCreator.CreateStagingQueue(connection, SqlConstants.TimeoutMigrationStagingTable, schema, connection.Database, preview : false); await sut.Complete(ExistingEndpointName); var sqlStatement = $"SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = '{SqlConstants.TimeoutMigrationStagingTable}' AND TABLE_CATALOG = '{databaseName}'"; await using var command = new SqlCommand(sqlStatement, connection) { CommandType = CommandType.Text }; var result = await command.ExecuteScalarAsync().ConfigureAwait(false) as int?; Assert.That(result, Is.EqualTo(0)); }
public async Task Should_delete_staging_queue_when_completing() { var sut = new SqlTTimeoutsTarget(new TestLoggingAdapter(), connectionString, schema); var endpointName = "FakeEndpoint"; await using var endpointTarget = await sut.PrepareTargetEndpointBatchMigrator(endpointName); await sut.Complete(endpointName); await using var connection = new SqlConnection(connectionString); await connection.OpenAsync(); await using var command = connection.CreateCommand(); command.CommandText = string.Format(@" SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '{1}' AND TABLE_NAME = '{0}' AND TABLE_CATALOG = '{2}' ", SqlConstants.TimeoutMigrationStagingTable, schema, databaseName); var result = await command.ExecuteScalarAsync() as int?; Assert.That(Convert.ToBoolean(result), Is.False); }
public async Task Should_throw_when_staging_table_not_empty() { var sut = new SqlTTimeoutsTarget(new TestLoggingAdapter(), connectionString, schema); await using var connection = new SqlConnection(connectionString); await connection.OpenAsync(); await SqlTQueueCreator.CreateStagingQueue(connection, SqlConstants.TimeoutMigrationStagingTable, schema, connection.Database, preview : false); var sql = $"INSERT INTO {schema}.{SqlConstants.TimeoutMigrationStagingTable} VALUES('headers', NULL, DATEADD(DAY, 1, GETDATE()))"; await using var command = new SqlCommand(sql, connection) { CommandType = CommandType.Text }; await command.ExecuteNonQueryAsync(); Assert.ThrowsAsync <Exception>(async() => { await sut.Complete(ExistingEndpointName); }); }
public async Task Should_migrate_into_delayed_table() { var endpointDelayedTableName = $"{ExistingEndpointName}.Delayed"; var sut = new SqlTTimeoutsTarget(new TestLoggingAdapter(), connectionString, schema); await using var connection = new SqlConnection(connectionString); await connection.OpenAsync(); await using var command = connection.CreateCommand(); command.CommandText = string.Format(@" CREATE TABLE [{1}].[{0}] ( Headers nvarchar(max) NOT NULL, Body varbinary(max), Due datetime NOT NULL, RowVersion bigint IDENTITY(1,1) NOT NULL ); ", endpointDelayedTableName, schema); await command.ExecuteNonQueryAsync(); const int BatchNumber = 2; await using var endpointTarget = await sut.PrepareTargetEndpointBatchMigrator(ExistingEndpointName); await endpointTarget.StageBatch(new List <TimeoutData> { new TimeoutData { Id = "SomeID", Headers = new Dictionary <string, string> { { "NServiceBus.MessageId", "SomeMessageId" } }, Destination = "SomeDestination", State = new byte[2], Time = new DateTime(2021, 12, 12, 12, 12, 12, DateTimeKind.Utc) }, new TimeoutData { Id = "SomeOtherId", Headers = new Dictionary <string, string> { { "NServiceBus.MessageId", "SomeOtherMessageId" } }, Destination = "SomeOtherDestination", State = new byte[2], Time = new DateTime(2021, 12, 12, 12, 13, 13, DateTimeKind.Utc) }, }, BatchNumber); await endpointTarget.CompleteBatch(BatchNumber); var endpointDelayedTableDataTable = new DataTable(); using var endpointDelayedTableDataAdapter = new SqlDataAdapter(string.Format("SELECT * FROM [{1}].[{0}]", endpointDelayedTableName, schema), connection); endpointDelayedTableDataAdapter.Fill(endpointDelayedTableDataTable); var migrationTableDataTable = new DataTable(); using var migrationTableDataAdapter = new SqlDataAdapter(string.Format("SELECT * FROM [{1}].[{0}]", SqlConstants.TimeoutMigrationStagingTable, schema), connection); migrationTableDataAdapter.Fill(migrationTableDataTable); Approver.Verify(endpointDelayedTableDataTable.Rows.OfType <DataRow>().SelectMany(r => r.ItemArray.Take(3))); Assert.IsEmpty(migrationTableDataTable.Rows); }
public async Task Can_migrate_timeouts() { var sourceEndpoint = NServiceBus.AcceptanceTesting.Customization.Conventions.EndpointNamingConvention(typeof(RavenDBSource)); var targetEndpoint = NServiceBus.AcceptanceTesting.Customization.Conventions.EndpointNamingConvention(typeof(SqlTTarget)); var ravenTimeoutPrefix = "TimeoutDatas"; var ravenVersion = RavenDbVersion.Four; var ravenAdapter = new Raven4Adapter(serverUrl, databaseName); await Scenario.Define <SourceContext>() .WithEndpoint <RavenDBSource>(b => b.CustomConfig(ec => { ec.UsePersistence <RavenDBPersistence>() .SetDefaultDocumentStore(GetDocumentStore(serverUrl, databaseName)); }) .When(async(session, c) => { var delayedMessage = new DelayedMessage(); var options = new SendOptions(); options.DelayDeliveryWith(TimeSpan.FromSeconds(20)); options.SetDestination(targetEndpoint); await session.Send(delayedMessage, options); await WaitUntilTheTimeoutIsSavedInRaven(ravenAdapter, sourceEndpoint); c.TimeoutSet = true; })) .Done(c => c.TimeoutSet) .Run(TimeSpan.FromSeconds(15)); var setupContext = await Scenario.Define <TargetContext>() .WithEndpoint <SqlTTarget>(b => b.CustomConfig(ec => { ec.OverrideLocalAddress(sourceEndpoint); ec.UseTransport <SqlServerTransport>() .ConnectionString(sqlConnectionString); })) .Done(c => c.EndpointsStarted) .Run(TimeSpan.FromSeconds(30)); var logger = new TestLoggingAdapter(setupContext); var timeoutsSource = new RavenDbTimeoutsSource(logger, serverUrl, databaseName, ravenTimeoutPrefix, ravenVersion, false); var timeoutsTarget = new SqlTTimeoutsTarget(logger, sqlConnectionString, "dbo"); var migrationRunner = new MigrationRunner(logger, timeoutsSource, timeoutsTarget); await migrationRunner.Run(DateTime.Now.AddDays(-1), EndpointFilter.SpecificEndpoint(sourceEndpoint), new Dictionary <string, string>()); var context = await Scenario.Define <TargetContext>() .WithEndpoint <SqlTTarget>(b => b.CustomConfig(ec => { ec.OverrideLocalAddress(sourceEndpoint); ec.UseTransport <SqlServerTransport>() .ConnectionString(sqlConnectionString); })) .Done(c => c.GotTheDelayedMessage) .Run(TimeSpan.FromSeconds(30)); Assert.True(context.GotTheDelayedMessage); }