public Task Cleanup() { using (var connection = connectionBuilder()) { connection.Open(); foreach (var definition in sagaDefinitions) { connection.ExecuteCommand(SagaScriptBuilder.BuildDropScript(definition, sqlDialect), tablePrefix, exceptionFilter); } connection.ExecuteCommand(TimeoutScriptBuilder.BuildDropScript(sqlDialect), tablePrefix, exceptionFilter); connection.ExecuteCommand(SubscriptionScriptBuilder.BuildDropScript(sqlDialect), tablePrefix, exceptionFilter); connection.ExecuteCommand(OutboxScriptBuilder.BuildDropScript(sqlDialect), tablePrefix, exceptionFilter); } return(Task.FromResult(0)); }
public void TransitionId() { var endpointName = nameof(TransitionId); var definition1 = new SagaDefinition( tableSuffix: "SagaWithCorrelation", name: "SagaWithCorrelation", correlationProperty: new CorrelationProperty ( name: "CorrelationProperty", type: CorrelationPropertyType.String ) ); using (var connection = dbConnection()) { connection.ExecuteCommand(SagaScriptBuilder.BuildDropScript(definition1, sqlVariant), endpointName, schema: schema); connection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(definition1, sqlVariant), endpointName, schema: schema); var definition2 = new SagaDefinition( tableSuffix: "SagaWithCorrelation", name: "SagaWithCorrelation", correlationProperty: new CorrelationProperty ( name: "CorrelationProperty", type: CorrelationPropertyType.String ), transitionalCorrelationProperty: new CorrelationProperty ( name: "TransitionalCorrelationProperty", type: CorrelationPropertyType.Guid ) ); connection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(definition2, sqlVariant), endpointName, schema: schema); var definition3 = new SagaDefinition( tableSuffix: "SagaWithCorrelation", name: "SagaWithCorrelation", correlationProperty: new CorrelationProperty ( name: "TransitionalCorrelationProperty", type: CorrelationPropertyType.Guid ) ); var buildCreateScript = SagaScriptBuilder.BuildCreateScript(definition3, sqlVariant); connection.ExecuteCommand(buildCreateScript, endpointName); } }
public Task Cleanup(CancellationToken cancellationToken = default) { using (var connection = connectionBuilder()) { connection.Open(); foreach (var definition in sagaDefinitions) { connection.ExecuteCommand(SagaScriptBuilder.BuildDropScript(definition, sqlDialect), tablePrefix, exceptionFilter); } connection.ExecuteCommand(TimeoutScriptBuilder.BuildDropScript(sqlDialect), tablePrefix, exceptionFilter); connection.ExecuteCommand(SubscriptionScriptBuilder.BuildDropScript(sqlDialect), tablePrefix, exceptionFilter); connection.ExecuteCommand(OutboxScriptBuilder.BuildDropScript(sqlDialect), tablePrefix, exceptionFilter); } return(Task.CompletedTask); }
public void CreateWithDiffCorrelationType() { var endpointName = nameof(CreateWithDiffCorrelationType); using (var connection = dbConnection()) { var definition1 = new SagaDefinition( tableSuffix: "SagaWithCorrelation", name: "SagaWithCorrelation", correlationProperty: new CorrelationProperty ( name: "CorrelationProperty", type: CorrelationPropertyType.String ) ); connection.ExecuteCommand(SagaScriptBuilder.BuildDropScript(definition1, sqlDialect), endpointName, schema: schema); connection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(definition1, sqlDialect), endpointName, schema: schema); var definition2 = new SagaDefinition( tableSuffix: "SagaWithCorrelation", name: "SagaWithCorrelation", correlationProperty: new CorrelationProperty ( name: "CorrelationProperty", type: CorrelationPropertyType.DateTime ) ); var createScript2 = SagaScriptBuilder.BuildCreateScript(definition2, sqlDialect); string exceptionMessage = null; try { connection.ExecuteCommand(createScript2, endpointName, schema: schema); } catch (Exception exception) { exceptionMessage = exception.Message; } Assert.IsNotNull(exceptionMessage, "Expected ExecuteCommand to throw"); StringAssert.Contains("Incorrect data type for Correlation_", exceptionMessage); } }
public static void WriteSagaScripts(string scriptPath, ModuleDefinition moduleDefinition, BuildSqlDialect sqlDialect, Action <string, string> logError) { var metaDataReader = new AllSagaDefinitionReader(moduleDefinition); var sagasScriptPath = Path.Combine(scriptPath, "Sagas"); Directory.CreateDirectory(sagasScriptPath); var index = 0; foreach (var saga in metaDataReader.GetSagas( logError: (exception, type) => { logError($"Error in '{type.FullName}'. Error:{exception.Message}", type.GetFileName()); })) { var sagaFileName = saga.TableSuffix; var maximumNameLength = 244 - sagasScriptPath.Length; if (sagaFileName.Length > maximumNameLength) { sagaFileName = $"{sagaFileName.Substring(0, maximumNameLength)}_{index}"; index++; } var createPath = Path.Combine(sagasScriptPath, $"{sagaFileName}_Create.sql"); File.Delete(createPath); using (var writer = File.CreateText(createPath)) { SagaScriptBuilder.BuildCreateScript(saga, sqlDialect, writer); } var dropPath = Path.Combine(sagasScriptPath, $"{sagaFileName}_Drop.sql"); File.Delete(dropPath); using (var writer = File.CreateText(dropPath)) { SagaScriptBuilder.BuildDropScript(saga, sqlDialect, writer); } } }
public void Write() { var directory = Path.Combine(TestContext.CurrentContext.TestDirectory, "../../../"); foreach (var variant in Enum.GetValues(typeof(BuildSqlDialect)).Cast <BuildSqlDialect>()) { Write(directory, variant, "TimeoutCreate", TimeoutScriptBuilder.BuildCreateScript(variant)); Write(directory, variant, "TimeoutDrop", TimeoutScriptBuilder.BuildDropScript(variant)); Write(directory, variant, "OutboxCreate", OutboxScriptBuilder.BuildCreateScript(variant)); Write(directory, variant, "OutboxDrop", OutboxScriptBuilder.BuildDropScript(variant)); Write(directory, variant, "SubscriptionCreate", SubscriptionScriptBuilder.BuildCreateScript(variant)); Write(directory, variant, "SubscriptionDrop", SubscriptionScriptBuilder.BuildDropScript(variant)); var sagaDefinition = new SagaDefinition( tableSuffix: "OrderSaga", name: "OrderSaga", correlationProperty: new CorrelationProperty( name: "OrderNumber", type: CorrelationPropertyType.Int), transitionalCorrelationProperty: new CorrelationProperty( name: "OrderId", type: CorrelationPropertyType.Guid)); Write(directory, variant, "SagaCreate", SagaScriptBuilder.BuildCreateScript(sagaDefinition, variant)); Write(directory, variant, "SagaDrop", SagaScriptBuilder.BuildDropScript(sagaDefinition, variant)); } var dialects = new SqlDialect[] { new SqlDialect.MsSqlServer(), new SqlDialect.MySql(), new SqlDialect.Oracle(), new SqlDialect.PostgreSql() }; var assembly = typeof(SqlPersistence).Assembly; foreach (var dialect in dialects) { var timeoutCommands = GetCommand(dialect, "TimeoutCommandBuilder"); Write(directory, dialect, "TimeoutAdd", GetValue(timeoutCommands, "Add")); Write(directory, dialect, "TimeoutNext", GetValue(timeoutCommands, "Next")); Write(directory, dialect, "TimeoutRange", GetValue(timeoutCommands, "Range")); Write(directory, dialect, "TimeoutRemoveById", GetValue(timeoutCommands, "RemoveById")); Write(directory, dialect, "TimeoutRemoveBySagaId", GetValue(timeoutCommands, "RemoveBySagaId")); Write(directory, dialect, "TimeoutPeek", GetValue(timeoutCommands, "Peek")); var outboxCommands = GetCommand(dialect, "OutboxCommandBuilder"); Write(directory, dialect, "OutboxCleanup", GetValue(outboxCommands, "Cleanup")); Write(directory, dialect, "OutboxGet", GetValue(outboxCommands, "Get")); Write(directory, dialect, "OutboxSetAsDispatched", GetValue(outboxCommands, "SetAsDispatched")); Write(directory, dialect, "OutboxStore", GetValue(outboxCommands, "Store")); var subscriptionCommands = GetCommand(dialect, "SubscriptionCommandBuilder"); Write(directory, dialect, "SubscriptionSubscribe", GetValue(subscriptionCommands, "Subscribe")); Write(directory, dialect, "SubscriptionUnsubscribe", GetValue(subscriptionCommands, "Unsubscribe")); Write(directory, dialect, "SubscriptionGetSubscribers", GetSubscribersValue(subscriptionCommands, new List <MessageType> { new MessageType("MessageTypeName", new Version()) })); dynamic dialectAsDynamic = new ExposeInternalMethods(dialect); Write(directory, dialect, "SagaComplete", dialectAsDynamic.BuildCompleteCommand("EndpointName_SagaName")); Write(directory, dialect, "SagaGetByProperty", dialectAsDynamic.BuildGetByPropertyCommand("PropertyName", "EndpointName_SagaName")); Write(directory, dialect, "SagaGetBySagaId", dialectAsDynamic.BuildGetBySagaIdCommand("EndpointName_SagaName")); Write(directory, dialect, "SagaSave", dialectAsDynamic.BuildSaveCommand("CorrelationProperty", "TransitionalCorrelationProperty", "EndpointName_SagaName")); Write(directory, dialect, "SagaUpdate", dialectAsDynamic.BuildUpdateCommand("TransitionalCorrelationProperty", "EndpointName_SagaName")); // since we don't have docs on oracle saga finders if (!(dialect is SqlDialect.Oracle)) { var createSelectWithWhereClause = dialectAsDynamic.BuildSelectFromCommand("EndpointName_SagaName"); Write(directory, dialect, "SagaSelect", createSelectWithWhereClause("1 = 1")); } } }
public void Write() { var directory = Path.Combine(TestContext.CurrentContext.TestDirectory, "../../"); foreach (var variant in Enum.GetValues(typeof(BuildSqlVariant)).Cast <BuildSqlVariant>()) { Write(directory, variant, "TimeoutCreate", TimeoutScriptBuilder.BuildCreateScript(variant)); Write(directory, variant, "TimeoutDrop", TimeoutScriptBuilder.BuildDropScript(variant)); Write(directory, variant, "OutboxCreate", OutboxScriptBuilder.BuildCreateScript(variant)); Write(directory, variant, "OutboxDrop", OutboxScriptBuilder.BuildDropScript(variant)); Write(directory, variant, "SubscriptionCreate", SubscriptionScriptBuilder.BuildCreateScript(variant)); Write(directory, variant, "SubscriptionDrop", SubscriptionScriptBuilder.BuildDropScript(variant)); var sagaDefinition = new SagaDefinition( tableSuffix: "OrderSaga", name: "OrderSaga", correlationProperty: new CorrelationProperty( name: "OrderNumber", type: CorrelationPropertyType.Int), transitionalCorrelationProperty: new CorrelationProperty( name: "OrderId", type: CorrelationPropertyType.Guid)); Write(directory, variant, "SagaCreate", SagaScriptBuilder.BuildCreateScript(sagaDefinition, variant)); Write(directory, variant, "SagaDrop", SagaScriptBuilder.BuildDropScript(sagaDefinition, variant)); } foreach (var variant in Enum.GetValues(typeof(SqlVariant)).Cast <SqlVariant>()) { var timeoutCommands = TimeoutCommandBuilder.Build( sqlVariant: variant, tablePrefix: "EndpointName", schema: "dbo"); Write(directory, variant, "TimeoutAdd", timeoutCommands.Add); Write(directory, variant, "TimeoutNext", timeoutCommands.Next); Write(directory, variant, "TimeoutRange", timeoutCommands.Range); Write(directory, variant, "TimeoutRemoveById", timeoutCommands.RemoveById); Write(directory, variant, "TimeoutRemoveBySagaId", timeoutCommands.RemoveBySagaId); Write(directory, variant, "TimeoutPeek", timeoutCommands.Peek); var outboxCommands = OutboxCommandBuilder.Build( tablePrefix: "EndpointName", schema: "dbo", sqlVariant: variant); Write(directory, variant, "OutboxCleanup", outboxCommands.Cleanup); Write(directory, variant, "OutboxGet", outboxCommands.Get); Write(directory, variant, "OutboxSetAsDispatched", outboxCommands.SetAsDispatched); Write(directory, variant, "OutboxStore", outboxCommands.Store); var subscriptionCommands = SubscriptionCommandBuilder.Build( sqlVariant: variant, tablePrefix: "EndpointName", schema: "dbo"); Write(directory, variant, "SubscriptionSubscribe", subscriptionCommands.Subscribe); Write(directory, variant, "SubscriptionUnsubscribe", subscriptionCommands.Unsubscribe); Write(directory, variant, "SubscriptionGetSubscribers", subscriptionCommands.GetSubscribers(new List <MessageType> { new MessageType("MessageTypeName", new Version()) })); var sagaCommandBuilder = new SagaCommandBuilder(); Write(directory, variant, "SagaComplete", sagaCommandBuilder.BuildCompleteCommand("EndpointName_SagaName")); Write(directory, variant, "SagadGetByProperty", sagaCommandBuilder.BuildGetByPropertyCommand("PropertyName", "EndpointName_SagaName")); Write(directory, variant, "SagaGetBySagaId", sagaCommandBuilder.BuildGetBySagaIdCommand("EndpointName_SagaName")); Write(directory, variant, "SagaSave", sagaCommandBuilder.BuildSaveCommand("CorrelationProperty", "TransitionalCorrelationProperty", "EndpointName_SagaName")); Write(directory, variant, "SagaUpdate", sagaCommandBuilder.BuildUpdateCommand("TransitionalCorrelationProperty", "EndpointName_SagaName")); Write(directory, variant, "SagaSelect", sagaCommandBuilder.BuildSelectFromCommand("EndpointName_SagaName")); } }
public void TearDown() { MsmqQueueDeletion.DeleteQueuesForEndpoint(endpointName); dbConnection.ExecuteCommand(SagaScriptBuilder.BuildDropScript(sagaDefinition, sqlVariant), nameof(MsmqTransportIntegrationTests)); dbConnection.ExecuteCommand(TimeoutScriptBuilder.BuildDropScript(sqlVariant), nameof(MsmqTransportIntegrationTests)); }
public void Write() { var directory = Path.Combine(TestContext.CurrentContext.TestDirectory, "../../../"); foreach (var variant in Enum.GetValues(typeof(BuildSqlDialect)).Cast <BuildSqlDialect>()) { Write(directory, variant, "TimeoutCreate", TimeoutScriptBuilder.BuildCreateScript(variant)); Write(directory, variant, "TimeoutDrop", TimeoutScriptBuilder.BuildDropScript(variant)); Write(directory, variant, "OutboxCreate", OutboxScriptBuilder.BuildCreateScript(variant)); Write(directory, variant, "OutboxDrop", OutboxScriptBuilder.BuildDropScript(variant)); Write(directory, variant, "SubscriptionCreate", SubscriptionScriptBuilder.BuildCreateScript(variant)); Write(directory, variant, "SubscriptionDrop", SubscriptionScriptBuilder.BuildDropScript(variant)); var sagaDefinition = new SagaDefinition( tableSuffix: "OrderSaga", name: "OrderSaga", correlationProperty: new CorrelationProperty( name: "OrderNumber", type: CorrelationPropertyType.Int), transitionalCorrelationProperty: new CorrelationProperty( name: "OrderId", type: CorrelationPropertyType.Guid)); Write(directory, variant, "SagaCreate", SagaScriptBuilder.BuildCreateScript(sagaDefinition, variant)); Write(directory, variant, "SagaDrop", SagaScriptBuilder.BuildDropScript(sagaDefinition, variant)); } var dialects = new SqlDialect[] { new SqlDialect.MsSqlServer(), new SqlDialect.MySql(), new SqlDialect.Oracle(), new SqlDialect.PostgreSql() }; foreach (var dialect in dialects) { var timeoutCommands = TimeoutCommandBuilder.Build( sqlDialect: dialect, tablePrefix: "EndpointName"); Write(directory, dialect, "TimeoutAdd", timeoutCommands.Add); Write(directory, dialect, "TimeoutNext", timeoutCommands.Next); Write(directory, dialect, "TimeoutRange", timeoutCommands.Range); Write(directory, dialect, "TimeoutRemoveById", timeoutCommands.RemoveById); Write(directory, dialect, "TimeoutRemoveBySagaId", timeoutCommands.RemoveBySagaId); Write(directory, dialect, "TimeoutPeek", timeoutCommands.Peek); var outboxCommands = OutboxCommandBuilder.Build( tablePrefix: "EndpointName", sqlDialect: dialect); Write(directory, dialect, "OutboxCleanup", outboxCommands.Cleanup); Write(directory, dialect, "OutboxGet", outboxCommands.Get); Write(directory, dialect, "OutboxSetAsDispatched", outboxCommands.SetAsDispatched); Write(directory, dialect, "OutboxStore", outboxCommands.Store); var subscriptionCommands = SubscriptionCommandBuilder.Build( sqlDialect: dialect, tablePrefix: "EndpointName"); Write(directory, dialect, "SubscriptionSubscribe", subscriptionCommands.Subscribe); Write(directory, dialect, "SubscriptionUnsubscribe", subscriptionCommands.Unsubscribe); Write(directory, dialect, "SubscriptionGetSubscribers", subscriptionCommands.GetSubscribers(new List <MessageType> { new MessageType("MessageTypeName", new Version()) })); Write(directory, dialect, "SagaComplete", dialect.BuildCompleteCommand("EndpointName_SagaName")); Write(directory, dialect, "SagaGetByProperty", dialect.BuildGetByPropertyCommand("PropertyName", "EndpointName_SagaName")); Write(directory, dialect, "SagaGetBySagaId", dialect.BuildGetBySagaIdCommand("EndpointName_SagaName")); Write(directory, dialect, "SagaSave", dialect.BuildSaveCommand("CorrelationProperty", "TransitionalCorrelationProperty", "EndpointName_SagaName")); Write(directory, dialect, "SagaUpdate", dialect.BuildUpdateCommand("TransitionalCorrelationProperty", "EndpointName_SagaName")); // since we don't have doco on oracle saga finders if (!(dialect is SqlDialect.Oracle)) { var createSelectWithWhereClause = dialect.BuildSelectFromCommand("EndpointName_SagaName"); Write(directory, dialect, "SagaSelect", createSelectWithWhereClause("1 = 1")); } } }
public void TearDown() { dbConnection.ExecuteCommand(SagaScriptBuilder.BuildDropScript(sagaDefinition, sqlDialect), nameof(MixedSagaAndNoOutbox)); dbConnection.ExecuteCommand(TimeoutScriptBuilder.BuildDropScript(sqlDialect), nameof(MixedSagaAndNoOutbox)); }
async Task RunTest(Action <EndpointConfiguration> testCase) { ManualResetEvent.Reset(); string message = null; var sagaDefinition = new SagaDefinition( tableSuffix: nameof(Saga1), name: nameof(Saga1), correlationProperty: new CorrelationProperty ( name: nameof(Saga1.SagaData.CorrelationId), type: CorrelationPropertyType.Guid ) ); Execute(SagaScriptBuilder.BuildDropScript(sagaDefinition, BuildSqlVariant.MsSqlServer)); Execute(OutboxScriptBuilder.BuildDropScript(BuildSqlVariant.MsSqlServer)); Execute(SagaScriptBuilder.BuildCreateScript(sagaDefinition, BuildSqlVariant.MsSqlServer)); Execute(OutboxScriptBuilder.BuildCreateScript(BuildSqlVariant.MsSqlServer)); var endpointConfiguration = EndpointConfigBuilder.BuildEndpoint(endpointName); var typesToScan = TypeScanner.NestedTypes <SagaConsistencyTests>(); endpointConfiguration.SetTypesToScan(typesToScan); endpointConfiguration.DisableFeature <NServiceBus.Features.TimeoutManager>(); var transport = endpointConfiguration.UseTransport <SqlServerTransport>(); testCase(endpointConfiguration); transport.ConnectionString(MsSqlConnectionBuilder.ConnectionString); var persistence = endpointConfiguration.UsePersistence <SqlPersistence>(); persistence.ConnectionBuilder(MsSqlConnectionBuilder.Build); persistence.SubscriptionSettings().DisableCache(); persistence.DisableInstaller(); endpointConfiguration.DefineCriticalErrorAction(c => { message = c.Error; ManualResetEvent.Set(); return(Task.FromResult(0)); }); endpointConfiguration.LimitMessageProcessingConcurrencyTo(1); endpointConfiguration.Pipeline.Register(new FailureTrigger(), "Failure trigger"); var endpoint = await Endpoint.Start(endpointConfiguration).ConfigureAwait(false); var sagaId = Guid.NewGuid(); await endpoint.SendLocal(new StartSagaMessage { SagaId = sagaId }).ConfigureAwait(false); await endpoint.SendLocal(new FailingMessage { SagaId = sagaId }).ConfigureAwait(false); await endpoint.SendLocal(new CheckMessage { SagaId = sagaId }).ConfigureAwait(false); ManualResetEvent.WaitOne(); await endpoint.Stop().ConfigureAwait(false); Assert.AreEqual("Success", message); }
public void TearDown() { dbConnection.ExecuteCommand(SagaScriptBuilder.BuildDropScript(sagaDefinition, sqlDialect), nameof(TransportIntegrationTests)); dbConnection.ExecuteCommand(TimeoutScriptBuilder.BuildDropScript(sqlDialect), nameof(TransportIntegrationTests)); }
public Task Configure(CancellationToken cancellationToken = default) { var variant = (SqlTestVariant)Variant.Values[0]; var dialect = variant.Dialect; var buildDialect = variant.BuildDialect; var connectionFactory = variant.ConnectionFactory; var pessimisticMode = variant.UsePessimisticMode; if (SessionTimeout.HasValue) { dialect = new TimeoutSettingDialect(dialect, (int)SessionTimeout.Value.TotalSeconds); } var infoCache = new SagaInfoCache( null, Serializer.JsonSerializer, reader => new JsonTextReader(reader), writer => new JsonTextWriter(writer), "PersistenceTests_", dialect, SagaMetadataCollection, name => ShortenSagaName(name)); var connectionManager = new ConnectionManager(connectionFactory); SagaIdGenerator = new DefaultSagaIdGenerator(); SagaStorage = new SagaPersister(infoCache, dialect); SynchronizedStorage = new SynchronizedStorage(connectionManager, infoCache, null); SynchronizedStorageAdapter = new StorageAdapter(connectionManager, infoCache, dialect, null); OutboxStorage = CreateOutboxPersister(connectionManager, dialect, false, false); SupportsPessimisticConcurrency = pessimisticMode; GetContextBagForSagaStorage = () => { var contextBag = new ContextBag(); contextBag.Set(new IncomingMessage("MessageId", new Dictionary <string, string>(), new byte[0])); return(contextBag); }; GetContextBagForOutbox = () => { var contextBag = new ContextBag(); contextBag.Set(new IncomingMessage("MessageId", new Dictionary <string, string>(), new byte[0])); return(contextBag); }; using (var connection = connectionFactory()) { connection.Open(); foreach (var saga in SagaMetadataCollection) { CorrelationProperty correlationProperty = null; if (saga.TryGetCorrelationProperty(out var propertyMetadata)) { correlationProperty = new CorrelationProperty(propertyMetadata.Name, CorrelationPropertyType.String); } var tableName = ShortenSagaName(saga.SagaType.Name); var definition = new SagaDefinition(tableName, saga.EntityName, correlationProperty); connection.ExecuteCommand(SagaScriptBuilder.BuildDropScript(definition, buildDialect), "PersistenceTests"); connection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(definition, buildDialect), "PersistenceTests"); } connection.ExecuteCommand(OutboxScriptBuilder.BuildDropScript(buildDialect), "PersistenceTests"); connection.ExecuteCommand(OutboxScriptBuilder.BuildCreateScript(buildDialect), "PersistenceTests"); } return(Task.CompletedTask); }