public void CanRunWorkItemWithClassHandler()
        {
            ServiceProvider.SetServiceProvider(typeof(MyBootstrappedServiceProvider));
            var queue           = new InMemoryQueue <WorkItemData>();
            var messageBus      = new InMemoryMessageBus();
            var handlerRegistry = new WorkItemHandlers();
            var job             = new WorkItemJob(queue, messageBus, handlerRegistry);

            handlerRegistry.Register <MyWorkItem, MyWorkItemHandler>();

            var jobId = queue.Enqueue(new MyWorkItem {
                SomeData = "Test"
            }, true);

            int statusCount = 0;

            messageBus.Subscribe <WorkItemStatus>(status => {
                Assert.Equal(jobId, status.WorkItemId);
                statusCount++;
            });

            job.RunUntilEmpty();

            Assert.Equal(12, statusCount);
        }
        public async Task CanRunWorkItem() {
            using (var queue = new InMemoryQueue<WorkItemData>()) {
                using (var messageBus = new InMemoryMessageBus()) {
                    var handlerRegistry = new WorkItemHandlers();
                    var job = new WorkItemJob(queue, messageBus, handlerRegistry, Log);

                    handlerRegistry.Register<MyWorkItem>(async ctx => {
                        var jobData = ctx.GetData<MyWorkItem>();
                        Assert.Equal("Test", jobData.SomeData);

                        for (int i = 0; i < 10; i++) {
                            await SystemClock.SleepAsync(100);
                            await ctx.ReportProgressAsync(10 * i);
                        }
                    });

                    var jobId = await queue.EnqueueAsync(new MyWorkItem {
                        SomeData = "Test"
                    }, true);

                    int statusCount = 0;
                    messageBus.Subscribe<WorkItemStatus>(status => {
                        _logger.Trace("Progress: {progress}", status.Progress);
                        Assert.Equal(jobId, status.WorkItemId);
                        statusCount++;
                    });

                    await job.RunUntilEmptyAsync();
                    Assert.Equal(12, statusCount);
                }
            }
        }
Beispiel #3
0
        public async Task CanRunBadWorkItem()
        {
            using (var queue = new InMemoryQueue <WorkItemData>(o => o.RetryDelay(TimeSpan.FromMilliseconds(500)).LoggerFactory(Log))) {
                using (var messageBus = new InMemoryMessageBus(o => o.LoggerFactory(Log))) {
                    var handlerRegistry = new WorkItemHandlers();
                    var job             = new WorkItemJob(queue, messageBus, handlerRegistry, Log);

                    handlerRegistry.Register <MyWorkItem>(ctx => {
                        var jobData = ctx.GetData <MyWorkItem>();
                        Assert.Equal("Test", jobData.SomeData);
                        throw new Exception();
                    });

                    string jobId = await queue.EnqueueAsync(new MyWorkItem {
                        SomeData = "Test"
                    }, true);

                    var countdown = new AsyncCountdownEvent(1);
                    await messageBus.SubscribeAsync <WorkItemStatus>(status => {
                        if (_logger.IsEnabled(LogLevel.Trace))
                        {
                            _logger.LogTrace("Progress: {Progress}", status.Progress);
                        }
                        Assert.Equal(jobId, status.WorkItemId);
                        countdown.Signal();
                    });

                    await job.RunUntilEmptyAsync();

                    await countdown.WaitAsync(TimeSpan.FromSeconds(2));

                    Assert.Equal(0, countdown.CurrentCount);
                }
            }
        }
Beispiel #4
0
        public async Task CanRunWorkItem()
        {
            using (var queue = new InMemoryQueue <WorkItemData>()) {
                using (var messageBus = new InMemoryMessageBus()) {
                    var handlerRegistry = new WorkItemHandlers();
                    var job             = new WorkItemJob(queue, messageBus, handlerRegistry, Log);

                    handlerRegistry.Register <MyWorkItem>(async ctx => {
                        var jobData = ctx.GetData <MyWorkItem>();
                        Assert.Equal("Test", jobData.SomeData);

                        for (int i = 0; i < 10; i++)
                        {
                            await SystemClock.SleepAsync(100);
                            await ctx.ReportProgressAsync(10 * i);
                        }
                    });

                    var jobId = await queue.EnqueueAsync(new MyWorkItem {
                        SomeData = "Test"
                    }, true);

                    int statusCount = 0;
                    messageBus.Subscribe <WorkItemStatus>(status => {
                        _logger.Trace("Progress: {progress}", status.Progress);
                        Assert.Equal(jobId, status.WorkItemId);
                        statusCount++;
                    });

                    await job.RunUntilEmptyAsync();

                    Assert.Equal(12, statusCount);
                }
            }
        }
        public static void RegisterServices(Container container, ILoggerFactory loggerFactory) {
            container.RegisterSingleton<ILoggerFactory>(loggerFactory);
            container.RegisterSingleton(typeof(ILogger<>), typeof(Logger<>));

            ServiceProvider.Current = container;
            container.RegisterSingleton<ISerializer>(() => new JsonNetSerializer());

            var metricsClient = new InMemoryMetricsClient();
            container.RegisterSingleton<IMetricsClient>(metricsClient);
            container.RegisterSingleton<ICacheClient, InMemoryCacheClient>();

            container.RegisterCollection(typeof(IQueueBehavior<ValuesPost>), new[] {
                Lifestyle.Singleton.CreateRegistration(
                    () => new MetricsQueueBehavior<ValuesPost>(metricsClient), container)
            });
            container.RegisterSingleton<IQueue<ValuesPost>>(() => new InMemoryQueue<ValuesPost>(behaviors: container.GetAllInstances<IQueueBehavior<ValuesPost>>()));
            
            container.RegisterCollection(typeof(IQueueBehavior<WorkItemData>), new[] {
                Lifestyle.Singleton.CreateRegistration(
                    () => new MetricsQueueBehavior<WorkItemData>(metricsClient), container)
            });

            var handlers = new WorkItemHandlers();
            handlers.Register<DeleteValueWorkItem, DeleteValueWorkItemHandler>();
            container.RegisterSingleton(handlers);

            container.RegisterSingleton<IQueue<WorkItemData>>(() => new InMemoryQueue<WorkItemData>(behaviors: container.GetAllInstances<IQueueBehavior<WorkItemData>>(), workItemTimeout: TimeSpan.FromHours(1)));
            
            container.RegisterSingleton<IMessageBus, InMemoryMessageBus>();
            container.RegisterSingleton<IMessagePublisher>(container.GetInstance<IMessageBus>);
            container.RegisterSingleton<IMessageSubscriber>(container.GetInstance<IMessageBus>);

            container.RegisterSingleton<ILockProvider, CacheLockProvider>();
            container.RegisterSingleton<IFileStorage>(new InMemoryFileStorage());
        }
Beispiel #6
0
        public async Task CanHandleMultipleWorkItemInstances()
        {
            var metrics = new InMemoryMetricsClient();
            var queue = new InMemoryQueue<WorkItemData>(retryDelay: TimeSpan.Zero, retries: 0);
            queue.AttachBehavior(new MetricsQueueBehavior<WorkItemData>(metrics));
            var messageBus = new InMemoryMessageBus();
            var handlerRegistry = new WorkItemHandlers();
            var j1 = new WorkItemJob(queue, messageBus, handlerRegistry);
            var j2 = new WorkItemJob(queue, messageBus, handlerRegistry);
            var j3 = new WorkItemJob(queue, messageBus, handlerRegistry);
            int errors = 0;
            var jobIds = new ConcurrentDictionary<string, int>();

            handlerRegistry.Register<MyWorkItem>(ctx => {
                var jobData = ctx.GetData<MyWorkItem>();
                Assert.Equal("Test", jobData.SomeData);

                jobIds.AddOrUpdate(ctx.JobId, 1, (key, value) => value + 1);
                
                for (int i = 0; i < 10; i++)
                    ctx.ReportProgress(10 * i);

                if (RandomData.GetBool(1))
                {
                    Interlocked.Increment(ref errors);
                    throw new ApplicationException("Boom!");
                }
                
                return TaskHelper.Completed();
            });

            for (int i = 0; i < 100; i++)
                queue.Enqueue(new MyWorkItem { SomeData = "Test", Index = i }, true);
            
            var completedItems = new List<string>();
            object completedItemsLock = new object();
            messageBus.Subscribe<WorkItemStatus>(status =>
            {
                if (status.Progress < 100)
                    return;

                lock (completedItemsLock)
                    completedItems.Add(status.WorkItemId);
            });
            
            var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(10));
            var token = cancellationTokenSource.Token;
            var tasks = new List<Task>();
            tasks.AddRange(new[] {
                Task.Run(async () => await j1.RunUntilEmptyAsync(token), token),
                Task.Run(async () => await j2.RunUntilEmptyAsync(token), token),
                Task.Run(async () => await j3.RunUntilEmptyAsync(token), token),
            });

            await Task.WhenAll(tasks);
            Thread.Sleep(10);
            Assert.Equal(100, completedItems.Count + errors);
            Assert.Equal(3, jobIds.Count);
            Assert.Equal(100, jobIds.Sum(kvp => kvp.Value));
        }
Beispiel #7
0
        public async Task CanRunWorkItemWithClassHandler()
        {
            using (var queue = new InMemoryQueue <WorkItemData>(new InMemoryQueueOptions <WorkItemData> {
                LoggerFactory = Log
            })) {
                using (var messageBus = new InMemoryMessageBus(new InMemoryMessageBusOptions {
                    LoggerFactory = Log
                })) {
                    var handlerRegistry = new WorkItemHandlers();
                    var job             = new WorkItemJob(queue, messageBus, handlerRegistry, Log);

                    handlerRegistry.Register <MyWorkItem>(new MyWorkItemHandler(Log));

                    string jobId = await queue.EnqueueAsync(new MyWorkItem {
                        SomeData = "Test"
                    }, true);

                    int statusCount = 0;
                    await messageBus.SubscribeAsync <WorkItemStatus>(status => {
                        _logger.Trace("Progress: {progress}", status.Progress);
                        Assert.Equal(jobId, status.WorkItemId);
                        statusCount++;
                    });

                    await job.RunUntilEmptyAsync();

                    Assert.Equal(11, statusCount);
                }
            }
        }
Beispiel #8
0
        public void CanRunWorkItem() {
            var queue = new InMemoryQueue<WorkItemData>();
            var messageBus = new InMemoryMessageBus();
            var handlerRegistry = new WorkItemHandlers();
            var job = new WorkItemJob(queue, messageBus, handlerRegistry);

            handlerRegistry.Register<MyWorkItem>(async ctx => {
                var jobData = ctx.GetData<MyWorkItem>();
                Assert.Equal("Test", jobData.SomeData);

                for (int i = 0; i < 10; i++) {
                    await Task.Delay(100);
                    ctx.ReportProgress(10 * i);
                }
            });

            var jobId = queue.Enqueue(new MyWorkItem { SomeData = "Test" }, true);

            int statusCount = 0;
            messageBus.Subscribe<WorkItemStatus>(status => {
                Assert.Equal(jobId, status.WorkItemId);
                statusCount++;
            });

            job.RunUntilEmpty();

            Assert.Equal(12, statusCount);
        }
Beispiel #9
0
        public async Task CanRunWorkItemJobUntilEmpty()
        {
            using (var queue = new InMemoryQueue <WorkItemData>(new InMemoryQueueOptions <WorkItemData> {
                LoggerFactory = Log
            })) {
                using (var messageBus = new InMemoryMessageBus(new InMemoryMessageBusOptions {
                    LoggerFactory = Log
                })) {
                    var handlerRegistry = new WorkItemHandlers();
                    var job             = new WorkItemJob(queue, messageBus, handlerRegistry, Log);

                    handlerRegistry.Register <MyWorkItem>(new MyWorkItemHandler(Log));

                    await queue.EnqueueAsync(new MyWorkItem {
                        SomeData = "Test"
                    }, true);

                    await queue.EnqueueAsync(new MyWorkItem {
                        SomeData = "Test"
                    }, true);

                    await job.RunUntilEmptyAsync();

                    var stats = await queue.GetQueueStatsAsync();

                    Assert.Equal(2, stats.Enqueued);
                    Assert.Equal(2, stats.Dequeued);
                    Assert.Equal(2, stats.Completed);
                }
            }
        }
Beispiel #10
0
        public async Task CanRunBadWorkItem()
        {
            using (var queue = new InMemoryQueue <WorkItemData>(new InMemoryQueueOptions <WorkItemData> {
                RetryDelay = TimeSpan.FromMilliseconds(500), LoggerFactory = Log
            })) {
                using (var messageBus = new InMemoryMessageBus(new InMemoryMessageBusOptions {
                    LoggerFactory = Log
                })) {
                    var handlerRegistry = new WorkItemHandlers();
                    var job             = new WorkItemJob(queue, messageBus, handlerRegistry, Log);

                    handlerRegistry.Register <MyWorkItem>(ctx => {
                        var jobData = ctx.GetData <MyWorkItem>();
                        Assert.Equal("Test", jobData.SomeData);
                        throw new Exception();
                    });

                    string jobId = await queue.EnqueueAsync(new MyWorkItem {
                        SomeData = "Test"
                    }, true);

                    int statusCount = 0;
                    await messageBus.SubscribeAsync <WorkItemStatus>(status => {
                        _logger.Trace("Progress: {progress}", status.Progress);
                        Assert.Equal(jobId, status.WorkItemId);
                        statusCount++;
                    });

                    await job.RunUntilEmptyAsync();

                    Assert.Equal(1, statusCount);
                }
            }
        }
Beispiel #11
0
        public async Task CanRunWorkItemWithClassHandler()
        {
            ServiceProvider.SetServiceProvider(typeof(MyBootstrappedServiceProvider));
            var queue           = new InMemoryQueue <WorkItemData>();
            var messageBus      = new InMemoryMessageBus();
            var handlerRegistry = new WorkItemHandlers();
            var job             = new WorkItemJob(queue, messageBus, handlerRegistry, Log);

            handlerRegistry.Register <MyWorkItem, MyWorkItemHandler>();

            var jobId = await queue.EnqueueAsync(new MyWorkItem {
                SomeData = "Test"
            }, true);

            int statusCount = 0;

            messageBus.Subscribe <WorkItemStatus>(status => {
                _logger.Trace("Progress: {progress}", status.Progress);
                Assert.Equal(jobId, status.WorkItemId);
                statusCount++;
            });

            await job.RunUntilEmptyAsync();

            Assert.Equal(11, statusCount);
        }
        public void CanRunWorkItem()
        {
            var queue           = new InMemoryQueue <WorkItemData>();
            var messageBus      = new InMemoryMessageBus();
            var handlerRegistry = new WorkItemHandlers();
            var job             = new WorkItemJob(queue, messageBus, handlerRegistry);

            handlerRegistry.Register <MyWorkItem>(async ctx => {
                var jobData = ctx.GetData <MyWorkItem>();
                Assert.Equal("Test", jobData.SomeData);

                for (int i = 0; i < 10; i++)
                {
                    Thread.Sleep(100);
                    ctx.ReportProgress(10 * i);
                }
            });

            var jobId = queue.Enqueue(new MyWorkItem {
                SomeData = "Test"
            }, true);

            int statusCount = 0;

            messageBus.Subscribe <WorkItemStatus>(status => {
                Assert.Equal(jobId, status.WorkItemId);
                statusCount++;
            });

            job.RunUntilEmpty();

            Assert.Equal(12, statusCount);
        }
Beispiel #13
0
        public async Task CanRunBadWorkItem()
        {
            var queue           = new InMemoryQueue <WorkItemData>(retries: 2, retryDelay: TimeSpan.FromMilliseconds(500));
            var messageBus      = new InMemoryMessageBus();
            var handlerRegistry = new WorkItemHandlers();
            var job             = new WorkItemJob(queue, messageBus, handlerRegistry);

            handlerRegistry.Register <MyWorkItem>(ctx => {
                var jobData = ctx.GetData <MyWorkItem>();
                Assert.Equal("Test", jobData.SomeData);
                throw new ApplicationException();
            });

            var jobId = await queue.EnqueueAsync(new MyWorkItem {
                SomeData = "Test"
            }, true);

            int statusCount = 0;

            messageBus.Subscribe <WorkItemStatus>(status => {
                Logger.Trace().Message($"Progress: {status.Progress}").Write();
                Assert.Equal(jobId, status.WorkItemId);
                statusCount++;
            });

            await job.RunUntilEmptyAsync();

            Assert.Equal(1, statusCount);
        }
        public async Task CanRunWorkItemWithDelegateHandler()
        {
            using (var queue = new InMemoryQueue <WorkItemData>(new InMemoryQueueOptions <WorkItemData> {
                LoggerFactory = Log
            })) {
                using (var messageBus = new InMemoryMessageBus(new InMemoryMessageBusOptions {
                    LoggerFactory = Log
                })) {
                    var handlerRegistry = new WorkItemHandlers();
                    var job             = new WorkItemJob(queue, messageBus, handlerRegistry, Log);

                    handlerRegistry.Register <MyWorkItem>(async ctx => {
                        var jobData = ctx.GetData <MyWorkItem>();
                        Assert.Equal("Test", jobData.SomeData);

                        for (int i = 1; i < 10; i++)
                        {
                            await SystemClock.SleepAsync(100);
                            await ctx.ReportProgressAsync(10 * i);
                        }
                    }, Log.CreateLogger("MyWorkItem"));

                    string jobId = await queue.EnqueueAsync(new MyWorkItem {
                        SomeData = "Test"
                    }, true);

                    int statusCount = 0;
                    await messageBus.SubscribeAsync <WorkItemStatus>(status => {
                        if (_logger.IsEnabled(LogLevel.Trace))
                        {
                            _logger.LogTrace("Progress: {Progress}", status.Progress);
                        }
                        Assert.Equal(jobId, status.WorkItemId);
                        Interlocked.Increment(ref statusCount);
                    });

                    await job.RunUntilEmptyAsync();

                    Assert.Equal(11, statusCount);
                }
            }
        }
        public void CanRunBadWorkItem()
        {
            var queue           = new InMemoryQueue <WorkItemData>();
            var messageBus      = new InMemoryMessageBus();
            var handlerRegistry = new WorkItemHandlers();
            var job             = new WorkItemJob(queue, messageBus, handlerRegistry);

            handlerRegistry.Register <MyWorkItem>(async ctx => {
                var jobData = ctx.GetData <MyWorkItem>();
                Assert.Equal("Test", jobData.SomeData);
                throw new ApplicationException();
            });

            var jobId = queue.Enqueue(new MyWorkItem {
                SomeData = "Test"
            }, true);

            int statusCount = 0;

            messageBus.Subscribe <WorkItemStatus>(status => {
                Assert.Equal(jobId, status.WorkItemId);
                statusCount++;
            });

            job.RunUntilEmpty();

            Assert.Equal(1, statusCount);

            handlerRegistry.Register <MyWorkItem>(async ctx => {
                var jobData = ctx.GetData <MyWorkItem>();
                Assert.Equal("Test", jobData.SomeData);
            });

            jobId = queue.Enqueue(new MyWorkItem {
                SomeData = "Test"
            }, true);

            job.RunUntilEmpty();

            Assert.Equal(2, statusCount);
        }
Beispiel #16
0
        public async Task CanRunWorkItemWithDelegateHandler()
        {
            using (var queue = new InMemoryQueue <WorkItemData>(o => o.LoggerFactory(Log))) {
                using (var messageBus = new InMemoryMessageBus(o => o.LoggerFactory(Log))) {
                    var handlerRegistry = new WorkItemHandlers();
                    var job             = new WorkItemJob(queue, messageBus, handlerRegistry, Log);

                    handlerRegistry.Register <MyWorkItem>(async ctx => {
                        var jobData = ctx.GetData <MyWorkItem>();
                        Assert.Equal("Test", jobData.SomeData);

                        for (int i = 1; i < 10; i++)
                        {
                            await SystemClock.SleepAsync(100);
                            await ctx.ReportProgressAsync(10 * i);
                        }
                    }, Log.CreateLogger("MyWorkItem"));

                    string jobId = await queue.EnqueueAsync(new MyWorkItem {
                        SomeData = "Test"
                    }, true);

                    var countdown = new AsyncCountdownEvent(11);
                    await messageBus.SubscribeAsync <WorkItemStatus>(status => {
                        if (_logger.IsEnabled(LogLevel.Trace))
                        {
                            _logger.LogTrace("Progress: {Progress}", status.Progress);
                        }
                        Assert.Equal(jobId, status.WorkItemId);
                        countdown.Signal();
                    });

                    await job.RunUntilEmptyAsync();

                    await countdown.WaitAsync(TimeSpan.FromSeconds(2));

                    Assert.Equal(0, countdown.CurrentCount);
                }
            }
        }
Beispiel #17
0
        public static void RegisterServices(Container container, ILoggerFactory loggerFactory)
        {
            container.RegisterSingleton <ILoggerFactory>(loggerFactory);
            container.RegisterSingleton(typeof(ILogger <>), typeof(Logger <>));

            ServiceProvider.Current = container;
            container.RegisterSingleton <ISerializer>(() => new JsonNetSerializer());

            var metricsClient = new InMemoryMetricsClient();

            container.RegisterSingleton <IMetricsClient>(metricsClient);
            container.RegisterSingleton <ICacheClient, InMemoryCacheClient>();

            container.RegisterCollection(typeof(IQueueBehavior <ValuesPost>), new[] {
                Lifestyle.Singleton.CreateRegistration(
                    () => new MetricsQueueBehavior <ValuesPost>(metricsClient), container)
            });
            container.RegisterSingleton <IQueue <ValuesPost> >(() => new InMemoryQueue <ValuesPost>(behaviors: container.GetAllInstances <IQueueBehavior <ValuesPost> >()));

            container.RegisterCollection(typeof(IQueueBehavior <WorkItemData>), new[] {
                Lifestyle.Singleton.CreateRegistration(
                    () => new MetricsQueueBehavior <WorkItemData>(metricsClient), container)
            });

            var handlers = new WorkItemHandlers();

            handlers.Register <DeleteValueWorkItem, DeleteValueWorkItemHandler>();
            container.RegisterSingleton(handlers);

            container.RegisterSingleton <IQueue <WorkItemData> >(() => new InMemoryQueue <WorkItemData>(behaviors: container.GetAllInstances <IQueueBehavior <WorkItemData> >(), workItemTimeout: TimeSpan.FromHours(1)));

            container.RegisterSingleton <IMessageBus, InMemoryMessageBus>();
            container.RegisterSingleton <IMessagePublisher>(container.GetInstance <IMessageBus>);
            container.RegisterSingleton <IMessageSubscriber>(container.GetInstance <IMessageBus>);

            container.RegisterSingleton <ILockProvider, CacheLockProvider>();
            container.RegisterSingleton <IFileStorage>(new InMemoryFileStorage());
        }
        public static void RegisterServices(IServiceCollection container)
        {
            container.ConfigureOptions <ConfigureAppOptions>();
            container.ConfigureOptions <ConfigureAuthOptions>();
            container.ConfigureOptions <ConfigureCacheOptions>();
            container.ConfigureOptions <ConfigureElasticsearchOptions>();
            container.ConfigureOptions <ConfigureEmailOptions>();
            container.ConfigureOptions <ConfigureIntercomOptions>();
            container.ConfigureOptions <ConfigureMessageBusOptions>();
            container.ConfigureOptions <ConfigureMetricOptions>();
            container.ConfigureOptions <ConfigureQueueOptions>();
            container.ConfigureOptions <ConfigureSlackOptions>();
            container.ConfigureOptions <ConfigureStorageOptions>();
            container.ConfigureOptions <ConfigureStripeOptions>();

            JsonConvert.DefaultSettings = () => new JsonSerializerSettings {
                DateParseHandling = DateParseHandling.DateTimeOffset
            };

            container.AddSingleton <IContractResolver>(s => GetJsonContractResolver());
            container.AddSingleton <JsonSerializerSettings>(s => {
                var settings = new JsonSerializerSettings {
                    MissingMemberHandling = MissingMemberHandling.Ignore,
                    DateParseHandling     = DateParseHandling.DateTimeOffset,
                    ContractResolver      = s.GetRequiredService <IContractResolver>()
                };

                settings.AddModelConverters(s.GetRequiredService <ILogger <Bootstrapper> >());
                return(settings);
            });

            container.AddSingleton <JsonSerializer>(s => JsonSerializer.Create(s.GetRequiredService <JsonSerializerSettings>()));
            container.AddSingleton <ISerializer>(s => new JsonNetSerializer(s.GetRequiredService <JsonSerializerSettings>()));
            container.AddSingleton <ITextSerializer>(s => new JsonNetSerializer(s.GetRequiredService <JsonSerializerSettings>()));

            container.AddSingleton <ICacheClient>(s => new InMemoryCacheClient(new InMemoryCacheClientOptions {
                LoggerFactory = s.GetRequiredService <ILoggerFactory>()
            }));
            container.AddSingleton <IMetricsClient>(s => new InMemoryMetricsClient(new InMemoryMetricsClientOptions {
                LoggerFactory = s.GetRequiredService <ILoggerFactory>()
            }));

            container.AddSingleton <ExceptionlessElasticConfiguration>();
            container.AddSingleton <IElasticConfiguration>(s => s.GetRequiredService <ExceptionlessElasticConfiguration>());
            container.AddStartupAction <ExceptionlessElasticConfiguration>();

            container.AddStartupAction(CreateSampleDataAsync);

            container.AddSingleton <IQueueBehavior <EventPost> >(s => new MetricsQueueBehavior <EventPost>(s.GetRequiredService <IMetricsClient>()));
            container.AddSingleton <IQueueBehavior <EventUserDescription> >(s => new MetricsQueueBehavior <EventUserDescription>(s.GetRequiredService <IMetricsClient>()));
            container.AddSingleton <IQueueBehavior <EventNotificationWorkItem> >(s => new MetricsQueueBehavior <EventNotificationWorkItem>(s.GetRequiredService <IMetricsClient>()));
            container.AddSingleton <IQueueBehavior <WebHookNotification> >(s => new MetricsQueueBehavior <WebHookNotification>(s.GetRequiredService <IMetricsClient>()));
            container.AddSingleton <IQueueBehavior <MailMessage> >(s => new MetricsQueueBehavior <MailMessage>(s.GetRequiredService <IMetricsClient>()));
            container.AddSingleton <IQueueBehavior <WorkItemData> >(s => new MetricsQueueBehavior <WorkItemData>(s.GetRequiredService <IMetricsClient>()));

            container.AddSingleton(typeof(IWorkItemHandler), typeof(Bootstrapper).Assembly);
            container.AddSingleton <WorkItemHandlers>(s => {
                var handlers = new WorkItemHandlers();
                handlers.Register <ReindexWorkItem>(s.GetRequiredService <ReindexWorkItemHandler>);
                handlers.Register <RemoveOrganizationWorkItem>(s.GetRequiredService <RemoveOrganizationWorkItemHandler>);
                handlers.Register <RemoveProjectWorkItem>(s.GetRequiredService <RemoveProjectWorkItemHandler>);
                handlers.Register <SetLocationFromGeoWorkItem>(s.GetRequiredService <SetLocationFromGeoWorkItemHandler>);
                handlers.Register <SetProjectIsConfiguredWorkItem>(s.GetRequiredService <SetProjectIsConfiguredWorkItemHandler>);
                handlers.Register <StackWorkItem>(s.GetRequiredService <StackWorkItemHandler>);
                handlers.Register <ThrottleBotsWorkItem>(s.GetRequiredService <ThrottleBotsWorkItemHandler>);
                handlers.Register <OrganizationMaintenanceWorkItem>(s.GetRequiredService <OrganizationMaintenanceWorkItemHandler>);
                handlers.Register <OrganizationNotificationWorkItem>(s.GetRequiredService <OrganizationNotificationWorkItemHandler>);
                handlers.Register <ProjectMaintenanceWorkItem>(s.GetRequiredService <ProjectMaintenanceWorkItemHandler>);
                handlers.Register <UserMaintenanceWorkItem>(s.GetRequiredService <UserMaintenanceWorkItemHandler>);
                return(handlers);
            });

            container.AddSingleton(s => CreateQueue <EventPost>(s));
            container.AddSingleton(s => CreateQueue <EventUserDescription>(s));
            container.AddSingleton(s => CreateQueue <EventNotificationWorkItem>(s));
            container.AddSingleton(s => CreateQueue <WebHookNotification>(s));
            container.AddSingleton(s => CreateQueue <MailMessage>(s));
            container.AddSingleton(s => CreateQueue <WorkItemData>(s, TimeSpan.FromHours(1)));

            container.AddSingleton <IConnectionMapping, ConnectionMapping>();
            container.AddSingleton <MessageService>();
            container.AddStartupAction <MessageService>();
            container.AddSingleton <IMessageBus>(s => new InMemoryMessageBus(new InMemoryMessageBusOptions {
                LoggerFactory = s.GetRequiredService <ILoggerFactory>()
            }));
            container.AddSingleton <IMessagePublisher>(s => s.GetRequiredService <IMessageBus>());
            container.AddSingleton <IMessageSubscriber>(s => s.GetRequiredService <IMessageBus>());

            container.AddSingleton <IFileStorage>(s => new InMemoryFileStorage(new InMemoryFileStorageOptions {
                Serializer    = s.GetRequiredService <ITextSerializer>(),
                LoggerFactory = s.GetRequiredService <ILoggerFactory>()
            }));

            container.AddSingleton <IStackRepository, StackRepository>();
            container.AddSingleton <IEventRepository, EventRepository>();
            container.AddSingleton <IOrganizationRepository, OrganizationRepository>();
            container.AddSingleton <IProjectRepository, ProjectRepository>();
            container.AddSingleton <IUserRepository, UserRepository>();
            container.AddSingleton <IWebHookRepository, WebHookRepository>();
            container.AddSingleton <ITokenRepository, TokenRepository>();

            container.AddSingleton <IGeoIpService, MaxMindGeoIpService>();
            container.AddSingleton <IGeocodeService, NullGeocodeService>();

            container.AddSingleton <IQueryParser>(s => new ElasticQueryParser());
            container.AddSingleton <IQueryValidator, QueryValidator>();
            container.AddSingleton <PersistentEventQueryValidator>();
            container.AddSingleton <StackQueryValidator>();

            container.AddSingleton(typeof(IValidator <>), typeof(Bootstrapper).Assembly);
            container.AddSingleton(typeof(IPipelineAction <EventContext>), typeof(Bootstrapper).Assembly);
            container.AddSingleton(typeof(IPlugin), typeof(Bootstrapper).Assembly);
            container.AddSingleton <EventParserPluginManager>();
            container.AddSingleton <EventPluginManager>();
            container.AddSingleton <EventUpgraderPluginManager>();
            container.AddSingleton <FormattingPluginManager>();
            container.AddSingleton <WebHookDataPluginManager>();
            container.AddSingleton(typeof(IJob), typeof(Bootstrapper).Assembly);
            container.AddSingleton <WorkItemJob>();
            container.AddSingleton <MaintainIndexesJob>();

            container.AddSingleton <IMailer, Mailer>();
            container.AddSingleton <IMailSender>(s => new InMemoryMailSender());

            container.AddSingleton <CacheLockProvider>(s => new CacheLockProvider(s.GetRequiredService <ICacheClient>(), s.GetRequiredService <IMessageBus>(), s.GetRequiredService <ILoggerFactory>()));
            container.AddSingleton <ILockProvider>(s => s.GetRequiredService <CacheLockProvider>());
            container.AddTransient <StripeEventHandler>();
            container.AddSingleton <BillingManager>();
            container.AddSingleton <BillingPlans>();
            container.AddSingleton <EventPostService>();
            container.AddSingleton <SampleDataService>();
            container.AddSingleton <SemanticVersionParser>();
            container.AddSingleton <EventParserPluginManager>();
            container.AddSingleton <EventPipeline>();
            container.AddSingleton <EventPluginManager>();
            container.AddSingleton <FormattingPluginManager>();
            container.AddSingleton <WebHookDataPluginManager>();
            container.AddSingleton <UserAgentParser>();
            container.AddSingleton <SystemHealthChecker>();
            container.AddSingleton <ICoreLastReferenceIdManager, NullCoreLastReferenceIdManager>();

            container.AddSingleton <UsageService>();
            container.AddSingleton <SlackService>();
            container.AddSingleton <StackService>();

            container.AddTransient <IDomainLoginProvider, ActiveDirectoryLoginProvider>();

            container.AddTransient <AutoMapper.Profile, CoreMappings>();
            container.AddSingleton <IMapper>(s => {
                var profiles = s.GetServices <AutoMapper.Profile>();
                var c        = new MapperConfiguration(cfg => {
                    cfg.AddCollectionMappers();
                    cfg.ConstructServicesUsing(s.GetRequiredService);

                    foreach (var profile in profiles)
                    {
                        cfg.AddProfile(profile);
                    }
                });

                return(c.CreateMapper());
            });
        }
Beispiel #19
0
        public async Task CanHandleMultipleWorkItemInstances()
        {
            const int workItemCount = 1000;

            using (var metrics = new InMemoryMetricsClient(new InMemoryMetricsClientOptions {
                LoggerFactory = Log
            })) {
                var options = new InMemoryQueueOptions <WorkItemData> {
                    Retries = 0, RetryDelay = TimeSpan.Zero, LoggerFactory = Log
                };
                using (var queue = new InMemoryQueue <WorkItemData>(options)) {
                    queue.AttachBehavior(new MetricsQueueBehavior <WorkItemData>(metrics, loggerFactory: Log));
                    using (var messageBus = new InMemoryMessageBus(new InMemoryMessageBusOptions {
                        LoggerFactory = Log
                    })) {
                        var handlerRegistry = new WorkItemHandlers();
                        var j1     = new WorkItemJob(queue, messageBus, handlerRegistry, Log);
                        var j2     = new WorkItemJob(queue, messageBus, handlerRegistry, Log);
                        var j3     = new WorkItemJob(queue, messageBus, handlerRegistry, Log);
                        int errors = 0;

                        var jobIds = new ConcurrentDictionary <string, int>();

                        handlerRegistry.Register <MyWorkItem>(async ctx => {
                            var jobData = ctx.GetData <MyWorkItem>();
                            Assert.Equal("Test", jobData.SomeData);

                            int jobWorkTotal = jobIds.AddOrUpdate(ctx.JobId, 1, (key, value) => value + 1);
                            if (jobData.Index % 100 == 0)
                            {
                                _logger.Trace("Job {jobId} processing work item #: {jobWorkTotal}", ctx.JobId, jobWorkTotal);
                            }

                            for (int i = 0; i < 10; i++)
                            {
                                await ctx.ReportProgressAsync(10 * i);
                            }

                            if (RandomData.GetBool(1))
                            {
                                Interlocked.Increment(ref errors);
                                throw new Exception("Boom!");
                            }
                        });

                        for (int i = 0; i < workItemCount; i++)
                        {
                            await queue.EnqueueAsync(new MyWorkItem {
                                SomeData = "Test",
                                Index    = i
                            }, true);
                        }

                        var    completedItems     = new List <string>();
                        object completedItemsLock = new object();
                        await messageBus.SubscribeAsync <WorkItemStatus>(status => {
                            if (status.Progress == 100)
                            {
                                _logger.Trace("Progress: {progress}", status.Progress);
                            }

                            if (status.Progress < 100)
                            {
                                return;
                            }

                            lock (completedItemsLock)
                                completedItems.Add(status.WorkItemId);
                        });

                        var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(10));
                        var tasks = new List <Task> {
                            Task.Run(async() => {
                                await j1.RunUntilEmptyAsync(cancellationTokenSource.Token);
                                cancellationTokenSource.Cancel();
                            }, cancellationTokenSource.Token),
                            Task.Run(async() => {
                                await j2.RunUntilEmptyAsync(cancellationTokenSource.Token);
                                cancellationTokenSource.Cancel();
                            }, cancellationTokenSource.Token),
                            Task.Run(async() => {
                                await j3.RunUntilEmptyAsync(cancellationTokenSource.Token);
                                cancellationTokenSource.Cancel();
                            }, cancellationTokenSource.Token)
                        };

                        try {
                            await Task.WhenAll(tasks);
                        } catch (OperationCanceledException ex) {
                            _logger.Error(ex, $"One or more tasks were cancelled: {ex.Message}");
                        }

                        await SystemClock.SleepAsync(100);

                        _logger.Info("Completed: {completedItems} Errors: {errors}", completedItems.Count, errors);
                        Assert.Equal(workItemCount, completedItems.Count + errors);
                        Assert.Equal(3, jobIds.Count);
                        Assert.Equal(workItemCount, jobIds.Sum(kvp => kvp.Value));
                    }
                }
            }
        }
Beispiel #20
0
        public void RegisterServices(Container container)
        {
            // Foundation service provider
            ServiceProvider.Current = container;
            container.RegisterSingleton <IDependencyResolver>(() => new SimpleInjectorCoreDependencyResolver(container));

            JsonConvert.DefaultSettings = () => new JsonSerializerSettings {
                DateParseHandling = DateParseHandling.DateTimeOffset
            };

            var contractResolver = new ExceptionlessContractResolver();

            contractResolver.UseDefaultResolverFor(typeof(DataDictionary), typeof(SettingsDictionary), typeof(VersionOne.VersionOneWebHookStack), typeof(VersionOne.VersionOneWebHookEvent));

            var settings = new JsonSerializerSettings {
                MissingMemberHandling = MissingMemberHandling.Ignore,
                DateParseHandling     = DateParseHandling.DateTimeOffset,
                ContractResolver      = contractResolver
            };

            settings.AddModelConverters();

            container.RegisterSingleton <IContractResolver>(() => contractResolver);
            container.RegisterSingleton <JsonSerializerSettings>(settings);
            container.RegisterSingleton <JsonSerializer>(JsonSerializer.Create(settings));
            container.RegisterSingleton <ISerializer>(() => new JsonNetSerializer(settings));

            container.RegisterSingleton <IMetricsClient, InMemoryMetricsClient>();
            container.RegisterSingleton <IElasticClient>(() => container.GetInstance <ElasticSearchConfiguration>().GetClient(Settings.Current.ElasticSearchConnectionString.Split(',').Select(url => new Uri(url))));
            container.RegisterSingleton <EventIndex, EventIndex>();
            container.RegisterSingleton <OrganizationIndex, OrganizationIndex>();
            container.RegisterSingleton <StackIndex, StackIndex>();

            container.RegisterSingleton <ICacheClient, InMemoryCacheClient>();

            container.RegisterSingleton <IEnumerable <IQueueBehavior <EventPost> > >(() => new[] { new MetricsQueueBehavior <EventPost>(container.GetInstance <IMetricsClient>()) });
            container.RegisterSingleton <IEnumerable <IQueueBehavior <EventUserDescription> > >(() => new[] { new MetricsQueueBehavior <EventUserDescription>(container.GetInstance <IMetricsClient>()) });
            container.RegisterSingleton <IEnumerable <IQueueBehavior <EventNotificationWorkItem> > >(() => new[] { new MetricsQueueBehavior <EventNotificationWorkItem>(container.GetInstance <IMetricsClient>()) });
            container.RegisterSingleton <IEnumerable <IQueueBehavior <WebHookNotification> > >(() => new[] { new MetricsQueueBehavior <WebHookNotification>(container.GetInstance <IMetricsClient>()) });
            container.RegisterSingleton <IEnumerable <IQueueBehavior <MailMessage> > >(() => new[] { new MetricsQueueBehavior <MailMessage>(container.GetInstance <IMetricsClient>()) });
            container.RegisterSingleton <IEnumerable <IQueueBehavior <WorkItemData> > >(() => new[] { new MetricsQueueBehavior <WorkItemData>(container.GetInstance <IMetricsClient>()) });

            container.RegisterSingleton <IQueue <EventPost> >(() => new InMemoryQueue <EventPost>(behaviors: container.GetAllInstances <IQueueBehavior <EventPost> >()));
            container.RegisterSingleton <IQueue <EventUserDescription> >(() => new InMemoryQueue <EventUserDescription>(behaviors: container.GetAllInstances <IQueueBehavior <EventUserDescription> >()));
            container.RegisterSingleton <IQueue <EventNotificationWorkItem> >(() => new InMemoryQueue <EventNotificationWorkItem>(behaviors: container.GetAllInstances <IQueueBehavior <EventNotificationWorkItem> >()));
            container.RegisterSingleton <IQueue <WebHookNotification> >(() => new InMemoryQueue <WebHookNotification>(behaviors: container.GetAllInstances <IQueueBehavior <WebHookNotification> >()));
            container.RegisterSingleton <IQueue <MailMessage> >(() => new InMemoryQueue <MailMessage>(behaviors: container.GetAllInstances <IQueueBehavior <MailMessage> >()));
            container.RegisterSingleton <IQueue <StatusMessage> >(() => new InMemoryQueue <StatusMessage>());

            var workItemHandlers = new WorkItemHandlers();

            workItemHandlers.Register <ReindexWorkItem, ReindexWorkItemHandler>();
            workItemHandlers.Register <RemoveOrganizationWorkItem, RemoveOrganizationWorkItemHandler>();
            workItemHandlers.Register <RemoveProjectWorkItem, RemoveProjectWorkItemHandler>();
            workItemHandlers.Register <SetProjectIsConfiguredWorkItem, SetProjectIsConfiguredWorkItemHandler>();
            workItemHandlers.Register <StackWorkItem, StackWorkItemHandler>();
            workItemHandlers.Register <ThrottleBotsWorkItem, ThrottleBotsWorkItemHandler>();
            container.RegisterSingleton <WorkItemHandlers>(workItemHandlers);
            container.RegisterSingleton <IQueue <WorkItemData> >(() => new InMemoryQueue <WorkItemData>(behaviors: container.GetAllInstances <IQueueBehavior <WorkItemData> >(), workItemTimeout: TimeSpan.FromHours(1)));

            container.RegisterSingleton <IMessageBus, InMemoryMessageBus>();
            container.RegisterSingleton <IMessagePublisher>(container.GetInstance <IMessageBus>);
            container.RegisterSingleton <IMessageSubscriber>(container.GetInstance <IMessageBus>);

            if (!String.IsNullOrEmpty(Settings.Current.StorageFolder))
            {
                container.RegisterSingleton <IFileStorage>(new FolderFileStorage(Settings.Current.StorageFolder));
            }
            else
            {
                container.RegisterSingleton <IFileStorage>(new InMemoryFileStorage());
            }

            container.RegisterSingleton <IStackRepository, StackRepository>();
            container.RegisterSingleton <IEventRepository, EventRepository>();
            container.RegisterSingleton <IOrganizationRepository, OrganizationRepository>();
            container.RegisterSingleton <IProjectRepository, ProjectRepository>();
            container.RegisterSingleton <IUserRepository, UserRepository>();
            container.RegisterSingleton <IWebHookRepository, WebHookRepository>();
            container.RegisterSingleton <ITokenRepository, TokenRepository>();
            container.RegisterSingleton <IApplicationRepository, ApplicationRepository>();

            container.RegisterSingleton <IGeoIPResolver, MindMaxGeoIPResolver>();

            container.RegisterSingleton <IValidator <Application>, ApplicationValidator>();
            container.RegisterSingleton <IValidator <Organization>, OrganizationValidator>();
            container.RegisterSingleton <IValidator <PersistentEvent>, PersistentEventValidator>();
            container.RegisterSingleton <IValidator <Project>, ProjectValidator>();
            container.RegisterSingleton <IValidator <Stack>, StackValidator>();
            container.RegisterSingleton <IValidator <Models.Token>, TokenValidator>();
            container.RegisterSingleton <IValidator <UserDescription>, UserDescriptionValidator>();
            container.RegisterSingleton <IValidator <User>, UserValidator>();
            container.RegisterSingleton <IValidator <WebHook>, WebHookValidator>();

            container.RegisterSingleton <IEmailGenerator>(() => new RazorEmailGenerator(@"Mail\Templates"));
            container.RegisterSingleton <IMailer, Mailer>();
            if (Settings.Current.WebsiteMode != WebsiteMode.Dev)
            {
                container.RegisterSingleton <IMailSender, SmtpMailSender>();
            }
            else
            {
                container.RegisterSingleton <IMailSender>(() => new InMemoryMailSender());
            }

            container.RegisterSingleton <ILockProvider, CacheLockProvider>();
            container.Register <StripeEventHandler>();
            container.RegisterSingleton <BillingManager>();
            container.RegisterSingleton <DataHelper>();
            container.RegisterSingleton <EventStats>();
            container.RegisterSingleton <EventPipeline>();
            container.RegisterSingleton <EventPluginManager>();
            container.RegisterSingleton <FormattingPluginManager>();

            container.RegisterSingleton <ICoreLastReferenceIdManager, NullCoreLastReferenceIdManager>();
        }
Beispiel #21
0
        public void CanRunWorkItemWithClassHandler() {
            ServiceProvider.SetServiceProvider(typeof(MyBootstrappedServiceProvider));
            var queue = new InMemoryQueue<WorkItemData>();
            var messageBus = new InMemoryMessageBus();
            var handlerRegistry = new WorkItemHandlers();
            var job = new WorkItemJob(queue, messageBus, handlerRegistry);

            handlerRegistry.Register<MyWorkItem, MyWorkItemHandler>();

            var jobId = queue.Enqueue(new MyWorkItem { SomeData = "Test" }, true);

            int statusCount = 0;
            messageBus.Subscribe<WorkItemStatus>(status => {
                Assert.Equal(jobId, status.WorkItemId);
                statusCount++;
            });

            job.RunUntilEmpty();

            Assert.Equal(12, statusCount);
        }
Beispiel #22
0
        public void CanRunBadWorkItem() {
            var queue = new InMemoryQueue<WorkItemData>();
            var messageBus = new InMemoryMessageBus();
            var handlerRegistry = new WorkItemHandlers();
            var job = new WorkItemJob(queue, messageBus, handlerRegistry);

            handlerRegistry.Register<MyWorkItem>(ctx => {
                var jobData = ctx.GetData<MyWorkItem>();
                Assert.Equal("Test", jobData.SomeData);
                throw new ApplicationException();
            });

            var jobId = queue.Enqueue(new MyWorkItem { SomeData = "Test" }, true);

            int statusCount = 0;
            messageBus.Subscribe<WorkItemStatus>(status => {
                Assert.Equal(jobId, status.WorkItemId);
                statusCount++;
            });

            job.RunUntilEmpty();
            Thread.Sleep(1);

            Assert.Equal(1, statusCount);

            handlerRegistry.Register<MyWorkItem>(ctx => {
                var jobData = ctx.GetData<MyWorkItem>();
                Assert.Equal("Test", jobData.SomeData);
                return TaskHelper.Completed();
            });

            jobId = queue.Enqueue(new MyWorkItem { SomeData = "Test" }, true);

            job.RunUntilEmpty();

            Assert.Equal(2, statusCount);
        }
Beispiel #23
0
        public void RegisterServices(Container container) {
            // Foundation service provider
            ServiceProvider.Current = container;
            container.RegisterSingle<IDependencyResolver>(() => new SimpleInjectorCoreDependencyResolver(container));

            JsonConvert.DefaultSettings = () => new JsonSerializerSettings {
                DateParseHandling = DateParseHandling.DateTimeOffset
            };

            var contractResolver = new ExceptionlessContractResolver();
            contractResolver.UseDefaultResolverFor(typeof(DataDictionary), typeof(SettingsDictionary), typeof(VersionOne.VersionOneWebHookStack), typeof(VersionOne.VersionOneWebHookEvent));

            var settings = new JsonSerializerSettings {
                MissingMemberHandling = MissingMemberHandling.Ignore,
                DateParseHandling = DateParseHandling.DateTimeOffset,
                ContractResolver = contractResolver
            };
            settings.AddModelConverters();
            
            container.RegisterSingle<IContractResolver>(() => contractResolver);
            container.RegisterSingle<JsonSerializerSettings>(settings);
            container.RegisterSingle<JsonSerializer>(JsonSerializer.Create(settings));
            container.RegisterSingle<ISerializer>(() => new JsonNetSerializer(settings));

            var metricsClient = new InMemoryMetricsClient();
            metricsClient.StartDisplayingStats();
            container.RegisterSingle<IMetricsClient>(metricsClient);

            container.RegisterSingle<IElasticClient>(() => container.GetInstance<ElasticSearchConfiguration>().GetClient(Settings.Current.ElasticSearchConnectionString.Split(',').Select(url => new Uri(url))));
            container.RegisterSingle<ICacheClient, InMemoryCacheClient>();

            container.RegisterSingle<IQueue<EventPost>>(() => new InMemoryQueue<EventPost>(statName: MetricNames.PostsQueueSize, metrics: container.GetInstance<IMetricsClient>()));
            container.RegisterSingle<IQueue<EventUserDescription>>(() => new InMemoryQueue<EventUserDescription>(statName: MetricNames.EventsUserDescriptionQueueSize, metrics: container.GetInstance<IMetricsClient>()));
            container.RegisterSingle<IQueue<EventNotificationWorkItem>>(() => new InMemoryQueue<EventNotificationWorkItem>(statName: MetricNames.EventNotificationQueueSize, metrics: container.GetInstance<IMetricsClient>()));
            container.RegisterSingle<IQueue<WebHookNotification>>(() => new InMemoryQueue<WebHookNotification>(statName: MetricNames.WebHookQueueSize, metrics: container.GetInstance<IMetricsClient>()));
            container.RegisterSingle<IQueue<MailMessage>>(() => new InMemoryQueue<MailMessage>(statName: MetricNames.EmailsQueueSize, metrics: container.GetInstance<IMetricsClient>()));
            container.RegisterSingle<IQueue<StatusMessage>>(() => new InMemoryQueue<StatusMessage>());

            var workItemHandlers = new WorkItemHandlers();
            workItemHandlers.Register<ReindexWorkItem, ReindexWorkItemHandler>();
            container.RegisterSingle<WorkItemHandlers>(workItemHandlers);
            container.RegisterSingle<IQueue<WorkItemData>>(() => new InMemoryQueue<WorkItemData>(statName: MetricNames.WorkItemQueueSize, metrics: container.GetInstance<IMetricsClient>(), workItemTimeout: TimeSpan.FromHours(1)));
            

            container.RegisterSingle<IMessageBus, InMemoryMessageBus>();
            container.RegisterSingle<IMessagePublisher>(container.GetInstance<IMessageBus>);
            container.RegisterSingle<IMessageSubscriber>(container.GetInstance<IMessageBus>);

            if (!String.IsNullOrEmpty(Settings.Current.StorageFolder))
                container.RegisterSingle<IFileStorage>(new FolderFileStorage(Settings.Current.StorageFolder));
            else
                container.RegisterSingle<IFileStorage>(new InMemoryFileStorage());

            container.RegisterSingle<IStackRepository, StackRepository>();
            container.RegisterSingle<IEventRepository, EventRepository>();
            container.RegisterSingle<IOrganizationRepository, OrganizationRepository>();
            container.RegisterSingle<IProjectRepository, ProjectRepository>();
            container.RegisterSingle<IUserRepository, UserRepository>();
            container.RegisterSingle<IWebHookRepository, WebHookRepository>();
            container.RegisterSingle<ITokenRepository, TokenRepository>();
            container.RegisterSingle<IApplicationRepository, ApplicationRepository>();

            container.RegisterSingle<IGeoIPResolver, MindMaxGeoIPResolver>();

            container.RegisterSingle<IValidator<Application>, ApplicationValidator>();
            container.RegisterSingle<IValidator<Organization>, OrganizationValidator>();
            container.RegisterSingle<IValidator<PersistentEvent>, PersistentEventValidator>();
            container.RegisterSingle<IValidator<Project>, ProjectValidator>();
            container.RegisterSingle<IValidator<Stack>, StackValidator>();
            container.RegisterSingle<IValidator<Models.Token>, TokenValidator>();
            container.RegisterSingle<IValidator<UserDescription>, UserDescriptionValidator>();
            container.RegisterSingle<IValidator<User>, UserValidator>();
            container.RegisterSingle<IValidator<WebHook>, WebHookValidator>();

            container.RegisterSingle<IEmailGenerator>(() => new RazorEmailGenerator(@"Mail\Templates"));
            container.RegisterSingle<IMailer, Mailer>();
            if (Settings.Current.WebsiteMode != WebsiteMode.Dev)
                container.RegisterSingle<IMailSender, SmtpMailSender>();
            else
                container.RegisterSingle<IMailSender>(() => new InMemoryMailSender());

            container.Register<ILockProvider, CacheLockProvider>();
            container.Register<StripeEventHandler>();
            container.RegisterSingle<BillingManager>();
            container.RegisterSingle<DataHelper>();
            container.RegisterSingle<EventStats>();
            container.RegisterSingle<EventPipeline>();
            container.RegisterSingle<EventPluginManager>();
            container.RegisterSingle<FormattingPluginManager>();

            container.RegisterSingle<ICoreLastReferenceIdManager, NullCoreLastReferenceIdManager>();
        }
Beispiel #24
0
        public async Task CanHandleMultipleWorkItemInstances()
        {
            const int workItemCount = 1000;

            var metrics = new InMemoryMetricsClient();
            var queue   = new InMemoryQueue <WorkItemData>(retries: 0, retryDelay: TimeSpan.Zero);

            queue.AttachBehavior(new MetricsQueueBehavior <WorkItemData>(metrics));
            var messageBus      = new InMemoryMessageBus();
            var handlerRegistry = new WorkItemHandlers();
            var j1     = new WorkItemJob(queue, messageBus, handlerRegistry);
            var j2     = new WorkItemJob(queue, messageBus, handlerRegistry);
            var j3     = new WorkItemJob(queue, messageBus, handlerRegistry);
            int errors = 0;

            var jobIds = new ConcurrentDictionary <string, int>();

            handlerRegistry.Register <MyWorkItem>(async ctx => {
                var jobData = ctx.GetData <MyWorkItem>();
                Assert.Equal("Test", jobData.SomeData);

                var jobWorkTotal = jobIds.AddOrUpdate(ctx.JobId, 1, (key, value) => value + 1);
                Logger.Trace().Message($"Job {ctx.JobId} processing work item #: {jobWorkTotal}").Write();

                for (int i = 0; i < 10; i++)
                {
                    await ctx.ReportProgressAsync(10 * i);
                }

                if (RandomData.GetBool(1))
                {
                    Interlocked.Increment(ref errors);
                    throw new ApplicationException("Boom!");
                }
            });

            for (int i = 0; i < workItemCount; i++)
            {
                await queue.EnqueueAsync(new MyWorkItem {
                    SomeData = "Test",
                    Index    = i
                }, true);
            }

            var    completedItems     = new List <string>();
            object completedItemsLock = new object();

            messageBus.Subscribe <WorkItemStatus>(status => {
                Logger.Trace().Message($"Progress: {status.Progress}").Write();
                if (status.Progress < 100)
                {
                    return;
                }

                lock (completedItemsLock)
                    completedItems.Add(status.WorkItemId);
            });

            var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(10));
            var tasks = new List <Task> {
                Task.Run(async() => {
                    await j1.RunUntilEmptyAsync(cancellationTokenSource.Token);
                    cancellationTokenSource.Cancel();
                }, cancellationTokenSource.Token),
                Task.Run(async() => {
                    await j2.RunUntilEmptyAsync(cancellationTokenSource.Token);
                    cancellationTokenSource.Cancel();
                }, cancellationTokenSource.Token),
                Task.Run(async() => {
                    await j3.RunUntilEmptyAsync(cancellationTokenSource.Token);
                    cancellationTokenSource.Cancel();
                }, cancellationTokenSource.Token)
            };

            try {
                await Task.WhenAll(tasks);

                await Task.Delay(100);
            } catch (TaskCanceledException) {}

            Logger.Info().Message($"Completed: {completedItems.Count} Errors: {errors}").Write();
            metrics.DisplayStats(_writer);

            Assert.Equal(workItemCount, completedItems.Count + errors);
            Assert.Equal(3, jobIds.Count);
            Assert.Equal(workItemCount, jobIds.Sum(kvp => kvp.Value));
        }
Beispiel #25
0
        public static void RegisterServices(Container container, ILoggerFactory loggerFactory)
        {
            container.RegisterLogger(loggerFactory);
            container.RegisterSingleton <IDependencyResolver>(() => new SimpleInjectorDependencyResolver(container));

            JsonConvert.DefaultSettings = () => new JsonSerializerSettings {
                DateParseHandling = DateParseHandling.DateTimeOffset
            };

            var contractResolver = new ExceptionlessContractResolver();

            contractResolver.UseDefaultResolverFor(typeof(DataDictionary), typeof(SettingsDictionary), typeof(VersionOne.VersionOneWebHookStack), typeof(VersionOne.VersionOneWebHookEvent));

            var settings = new JsonSerializerSettings {
                MissingMemberHandling = MissingMemberHandling.Ignore,
                DateParseHandling     = DateParseHandling.DateTimeOffset,
                ContractResolver      = contractResolver
            };

            settings.AddModelConverters(loggerFactory.CreateLogger(nameof(Bootstrapper)));

            container.RegisterSingleton <IContractResolver>(() => contractResolver);
            container.RegisterSingleton <JsonSerializerSettings>(settings);
            container.RegisterSingleton <JsonSerializer>(JsonSerializer.Create(settings));
            container.RegisterSingleton <ISerializer>(() => new JsonNetSerializer(settings));

            container.RegisterSingleton <IMetricsClient>(() => new InMemoryMetricsClient(loggerFactory: loggerFactory));

            container.RegisterSingleton <QueryBuilderRegistry>(() => {
                var builder = new QueryBuilderRegistry();
                builder.RegisterDefaults();
                builder.Register(new OrganizationIdQueryBuilder());
                builder.Register(new ProjectIdQueryBuilder());
                builder.Register(new StackIdQueryBuilder());

                return(builder);
            });

            container.RegisterSingleton <ElasticConfigurationBase, ElasticConfiguration>();
            container.RegisterSingleton <IElasticClient>(() => container.GetInstance <ElasticConfigurationBase>().GetClient(Settings.Current.ElasticSearchConnectionString.Split(',').Select(url => new Uri(url))));
            container.RegisterSingleton <EventIndex, EventIndex>();
            container.RegisterSingleton <OrganizationIndex, OrganizationIndex>();
            container.RegisterSingleton <StackIndex, StackIndex>();

            container.RegisterSingleton <ICacheClient, InMemoryCacheClient>();

            container.RegisterSingleton <IEnumerable <IQueueBehavior <EventPost> > >(() => new[] { new MetricsQueueBehavior <EventPost>(container.GetInstance <IMetricsClient>()) });
            container.RegisterSingleton <IEnumerable <IQueueBehavior <EventUserDescription> > >(() => new[] { new MetricsQueueBehavior <EventUserDescription>(container.GetInstance <IMetricsClient>()) });
            container.RegisterSingleton <IEnumerable <IQueueBehavior <EventNotificationWorkItem> > >(() => new[] { new MetricsQueueBehavior <EventNotificationWorkItem>(container.GetInstance <IMetricsClient>()) });
            container.RegisterSingleton <IEnumerable <IQueueBehavior <WebHookNotification> > >(() => new[] { new MetricsQueueBehavior <WebHookNotification>(container.GetInstance <IMetricsClient>()) });
            container.RegisterSingleton <IEnumerable <IQueueBehavior <MailMessage> > >(() => new[] { new MetricsQueueBehavior <MailMessage>(container.GetInstance <IMetricsClient>()) });
            container.RegisterSingleton <IEnumerable <IQueueBehavior <WorkItemData> > >(() => new[] { new MetricsQueueBehavior <WorkItemData>(container.GetInstance <IMetricsClient>()) });

            container.RegisterSingleton <IQueue <EventPost> >(() => new InMemoryQueue <EventPost>(behaviors: container.GetAllInstances <IQueueBehavior <EventPost> >()));
            container.RegisterSingleton <IQueue <EventUserDescription> >(() => new InMemoryQueue <EventUserDescription>(behaviors: container.GetAllInstances <IQueueBehavior <EventUserDescription> >()));
            container.RegisterSingleton <IQueue <EventNotificationWorkItem> >(() => new InMemoryQueue <EventNotificationWorkItem>(behaviors: container.GetAllInstances <IQueueBehavior <EventNotificationWorkItem> >()));
            container.RegisterSingleton <IQueue <WebHookNotification> >(() => new InMemoryQueue <WebHookNotification>(behaviors: container.GetAllInstances <IQueueBehavior <WebHookNotification> >()));
            container.RegisterSingleton <IQueue <MailMessage> >(() => new InMemoryQueue <MailMessage>(behaviors: container.GetAllInstances <IQueueBehavior <MailMessage> >()));

            var workItemHandlers = new WorkItemHandlers();

            workItemHandlers.Register <ReindexWorkItem>(container.GetInstance <ReindexWorkItemHandler>);
            workItemHandlers.Register <RemoveOrganizationWorkItem>(container.GetInstance <RemoveOrganizationWorkItemHandler>);
            workItemHandlers.Register <RemoveProjectWorkItem>(container.GetInstance <RemoveProjectWorkItemHandler>);
            workItemHandlers.Register <SetLocationFromGeoWorkItem>(container.GetInstance <SetLocationFromGeoWorkItemHandler>);
            workItemHandlers.Register <SetProjectIsConfiguredWorkItem>(container.GetInstance <SetProjectIsConfiguredWorkItemHandler>);
            workItemHandlers.Register <StackWorkItem>(container.GetInstance <StackWorkItemHandler>);
            workItemHandlers.Register <ThrottleBotsWorkItem>(container.GetInstance <ThrottleBotsWorkItemHandler>);
            workItemHandlers.Register <OrganizationMaintenanceWorkItem>(container.GetInstance <OrganizationMaintenanceWorkItemHandler>);
            workItemHandlers.Register <OrganizationNotificationWorkItem>(container.GetInstance <OrganizationNotificationWorkItemHandler>);
            workItemHandlers.Register <ProjectMaintenanceWorkItem>(container.GetInstance <ProjectMaintenanceWorkItemHandler>);
            container.RegisterSingleton <WorkItemHandlers>(workItemHandlers);
            container.RegisterSingleton <IQueue <WorkItemData> >(() => new InMemoryQueue <WorkItemData>(behaviors: container.GetAllInstances <IQueueBehavior <WorkItemData> >(), workItemTimeout: TimeSpan.FromHours(1)));

            container.RegisterSingleton <IMessageBus, InMemoryMessageBus>();
            container.RegisterSingleton <IMessagePublisher>(container.GetInstance <IMessageBus>);
            container.RegisterSingleton <IMessageSubscriber>(container.GetInstance <IMessageBus>);

            if (!String.IsNullOrEmpty(Settings.Current.StorageFolder))
            {
                container.RegisterSingleton <IFileStorage>(new FolderFileStorage(Settings.Current.StorageFolder));
            }
            else
            {
                container.RegisterSingleton <IFileStorage>(new InMemoryFileStorage());
            }

            container.RegisterSingleton <IStackRepository, StackRepository>();
            container.RegisterSingleton <IEventRepository, EventRepository>();
            container.RegisterSingleton <IOrganizationRepository, OrganizationRepository>();
            container.RegisterSingleton <IProjectRepository, ProjectRepository>();
            container.RegisterSingleton <IUserRepository, UserRepository>();
            container.RegisterSingleton <IWebHookRepository, WebHookRepository>();
            container.RegisterSingleton <ITokenRepository, TokenRepository>();
            container.RegisterSingleton <IApplicationRepository, ApplicationRepository>();

            container.RegisterSingleton <IGeoIpService, MaxMindGeoIpService>();
            container.RegisterSingleton <IGeocodeService, NullGeocodeService>();

            container.Register(typeof(IValidator <>), new[] { typeof(Bootstrapper).Assembly }, Lifestyle.Singleton);
            container.Register(typeof(ElasticRepositoryContext <>), typeof(ElasticRepositoryContext <>), Lifestyle.Singleton);

            container.RegisterSingleton <IEmailGenerator>(() => new RazorEmailGenerator(@"Mail\Templates"));
            container.RegisterSingleton <IMailer, Mailer>();
            if (Settings.Current.WebsiteMode != WebsiteMode.Dev)
            {
                container.RegisterSingleton <IMailSender, SmtpMailSender>();
            }
            else
            {
                container.RegisterSingleton <IMailSender>(() => new InMemoryMailSender());
            }

            container.RegisterSingleton <ILockProvider, CacheLockProvider>();
            container.Register <StripeEventHandler>();
            container.RegisterSingleton <BillingManager>();
            container.RegisterSingleton <SampleDataService>();
            container.RegisterSingleton <EventStats>();
            container.RegisterSingleton <EventPipeline>();
            container.RegisterSingleton <EventPluginManager>();
            container.RegisterSingleton <FormattingPluginManager>();
            container.RegisterSingleton <UserAgentParser>();

            container.RegisterSingleton <SystemHealthChecker>();

            container.RegisterSingleton <ICoreLastReferenceIdManager, NullCoreLastReferenceIdManager>();

            container.RegisterSingleton <IMapper>(() => {
                var profiles = container.GetAllInstances <Profile>();
                var config   = new MapperConfiguration(cfg => {
                    cfg.ConstructServicesUsing(container.GetInstance);

                    foreach (var profile in profiles)
                    {
                        cfg.AddProfile(profile);
                    }
                });

                return(config.CreateMapper());
            });
        }
Beispiel #26
0
        public async Task CanRunWorkItemWithClassHandler() {
            ServiceProvider.SetServiceProvider(typeof(MyBootstrappedServiceProvider));
            var queue = new InMemoryQueue<WorkItemData>();
            var messageBus = new InMemoryMessageBus();
            var handlerRegistry = new WorkItemHandlers();
            var job = new WorkItemJob(queue, messageBus, handlerRegistry);

            handlerRegistry.Register<MyWorkItem, MyWorkItemHandler>();

            var jobId = await queue.EnqueueAsync(new MyWorkItem {
                SomeData = "Test"
            }, true);

            int statusCount = 0;
            messageBus.Subscribe<WorkItemStatus>(status => {
                Logger.Trace().Message($"Progress: {status.Progress}").Write();
                Assert.Equal(jobId, status.WorkItemId);
                statusCount++;
            });

            await job.RunUntilEmptyAsync();

            Assert.Equal(11, statusCount);
        }
Beispiel #27
0
 public WorkItemJob(IQueue<WorkItemData> queue, IMessageBus messageBus, WorkItemHandlers handlers, ILoggerFactory loggerFactory = null) {
     _messageBus = messageBus;
     _handlers = handlers;
     _queue = queue;
     _logger = loggerFactory.CreateLogger(GetType());
 }
Beispiel #28
0
        public async Task CanHandleMultipleWorkItemInstances() {
            const int workItemCount = 1000;

            using (var metrics = new InMemoryMetricsClient(loggerFactory: Log)) {
                using (var queue = new InMemoryQueue<WorkItemData>(retries: 0, retryDelay: TimeSpan.Zero, loggerFactory: Log)) {
                    queue.AttachBehavior(new MetricsQueueBehavior<WorkItemData>(metrics, loggerFactory: Log));
                    using (var messageBus = new InMemoryMessageBus(Log)) {
                        var handlerRegistry = new WorkItemHandlers();
                        var j1 = new WorkItemJob(queue, messageBus, handlerRegistry, Log);
                        var j2 = new WorkItemJob(queue, messageBus, handlerRegistry, Log);
                        var j3 = new WorkItemJob(queue, messageBus, handlerRegistry, Log);
                        int errors = 0;

                        var jobIds = new ConcurrentDictionary<string, int>();

                        handlerRegistry.Register<MyWorkItem>(async ctx => {
                            var jobData = ctx.GetData<MyWorkItem>();
                            Assert.Equal("Test", jobData.SomeData);

                            var jobWorkTotal = jobIds.AddOrUpdate(ctx.JobId, 1, (key, value) => value + 1);
                            if (jobData.Index % 100 == 0)
                                _logger.Trace("Job {jobId} processing work item #: {jobWorkTotal}", ctx.JobId, jobWorkTotal);

                            for (int i = 0; i < 10; i++)
                                await ctx.ReportProgressAsync(10 * i);

                            if (RandomData.GetBool(1)) {
                                Interlocked.Increment(ref errors);
                                throw new Exception("Boom!");
                            }
                        });

                        for (int i = 0; i < workItemCount; i++)
                            await queue.EnqueueAsync(new MyWorkItem {
                                SomeData = "Test",
                                Index = i
                            }, true);

                        var completedItems = new List<string>();
                        object completedItemsLock = new object();
                        messageBus.Subscribe<WorkItemStatus>(status => {
                            if (status.Progress == 100)
                                _logger.Trace("Progress: {progress}", status.Progress);

                            if (status.Progress < 100)
                                return;

                            lock (completedItemsLock)
                                completedItems.Add(status.WorkItemId);
                        });
            
                        var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(10));
                        var tasks = new List<Task> {
                            Task.Run(async () => {
                                await j1.RunUntilEmptyAsync(cancellationTokenSource.Token);
                                cancellationTokenSource.Cancel();
                            }, cancellationTokenSource.Token),
                            Task.Run(async () => {
                                await j2.RunUntilEmptyAsync(cancellationTokenSource.Token);
                                cancellationTokenSource.Cancel();
                            }, cancellationTokenSource.Token),
                            Task.Run(async () => {
                                await j3.RunUntilEmptyAsync(cancellationTokenSource.Token);
                                cancellationTokenSource.Cancel();
                            }, cancellationTokenSource.Token)
                        };

                        try {
                            await Task.WhenAll(tasks);
                            await SystemClock.SleepAsync(100);
                        } catch (TaskCanceledException) {}

                        _logger.Info("Completed: {completedItems} Errors: {errors}", completedItems.Count, errors);
            
                        Assert.Equal(workItemCount, completedItems.Count + errors);
                        Assert.Equal(3, jobIds.Count);
                        Assert.Equal(workItemCount, jobIds.Sum(kvp => kvp.Value));
                    }
                }
            }
        }
Beispiel #29
0
        public async Task CanRunBadWorkItem() {
            using (var queue = new InMemoryQueue<WorkItemData>(retries: 2, retryDelay: TimeSpan.FromMilliseconds(500))) {
                using (var messageBus = new InMemoryMessageBus()) {
                    var handlerRegistry = new WorkItemHandlers();
                    var job = new WorkItemJob(queue, messageBus, handlerRegistry, Log);

                    handlerRegistry.Register<MyWorkItem>(ctx => {
                        var jobData = ctx.GetData<MyWorkItem>();
                        Assert.Equal("Test", jobData.SomeData);
                        throw new Exception();
                    });

                    var jobId = await queue.EnqueueAsync(new MyWorkItem {
                        SomeData = "Test"
                    }, true);

                    int statusCount = 0;
                    messageBus.Subscribe<WorkItemStatus>(status => {
                        _logger.Trace("Progress: {progress}", status.Progress);
                        Assert.Equal(jobId, status.WorkItemId);
                        statusCount++;
                    });

                    await job.RunUntilEmptyAsync();
                    Assert.Equal(1, statusCount);
                }
            }
        }
Beispiel #30
0
        public async Task CanRunWorkItemWithClassHandler() {
            using (var queue = new InMemoryQueue<WorkItemData>()) {
                using (var messageBus = new InMemoryMessageBus()) {
                    var handlerRegistry = new WorkItemHandlers();
                    var job = new WorkItemJob(queue, messageBus, handlerRegistry, Log);

                    handlerRegistry.Register<MyWorkItem>(new MyWorkItemHandler(Log));

                    var jobId = await queue.EnqueueAsync(new MyWorkItem {
                        SomeData = "Test"
                    }, true);

                    int statusCount = 0;
                    messageBus.Subscribe<WorkItemStatus>(status => {
                        _logger.Trace("Progress: {progress}", status.Progress);
                        Assert.Equal(jobId, status.WorkItemId);
                        statusCount++;
                    });

                    await job.RunUntilEmptyAsync();

                    Assert.Equal(11, statusCount);
                }
            }
        }
        public static void RegisterServices(Container container, ILoggerFactory loggerFactory)
        {
            var logger = loggerFactory.CreateLogger <Bootstrapper>();

            logger.Info().Message(() => $"Bootstrapping \"{Process.GetCurrentProcess().ProcessName}\" on \"{Environment.MachineName}\".").Property("data", Settings.Current).Write();

            container.RegisterLogger(loggerFactory);

            container.RegisterSingleton <IDependencyResolver>(() => new SimpleInjectorDependencyContainer(container));
            container.RegisterSingleton <IMetricsClient>(() => new InMemoryMetricsClient());

            container.RegisterSingleton <AppElasticConfiguration>();
            container.RegisterSingleton <IIndexType <Migration> >(() => container.GetInstance <AppElasticConfiguration>().Organizations.MigrationType);
            container.RegisterSingleton <IElasticClient>(() => container.GetInstance <AppElasticConfiguration>().Client);

            container.RegisterSingleton <ICacheClient, InMemoryCacheClient>();

            container.RegisterSingleton <IEnumerable <IQueueBehavior <MailMessage> > >(() => new[] { new MetricsQueueBehavior <MailMessage>(container.GetInstance <IMetricsClient>()) });
            container.RegisterSingleton <IEnumerable <IQueueBehavior <WorkItemData> > >(() => new[] { new MetricsQueueBehavior <WorkItemData>(container.GetInstance <IMetricsClient>()) });

            var handlers = new WorkItemHandlers();

            handlers.Register <ReindexWorkItem>(container.GetInstance <ReindexWorkItemHandler>);
            container.RegisterSingleton(handlers);

            container.RegisterSingleton <IQueue <WorkItemData> >(() => new InMemoryQueue <WorkItemData>(behaviors: container.GetAllInstances <IQueueBehavior <WorkItemData> >(), workItemTimeout: TimeSpan.FromHours(1)));
            container.RegisterSingleton <IQueue <MailMessage> >(() => new InMemoryQueue <MailMessage>(behaviors: container.GetAllInstances <IQueueBehavior <MailMessage> >()));

            container.RegisterSingleton <IMessageBus, InMemoryMessageBus>();
            container.RegisterSingleton <IMessagePublisher>(container.GetInstance <IMessageBus>);
            container.RegisterSingleton <IMessageSubscriber>(container.GetInstance <IMessageBus>);
            container.RegisterSingleton <HttpMessageHandler, HttpClientHandler>();

            if (!String.IsNullOrEmpty(Settings.Current.StorageFolder))
            {
                try {
                    container.RegisterSingleton <IFileStorage>(new FolderFileStorage($"{Settings.Current.StorageFolder}\\private"));
                    container.RegisterSingleton <IPublicFileStorage>(new PublicFileStorage(new FolderFileStorage($"{Settings.Current.StorageFolder}\\public")));
                } catch (Exception ex) {
                    logger.Error(ex, $"Error setting folder storage: {ex.Message}");
                    container.RegisterSingleton <IFileStorage>(new InMemoryFileStorage());
                    container.RegisterSingleton <IPublicFileStorage>(new PublicFileStorage(new InMemoryFileStorage()));
                }
            }
            else
            {
                container.RegisterSingleton <IFileStorage>(new InMemoryFileStorage());
                container.RegisterSingleton <IPublicFileStorage>(new PublicFileStorage(new InMemoryFileStorage()));
            }

            container.Register(typeof(IValidator <>), new[] { typeof(Bootstrapper).Assembly }, Lifestyle.Singleton);

            container.RegisterSingleton <IOrganizationRepository, OrganizationRepository>();
            container.RegisterSingleton <IUserRepository, UserRepository>();
            container.RegisterSingleton <INotificationRepository, NotificationRepository>();
            container.RegisterSingleton <ITokenRepository, TokenRepository>();
            container.RegisterSingleton <ILogRepository, LogRepository>();
            container.RegisterSingleton <IMigrationRepository, MigrationRepository>();
            container.RegisterSingleton <IIndexType <Migration> >(() => container.GetInstance <AppElasticConfiguration>().Organizations.MigrationType);

            container.RegisterSingleton <IEmailGenerator>(() => new RazorEmailGenerator(@"Mail\Templates"));
            container.RegisterSingleton <ITemplatedMailService, TemplatedMailService>();

            if (Settings.Current.AppMode == AppMode.Local)
            {
                container.RegisterSingleton <IMailSender>(() => new InMemoryMailSender());
            }
            else
            {
                container.RegisterSingleton <IMailSender, SmtpMailSender>();
            }

            container.RegisterSingleton <ILockProvider, CacheLockProvider>();
            container.RegisterSingleton <SampleDataService>();

            if (Settings.Current.EnableIndexConfiguration)
            {
                container.AddStartupAction(() => {
                    var config = container.GetInstance <AppElasticConfiguration>();
                    config.ConfigureIndexesAsync().GetAwaiter().GetResult();
                });
            }

            container.AppendToCollection(typeof(Profile), typeof(DomainMappings));
            container.RegisterSingleton <IMapper>(() => {
                var profiles = container.GetAllInstances <Profile>();
                var config   = new MapperConfiguration(cfg => {
                    cfg.ConstructServicesUsing(container.GetInstance);

                    foreach (var profile in profiles)
                    {
                        cfg.AddProfile(profile);
                    }
                });

                return(config.CreateMapper());
            });
        }
Beispiel #32
0
        public static void RegisterServices(Container container, ILoggerFactory loggerFactory, CancellationToken shutdownCancellationToken)
        {
            var logger = loggerFactory.CreateLogger <Bootstrapper>();

            container.RegisterLogger(loggerFactory);
            container.RegisterSingleton <IDependencyResolver>(() => new SimpleInjectorDependencyResolver(container));

            JsonConvert.DefaultSettings = () => new JsonSerializerSettings {
                DateParseHandling = DateParseHandling.DateTimeOffset
            };

            var resolver = new DynamicTypeContractResolver(new LowerCaseUnderscorePropertyNamesContractResolver());

            resolver.UseDefaultResolverFor(typeof(DataDictionary), typeof(SettingsDictionary), typeof(VersionOne.VersionOneWebHookStack), typeof(VersionOne.VersionOneWebHookEvent));

            var settings = new JsonSerializerSettings {
                MissingMemberHandling = MissingMemberHandling.Ignore,
                DateParseHandling     = DateParseHandling.DateTimeOffset,
                ContractResolver      = resolver
            };

            settings.AddModelConverters(loggerFactory.CreateLogger(nameof(Bootstrapper)));

            container.RegisterSingleton <IContractResolver>(() => resolver);
            container.RegisterSingleton <JsonSerializerSettings>(settings);
            container.RegisterSingleton <JsonSerializer>(JsonSerializer.Create(settings));
            container.RegisterSingleton <ISerializer>(() => new JsonNetSerializer(settings));

            container.RegisterSingleton <IMetricsClient>(() => new InMemoryMetricsClient(loggerFactory: loggerFactory));

            container.RegisterSingleton <ExceptionlessElasticConfiguration>();
            if (!Settings.Current.DisableIndexConfiguration)
            {
                container.AddStartupAction(() => container.GetInstance <ExceptionlessElasticConfiguration>().ConfigureIndexesAsync(beginReindexingOutdated: false));
            }

            container.RegisterSingleton <ICacheClient, InMemoryCacheClient>();

            container.RegisterSingleton <IEnumerable <IQueueBehavior <EventPost> > >(() => new[] { new MetricsQueueBehavior <EventPost>(container.GetInstance <IMetricsClient>()) });
            container.RegisterSingleton <IEnumerable <IQueueBehavior <EventUserDescription> > >(() => new[] { new MetricsQueueBehavior <EventUserDescription>(container.GetInstance <IMetricsClient>()) });
            container.RegisterSingleton <IEnumerable <IQueueBehavior <EventNotificationWorkItem> > >(() => new[] { new MetricsQueueBehavior <EventNotificationWorkItem>(container.GetInstance <IMetricsClient>()) });
            container.RegisterSingleton <IEnumerable <IQueueBehavior <WebHookNotification> > >(() => new[] { new MetricsQueueBehavior <WebHookNotification>(container.GetInstance <IMetricsClient>()) });
            container.RegisterSingleton <IEnumerable <IQueueBehavior <MailMessage> > >(() => new[] { new MetricsQueueBehavior <MailMessage>(container.GetInstance <IMetricsClient>()) });
            container.RegisterSingleton <IEnumerable <IQueueBehavior <WorkItemData> > >(() => new[] { new MetricsQueueBehavior <WorkItemData>(container.GetInstance <IMetricsClient>()) });

            container.RegisterSingleton <IQueue <EventPost> >(() => new InMemoryQueue <EventPost>(behaviors: container.GetAllInstances <IQueueBehavior <EventPost> >(), loggerFactory: loggerFactory));
            container.RegisterSingleton <IQueue <EventUserDescription> >(() => new InMemoryQueue <EventUserDescription>(behaviors: container.GetAllInstances <IQueueBehavior <EventUserDescription> >(), loggerFactory: loggerFactory));
            container.RegisterSingleton <IQueue <EventNotificationWorkItem> >(() => new InMemoryQueue <EventNotificationWorkItem>(behaviors: container.GetAllInstances <IQueueBehavior <EventNotificationWorkItem> >(), loggerFactory: loggerFactory));
            container.RegisterSingleton <IQueue <WebHookNotification> >(() => new InMemoryQueue <WebHookNotification>(behaviors: container.GetAllInstances <IQueueBehavior <WebHookNotification> >(), loggerFactory: loggerFactory));
            container.RegisterSingleton <IQueue <MailMessage> >(() => new InMemoryQueue <MailMessage>(behaviors: container.GetAllInstances <IQueueBehavior <MailMessage> >(), loggerFactory: loggerFactory));

            var workItemHandlers = new WorkItemHandlers();

            workItemHandlers.Register <ReindexWorkItem>(container.GetInstance <ReindexWorkItemHandler>);
            workItemHandlers.Register <RemoveOrganizationWorkItem>(container.GetInstance <RemoveOrganizationWorkItemHandler>);
            workItemHandlers.Register <RemoveProjectWorkItem>(container.GetInstance <RemoveProjectWorkItemHandler>);
            workItemHandlers.Register <SetLocationFromGeoWorkItem>(container.GetInstance <SetLocationFromGeoWorkItemHandler>);
            workItemHandlers.Register <SetProjectIsConfiguredWorkItem>(container.GetInstance <SetProjectIsConfiguredWorkItemHandler>);
            workItemHandlers.Register <StackWorkItem>(container.GetInstance <StackWorkItemHandler>);
            workItemHandlers.Register <ThrottleBotsWorkItem>(container.GetInstance <ThrottleBotsWorkItemHandler>);
            workItemHandlers.Register <OrganizationMaintenanceWorkItem>(container.GetInstance <OrganizationMaintenanceWorkItemHandler>);
            workItemHandlers.Register <OrganizationNotificationWorkItem>(container.GetInstance <OrganizationNotificationWorkItemHandler>);
            workItemHandlers.Register <ProjectMaintenanceWorkItem>(container.GetInstance <ProjectMaintenanceWorkItemHandler>);
            workItemHandlers.Register <UserMaintenanceWorkItem>(container.GetInstance <UserMaintenanceWorkItemHandler>);
            container.RegisterSingleton <WorkItemHandlers>(workItemHandlers);
            container.RegisterSingleton <IQueue <WorkItemData> >(() => new InMemoryQueue <WorkItemData>(behaviors: container.GetAllInstances <IQueueBehavior <WorkItemData> >(), workItemTimeout: TimeSpan.FromHours(1), loggerFactory: loggerFactory));

            container.RegisterSingleton <IMessageBus, InMemoryMessageBus>();
            container.RegisterSingleton <IMessagePublisher>(container.GetInstance <IMessageBus>);
            container.RegisterSingleton <IMessageSubscriber>(container.GetInstance <IMessageBus>);

            if (!String.IsNullOrEmpty(Settings.Current.StorageFolder))
            {
                container.RegisterSingleton <IFileStorage>(new FolderFileStorage(Settings.Current.StorageFolder));
            }
            else
            {
                container.RegisterSingleton <IFileStorage>(new InMemoryFileStorage());
            }

            container.RegisterSingleton <IStackRepository, StackRepository>();
            container.RegisterSingleton <IEventRepository, EventRepository>();
            container.RegisterSingleton <IOrganizationRepository, OrganizationRepository>();
            container.RegisterSingleton <IProjectRepository, ProjectRepository>();
            container.RegisterSingleton <IUserRepository, UserRepository>();
            container.RegisterSingleton <IWebHookRepository, WebHookRepository>();
            container.RegisterSingleton <ITokenRepository, TokenRepository>();

            container.RegisterSingleton <IGeoIpService, MaxMindGeoIpService>();
            container.RegisterSingleton <IGeocodeService, NullGeocodeService>();

            container.RegisterSingleton <IQueryParser>(() => new ElasticQueryParser());
            container.Register(typeof(IValidator <>), new[] { typeof(Bootstrapper).Assembly }, Lifestyle.Singleton);

            container.RegisterSingleton <IEmailGenerator>(() => new RazorEmailGenerator(@"Mail\Templates"));
            container.RegisterSingleton <IMailer, Mailer>();
            if (Settings.Current.WebsiteMode != WebsiteMode.Dev)
            {
                container.RegisterSingleton <IMailSender, SmtpMailSender>();
            }
            else
            {
                container.RegisterSingleton <IMailSender>(() => new InMemoryMailSender());
                logger.Warn("Emails will NOT be sent in Dev mode.");
            }

            container.RegisterSingleton <ILockProvider, CacheLockProvider>();
            container.Register <StripeEventHandler>();
            container.RegisterSingleton <BillingManager>();
            container.RegisterSingleton <SampleDataService>();
            container.RegisterSingleton <EventPipeline>();
            container.RegisterSingleton <EventPluginManager>();
            container.RegisterSingleton <FormattingPluginManager>();
            container.RegisterSingleton <UserAgentParser>();
            container.RegisterSingleton <SystemHealthChecker>();
            container.RegisterSingleton <ICoreLastReferenceIdManager, NullCoreLastReferenceIdManager>();

            container.Register <IDomainLoginProvider, ActiveDirectoryLoginProvider>();

            container.AppendToCollection(typeof(Profile), typeof(CoreMappings));
            container.RegisterSingleton <IMapper>(() => {
                var profiles = container.GetAllInstances <Profile>();
                var config   = new MapperConfiguration(cfg => {
                    cfg.ConstructServicesUsing(container.GetInstance);

                    foreach (var profile in profiles)
                    {
                        cfg.AddProfile(profile);
                    }
                });

                return(config.CreateMapper());
            });
        }
Beispiel #33
0
        public static void RegisterServices(Container container, ILoggerFactory loggerFactory) {
            container.RegisterLogger(loggerFactory);
            container.RegisterSingleton<IDependencyResolver>(() => new SimpleInjectorDependencyResolver(container));

            JsonConvert.DefaultSettings = () => new JsonSerializerSettings {
                DateParseHandling = DateParseHandling.DateTimeOffset
            };

            var contractResolver = new ExceptionlessContractResolver();
            contractResolver.UseDefaultResolverFor(typeof(DataDictionary), typeof(SettingsDictionary), typeof(VersionOne.VersionOneWebHookStack), typeof(VersionOne.VersionOneWebHookEvent));

            var settings = new JsonSerializerSettings {
                MissingMemberHandling = MissingMemberHandling.Ignore,
                DateParseHandling = DateParseHandling.DateTimeOffset,
                ContractResolver = contractResolver
            };

            settings.AddModelConverters(loggerFactory.CreateLogger(nameof(Bootstrapper)));

            container.RegisterSingleton<IContractResolver>(() => contractResolver);
            container.RegisterSingleton<JsonSerializerSettings>(settings);
            container.RegisterSingleton<JsonSerializer>(JsonSerializer.Create(settings));
            container.RegisterSingleton<ISerializer>(() => new JsonNetSerializer(settings));

            container.RegisterSingleton<IMetricsClient>(() => new InMemoryMetricsClient(loggerFactory: loggerFactory));

            container.RegisterSingleton<QueryBuilderRegistry>(() => {
                var builder = new QueryBuilderRegistry();
                builder.RegisterDefaults();
                builder.Register(new OrganizationIdQueryBuilder());
                builder.Register(new ProjectIdQueryBuilder());
                builder.Register(new StackIdQueryBuilder());

                return builder;
            });

            container.RegisterSingleton<ElasticConfigurationBase, ElasticConfiguration>();
            container.RegisterSingleton<IElasticClient>(() => container.GetInstance<ElasticConfigurationBase>().GetClient(Settings.Current.ElasticSearchConnectionString.Split(',').Select(url => new Uri(url))));
            container.RegisterSingleton<EventIndex, EventIndex>();
            container.RegisterSingleton<OrganizationIndex, OrganizationIndex>();
            container.RegisterSingleton<StackIndex, StackIndex>();

            container.RegisterSingleton<ICacheClient, InMemoryCacheClient>();

            container.RegisterSingleton<IEnumerable<IQueueBehavior<EventPost>>>(() => new[] { new MetricsQueueBehavior<EventPost>(container.GetInstance<IMetricsClient>()) });
            container.RegisterSingleton<IEnumerable<IQueueBehavior<EventUserDescription>>>(() => new[] { new MetricsQueueBehavior<EventUserDescription>(container.GetInstance<IMetricsClient>()) });
            container.RegisterSingleton<IEnumerable<IQueueBehavior<EventNotificationWorkItem>>>(() => new[] { new MetricsQueueBehavior<EventNotificationWorkItem>(container.GetInstance<IMetricsClient>()) });
            container.RegisterSingleton<IEnumerable<IQueueBehavior<WebHookNotification>>>(() => new[] { new MetricsQueueBehavior<WebHookNotification>(container.GetInstance<IMetricsClient>()) });
            container.RegisterSingleton<IEnumerable<IQueueBehavior<MailMessage>>>(() => new[] { new MetricsQueueBehavior<MailMessage>(container.GetInstance<IMetricsClient>()) });
            container.RegisterSingleton<IEnumerable<IQueueBehavior<WorkItemData>>>(() => new[] { new MetricsQueueBehavior<WorkItemData>(container.GetInstance<IMetricsClient>()) });

            container.RegisterSingleton<IQueue<EventPost>>(() => new InMemoryQueue<EventPost>(behaviors: container.GetAllInstances<IQueueBehavior<EventPost>>()));
            container.RegisterSingleton<IQueue<EventUserDescription>>(() => new InMemoryQueue<EventUserDescription>(behaviors: container.GetAllInstances<IQueueBehavior<EventUserDescription>>()));
            container.RegisterSingleton<IQueue<EventNotificationWorkItem>>(() => new InMemoryQueue<EventNotificationWorkItem>(behaviors: container.GetAllInstances<IQueueBehavior<EventNotificationWorkItem>>()));
            container.RegisterSingleton<IQueue<WebHookNotification>>(() => new InMemoryQueue<WebHookNotification>(behaviors: container.GetAllInstances<IQueueBehavior<WebHookNotification>>()));
            container.RegisterSingleton<IQueue<MailMessage>>(() => new InMemoryQueue<MailMessage>(behaviors: container.GetAllInstances<IQueueBehavior<MailMessage>>()));
            
            var workItemHandlers = new WorkItemHandlers();
            workItemHandlers.Register<ReindexWorkItem>(container.GetInstance<ReindexWorkItemHandler>);
            workItemHandlers.Register<RemoveOrganizationWorkItem>(container.GetInstance<RemoveOrganizationWorkItemHandler>);
            workItemHandlers.Register<RemoveProjectWorkItem>(container.GetInstance<RemoveProjectWorkItemHandler>);
            workItemHandlers.Register<SetLocationFromGeoWorkItem>(container.GetInstance<SetLocationFromGeoWorkItemHandler>);
            workItemHandlers.Register<SetProjectIsConfiguredWorkItem>(container.GetInstance<SetProjectIsConfiguredWorkItemHandler>);
            workItemHandlers.Register<StackWorkItem>(container.GetInstance<StackWorkItemHandler>);
            workItemHandlers.Register<ThrottleBotsWorkItem>(container.GetInstance<ThrottleBotsWorkItemHandler>);
            workItemHandlers.Register<OrganizationMaintenanceWorkItem>(container.GetInstance<OrganizationMaintenanceWorkItemHandler>);
            workItemHandlers.Register<OrganizationNotificationWorkItem>(container.GetInstance<OrganizationNotificationWorkItemHandler>);
            workItemHandlers.Register<ProjectMaintenanceWorkItem>(container.GetInstance<ProjectMaintenanceWorkItemHandler>);
            container.RegisterSingleton<WorkItemHandlers>(workItemHandlers);
            container.RegisterSingleton<IQueue<WorkItemData>>(() => new InMemoryQueue<WorkItemData>(behaviors: container.GetAllInstances<IQueueBehavior<WorkItemData>>(), workItemTimeout: TimeSpan.FromHours(1)));

            container.RegisterSingleton<IMessageBus, InMemoryMessageBus>();
            container.RegisterSingleton<IMessagePublisher>(container.GetInstance<IMessageBus>);
            container.RegisterSingleton<IMessageSubscriber>(container.GetInstance<IMessageBus>);

            if (!String.IsNullOrEmpty(Settings.Current.StorageFolder))
                container.RegisterSingleton<IFileStorage>(new FolderFileStorage(Settings.Current.StorageFolder));
            else
                container.RegisterSingleton<IFileStorage>(new InMemoryFileStorage());

            container.RegisterSingleton<IStackRepository, StackRepository>();
            container.RegisterSingleton<IEventRepository, EventRepository>();
            container.RegisterSingleton<IOrganizationRepository, OrganizationRepository>();
            container.RegisterSingleton<IProjectRepository, ProjectRepository>();
            container.RegisterSingleton<IUserRepository, UserRepository>();
            container.RegisterSingleton<IWebHookRepository, WebHookRepository>();
            container.RegisterSingleton<ITokenRepository, TokenRepository>();
            container.RegisterSingleton<IApplicationRepository, ApplicationRepository>();

            container.RegisterSingleton<IGeoIpService, MaxMindGeoIpService>();
            container.RegisterSingleton<IGeocodeService, NullGeocodeService>();

            container.Register(typeof(IValidator<>), new[] { typeof(Bootstrapper).Assembly }, Lifestyle.Singleton);
            container.Register(typeof(ElasticRepositoryContext<>), typeof(ElasticRepositoryContext<>), Lifestyle.Singleton);

            container.RegisterSingleton<IEmailGenerator>(() => new RazorEmailGenerator(@"Mail\Templates"));
            container.RegisterSingleton<IMailer, Mailer>();
            if (Settings.Current.WebsiteMode != WebsiteMode.Dev)
                container.RegisterSingleton<IMailSender, SmtpMailSender>();
            else
                container.RegisterSingleton<IMailSender>(() => new InMemoryMailSender());

            container.RegisterSingleton<ILockProvider, CacheLockProvider>();
            container.Register<StripeEventHandler>();
            container.RegisterSingleton<BillingManager>();
            container.RegisterSingleton<SampleDataService>();
            container.RegisterSingleton<EventStats>();
            container.RegisterSingleton<EventPipeline>();
            container.RegisterSingleton<EventPluginManager>();
            container.RegisterSingleton<FormattingPluginManager>();
            container.RegisterSingleton<UserAgentParser>();

            container.RegisterSingleton<SystemHealthChecker>();

            container.RegisterSingleton<ICoreLastReferenceIdManager, NullCoreLastReferenceIdManager>();
            
            container.RegisterSingleton<IMapper>(() => {
                var profiles = container.GetAllInstances<Profile>();
                var config = new MapperConfiguration(cfg => {
                    cfg.ConstructServicesUsing(container.GetInstance);

                    foreach (var profile in profiles)
                        cfg.AddProfile(profile);
                });

                return config.CreateMapper();
            });
        }