diff --git a/src/Core/Services/IEventWriteService.cs b/src/Core/Services/IEventWriteService.cs new file mode 100644 index 0000000000..e2bf59d9a7 --- /dev/null +++ b/src/Core/Services/IEventWriteService.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.WindowsAzure.Storage.Table; + +namespace Bit.Core.Services +{ + public interface IEventWriteService + { + Task CreateAsync(ITableEntity entity); + Task CreateManyAsync(IList entities); + } +} diff --git a/src/Core/Services/Implementations/AzureQueueEventWriteService.cs b/src/Core/Services/Implementations/AzureQueueEventWriteService.cs new file mode 100644 index 0000000000..f47cf1d424 --- /dev/null +++ b/src/Core/Services/Implementations/AzureQueueEventWriteService.cs @@ -0,0 +1,46 @@ +using System.Threading.Tasks; +using Bit.Core.Repositories; +using System.Collections.Generic; +using Microsoft.WindowsAzure.Storage.Table; +using Microsoft.WindowsAzure.Storage; +using Microsoft.WindowsAzure.Storage.Queue; +using Newtonsoft.Json; + +namespace Bit.Core.Services +{ + public class AzureQueueEventWriteService : IEventWriteService + { + private readonly CloudQueue _queue; + private readonly GlobalSettings _globalSettings; + + private JsonSerializerSettings _jsonSettings = new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore + }; + + public AzureQueueEventWriteService( + IEventRepository eventRepository, + GlobalSettings globalSettings) + { + var storageAccount = CloudStorageAccount.Parse(globalSettings.Storage.ConnectionString); + var queueClient = storageAccount.CreateCloudQueueClient(); + + _queue = queueClient.GetQueueReference("event"); + _globalSettings = globalSettings; + } + + public async Task CreateAsync(ITableEntity entity) + { + var json = JsonConvert.SerializeObject(entity, _jsonSettings); + var message = new CloudQueueMessage(json); + await _queue.AddMessageAsync(message); + } + + public async Task CreateManyAsync(IList entities) + { + var json = JsonConvert.SerializeObject(entities, _jsonSettings); + var message = new CloudQueueMessage(json); + await _queue.AddMessageAsync(message); + } + } +} diff --git a/src/Core/Services/Implementations/EventService.cs b/src/Core/Services/Implementations/EventService.cs index 80e91475c9..e79ddfbc4e 100644 --- a/src/Core/Services/Implementations/EventService.cs +++ b/src/Core/Services/Implementations/EventService.cs @@ -12,18 +12,18 @@ namespace Bit.Core.Services { public class EventService : IEventService { - private readonly IEventRepository _eventRepository; + private readonly IEventWriteService _eventWriteService; private readonly IOrganizationUserRepository _organizationUserRepository; private readonly CurrentContext _currentContext; private readonly GlobalSettings _globalSettings; public EventService( - IEventRepository eventRepository, + IEventWriteService eventWriteService, IOrganizationUserRepository organizationUserRepository, CurrentContext currentContext, GlobalSettings globalSettings) { - _eventRepository = eventRepository; + _eventWriteService = eventWriteService; _organizationUserRepository = organizationUserRepository; _currentContext = currentContext; _globalSettings = globalSettings; @@ -48,11 +48,11 @@ namespace Bit.Core.Services if(orgEvents.Any()) { events.AddRange(orgEvents); - await _eventRepository.CreateManyAsync(events); + await _eventWriteService.CreateManyAsync(events); } else { - await _eventRepository.CreateAsync(events.First()); + await _eventWriteService.CreateAsync(events.First()); } } @@ -64,31 +64,31 @@ namespace Bit.Core.Services } var e = new CipherEvent(cipher, _currentContext?.UserId, type); - await _eventRepository.CreateAsync(e); + await _eventWriteService.CreateAsync(e); } public async Task LogCollectionEventAsync(Collection collection, EventType type) { var e = new CollectionEvent(collection, _currentContext.UserId.Value, type); - await _eventRepository.CreateAsync(e); + await _eventWriteService.CreateAsync(e); } public async Task LogGroupEventAsync(Group group, EventType type) { var e = new GroupEvent(group, _currentContext.UserId.Value, type); - await _eventRepository.CreateAsync(e); + await _eventWriteService.CreateAsync(e); } public async Task LogOrganizationUserEventAsync(OrganizationUser organizationUser, EventType type) { var e = new OrganizationUserEvent(organizationUser, _currentContext.UserId.Value, type); - await _eventRepository.CreateAsync(e); + await _eventWriteService.CreateAsync(e); } public async Task LogOrganizationEventAsync(Organization organization, EventType type) { var e = new OrganizationEvent(organization, _currentContext.UserId.Value, type); - await _eventRepository.CreateAsync(e); + await _eventWriteService.CreateAsync(e); } } } diff --git a/src/Core/Services/Implementations/RepositoryEventWriteService.cs b/src/Core/Services/Implementations/RepositoryEventWriteService.cs new file mode 100644 index 0000000000..959abda31f --- /dev/null +++ b/src/Core/Services/Implementations/RepositoryEventWriteService.cs @@ -0,0 +1,31 @@ +using System.Threading.Tasks; +using Bit.Core.Repositories; +using System.Collections.Generic; +using Microsoft.WindowsAzure.Storage.Table; + +namespace Bit.Core.Services +{ + public class RepositoryEventWriteService : IEventWriteService + { + private readonly IEventRepository _eventRepository; + private readonly GlobalSettings _globalSettings; + + public RepositoryEventWriteService( + IEventRepository eventRepository, + GlobalSettings globalSettings) + { + _eventRepository = eventRepository; + _globalSettings = globalSettings; + } + + public async Task CreateAsync(ITableEntity entity) + { + await _eventRepository.CreateAsync(entity); + } + + public async Task CreateManyAsync(IList entities) + { + await _eventRepository.CreateManyAsync(entities); + } + } +} diff --git a/src/Core/Utilities/ServiceCollectionExtensions.cs b/src/Core/Utilities/ServiceCollectionExtensions.cs index ac02feb530..671caa0780 100644 --- a/src/Core/Utilities/ServiceCollectionExtensions.cs +++ b/src/Core/Utilities/ServiceCollectionExtensions.cs @@ -105,10 +105,12 @@ namespace Bit.Core.Utilities if(!globalSettings.SelfHosted && CoreHelpers.SettingHasValue(globalSettings.Storage.ConnectionString)) { services.AddSingleton(); + services.AddSingleton(); } else { services.AddSingleton(); + services.AddSingleton(); } if(CoreHelpers.SettingHasValue(globalSettings.Attachment.ConnectionString))