|
|
using Microsoft.Azure.Cosmos; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;
namespace CDP { public class GroupsDB { private static Lazy<CosmosClient> lazyClient = new Lazy<CosmosClient>(InitializeCosmosClient); private static CosmosClient cosmosClient => lazyClient.Value; private static string DatabaseName = "CDP"; private static string ContainerName = "Groups";
private static CosmosClient InitializeCosmosClient() { // Perform any initialization here
var uri = "https://cdplite.documents.azure.com:443/"; var authKey = "VPbg8RpzyI3XwhC2o0dIUtYFs33ghxORCqZeNAyg8vg4HWUBjM41BUxP0qLFXEvFh6ewQY1uKv52ACDbsEN1AQ==";
return new CosmosClient(uri, authKey); }
public static async Task<List<GroupsRecord>> GetUserGroups(string AppKey, string UserId) { var results = new List<GroupsRecord>(); Container container = cosmosClient.GetContainer(DatabaseName, ContainerName);
// Fetch the metadata document for the customer ID
var metadataDocumentId = GetMetaDocumentKey(AppKey, UserId); MetadataDocumentGroups metadataDocument = null; try { var metadataDocumentResponse = await container.ReadItemAsync<MetadataDocumentGroups>(metadataDocumentId, new PartitionKey(metadataDocumentId)); metadataDocument = metadataDocumentResponse.Resource; } catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound) { } catch (Exception e) { // Helpers.LogIt(e.Message);
}
if (metadataDocument == null) return results;
// Determine the partition keys within the date range
var partitionKeysInDocument = metadataDocument.PartitionKeys; // Fetch the audit records for each partition key within the date range
foreach (var partitionKey in partitionKeysInDocument) {
ItemResponse<GroupsDocument> response = await container.ReadItemAsync<GroupsDocument>(partitionKey, new PartitionKey(partitionKey)); if (response == null) continue;
GroupsDocument t = response.Resource; results.AddRange(t.Records); }
return results; }
public static async Task<bool> RemoveGroup(string appKey, string userId, string groupId) { Container container = cosmosClient.GetContainer(DatabaseName, ContainerName);
// Fetch the metadata document for the customer ID
var metadataDocumentId = GetMetaDocumentKey(appKey, userId); MetadataDocumentContact metadataDocument = null; try { var metadataDocumentResponse = await container.ReadItemAsync<MetadataDocumentContact>(metadataDocumentId, new PartitionKey(metadataDocumentId)); metadataDocument = metadataDocumentResponse.Resource; } catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound) { } catch (Exception e) { // Helpers.LogIt(e.Message);
}
if (metadataDocument == null) return false;
// Determine the partition keys within the date range
var partitionKeysInDocument = metadataDocument.PartitionKeys; // Fetch the audit records for each partition key within the date range
foreach (var partitionKey in partitionKeysInDocument) {
ItemResponse<GroupsDocument> response = await container.ReadItemAsync<GroupsDocument>(partitionKey, new PartitionKey(partitionKey)); if (response == null) continue;
GroupsDocument t = response.Resource; var originalCount = t.Records.Count; t.Records = t.Records.Where(item => item.id != groupId).ToList(); var afterFilterCount = t.Records.Count;
if (originalCount != afterFilterCount) { ItemResponse<GroupsDocument> updateResponse = await container.ReplaceItemAsync( item: t, id: t.id, partitionKey: new PartitionKey(partitionKey)); return true; } }
return false; }
public static async Task<bool> AppendGroup(string appKey, string userId, String grpName, string grpDescription, List<ContactRecord> rec) { try { var metadataDocument = await GetMetadataDocument(appKey, userId); if (metadataDocument == null) return false;
string dayKey = metadataDocument.GetLatestKey(appKey, userId); GroupsDocument al = await GetGroupDocument(dayKey); if (al == null) { al = new GroupsDocument(); al.AppKey = appKey; al.UserId = userId; } GroupsRecord gr = new GroupsRecord(grpName, grpDescription, rec); al.Records.Add(gr); await UpdateGroupsDocument(al); return true; } catch (Exception e) { return false; } }
public static async Task<bool> UpdateGroup(string appKey, string userId, string grpId, string grpName, string grpDescription, List<ContactRecord> contacts) { Container container = cosmosClient.GetContainer(DatabaseName, ContainerName);
// Fetch the metadata document for the customer ID
var metadataDocumentId = GetMetaDocumentKey(appKey, userId); MetadataDocumentContact metadataDocument = null; try { var metadataDocumentResponse = await container.ReadItemAsync<MetadataDocumentContact>(metadataDocumentId, new PartitionKey(metadataDocumentId)); metadataDocument = metadataDocumentResponse.Resource; } catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound) { } catch (Exception e) { // Helpers.LogIt(e.Message);
}
if (metadataDocument == null) return false;
// Determine the partition keys within the date range
var partitionKeysInDocument = metadataDocument.PartitionKeys; // Fetch the audit records for each partition key within the date range
foreach (var partitionKey in partitionKeysInDocument) {
ItemResponse<GroupsDocument> response = await container.ReadItemAsync<GroupsDocument>(partitionKey, new PartitionKey(partitionKey)); if (response == null) continue;
GroupsDocument t = response.Resource; bool groupFound = false; foreach (GroupsRecord gr in t.Records) { if (gr.id == grpId) { gr.Name = grpName != "" ? grpName : gr.Name; gr.Description = grpDescription != "" ? grpDescription : gr.Description; gr.Contacts = contacts; groupFound = true; break; } }
if (groupFound) { ItemResponse<GroupsDocument> updateResponse = await container.ReplaceItemAsync( item: t, id: t.id, partitionKey: new PartitionKey(partitionKey)); return true; } }
return false; }
public static async Task UpdateGroupsDocument(GroupsDocument al) { if (al.Records.Count == 0) return;
List<GroupsDocument> lal = await SplitUserGroups(al);
Container container = cosmosClient.GetContainer(DatabaseName, ContainerName);
foreach (GroupsDocument ial in lal) { ItemResponse<GroupsDocument> r = await container.UpsertItemAsync(ial, new PartitionKey(ial.id)); }
await UpdateMetadata(container, lal); }
static async Task UpdateMetadata(Container container, List<GroupsDocument> lal) { bool update = false; string pKey = GetMetaDocumentKey(lal[0].AppKey, lal[0].UserId); MetadataDocument md = null; try { ItemResponse<MetadataDocument> response = await container.ReadItemAsync<MetadataDocument>(pKey, new PartitionKey(pKey)); md = response.Resource; } catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound) { md = new MetadataDocument() { id = GetMetaDocumentKey(lal[0].AppKey, lal[0].UserId), PartitionKeys = new List<string>() }; } catch (Exception e) { // Helpers.LogIt(e.Message);
return; }
if (md == null) { // Helpers.LogIt("Something ugly happened!");
return; }
foreach (GroupsDocument log in lal) { if (md.PartitionKeys.Contains(log.id)) continue; md.PartitionKeys.Add(log.id); update = true; }
if (update) { try { ItemResponse<MetadataDocument> r = await container.UpsertItemAsync(md, new PartitionKey(pKey)); } catch (Exception e) { // Helpers.LogIt(e.Message);
return; } } }
static async Task<List<GroupsDocument>> SplitUserGroups(GroupsDocument al) { List<GroupsDocument> lal = new List<GroupsDocument>(); var sortedRecords = al.Records.OrderBy(record => record.EventTime).ToList();
var currentGroup = new List<GroupsRecord>(); var currentGroupSize = 0;
int MaxDocumentSizeInBytes = 2 * 1024 * 1024; // 2MB
int index = al.Index; // start for index passed in
foreach (var record in sortedRecords) { var recordSize = record.CalculateRecordSize();
if (currentGroupSize + recordSize > MaxDocumentSizeInBytes) { GroupsDocument i = new GroupsDocument(); i.Index = index++; i.Records = currentGroup; i.AppKey = al.AppKey; i.UserId = al.UserId; lal.Add(i);
currentGroup = new List<GroupsRecord>(); currentGroupSize = 0; }
currentGroup.Add(record); currentGroupSize += recordSize; }
if (currentGroup.Any()) { GroupsDocument i = new GroupsDocument(); i.Index = index++; i.Records = currentGroup; i.AppKey = al.AppKey; i.UserId = al.UserId; lal.Add(i); }
return lal; }
public static async Task<GroupsDocument> GetGroupDocument(string key) { try { Container container = cosmosClient.GetContainer(DatabaseName, ContainerName); ItemResponse<GroupsDocument> response = await container.ReadItemAsync<GroupsDocument>(key, new PartitionKey(key)); if (response == null) return null;
GroupsDocument t = response.Resource; return t; } catch (Exception e) { return null; } }
static async Task<MetadataDocumentGroups> GetMetadataDocument(string appKey, string userId) { MetadataDocumentGroups md = null; string pKey = GetMetaDocumentKey(appKey, userId); string id = GetDocumentId(appKey, userId);
PartitionKey partitionKey = new PartitionKeyBuilder() .Add(pKey) .Build(); Container container = cosmosClient.GetContainer(DatabaseName, ContainerName); try { ItemResponse<MetadataDocumentGroups> response = await container.ReadItemAsync<MetadataDocumentGroups>(pKey, partitionKey); md = response.Resource; } catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound) { md = new MetadataDocumentGroups() { id = id, PartitionKeys = new List<string>() }; } catch (Exception e) { // Helpers.LogIt(e.Message);
return null; }
if (md == null) { // Helpers.LogIt("Something ugly happened!");
return null; } return md; }
static string GetMetaDocumentKey(string appKey, string userId) { return $"{appKey}-{userId}-meta"; }
static string GetDocumentId(string appKey, string userId) { return $"{appKey}-{userId}"; } } }
|