public async Task Should_remove_old_property_after_phase_three()
    {
        var dialect    = BuildSqlDialect.MsSqlServer;
        var sagaPhase1 = RuntimeSagaDefinitionReader.GetSagaDefinition(typeof(Phase1Saga), dialect);
        var sagaPhase2 = RuntimeSagaDefinitionReader.GetSagaDefinition(typeof(Phase2Saga), dialect);
        var sagaPhase3 = RuntimeSagaDefinitionReader.GetSagaDefinition(typeof(Phase3Saga), dialect);

        using (var connection = MsSqlSystemDataClientConnectionBuilder.Build())
        {
            await connection.OpenAsync().ConfigureAwait(false);

            connection.ExecuteCommand(SagaScriptBuilder.BuildDropScript(sagaPhase1, dialect), "");
            connection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(sagaPhase1, dialect), "");
            var phase1Schema = GetSchema(connection);
            connection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(sagaPhase2, dialect), "");
            var phase2Schema = GetSchema(connection);
            connection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(sagaPhase3, dialect), "");
            var phase3Schema = GetSchema(connection);

            CollectionAssert.Contains(phase1Schema, "Correlation_OrderNumber");
            CollectionAssert.DoesNotContain(phase1Schema, "Correlation_OrderId");

            CollectionAssert.Contains(phase2Schema, "Correlation_OrderNumber");
            CollectionAssert.Contains(phase2Schema, "Correlation_OrderId");

            CollectionAssert.DoesNotContain(phase3Schema, "Correlation_OrderNumber");
            CollectionAssert.Contains(phase3Schema, "Correlation_OrderId");
        }
    }
    public void CreateWithCorrelation(BuildSqlDialect sqlDialect)
    {
        var saga = new SagaDefinition(
            name: "theSaga",
            tableSuffix: "theSaga",
            correlationProperty: new CorrelationProperty
            (
                name: "CorrelationProperty",
                type: CorrelationPropertyType.String
            )
            );

        var builder = new StringBuilder();

        using (var writer = new StringWriter(builder))
        {
            SagaScriptBuilder.BuildCreateScript(saga, sqlDialect, writer);
        }
        var script = builder.ToString();

        if (sqlDialect == BuildSqlDialect.MsSqlServer)
        {
            SqlValidator.Validate(script);
        }
#if NET452
        using (ApprovalResults.ForScenario(sqlDialect))
        {
            Approvals.Verify(script);
        }
#endif
    }
 public ConfigureEndpointHelper(EndpointConfiguration configuration, string tablePrefix, Func <DbConnection> connectionBuilder, BuildSqlDialect sqlDialect, Func <Exception, bool> exceptionFilter = null)
 {
     this.tablePrefix       = tablePrefix;
     this.connectionBuilder = connectionBuilder;
     this.sqlDialect        = sqlDialect;
     this.exceptionFilter   = exceptionFilter;
     sagaDefinitions        = RuntimeSagaDefinitionReader.GetSagaDefinitions(configuration, sqlDialect).ToList();
     using (var connection = connectionBuilder())
     {
         connection.Open();
         foreach (var definition in sagaDefinitions)
         {
             connection.ExecuteCommand(SagaScriptBuilder.BuildDropScript(definition, sqlDialect), tablePrefix, exceptionFilter);
             try
             {
                 connection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(definition, sqlDialect), tablePrefix);
             }
             catch (Exception exception) when(exception.Message.Contains("Can't DROP"))
             {
                 //ignore cleanup exceptions caused by async database operations
             }
         }
         connection.ExecuteCommand(TimeoutScriptBuilder.BuildDropScript(sqlDialect), tablePrefix, exceptionFilter);
         connection.ExecuteCommand(TimeoutScriptBuilder.BuildCreateScript(sqlDialect), tablePrefix);
         connection.ExecuteCommand(SubscriptionScriptBuilder.BuildDropScript(sqlDialect), tablePrefix, exceptionFilter);
         connection.ExecuteCommand(SubscriptionScriptBuilder.BuildCreateScript(sqlDialect), tablePrefix);
         connection.ExecuteCommand(OutboxScriptBuilder.BuildDropScript(sqlDialect), tablePrefix, exceptionFilter);
         connection.ExecuteCommand(OutboxScriptBuilder.BuildCreateScript(sqlDialect), tablePrefix);
     }
 }
Exemple #4
0
 public void Setup()
 {
     dbConnection.ExecuteCommand(SagaScriptBuilder.BuildDropScript(sagaDefinition, sqlDialect), nameof(TransportIntegrationTests));
     dbConnection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(sagaDefinition, sqlDialect), nameof(TransportIntegrationTests));
     dbConnection.ExecuteCommand(TimeoutScriptBuilder.BuildDropScript(sqlDialect), nameof(TransportIntegrationTests));
     dbConnection.ExecuteCommand(TimeoutScriptBuilder.BuildCreateScript(sqlDialect), nameof(TransportIntegrationTests));
 }
Exemple #5
0
    public static void WriteSagaScripts(string scriptPath, ModuleDefinition moduleDefinition, BuildSqlVariant sqlVariant, 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((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, sqlVariant, writer);
            }

            var dropPath = Path.Combine(sagasScriptPath, $"{sagaFileName}_Drop.sql");
            File.Delete(dropPath);
            using (var writer = File.CreateText(dropPath))
            {
                SagaScriptBuilder.BuildDropScript(saga, sqlVariant, writer);
            }
        }
    }
    public void ExecuteCreateTwice()
    {
        var endpointName = nameof(ExecuteCreateTwice);
        var definition   = new SagaDefinition(
            tableSuffix: "SagaWithCorrelation",
            name: "SagaWithCorrelation",
            correlationProperty: new CorrelationProperty
            (
                name: "CorrelationProperty",
                type: CorrelationPropertyType.String
            ),
            transitionalCorrelationProperty: new CorrelationProperty
            (
                name: "TransitionalCorrelationProperty",
                type: CorrelationPropertyType.String
            )
            );

        using (var connection = dbConnection())
        {
            connection.ExecuteCommand(SagaScriptBuilder.BuildDropScript(definition, sqlDialect), endpointName, schema: schema);
            var createScript = SagaScriptBuilder.BuildCreateScript(definition, sqlDialect);
            connection.ExecuteCommand(createScript, endpointName, schema: schema);
            connection.ExecuteCommand(createScript, endpointName, schema: schema);
        }
    }
    public void CreateWithCorrelationAndTransitional(BuildSqlVariant sqlVariant)
    {
        var saga = new SagaDefinition(
            tableSuffix: "theSaga",
            name: "theSaga",
            correlationProperty: new CorrelationProperty
            (
                name: "CorrelationProperty",
                type: CorrelationPropertyType.String
            ),
            transitionalCorrelationProperty: new CorrelationProperty
            (
                name: "TransitionalProperty",
                type: CorrelationPropertyType.String
            )
            );

        var builder = new StringBuilder();

        using (var writer = new StringWriter(builder))
        {
            SagaScriptBuilder.BuildCreateScript(saga, sqlVariant, writer);
        }
        var script = builder.ToString();

        if (sqlVariant == BuildSqlVariant.MsSqlServer)
        {
            SqlValidator.Validate(script);
        }

        using (ApprovalResults.ForScenario(sqlVariant))
        {
            Approvals.Verify(script);
        }
    }
    public override void WriteScripts(BuildSqlDialect dialect)
    {
        Directory.CreateDirectory(sagaPath);

        var metaDataReader = new AllSagaDefinitionReader(moduleDefinition);

        var index = 0;

        foreach (var saga in metaDataReader.GetSagas(logError))
        {
            var sagaFileName      = saga.TableSuffix;
            var maximumNameLength = 244 - ScriptPath.Length;
            if (sagaFileName.Length > maximumNameLength)
            {
                sagaFileName = $"{sagaFileName.Substring(0, maximumNameLength)}_{index}";
                index++;
            }

            var createPath = Path.Combine(sagaPath, $"{sagaFileName}_Create.sql");
            WriteScript(createPath, writer => SagaScriptBuilder.BuildCreateScript(saga, dialect, writer));

            var dropPath = Path.Combine(sagaPath, $"{sagaFileName}_Drop.sql");
            WriteScript(dropPath, writer => SagaScriptBuilder.BuildDropScript(saga, dialect, writer));
        }
    }
    public void Should_remove_old_property_after_phase_three()
    {
        var dialect = BuildSqlDialect.MySql;

        using (var connection = MySqlConnectionBuilder.Build())
        {
            connection.Open();

            //HACK: Thread Sleeps required since information_schema.statistics takes some time to update

            var sagaPhase1 = RuntimeSagaDefinitionReader.GetSagaDefinition(typeof(Phase1Saga), dialect);
            connection.ExecuteCommand(SagaScriptBuilder.BuildDropScript(sagaPhase1, dialect), "");
            Thread.Sleep(200);
            connection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(sagaPhase1, dialect), "");
            Thread.Sleep(200);
            var phase1Schema = GetSchema(connection);
            CollectionAssert.Contains(phase1Schema, "Correlation_OrderNumber");
            CollectionAssert.DoesNotContain(phase1Schema, "Correlation_OrderId");

            var sagaPhase2 = RuntimeSagaDefinitionReader.GetSagaDefinition(typeof(Phase2Saga), dialect);
            connection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(sagaPhase2, dialect), "");
            Thread.Sleep(200);
            var phase2Schema = GetSchema(connection);
            CollectionAssert.Contains(phase2Schema, "Correlation_OrderNumber");
            CollectionAssert.Contains(phase2Schema, "Correlation_OrderId");

            var sagaPhase3 = RuntimeSagaDefinitionReader.GetSagaDefinition(typeof(Phase3Saga), dialect);
            connection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(sagaPhase3, dialect), "");
            Thread.Sleep(200);
            var phase3Schema = GetSchema(connection);
            CollectionAssert.DoesNotContain(phase3Schema, "Correlation_OrderNumber");
            CollectionAssert.Contains(phase3Schema, "Correlation_OrderId");
        }
    }
Exemple #10
0
    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");
            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(variant, "EndpointName");
            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(variant, "EndpointName");
            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(variant, "EndpointName");
            Write(directory, variant, "SagaComplete", sagaCommandBuilder.BuildCompleteCommand("SagaName"));
            Write(directory, variant, "SagadGetByProperty", sagaCommandBuilder.BuildGetByPropertyCommand("SagaName", "PropertyName"));
            Write(directory, variant, "SagaGetBySagaId", sagaCommandBuilder.BuildGetBySagaIdCommand("SagaName"));
            Write(directory, variant, "SagaSave", sagaCommandBuilder.BuildSaveCommand("SagaName", "CorrelationPproperty", "TransitionalCorrelationPproperty"));
            Write(directory, variant, "SagaUpdate", sagaCommandBuilder.BuildUpdateCommand("SagaName", "TransitionalCorrelationPproperty"));
        }
    }
 void DropAndCreate(SagaDefinition definition, string endpointName, string theSchema)
 {
     using (var connection = GetConnection()(theSchema))
     {
         connection.ExecuteCommand(SagaScriptBuilder.BuildDropScript(definition, sqlDialect), endpointName, schema: theSchema);
         connection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(definition, sqlDialect), endpointName, schema: theSchema);
     }
 }
 public void Setup()
 {
     MsmqQueueDeletion.DeleteQueuesForEndpoint(endpointName);
     dbConnection.ExecuteCommand(SagaScriptBuilder.BuildDropScript(sagaDefinition, sqlVariant), nameof(MsmqTransportIntegrationTests));
     dbConnection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(sagaDefinition, sqlVariant), nameof(MsmqTransportIntegrationTests));
     dbConnection.ExecuteCommand(TimeoutScriptBuilder.BuildDropScript(sqlVariant), nameof(MsmqTransportIntegrationTests));
     dbConnection.ExecuteCommand(TimeoutScriptBuilder.BuildCreateScript(sqlVariant), nameof(MsmqTransportIntegrationTests));
 }
 public void Setup()
 {
     manualResetEvent = new ManualResetEvent(false);
     dbConnection.ExecuteCommand(SagaScriptBuilder.BuildDropScript(sagaDefinition, sqlDialect), nameof(MixedSagaAndNoOutbox));
     dbConnection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(sagaDefinition, sqlDialect), nameof(MixedSagaAndNoOutbox));
     dbConnection.ExecuteCommand(TimeoutScriptBuilder.BuildDropScript(sqlDialect), nameof(MixedSagaAndNoOutbox));
     dbConnection.ExecuteCommand(TimeoutScriptBuilder.BuildCreateScript(sqlDialect), nameof(MixedSagaAndNoOutbox));
 }
 void DropAndCreate(SagaDefinition definition, string endpointName)
 {
     using (var connection = dbConnection())
     {
         connection.ExecuteCommand(SagaScriptBuilder.BuildDropScript(definition, sqlVariant), endpointName, schema: schema);
         connection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(definition, sqlVariant), endpointName, schema: schema);
     }
 }
    public void TransitionalProcess()
    {
        var endpointName = nameof(TransitionalProcess);

        using (var connection = dbConnection())
        {
            var definition1 = new SagaDefinition(
                tableSuffix: "CorrAndTransitionalSaga",
                name: "CorrAndTransitionalSaga",
                correlationProperty: new CorrelationProperty
                (
                    name: "Property1",
                    type: CorrelationPropertyType.String
                )
                );
            connection.ExecuteCommand(SagaScriptBuilder.BuildDropScript(definition1, sqlDialect), endpointName, schema: schema);
            connection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(definition1, sqlDialect), endpointName, schema: schema);
            Assert.IsTrue(PropertyExists(TestTableName("TransitionalProcess", "CorrAndTransitionalSaga"), CorrelationPropertyName("Property1")));

            var definition2 = new SagaDefinition(
                tableSuffix: "CorrAndTransitionalSaga",
                name: "CorrAndTransitionalSaga",
                correlationProperty: new CorrelationProperty
                (
                    name: "Property1",
                    type: CorrelationPropertyType.String
                ),
                transitionalCorrelationProperty: new CorrelationProperty
                (
                    name: "Property2",
                    type: CorrelationPropertyType.String
                )
                );

            connection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(definition2, sqlDialect), endpointName, schema: schema);
            Assert.IsTrue(PropertyExists(TestTableName("TransitionalProcess", "CorrAndTransitionalSaga"), CorrelationPropertyName("Property1")));
            Assert.IsTrue(PropertyExists(TestTableName("TransitionalProcess", "CorrAndTransitionalSaga"), CorrelationPropertyName("Property2")));


            var definition3 = new SagaDefinition(
                tableSuffix: "CorrAndTransitionalSaga",
                name: "CorrAndTransitionalSaga",
                correlationProperty: new CorrelationProperty
                (
                    name: "Property2",
                    type: CorrelationPropertyType.String
                )
                );
            var buildCreateScript = SagaScriptBuilder.BuildCreateScript(definition3, sqlDialect);
            connection.ExecuteCommand(buildCreateScript, endpointName, schema: schema);
            Assert.IsFalse(PropertyExists(TestTableName("TransitionalProcess", "CorrAndTransitionalSaga"), CorrelationPropertyName("Property1")));
            Assert.IsTrue(PropertyExists(TestTableName("TransitionalProcess", "CorrAndTransitionalSaga"), CorrelationPropertyName("Property2")));
        }
    }
    public void CreateWithDiffTransType()
    {
        var endpointName = nameof(CreateWithDiffTransType);

        using (var connection = dbConnection())
        {
            var definition1 = new SagaDefinition(
                tableSuffix: "SagaWithCorrelation",
                name: "SagaWithCorrelation",
                correlationProperty: new CorrelationProperty
                (
                    name: "CorrelationProperty",
                    type: CorrelationPropertyType.String
                ),
                transitionalCorrelationProperty: new CorrelationProperty
                (
                    name: "TransCorrelationProperty",
                    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.String
                ),
                transitionalCorrelationProperty: new CorrelationProperty
                (
                    name: "TransCorrelationProperty",
                    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 async Task Should_remove_old_property_after_phase_three()
    {
        var dialect    = BuildSqlDialect.Oracle;
        var sagaPhase1 = RuntimeSagaDefinitionReader.GetSagaDefinition(typeof(Phase1Saga), dialect);
        var sagaPhase2 = RuntimeSagaDefinitionReader.GetSagaDefinition(typeof(Phase2Saga), dialect);
        var sagaPhase3 = RuntimeSagaDefinitionReader.GetSagaDefinition(typeof(Phase3Saga), dialect);

        string[] phase1Schema, phase2Schema, phase3Schema;

        using (var connection = OracleConnectionBuilder.Build(disableMetadataPooling: true))
        {
            await connection.OpenAsync().ConfigureAwait(false);

            connection.ExecuteCommand(SagaScriptBuilder.BuildDropScript(sagaPhase1, dialect), "");
            connection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(sagaPhase1, dialect), "");
            phase1Schema = GetSchema(connection);

            connection.PurgeStatementCache();
        }

        using (var connection = OracleConnectionBuilder.Build(disableMetadataPooling: true))
        {
            await connection.OpenAsync().ConfigureAwait(false);

            connection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(sagaPhase2, dialect), "");
            phase2Schema = GetSchema(connection);

            connection.PurgeStatementCache();
        }

        using (var connection = OracleConnectionBuilder.Build(disableMetadataPooling: true))
        {
            await connection.OpenAsync().ConfigureAwait(false);

            connection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(sagaPhase3, dialect), "");
            phase3Schema = GetSchema(connection);

            connection.PurgeStatementCache();
        }

        CollectionAssert.Contains(phase1Schema, "CORR_ORDERNUMBER");
        CollectionAssert.DoesNotContain(phase1Schema, "CORR_ORDERID");

        CollectionAssert.Contains(phase2Schema, "CORR_ORDERNUMBER");
        CollectionAssert.Contains(phase2Schema, "CORR_ORDERID");

        CollectionAssert.DoesNotContain(phase3Schema, "CORR_ORDERNUMBER");
        CollectionAssert.Contains(phase3Schema, "CORR_ORDERID");
    }
    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 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"));
            }
        }
    }
    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 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 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);
        }