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();
        }
Example #5
0
        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);
        }
Example #6
0
        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"
            }
                );
        }
Example #7
0
        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");
        }
Example #9
0
        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;
 }
Example #13
0
        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)
                    );
            }
        }