From 992fac1328585d5daa5bfda541485aaa146d6ef4 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin <kyle.spearrin@gmail.com> Date: Thu, 14 Dec 2017 17:23:46 -0500 Subject: [PATCH] index table entity events --- src/Core/Models/Data/EventTableEntity.cs | 134 ++++++++---------- .../Repositories/SqlServer/EventRepository.cs | 8 +- src/EventsProcessor/Functions.cs | 14 +- 3 files changed, 75 insertions(+), 81 deletions(-) diff --git a/src/Core/Models/Data/EventTableEntity.cs b/src/Core/Models/Data/EventTableEntity.cs index 7b9e3a1cfa..8ba9f4cb3b 100644 --- a/src/Core/Models/Data/EventTableEntity.cs +++ b/src/Core/Models/Data/EventTableEntity.cs @@ -11,7 +11,7 @@ namespace Bit.Core.Models.Data { public EventTableEntity() { } - public EventTableEntity(IEvent e) + private EventTableEntity(IEvent e) { Date = e.Date; Type = e.Type; @@ -22,80 +22,6 @@ namespace Bit.Core.Models.Data GroupId = e.GroupId; OrganizationUserId = e.OrganizationUserId; ActingUserId = e.ActingUserId; - - switch(e.Type) - { - case EventType.User_LoggedIn: - case EventType.User_ChangedPassword: - case EventType.User_Enabled2fa: - case EventType.User_Disabled2fa: - case EventType.User_Recovered2fa: - case EventType.User_FailedLogIn: - case EventType.User_FailedLogIn2fa: - if(e.OrganizationId.HasValue) - { - PartitionKey = $"OrganizationId={OrganizationId}"; - RowKey = string.Format("Date={0}__UserId={1}__Type={2}", - CoreHelpers.DateTimeToTableStorageKey(Date), UserId, (int)Type); - } - else - { - PartitionKey = $"UserId={UserId}"; - RowKey = string.Format("Date={0}__Type={1}", - CoreHelpers.DateTimeToTableStorageKey(Date), (int)Type); - } - break; - case EventType.Cipher_Created: - case EventType.Cipher_Updated: - case EventType.Cipher_Deleted: - case EventType.Cipher_AttachmentCreated: - case EventType.Cipher_AttachmentDeleted: - case EventType.Cipher_Shared: - case EventType.Cipher_UpdatedCollections: - if(OrganizationId.HasValue) - { - PartitionKey = $"OrganizationId={OrganizationId}"; - RowKey = string.Format("Date={0}__CipherId={1}__ActingUserId={2}__Type={3}", - CoreHelpers.DateTimeToTableStorageKey(Date), CipherId, ActingUserId, (int)Type); - } - else - { - PartitionKey = $"UserId={UserId}"; - RowKey = string.Format("Date={0}__CipherId={1}__Type={2}", - CoreHelpers.DateTimeToTableStorageKey(Date), CipherId, (int)Type); - } - break; - case EventType.Collection_Created: - case EventType.Collection_Updated: - case EventType.Collection_Deleted: - PartitionKey = $"OrganizationId={OrganizationId}"; - RowKey = string.Format("Date={0}__ActingUserId={1}__Type={2}", - CoreHelpers.DateTimeToTableStorageKey(Date), ActingUserId, (int)Type); - break; - case EventType.Group_Created: - case EventType.Group_Updated: - case EventType.Group_Deleted: - PartitionKey = $"OrganizationId={OrganizationId}"; - RowKey = string.Format("Date={0}__ActingUserId={1}__Type={2}", - CoreHelpers.DateTimeToTableStorageKey(Date), ActingUserId, (int)Type); - break; - case EventType.OrganizationUser_Invited: - case EventType.OrganizationUser_Confirmed: - case EventType.OrganizationUser_Updated: - case EventType.OrganizationUser_Removed: - case EventType.OrganizationUser_UpdatedGroups: - PartitionKey = $"OrganizationId={OrganizationId}"; - RowKey = string.Format("Date={0}__ActingUserId={1}__Type={2}", - CoreHelpers.DateTimeToTableStorageKey(Date), ActingUserId, (int)Type); - break; - case EventType.Organization_Updated: - PartitionKey = $"OrganizationId={OrganizationId}"; - RowKey = string.Format("Date={0}__ActingUserId={1}__Type={2}", - CoreHelpers.DateTimeToTableStorageKey(Date), ActingUserId, (int)Type); - break; - default: - break; - } } public DateTime Date { get; set; } @@ -130,5 +56,63 @@ namespace Bit.Core.Models.Data Type = (EventType)properties[nameof(Type)].Int32Value; } } + + public static List<EventTableEntity> IndexEvent(IEvent e) + { + if(e.OrganizationId.HasValue) + { + return IndexOrgEvent(e); + } + else + { + return new List<EventTableEntity> { IndexUserEvent(e) }; + } + } + + private static List<EventTableEntity> IndexOrgEvent(IEvent e) + { + var uniquifier = Guid.NewGuid(); + var pKey = $"OrganizationId={e.OrganizationId}"; + var dateKey = CoreHelpers.DateTimeToTableStorageKey(e.Date); + + var entities = new List<EventTableEntity> + { + new EventTableEntity(e) + { + PartitionKey = pKey, + RowKey = string.Format("Date={0}__Uniquifier={1}", dateKey, uniquifier) + } + }; + + if(e.ActingUserId.HasValue) + { + entities.Add(new EventTableEntity(e) + { + PartitionKey = pKey, + RowKey = string.Format("ActingUserId={0}__Date={1}__Uniquifier={2}", e.ActingUserId, dateKey, uniquifier) + }); + } + + if(e.CipherId.HasValue) + { + entities.Add(new EventTableEntity(e) + { + PartitionKey = pKey, + RowKey = string.Format("CipherId={0}__Date={1}__Uniquifier={2}", e.CipherId, dateKey, uniquifier) + }); + } + + return entities; + } + + private static EventTableEntity IndexUserEvent(IEvent e) + { + var uniquifier = Guid.NewGuid(); + return new EventTableEntity(e) + { + PartitionKey = $"UserId={e.UserId}", + RowKey = string.Format("Date={0}__Uniquifier={1}", CoreHelpers.DateTimeToTableStorageKey(e.Date), uniquifier) + }; + } } } diff --git a/src/Core/Repositories/SqlServer/EventRepository.cs b/src/Core/Repositories/SqlServer/EventRepository.cs index d96d689d73..bbc40bc524 100644 --- a/src/Core/Repositories/SqlServer/EventRepository.cs +++ b/src/Core/Repositories/SqlServer/EventRepository.cs @@ -42,11 +42,17 @@ namespace Bit.Core.Repositories.SqlServer public async Task CreateManyAsync(IList<IEvent> entities) { - if(!entities.Any()) + if(!entities?.Any() ?? true) { return; } + if(entities.Count == 1) + { + await CreateAsync(entities.First()); + return; + } + using(var connection = new SqlConnection(ConnectionString)) { connection.Open(); diff --git a/src/EventsProcessor/Functions.cs b/src/EventsProcessor/Functions.cs index 77b2af2c8d..81491a38c7 100644 --- a/src/EventsProcessor/Functions.cs +++ b/src/EventsProcessor/Functions.cs @@ -39,18 +39,22 @@ namespace Bit.EventsProcessor try { + var events = new List<IEvent>(); + var token = JToken.Parse(message); if(token is JArray) { - var events = token.ToObject<List<EventMessage>>() - .Select(e => new EventTableEntity(e) as IEvent).ToList(); - await _eventWriteService.CreateManyAsync(events); + var indexedEntities = token.ToObject<List<EventMessage>>() + .SelectMany(e => EventTableEntity.IndexEvent(e)); + events.AddRange(indexedEntities); } else if(token is JObject) { - var e = token.ToObject<EventMessage>(); - await _eventWriteService.CreateAsync(new EventTableEntity(e)); + var eventMessage = token.ToObject<EventMessage>(); + events.AddRange(EventTableEntity.IndexEvent(eventMessage)); } + + await _eventWriteService.CreateManyAsync(events); } catch(JsonReaderException) {