protected override void Setup(FeatureConfigurationContext context)
    {
        context.Settings.EnableFeature<StorageType.Sagas>();

        var settings = context.Settings;
        var endpointName = settings.GetTablePrefix<StorageType.Sagas>();
        var sqlVarient = settings.GetSqlVarient();
        var commandBuilder = new SagaCommandBuilder(sqlVarient,endpointName);
        var jsonSerializerSettings = SagaSettings.GetJsonSerializerSettings(settings);
        var jsonSerializer = BuildJsonSerializer(jsonSerializerSettings);
        var readerCreator = SagaSettings.GetReaderCreator(settings);
        if (readerCreator == null)
        {
            readerCreator = reader => new JsonTextReader(reader);
        }
        var writerCreator = SagaSettings.GetWriterCreator(settings);
        if (writerCreator == null)
        {
            writerCreator = writer => new JsonTextWriter(writer);
        }
        var versionDeserializeBuilder = SagaSettings.GetVersionSettings(settings);
        var infoCache = new SagaInfoCache(versionDeserializeBuilder, jsonSerializer, readerCreator, writerCreator, commandBuilder);
        var sagaPersister = new SagaPersister(infoCache);
        context.Container.ConfigureComponent<ISagaPersister>(() => sagaPersister, DependencyLifecycle.SingleInstance);
    }
Beispiel #2
0
    protected override void Setup(FeatureConfigurationContext context)
    {
        var settings = context.Settings;

        ValidateSagaOutboxCombo(settings);

        var sqlDialect        = settings.GetSqlDialect();
        var container         = context.Container;
        var connectionManager = settings.GetConnectionBuilder <StorageType.Sagas>();

        var sqlSagaPersistenceActivated = settings.IsFeatureActive(typeof(SqlSagaFeature));

        SagaInfoCache infoCache = null;

        if (sqlSagaPersistenceActivated)
        {
            infoCache = BuildSagaInfoCache(sqlDialect, settings);
        }

        var sessionHolder = new CurrentSessionHolder();

        //Info cache can be null if Outbox is enabled but Sagas are disabled.
        container.ConfigureComponent(() => new SynchronizedStorage(connectionManager, infoCache, sessionHolder), DependencyLifecycle.SingleInstance);
        container.ConfigureComponent(() => new StorageAdapter(connectionManager, infoCache, sqlDialect, sessionHolder), DependencyLifecycle.SingleInstance);

        container.ConfigureComponent(() => sessionHolder.Current, DependencyLifecycle.InstancePerCall);
        context.Pipeline.Register(new CurrentSessionBehavior(sessionHolder), "Manages the lifecycle of the current session holder.");

        if (sqlSagaPersistenceActivated)
        {
            var sagaPersister = new SagaPersister(infoCache, sqlDialect);
            container.ConfigureComponent <ISagaPersister>(() => sagaPersister, DependencyLifecycle.SingleInstance);
        }
    }
    protected override void Setup(FeatureConfigurationContext context)
    {
        var settings = context.Settings;

        ValidateSagaOutboxCombo(settings);

        var sqlDialect        = settings.GetSqlDialect();
        var services          = context.Services;
        var connectionManager = settings.GetConnectionBuilder <StorageType.Sagas>();

        var sqlSagaPersistenceActivated = settings.IsFeatureActive(typeof(SqlSagaFeature));

        SagaInfoCache infoCache = null;

        if (sqlSagaPersistenceActivated)
        {
            infoCache = BuildSagaInfoCache(sqlDialect, settings);
        }

        var sessionHolder = new CurrentSessionHolder();

        //Info cache can be null if Outbox is enabled but Sagas are disabled.
        services.AddSingleton <ISynchronizedStorage>(new SynchronizedStorage(connectionManager, infoCache, sessionHolder));
        services.AddSingleton <ISynchronizedStorageAdapter>(new StorageAdapter(connectionManager, infoCache, sqlDialect, sessionHolder));

        services.AddTransient(_ => sessionHolder.Current);
        context.Pipeline.Register(new CurrentSessionBehavior(sessionHolder), "Manages the lifecycle of the current session holder.");

        if (sqlSagaPersistenceActivated)
        {
            var sagaPersister = new SagaPersister(infoCache, sqlDialect);
            services.AddSingleton <ISagaPersister>(sagaPersister);
        }
    }
 public StorageAdapter(IConnectionManager connectionBuilder, SagaInfoCache infoCache, SqlDialect dialect, CurrentSessionHolder currentSessionHolder)
 {
     this.connectionBuilder    = connectionBuilder;
     this.infoCache            = infoCache;
     this.dialect              = dialect;
     this.currentSessionHolder = currentSessionHolder;
 }
    protected override void Setup(FeatureConfigurationContext context)
    {
        var settings = context.Settings;

        ValidateSagaOutboxCombo(settings);

        var sqlDialect        = settings.GetSqlDialect();
        var container         = context.Container;
        var connectionBuilder = settings.GetConnectionBuilder();

        var isSagasEnabledForSqlPersistence  = settings.IsFeatureActive(typeof(SqlSagaFeature));
        var isOutboxEnabledForSqlPersistence = settings.IsFeatureActive(typeof(SqlOutboxFeature));

        SagaInfoCache infoCache = null;

        if (isSagasEnabledForSqlPersistence)
        {
            infoCache = BuildSagaInfoCache(sqlDialect, settings);
        }

        if (isOutboxEnabledForSqlPersistence || isSagasEnabledForSqlPersistence)
        {
            //Info cache can be null if Outbox is enabled but Sagas are disabled.
            container.ConfigureComponent(() => new SynchronizedStorage(connectionBuilder, infoCache), DependencyLifecycle.SingleInstance);
            container.ConfigureComponent(() => new StorageAdapter(connectionBuilder, infoCache, sqlDialect), DependencyLifecycle.SingleInstance);
        }
        if (isSagasEnabledForSqlPersistence)
        {
            var sagaPersister = new SagaPersister(infoCache, sqlDialect);
            container.ConfigureComponent <ISagaPersister>(() => sagaPersister, DependencyLifecycle.SingleInstance);
        }
    }
    public StorageSession(DbConnection connection, DbTransaction transaction, bool ownsTransaction, SagaInfoCache infoCache)
    {
        Guard.AgainstNull(nameof(connection), connection);

        Connection           = connection;
        this.ownsTransaction = ownsTransaction;
        InfoCache            = infoCache;
        Transaction          = transaction;
    }
Beispiel #7
0
    protected override void Setup(FeatureConfigurationContext context)
    {
        var settings = context.Settings;

        settings.EnableFeature <StorageType.Sagas>();

        var sqlVariant = settings.GetSqlVariant();

#pragma warning disable 618
        var commandBuilder = new SagaCommandBuilder(sqlVariant);
#pragma warning restore 618
        var jsonSerializerSettings = SagaSettings.GetJsonSerializerSettings(settings);
        var jsonSerializer         = BuildJsonSerializer(jsonSerializerSettings);
        var readerCreator          = SagaSettings.GetReaderCreator(settings);
        if (readerCreator == null)
        {
            readerCreator = reader => new JsonTextReader(reader);
        }
        var writerCreator = SagaSettings.GetWriterCreator(settings);
        if (writerCreator == null)
        {
            writerCreator = writer => new JsonTextWriter(writer);
        }
        var nameFilter = SagaSettings.GetNameFilter(settings);
        if (nameFilter == null)
        {
            nameFilter = (sagaName => sagaName);
        }
        var versionDeserializeBuilder = SagaSettings.GetVersionSettings(settings);
        var tablePrefix = settings.GetTablePrefix();
        var schema      = settings.GetSchema();
        var infoCache   = new SagaInfoCache(
            versionSpecificSettings: versionDeserializeBuilder,
            jsonSerializer: jsonSerializer,
            readerCreator: readerCreator,
            writerCreator: writerCreator,
            commandBuilder: commandBuilder,
            tablePrefix: tablePrefix,
            schema: schema,
            sqlVariant: sqlVariant,
            metadataCollection: settings.Get <SagaMetadataCollection>(),
            nameFilter: nameFilter);
        var sagaPersister = new SagaPersister(infoCache, sqlVariant);
        var container     = context.Container;
        container.ConfigureComponent(() => infoCache, DependencyLifecycle.SingleInstance);
        container.ConfigureComponent <ISagaPersister>(() => sagaPersister, DependencyLifecycle.SingleInstance);
    }
    SagaPersister SetUp(string endpointName, string theSchema)
    {
        var runtimeSqlDialect = sqlDialect.Convert(theSchema);

        var sagaMetadataCollection = new SagaMetadataCollection();

        sagaMetadataCollection.Initialize(GetSagasAndFinders());

        var infoCache = new SagaInfoCache(
            versionSpecificSettings: null,
            jsonSerializer: Serializer.JsonSerializer,
            readerCreator: reader => new JsonTextReader(reader),
            writerCreator: writer => new JsonTextWriter(writer),
            tablePrefix: $"{endpointName}_",
            sqlDialect: runtimeSqlDialect,
            metadataCollection: sagaMetadataCollection,
            nameFilter: sagaName => sagaName);

        return(new SagaPersister(infoCache, runtimeSqlDialect));
    }
Beispiel #9
0
        public PersistenceTestsConfiguration()
        {
            var statefulService = (StatefulService)TestContext.CurrentContext.Test.Properties.Get("StatefulService");

            stateManager = statefulService.StateManager;

            SynchronizedStorage        = new SynchronizedStorage(stateManager);
            SynchronizedStorageAdapter = new SynchronizedStorageAdapter();

            var sagaInfoCache = new SagaInfoCache();

            sagaInfoCache.Initialize(SagaMetadataCollection);
            SagaStorage = new SagaPersister(sagaInfoCache);

            var sagaIdGenerator = new SagaIdGenerator();

            sagaIdGenerator.Initialize(sagaInfoCache);
            SagaIdGenerator = sagaIdGenerator;

            OutboxStorage = new OutboxStorage(statefulService.StateManager);
        }
Beispiel #10
0
    static RuntimeSagaInfo BuildSagaInfo <TSaga, TSagaData>(SqlDialect dialect)
        where TSaga : SqlSaga <TSagaData>
        where TSagaData : IContainSagaData, new()
    {
        var sagaMetadataCollection = new SagaMetadataCollection();

        sagaMetadataCollection.Initialize(new[]
        {
            typeof(TSaga)
        });

        var infoCache = new SagaInfoCache(
            null,
            Serializer.JsonSerializer,
            readerCreator: reader => new JsonTextReader(reader),
            writerCreator: writer => new JsonTextWriter(writer),
            tablePrefix: "some",
            sqlDialect: dialect,
            metadataCollection: sagaMetadataCollection,
            nameFilter: sagaName => sagaName);

        return(infoCache.GetInfo(typeof(TSagaData)));
    }
    SagaPersister SetUp(string endpointName)
    {
        var runtimeSqlVariant = sqlVariant.Convert();

#pragma warning disable 618
        var commandBuilder = new SagaCommandBuilder(runtimeSqlVariant);
#pragma warning restore 618

        var sagaMetadataCollection = new SagaMetadataCollection();
        sagaMetadataCollection.Initialize(GetSagasAndFinders());

        var infoCache = new SagaInfoCache(
            versionSpecificSettings: null,
            jsonSerializer: Serializer.JsonSerializer,
            commandBuilder: commandBuilder,
            readerCreator: reader => new JsonTextReader(reader),
            writerCreator: writer => new JsonTextWriter(writer),
            tablePrefix: $"{endpointName}_",
            schema: schema,
            sqlVariant: runtimeSqlVariant,
            metadataCollection: sagaMetadataCollection,
            nameFilter: sagaName => sagaName);
        return(new SagaPersister(infoCache, runtimeSqlVariant));
    }
        public async Task Configure(CancellationToken cancellationToken = default)
        {
            var statefulService = (StatefulService)TestContext.CurrentContext.Test.Properties.Get("StatefulService");

            stateManager = statefulService.StateManager;

            var timeout = SessionTimeout ?? TimeSpan.FromSeconds(4);

            SynchronizedStorage        = new SynchronizedStorage(stateManager, timeout);
            SynchronizedStorageAdapter = new SynchronizedStorageAdapter();

            var sagaInfoCache = new SagaInfoCache();

            sagaInfoCache.Initialize(SagaMetadataCollection);
            SagaStorage = new SagaPersister(sagaInfoCache);

            var sagaIdGenerator = new SagaIdGenerator();

            sagaIdGenerator.Initialize(sagaInfoCache);
            SagaIdGenerator = sagaIdGenerator;

            OutboxStorage = new OutboxStorage(statefulService.StateManager, timeout);
            await stateManager.RegisterOutboxStorage((OutboxStorage)OutboxStorage, cancellationToken).ConfigureAwait(false);
        }
 public StorageAdapter(Func <DbConnection> connectionBuilder, SagaInfoCache infoCache)
 {
     this.connectionBuilder = connectionBuilder;
     this.infoCache         = infoCache;
 }
 public SagaPersister(SagaInfoCache sagaInfoCache, SqlVariant sqlVariant)
 {
     this.sagaInfoCache = sagaInfoCache;
     commandBuilder     = new CommandBuilder(sqlVariant);
 }
 public SagaPersister(SagaInfoCache sagaInfoCache, SqlDialect sqlDialect)
 {
     this.sagaInfoCache = sagaInfoCache;
     this.sqlDialect    = sqlDialect;
 }
Beispiel #16
0
    static Task <Concurrency <TSagaData> > GetByWhereClause <TSagaData>(string whereClause, SynchronizedStorageSession session, ParameterAppender appendParameters, SagaInfoCache sagaInfoCache)
        where TSagaData : class, IContainSagaData
    {
        var sagaInfo    = sagaInfoCache.GetInfo(typeof(TSagaData));
        var commandText = sagaInfo.SelectFromCommandBuilder(whereClause);

        return(GetSagaData <TSagaData>(session, commandText, sagaInfo, appendParameters));
    }
Beispiel #17
0
 public SynchronizedStorage(Func <DbConnection> connectionBuilder, SagaInfoCache infoCache)
 {
     this.connectionBuilder = connectionBuilder;
     this.infoCache         = infoCache;
 }
Beispiel #18
0
    internal static async Task <TSagaData> GetByWhereClause <TSagaData>(string whereClause, SynchronizedStorageSession session, ContextBag context, ParameterAppender appendParameters, SagaInfoCache sagaInfoCache)
        where TSagaData : class, IContainSagaData
    {
        var result = await GetByWhereClause <TSagaData>(whereClause, session, appendParameters, sagaInfoCache).ConfigureAwait(false);

        return(SetConcurrency(result, context));
    }
 public StorageAdapter(Func <DbConnection> connectionBuilder, SagaInfoCache infoCache, SqlDialect dialect)
 {
     this.connectionBuilder = connectionBuilder;
     this.infoCache         = infoCache;
     this.dialect           = dialect;
 }
        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);
        }
 public SynchronizedStorage(IConnectionManager connectionManager, SagaInfoCache infoCache)
 {
     this.connectionManager = connectionManager;
     this.infoCache         = infoCache;
 }
Beispiel #22
0
 public SynchronizedStorage(IConnectionManager connectionManager, SagaInfoCache infoCache, CurrentSessionHolder currentSessionHolder)
 {
     this.connectionManager    = connectionManager;
     this.infoCache            = infoCache;
     this.currentSessionHolder = currentSessionHolder;
 }