public void SetUp()
        {
            var builder = new NHibernateSagaStorage();

            var cfg = new Configuration()
                      .DataBaseIntegration(x =>
            {
                x.Dialect <MsSql2012Dialect>();
                x.ConnectionString = Consts.SqlConnectionString;
            });

            var settings = new SettingsHolder();

            var metaModel = new SagaMetadataCollection();
            var types     = new [] { typeof(TestSaga), typeof(TestSagaData), typeof(TestComponent), typeof(PolymorphicPropertyBase),
                                     typeof(AlsoDerivedFromTestSagaWithTableNameAttributeActualSaga), typeof(AlsoDerivedFromTestSagaWithTableNameAttribute),
                                     typeof(DerivedFromTestSagaWithTableNameAttributeActualSaga), typeof(DerivedFromTestSagaWithTableNameAttribute),
                                     typeof(TestSagaWithTableNameAttributeActualSaga), typeof(TestSagaWithTableNameAttribute),
                                     typeof(SagaWithVersionedPropertyAttributeActualSaga), typeof(SagaWithVersionedPropertyAttribute),
                                     typeof(SagaWithoutVersionedPropertyAttributeActualSaga), typeof(SagaWithoutVersionedPropertyAttribute),
                                     typeof(object) };

            metaModel.Initialize(types);
            settings.Set <SagaMetadataCollection>(metaModel);

            settings.Set("TypesToScan", types);
            builder.ApplyMappings(settings, cfg);
            sessionFactory = cfg.BuildSessionFactory() as SessionFactoryImpl;

            persisterForTestSaga = sessionFactory.GetEntityPersisterFor <TestSagaData>();
        }
        public static void AddMappings(Configuration configuration, SagaMetadataCollection allSagaMetadata, IEnumerable <Type> types, Func <Type, string> tableNamingConvention = null)
        {
            var modelMapper = new SagaModelMapper(allSagaMetadata, types, tableNamingConvention);

            configuration.AddMapping(modelMapper.Compile());
            configuration.BuildMappings();
            var mappings = configuration.CreateMappings(Dialect.GetDialect(configuration.Properties));

            foreach (var type in modelMapper.childTables)
            {
                var table = mappings.GetClass(type.FullName)?.Table;
                if (table == null)
                {
                    continue;
                }
                foreach (var foreignKey in table.ForeignKeyIterator)
                {
                    var idx = new Index();
                    idx.AddColumns(foreignKey.ColumnIterator);
                    idx.Name  = "IDX" + foreignKey.Name.Substring(2);
                    idx.Table = table;
                    table.AddIndex(idx);
                }
            }
        }
        /// <summary>
        /// Generates the table creation script for the saga data table
        /// </summary>
        /// <param name="tableNamingConvention">Optional custom table naming convention.</param>
        /// <typeparam name="TSaga">Saga type.</typeparam>
        public static string GenerateSagaScript <TSaga>(Func <Type, string> tableNamingConvention = null)
            where TSaga : Saga
        {
            var sagaBase     = typeof(TSaga).BaseType;
            var sagaDataType = sagaBase.GetGenericArguments()[0];

            var metadata = new SagaMetadataCollection();

            metadata.Initialize(new[]
            {
                typeof(TSaga)
            });
            var typesToScan = new List <Type>
            {
                sagaDataType
            };
            var sagaDataBase = sagaDataType.BaseType;

            while (sagaDataBase != null)
            {
                typesToScan.Add(sagaDataBase);
                sagaDataBase = sagaDataBase.BaseType;
            }

            var config = new Configuration();

            config.DataBaseIntegration(db => { db.Dialect <T>(); });
            SagaModelMapper.AddMappings(config, metadata, typesToScan, tableNamingConvention);
            return(GenerateScript(config));
        }
Esempio n. 4
0
        public void SetUp()
        {
            ConnectionString = $@"Data Source={Path.GetTempFileName()};New=True;";

            var configuration = new global::NHibernate.Cfg.Configuration()
                                .AddProperties(new Dictionary <string, string>
            {
                { "dialect", dialect },
                { global::NHibernate.Cfg.Environment.ConnectionString, ConnectionString }
            });

            var metaModel = new SagaMetadataCollection();

            metaModel.Initialize(new[] { typeof(T) });
            var metadata = metaModel.Find(typeof(T));

            var modelMapper = new SagaModelMapper(metaModel, new[] { metadata.SagaEntityType });

            configuration.AddMapping(modelMapper.Compile());

            SessionFactory = configuration.BuildSessionFactory();

            new SchemaUpdate(configuration).Execute(false, true);

            SagaPersister = new SagaPersister();
        }
Esempio n. 5
0
        SagaMetadataCollection GetModel(params Type[] types)
        {
            var sagaMetaModel = new SagaMetadataCollection();

            sagaMetaModel.Initialize(types.ToList(), new Conventions());
            return(sagaMetaModel);
        }
        public void SetUp()
        {
            ConnectionString = $"Data Source={Path.GetTempFileName()};New=True;";

            var configuration = new Configuration()
                                .AddProperties(new Dictionary <string, string>
            {
                { "dialect", dialect },
                { Environment.ConnectionString, ConnectionString }
            });

            var metaModel = new SagaMetadataCollection();

            metaModel.Initialize(SagaTypes);

            var sagaDataTypes = new List <Type>();

            using (var enumerator = metaModel.GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    sagaDataTypes.Add(enumerator.Current.SagaEntityType);
                }
            }

            sagaDataTypes.Add(typeof(ContainSagaData));

            SagaModelMapper.AddMappings(configuration, metaModel, sagaDataTypes);
            SessionFactory = configuration.BuildSessionFactory();

            new SchemaUpdate(configuration).Execute(true, true);

            SagaPersister = new SagaPersister();
        }
        public void SetUp()
        {
            var builder    = new NHibernateSagaStorage();
            var properties = SQLiteConfiguration.InMemory();

            var configuration = new Configuration().AddProperties(properties);
            var settings      = new SettingsHolder();

            var metaModel = new SagaMetadataCollection();
            var types     = new [] { typeof(TestSaga), typeof(TestSagaData), typeof(TestComponent), typeof(PolymorphicPropertyBase),
                                     typeof(AlsoDerivedFromTestSagaWithTableNameAttributeActualSaga), typeof(AlsoDerivedFromTestSagaWithTableNameAttribute),
                                     typeof(DerivedFromTestSagaWithTableNameAttributeActualSaga), typeof(DerivedFromTestSagaWithTableNameAttribute),
                                     typeof(TestSagaWithTableNameAttributeActualSaga), typeof(TestSagaWithTableNameAttribute),
                                     typeof(SagaWithVersionedPropertyAttributeActualSaga), typeof(SagaWithVersionedPropertyAttribute),
                                     typeof(SagaWithoutVersionedPropertyAttributeActualSaga), typeof(SagaWithoutVersionedPropertyAttribute),
                                     typeof(object) };

            metaModel.Initialize(types);
            settings.Set <SagaMetadataCollection>(metaModel);

            settings.Set("TypesToScan", types);
            builder.ApplyMappings(settings, configuration);
            sessionFactory = configuration.BuildSessionFactory() as SessionFactoryImpl;

            persisterForTestSaga = sessionFactory.GetEntityPersisterFor <TestSagaData>();
        }
Esempio n. 8
0
        public async Task SetUp()
        {
            var cfg = new Configuration()
                      .DataBaseIntegration(x =>
            {
                x.Dialect <MsSql2012Dialect>();
                x.ConnectionString = Consts.SqlConnectionString;
            });

            var metaModel = new SagaMetadataCollection();

            metaModel.Initialize(SagaTypes);

            var sagaDataTypes = new List <Type>();

            using (var enumerator = metaModel.GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    sagaDataTypes.Add(enumerator.Current.SagaEntityType);
                }
            }

            sagaDataTypes.Add(typeof(ContainSagaData));

            SagaModelMapper.AddMappings(cfg, metaModel, sagaDataTypes);
            SessionFactory = cfg.BuildSessionFactory();

            schema = new SchemaExport(cfg);
            await schema.CreateAsync(false, true);

            SagaPersister = new SagaPersister();
        }
Esempio n. 9
0
        public void SetUp()
        {
            var builder = new NHibernateSagaStorage();

            var cfg = new Configuration()
                      .DataBaseIntegration(x =>
            {
                x.Dialect <MsSql2012Dialect>();
                x.ConnectionString = Consts.SqlConnectionString;
            });

            var types = new[] { typeof(SagaWithAbstractBaseClassActualSaga), typeof(SagaWithAbstractBaseClass), typeof(ContainSagaData), typeof(MyOwnAbstractBase) };

            var allMetadata = new SagaMetadataCollection();

            allMetadata.Initialize(types);

            var settings = new SettingsHolder();

            settings.Set("TypesToScan", types);
            settings.Set <SagaMetadataCollection>(allMetadata);

            builder.ApplyMappings(settings, cfg);
            sessionFactory = cfg.BuildSessionFactory() as SessionFactoryImpl;
        }
        SagaModelMapper(SagaMetadataCollection allMetadata, IEnumerable <Type> typesToScan, Func <Type, string> tableNamingConvention = null)
        {
            this.tableNamingConvention = tableNamingConvention ?? DefaultTableNameConvention;
            mapper = new ConventionModelMapper();

            this.typesToScan = typesToScan.ToList();

            sagaMetaModel = allMetadata;

            sagaEntities =
                this.typesToScan.Where(t => typeof(IContainSagaData).IsAssignableFrom(t) && !t.IsInterface).ToList();

            PopulateTypesThatShouldBeAutoMapped();

            mapper.IsTablePerClass((type, b) => false);
            mapper.IsTablePerConcreteClass((type, b) => sagaEntities.Contains(type));
            mapper.IsTablePerClassHierarchy((type, b) => false);
            mapper.IsEntity((type, mapped) => entityTypes.Contains(type));
            mapper.IsArray((info, b) => false);
            mapper.IsBag((info, b) =>
            {
                var memberType = info.GetPropertyOrFieldType();
                return(typeof(IEnumerable).IsAssignableFrom(memberType) &&
                       !(memberType == typeof(string) || memberType == typeof(byte[]) || memberType.IsArray));
            });
            mapper.IsPersistentProperty((info, b) => !HasAttribute <RowVersionAttribute>(info));
            mapper.BeforeMapClass         += ApplyClassConvention;
            mapper.BeforeMapUnionSubclass += ApplySubClassConvention;
            mapper.BeforeMapProperty      += ApplyPropertyConvention;
            mapper.BeforeMapBag           += ApplyBagConvention;
            mapper.BeforeMapManyToOne     += ApplyManyToOneConvention;
        }
        /// <summary>
        /// Indicates the message bus configuration will have the specified saga metadata.
        /// </summary>
        /// <param name="value">The configured <see cref="SagaMetadataCollection">saga metadata</see>.</param>
        /// <returns>The original <see cref="MessageBusConfigurationBuilder"/> instance.</returns>
        public virtual MessageBusConfigurationBuilder HasSagaMetadata(SagaMetadataCollection value)
        {
            Arg.NotNull(value, nameof(value));
            Contract.Ensures(Contract.Result <MessageBusConfiguration>() != null);

            SagaMetadata = value;
            return(this);
        }
Esempio n. 12
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SagaConfiguration"/> class.
        /// </summary>
        /// <param name="storage">The configure <see cref="IStoreSagaData">saga storage</see>.</param>
        /// <param name="metadata">The configured <see cref="SagaMetadataCollection">collection saga metadata</see>.</param>
        public SagaConfiguration(IStoreSagaData storage, SagaMetadataCollection metadata)
        {
            Arg.NotNull(storage, nameof(storage));
            Arg.NotNull(metadata, nameof(metadata));

            Storage  = storage;
            Metadata = metadata;
        }
Esempio n. 13
0
        internal SagaActivator(IMessageBusConfiguration configuration)
        {
            Contract.Requires(configuration != null);

            var sagas = configuration.Sagas;

            this.configuration = configuration;
            clock        = configuration.Clock;
            storage      = sagas.Storage;
            sagaMetadata = sagas.Metadata;
        }
 public void Initialize(SagaMetadataCollection metadataCollection)
 {
     foreach (var metadata in metadataCollection)
     {
         var sagaDataType = metadata.SagaEntityType;
         if (serializerCache.TryGetValue(sagaDataType, out var existing))
         {
             throw new Exception($"The saga data '{sagaDataType.FullName}' is being used by both '{existing.SagaType}' and '{metadata.SagaType.FullName}'. Saga data can only be used by one saga.");
         }
         serializerCache[metadata.SagaEntityType] = BuildSagaInfo(metadata.SagaEntityType, metadata.SagaType);
     }
 }
        public static SessionFactoryImpl Build(Type[] types)
        {
            var builder    = new NHibernateSagaStorage();
            var properties = SQLiteConfiguration.InMemory();

            var configuration = new Configuration().AddProperties(properties);
            var settings      = new SettingsHolder();

            var metaModel = new SagaMetadataCollection();

            metaModel.Initialize(types);
            settings.Set <SagaMetadataCollection>(metaModel);

            settings.Set("TypesToScan", types);
            builder.ApplyMappings(settings, configuration);
            return(configuration.BuildSessionFactory() as SessionFactoryImpl);
        }
 void Initialize(SagaMetadataCollection metadataCollection)
 {
     foreach (var metadata in metadataCollection)
     {
         var sagaDataType = metadata.SagaEntityType;
         if (cache.TryGetValue(sagaDataType, out var existing))
         {
             throw new Exception($"The saga data '{sagaDataType.FullName}' is being used by both '{existing.SagaType}' and '{metadata.SagaType.FullName}'. Saga data can only be used by one saga.");
         }
         var sagaInfo = BuildSagaInfo(sagaDataType, metadata);
         cache[sagaDataType] = sagaInfo;
         if (sagaInfo.CorrelationProperty != null && !metadata.TryGetCorrelationProperty(out var _))
         {
             throw new Exception($"The saga '{metadata.SagaType.FullName}' defines a correlation property '{sagaInfo.CorrelationProperty}' which is not mapped to any message. Either map it or remove it from the saga definition.");
         }
     }
 }
 public SagaInfoCache(
     RetrieveVersionSpecificJsonSettings versionSpecificSettings,
     JsonSerializer jsonSerializer,
     Func <TextReader, JsonReader> readerCreator,
     Func <TextWriter, JsonWriter> writerCreator,
     string tablePrefix,
     SqlDialect sqlDialect,
     SagaMetadataCollection metadataCollection,
     Func <string, string> nameFilter)
 {
     this.versionSpecificSettings = versionSpecificSettings;
     this.writerCreator           = writerCreator;
     this.readerCreator           = readerCreator;
     this.jsonSerializer          = jsonSerializer;
     this.tablePrefix             = tablePrefix;
     this.sqlDialect = sqlDialect;
     this.nameFilter = nameFilter;
     Initialize(metadataCollection);
 }
        public void build_should_create_expected_configuration()
        {
            // arrange
            var serviceProvider        = new Mock <IServiceProvider>().Object;
            var clock                  = new Mock <IClock>().Object;
            var persistenceMapper      = new Mock <IMapPersistence>().Object;
            var messageSender          = new Mock <IMessageSender>().Object;
            var messageReceiver        = new Mock <IMessageReceiver>().Object;
            var commandHandlerRegistry = new Mock <ICommandHandlerRegistrar>().Object;
            var eventReceiverRegistry  = new Mock <IEventReceiverRegistrar>().Object;
            var sagaStorage            = new Mock <IStoreSagaData>().Object;
            var sagaMetadata           = new SagaMetadataCollection(Empty <Type>());
            var uniqueIdGenerator      = new Mock <IUniqueIdGenerator>().Object;
            var builder                = new MessageBusConfigurationBuilder();

            builder.HasServiceProvider(serviceProvider)
            .UseClock(clock)
            .MapPersistenceWith(persistenceMapper)
            .HasMessageSender(messageSender)
            .HasMessageReceiver(messageReceiver)
            .HasCommandHandlerRegistrar(commandHandlerRegistry)
            .HasEventReceiverRegistrar(eventReceiverRegistry)
            .HasSagaStorage(sagaStorage)
            .HasSagaMetadata(sagaMetadata)
            .UseUniqueIdGenerator(uniqueIdGenerator);

            // act
            var configuration = builder.CreateConfiguration();

            // assert
            configuration.Should().BeEquivalentTo(
                new
            {
                Clock             = clock,
                Persistence       = persistenceMapper,
                MessageSender     = messageSender,
                MessageReceiver   = messageReceiver,
                CommandHandlers   = commandHandlerRegistry,
                EventReceivers    = eventReceiverRegistry,
                Sagas             = new SagaConfiguration(sagaStorage, sagaMetadata),
                UniqueIdGenerator = uniqueIdGenerator
            });
        }
Esempio n. 19
0
        public void SetUp()
        {
            var builder    = new NHibernateSagaStorage();
            var properties = SQLiteConfiguration.InMemory();

            var configuration = new Configuration().AddProperties(properties);
            var types         = new[] { typeof(SagaWithAbstractBaseClassActualSaga), typeof(SagaWithAbstractBaseClass), typeof(ContainSagaData), typeof(MyOwnAbstractBase) };

            var allMetadata = new SagaMetadataCollection();

            allMetadata.Initialize(types);

            var settings = new SettingsHolder();

            settings.Set("TypesToScan", types);
            settings.Set <SagaMetadataCollection>(allMetadata);

            builder.ApplyMappings(settings, configuration);
            sessionFactory = configuration.BuildSessionFactory() as SessionFactoryImpl;
        }
    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));
    }
        public SagaManifestCollection(SagaMetadataCollection sagas, string storageLocation)
        {
            foreach (var metadata in sagas)
            {
                var sagaStorageDir = Path.Combine(storageLocation, metadata.SagaType.FullName.Replace("+", ""));

                if (!Directory.Exists(sagaStorageDir))
                {
                    Directory.CreateDirectory(sagaStorageDir);
                }

                var manifest = new SagaManifest
                {
                    StorageDirectory = sagaStorageDir,
                    SagaEntityType   = metadata.SagaEntityType
                };

                sagaManifests[metadata.SagaEntityType] = manifest;
            }
        }
        public SagaManifestCollection(SagaMetadataCollection sagas, string storageLocation, Func <string, string> sagaNameConverter)
        {
            foreach (var metadata in sagas)
            {
                var sagaStorageDir = Path.Combine(storageLocation, sagaNameConverter(metadata.SagaType.FullName));

                if (!Directory.Exists(sagaStorageDir))
                {
                    Directory.CreateDirectory(sagaStorageDir);
                }

                var manifest = new SagaManifest
                {
                    StorageDirectory = sagaStorageDir,
                    SagaEntityType   = metadata.SagaEntityType
                };

                sagaManifests[metadata.SagaEntityType] = manifest;
            }
        }
Esempio n. 23
0
        public static SessionFactoryImpl Build(Type[] types)
        {
            var builder = new NHibernateSagaStorage();

            var cfg = new Configuration()
                      .DataBaseIntegration(x =>
            {
                x.Dialect <MsSql2012Dialect>();
                x.ConnectionString = Consts.SqlConnectionString;
            });

            var settings = new SettingsHolder();

            var metaModel = new SagaMetadataCollection();

            metaModel.Initialize(types);
            settings.Set <SagaMetadataCollection>(metaModel);

            settings.Set("TypesToScan", types);
            builder.ApplyMappings(settings, cfg);
            return(cfg.BuildSessionFactory() as SessionFactoryImpl);
        }
Esempio n. 24
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 SagaPersistenceBehavior(ISagaPersister persister, ISagaIdGenerator sagaIdGenerator, ICancelDeferredMessages timeoutCancellation, SagaMetadataCollection sagaMetadataCollection)
 {
     this.sagaIdGenerator        = sagaIdGenerator;
     sagaPersister               = persister;
     this.timeoutCancellation    = timeoutCancellation;
     this.sagaMetadataCollection = sagaMetadataCollection;
 }
        internal static void InitializeSagaDataTypes(IMongoClient client, string databaseName, Func <Type, string> collectionNamingConvention, SagaMetadataCollection sagaMetadataCollection)
        {
            var databaseSettings = new MongoDatabaseSettings
            {
                ReadConcern    = ReadConcern.Majority,
                ReadPreference = ReadPreference.Primary,
                WriteConcern   = WriteConcern.WMajority
            };
            var database = client.GetDatabase(databaseName, databaseSettings);

            foreach (var sagaMetadata in sagaMetadataCollection)
            {
                if (!BsonClassMap.IsClassMapRegistered(sagaMetadata.SagaEntityType))
                {
                    var classMap = new BsonClassMap(sagaMetadata.SagaEntityType);
                    classMap.AutoMap();
                    classMap.SetIgnoreExtraElements(true);

                    BsonClassMap.RegisterClassMap(classMap);
                }

                var collectionName = collectionNamingConvention(sagaMetadata.SagaEntityType);

                if (sagaMetadata.TryGetCorrelationProperty(out var property) && property.Name != "Id")
                {
                    var propertyElementName = sagaMetadata.SagaEntityType.GetElementName(property.Name);

                    var indexModel = new CreateIndexModel <BsonDocument>(new BsonDocumentIndexKeysDefinition <BsonDocument>(new BsonDocument(propertyElementName, 1)), new CreateIndexOptions
                    {
                        Unique = true
                    });
                    database.GetCollection <BsonDocument>(collectionName).Indexes.CreateOne(indexModel);
                }
Esempio n. 28
0
 public SagaModelMapper(SagaMetadataCollection allMetadata, IEnumerable <Type> typesToScan)
     : this(allMetadata, typesToScan, DefaultTableNameConvention)
 {
 }
Esempio n. 29
0
 public SagaPersistenceBehavior(ISagaPersister persister, ISagaIdGenerator sagaIdGenerator, SagaMetadataCollection sagaMetadataCollection)
 {
     this.sagaIdGenerator        = sagaIdGenerator;
     sagaPersister               = persister;
     this.sagaMetadataCollection = sagaMetadataCollection;
 }