public RebuildProjectionEngine( EventUnwinder eventUnwinder, IConcurrentCheckpointTracker checkpointTracker, IProjection[] projections, IRebuildContext rebuildContext, ProjectionEngineConfig config, ProjectionEventInspector projectionInspector, ILoggerThreadContextManager loggerThreadContextManager) { _eventUnwinder = eventUnwinder; _checkpointTracker = checkpointTracker; _rebuildContext = rebuildContext; _config = config; _projectionInspector = projectionInspector; if (_config.Slots[0] != "*") { projections = projections .Where(x => _config.Slots.Any(y => y == x.Info.SlotName)) .ToArray(); } _allProjections = projections; _projectionsBySlot = projections .GroupBy(x => x.Info.SlotName) .ToDictionary(x => x.Key, x => x.OrderByDescending(p => p.Priority).ToArray()); _metrics = new ProjectionMetrics(_allProjections); _loggerThreadContextManager = loggerThreadContextManager; HealthChecks.RegisterHealthCheck("RebuildProjectionEngine", (Func <HealthCheckResult>)HealthCheck); }
public virtual void TestFixtureSetUp() { _logger = NSubstitute.Substitute.For <ILog>(); _eventStoreConnectionString = ConfigurationManager.ConnectionStrings["eventstore"].ConnectionString;; var url = new MongoUrl(_eventStoreConnectionString); var client = new MongoClient(url); _db = client.GetDatabase(url.DatabaseName); _db.Drop(); _identityConverter = new IdentityManager(new CounterService(_db)); _identityConverter.RegisterIdentitiesFromAssembly(typeof(SampleAggregateId).Assembly); ProjectionEngineConfig config = new ProjectionEngineConfig() { EventStoreConnectionString = _eventStoreConnectionString }; CommitEnhancer commitEnhancer = new CommitEnhancer(_identityConverter); sut = new EventUnwinder(config, NullLogger.Instance); _unwindedEventCollection = _db.GetCollection <UnwindedDomainEvent>("UnwindedEvents"); MongoFlatMapper.EnableFlatMapping(true); MongoFlatIdSerializerHelper.Initialize(_identityConverter); }
public EventUnwinder( ProjectionEngineConfig config, IPersistence persistence, ILogger logger) { _config = config; _persistence = persistence; _logger = logger; var url = new MongoUrl(_config.EventStoreConnectionString); var client = url.CreateClient(false); var _mongoDatabase = client.GetDatabase(url.DatabaseName); _unwindedEventCollection = _mongoDatabase.GetCollection <UnwindedDomainEvent>("UnwindedEvents"); _unwindedEventCollection.Indexes.CreateOne( Builders <UnwindedDomainEvent> .IndexKeys .Ascending(ude => ude.CheckpointToken) .Ascending(ude => ude.EventSequence) .Ascending(ude => ude.EventType), new CreateIndexOptions() { Name = "ScanPrimary" } ); }
protected void ConfigureProjectionEngine() { if (Engine != null) { Engine.Stop(); } _tracker = new ConcurrentCheckpointTracker(Database); _statusChecker = new ConcurrentCheckpointStatusChecker(Database); var tenantId = new TenantId("engine"); var config = new ProjectionEngineConfig() { Slots = new[] { "*" }, EventStoreConnectionString = _eventStoreConnectionString, TenantId = tenantId }; _rebuildContext = new RebuildContext(false); StorageFactory = new MongoStorageFactory(Database, _rebuildContext); Engine = new ConcurrentProjectionsEngine( _tracker, BuildProjections().ToArray(), new PollingClientWrapper(new CommitEnhancer(_identityConverter), true, _tracker), new NullHouseKeeper(), _rebuildContext, new NullNotifyCommitHandled(), config ); Engine.LoggerFactory = Substitute.For <ILoggerFactory>(); Engine.LoggerFactory.Create(Arg.Any <Type>()).Returns(NullLogger.Instance); Engine.StartWithManualPoll(); }
public RebuildProjectionEngine( EventUnwinder eventUnwinder, IConcurrentCheckpointTracker checkpointTracker, IProjection[] projections, IRebuildContext rebuildContext, ProjectionEngineConfig config, ProjectionEventInspector projectionInspector) { _eventUnwinder = eventUnwinder; _checkpointTracker = checkpointTracker; _rebuildContext = rebuildContext; _config = config; _projectionInspector = projectionInspector; if (_config.Slots[0] != "*") { projections = projections .Where(x => _config.Slots.Any(y => y == x.GetSlotName())) .ToArray(); } _allProjections = projections; _projectionsBySlot = projections .GroupBy(x => x.GetSlotName()) .ToDictionary(x => x.Key, x => x.OrderByDescending(p => p.Priority).ToArray()); _metrics = new ProjectionMetrics(_allProjections); }
public EventUnwinder( ProjectionEngineConfig config, ILogger logger) { _config = config; _logger = logger; _eventStore = Wireup .Init() .LogTo(t => new NEventStoreLog4NetLogger(_logger)) .UsingMongoPersistence(() => _config.EventStoreConnectionString, new DocumentObjectSerializer()) .InitializeStorageEngine() .Build(); var url = new MongoUrl(_config.EventStoreConnectionString); var client = new MongoClient(url); _mongoDatabase = client.GetDatabase(url.DatabaseName); _persistStream = _eventStore.Advanced; _unwindedEventCollection = _mongoDatabase.GetCollection <UnwindedDomainEvent>("UnwindedEvents"); _unwindedEventCollection.Indexes.CreateOne( Builders <UnwindedDomainEvent> .IndexKeys .Ascending(ude => ude.CheckpointToken) .Ascending(ude => ude.EventSequence) .Ascending(ude => ude.EventType), new CreateIndexOptions() { Name = "ScanPrimary" } ); }
protected void ConfigureProjectionEngine(Boolean dropCheckpoints = true) { if (Engine != null) { Engine.Stop(); } if (dropCheckpoints) { _checkpoints.Drop(); } _tracker = new ConcurrentCheckpointTracker(Database); _statusChecker = new ConcurrentCheckpointStatusChecker(Database); var tenantId = new TenantId("engine"); var config = new ProjectionEngineConfig() { Slots = new[] { "*" }, EventStoreConnectionString = _eventStoreConnectionString, TenantId = tenantId, BucketInfo = new List <BucketInfo>() { new BucketInfo() { Slots = new[] { "*" }, BufferSize = 10 } }, DelayedStartInMilliseconds = 1000, ForcedGcSecondsInterval = 0, EngineVersion = "v2", }; RebuildSettings.Init(OnShouldRebuild(), OnShouldUseNitro()); _rebuildContext = new RebuildContext(RebuildSettings.NitroMode); StorageFactory = new MongoStorageFactory(Database, _rebuildContext); Func <IPersistStreams, CommitPollingClient> pollingClientFactory = ps => new CommitPollingClient( ps, new CommitEnhancer(_identityConverter), OnGetPollingClientId(), NullLogger.Instance); Engine = new ProjectionEngine( pollingClientFactory, _tracker, BuildProjections().ToArray(), new NullHouseKeeper(), _rebuildContext, new NullNotifyCommitHandled(), config ); Engine.LoggerFactory = Substitute.For <ILoggerFactory>(); Engine.LoggerFactory.Create(Arg.Any <Type>()).Returns(NullLogger.Instance); OnStartPolling(); }
public virtual void TestFixtureSetUp() { _eventStoreConnectionString = ConfigurationManager.ConnectionStrings["eventstore"].ConnectionString; var url = new MongoUrl(_eventStoreConnectionString); var client = new MongoClient(url); _db = client.GetDatabase(url.DatabaseName); _db.Drop(); ProjectionEngineConfig config = new ProjectionEngineConfig(); config.EventStoreConnectionString = _eventStoreConnectionString; config.Slots = new string[] { "*" }; config.TenantId = new TenantId("A"); config.BucketInfo = new List <BucketInfo>(); config.BucketInfo.Add(new BucketInfo() { Slots = new[] { "*" }, BufferSize = 10000 }); _identityConverter = new IdentityManager(new CounterService(_db)); _identityConverter.RegisterIdentitiesFromAssembly(typeof(SampleAggregateId).Assembly); ConfigureEventStore(); CommitEnhancer commitEnhancer = new CommitEnhancer(_identityConverter); _eventUnwinder = new EventUnwinder(config, new TestLogger(LoggerLevel.Info)); _unwindedEventCollection = _db.GetCollection <UnwindedDomainEvent>("UnwindedEvents"); MongoFlatMapper.EnableFlatMapping(true); MongoFlatIdSerializerHelper.Initialize(_identityConverter); var rebuildContext = new RebuildContext(NitroEnabled); _storageFactory = new MongoStorageFactory(_db, rebuildContext); _reader1 = new MongoReader <SampleReadModel, string>(_db); _reader2 = new MongoReader <SampleReadModel2, string>(_db); _reader3 = new MongoReader <SampleReadModel3, string>(_db); //now configure RebuildProjectionEngine _tracker = new ConcurrentCheckpointTracker(_db); var projections = BuildProjections().ToArray(); _tracker.SetUp(projections, 1, false); ProjectionEventInspector inspector = new ProjectionEventInspector(); inspector.AddAssembly(Assembly.GetExecutingAssembly()); sut = new RebuildProjectionEngine(_eventUnwinder, _tracker, projections, rebuildContext, config, inspector); sut.Logger = new TestLogger(LoggerLevel.Debug); _checkpointCollection = _db.GetCollection <Checkpoint>("checkpoints"); }
public void InitSut() { var config = new ProjectionEngineConfig(); projections = new [] { new Projection(Substitute.For <ICollectionWrapper <SampleReadModel, String> >()) }; sut = new RebuildProjectionSlotDispatcher( NullLogger.Instance, "test", config, projections, Substitute.For <IConcurrentCheckpointTracker>(), 4); }
protected async Task ConfigureProjectionEngineAsync(Boolean dropCheckpoints = true) { Engine?.Stop(); if (dropCheckpoints) { _checkpoints.Drop(); } _tracker = new ConcurrentCheckpointTracker(Database); _statusChecker = new MongoDirectConcurrentCheckpointStatusChecker(Database); var tenantId = new TenantId("engine"); var config = new ProjectionEngineConfig() { Slots = new[] { "*" }, EventStoreConnectionString = _eventStoreConnectionString, TenantId = tenantId, BucketInfo = new List <BucketInfo>() { new BucketInfo() { Slots = new[] { "*" }, BufferSize = 10 } }, DelayedStartInMilliseconds = 0, ForcedGcSecondsInterval = 0, EngineVersion = "v2", }; RebuildSettings.Init(OnShouldRebuild(), OnShouldUseNitro()); var rebuildContext = new RebuildContext(RebuildSettings.NitroMode); StorageFactory = new MongoStorageFactory(Database, rebuildContext); Engine = new ProjectionEngine( _pollingClientFactory, Persistence, _tracker, BuildProjections().ToArray(), new NullHouseKeeper(), new NullNotifyCommitHandled(), config, NullLogger.Instance, NullLoggerThreadContextManager.Instance); Engine.LoggerFactory = Substitute.For <ILoggerFactory>(); Engine.LoggerFactory.Create(Arg.Any <Type>()).Returns(NullLogger.Instance); await OnStartPolling().ConfigureAwait(false); }
public void InitSut() { var config = new ProjectionEngineConfig(); projections = new [] { new Projection(Substitute.For <ICollectionWrapper <SampleReadModel, String> >()) }; sut = new RebuildProjectionSlotDispatcher( NullLogger.Instance, slotName, config, projections, 4, NullLoggerThreadContextManager.Instance); //Needed to avoid crash on wrong metrics dispatch. KernelMetricsHelper.CreateMeterForRebuildDispatcherBuffer(slotName, () => 0); }
/// <summary> /// TODO: We should pass a dictionary where we have the last dispatched /// checkpoint for EACH projection. /// </summary> /// <param name="logger"></param> /// <param name="slotName"></param> /// <param name="config"></param> /// <param name="projections"></param> /// <param name="lastCheckpointDispatched"></param> /// <param name="loggerThreadContextManager"></param> public RebuildProjectionSlotDispatcher( ILogger logger, String slotName, ProjectionEngineConfig config, IEnumerable <IProjection> projections, Int64 lastCheckpointDispatched, ILoggerThreadContextManager loggerThreadContextManager) { SlotName = slotName; _logger = logger; _config = config; _projections = projections; _metrics = new ProjectionMetrics(projections); _maxCheckpointDispatched = lastCheckpointDispatched; _lastCheckpointRebuilded = 0; _loggerThreadContextManager = loggerThreadContextManager; }
public void SetUp() { _db.Drop(); ConfigureEventStore(); //Creates the _persistence Repository = new Repository( new AggregateFactoryEx(null), new StreamsFactory(_persistence), Substitute.For <ISnapshotStore>() ); var config = new ProjectionEngineConfig() { EventStoreConnectionString = _eventStoreConnectionString }; sut = new EventUnwinder(config, _persistence, NullLogger.Instance); }
public RebuildProjectionSlotDispatcher( IExtendedLogger logger, String slotName, ProjectionEngineConfig config, IEnumerable <IProjection> projections, IConcurrentCheckpointTracker checkpointTracker, Int64 lastCheckpointDispatched) { SlotName = slotName; _logger = logger; _config = config; _projections = projections; _metrics = new ProjectionMetrics(projections); _checkpointTracker = checkpointTracker; _maxCheckpointDispatched = lastCheckpointDispatched; _lastCheckpointRebuilded = 0; }
public void Install(IWindsorContainer container, IConfigurationStore store) { // add rm prefix to collections CollectionNames.Customize = n => "rm." + n; var config = new ProjectionEngineConfig { EventStoreConnectionString = _tenant.GetConnectionString("events"), Slots = _config.EngineSlots, PollingMsInterval = _config.PollingMsInterval, ForcedGcSecondsInterval = _config.ForcedGcSecondsInterval, TenantId = _tenant.Id, DelayedStartInMilliseconds = _config.DelayedStartInMilliseconds, EngineVersion = _config.EngineVersion, BucketInfo = _config.BucketInfo, }; var readModelDb = _tenant.Get <IMongoDatabase>("readmodel.db"); container.Register( Component .For <IDocumentWriter>() .ImplementedBy <DocumentWriter>() .DependsOn(Dependency.OnValue <IMongoDatabase>(readModelDb)), Component .For(typeof(IReader <,>), typeof(IMongoDbReader <,>)) .ImplementedBy(typeof(MongoReaderForProjections <,>)) .DependsOn(Dependency.OnValue <IMongoDatabase>(readModelDb)) ); container.Register( Component .For <IHousekeeper>() .ImplementedBy <NullHouseKeeper>(), Component .For <INotifyToSubscribers>() .ImplementedBy <TNotifier>(), Component .For <ICommitEnhancer>() .ImplementedBy <CommitEnhancer>(), Component .For <INotifyCommitHandled>() .ImplementedBy <NullNotifyCommitHandled>(), Classes .FromAssemblyContaining <DocumentProjection>() .BasedOn <IProjection>() .Configure(r => r .DependsOn(Dependency.OnValue <TenantId>(_tenant.Id)) ) .WithServiceAllInterfaces() .LifestyleSingleton(), Component .For <IInitializeReadModelDb>() .ImplementedBy <InitializeReadModelDb>(), Component .For <IConcurrentCheckpointTracker>() .ImplementedBy <ConcurrentCheckpointTracker>() .DependsOn(Dependency.OnValue <IMongoDatabase>(readModelDb)), Component .For(new[] { typeof(ICollectionWrapper <,>), typeof(IReadOnlyCollectionWrapper <,>) }) .ImplementedBy(typeof(CollectionWrapper <,>)) .DependsOn(Dependency.OnValue <IMongoDatabase>(readModelDb)), Component .For <IRebuildContext>() .ImplementedBy <RebuildContext>() .DependsOn(Dependency.OnValue <bool>(RebuildSettings.NitroMode)), Component .For <IMongoStorageFactory>() .ImplementedBy <MongoStorageFactory>() .DependsOn(Dependency.OnValue <IMongoDatabase>(readModelDb)), Component .For <DocumentDescriptorByHashReader>(), Component .For <DeduplicationHelper>(), Component .For <IRecycleBin>() .ImplementedBy <RecycleBin>() .DependsOn(Dependency.OnValue <IMongoDatabase>(readModelDb)) ); if (!_config.IsReadmodelBuilder) { return; } //This registration made the entire ConcurrentProjectionEngine starts //so it is better to register after all the other components are registered //correctly. if (config.EngineVersion == "v1") { throw new NotSupportedException("V1 projection engine not supported anymore"); } else if (config.EngineVersion == "v2") { throw new NotSupportedException("V2 projection engine not supported anymore because of NES6 dropping standard commit polling client"); } else if (config.EngineVersion == "v3") { container.Register( Component.For <ProjectionEngineConfig>() .Instance(config), Component .For <ICommitPollingClient>() .ImplementedBy <CommitPollingClient2>() .DependsOn(Dependency.OnValue("id", "Main-Poller")) .LifeStyle.Transient, Component .For <ICommitPollingClientFactory>() .AsFactory(), Component .For <IRepositoryExFactory>() .AsFactory(), Component .For <Func <IPersistStreams, ICommitPollingClient> >() .Instance(ps => container.Resolve <ICommitPollingClient>( Arguments.FromProperties(new { persistStreams = ps }))), Component .For <ProjectionEngine, ITriggerProjectionsUpdate>() .ImplementedBy <ProjectionEngine>() .LifestyleSingleton() .StartUsingMethod(x => x.Start) .StopUsingMethod(x => x.Stop) ); } }