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 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); } } }
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()); }
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)); }
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 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); } } }
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); }
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); } } }
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); } } }
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); }
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 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); }
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 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); } } }
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()); }); }
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)); } } } }
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>(); }
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 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); }
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>(); }
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()); }); }
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)); } } } }
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); }
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); } } }
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 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)); }
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()); }); }
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()); }); }
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(); }); }