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)); }
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(); }
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>(); }
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(); }
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); }
/// <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; }
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 }); }
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; } }
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); }
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); }
public SagaModelMapper(SagaMetadataCollection allMetadata, IEnumerable <Type> typesToScan) : this(allMetadata, typesToScan, DefaultTableNameConvention) { }
public SagaPersistenceBehavior(ISagaPersister persister, ISagaIdGenerator sagaIdGenerator, SagaMetadataCollection sagaMetadataCollection) { this.sagaIdGenerator = sagaIdGenerator; sagaPersister = persister; this.sagaMetadataCollection = sagaMetadataCollection; }