using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Azure.Cosmos; using Microsoft.Azure.Functions.Worker; using Microsoft.Extensions.Logging; using System.Net; namespace CDP { public class FileRevision { private readonly ILogger _logger; private static Lazy lazyClient = new Lazy(InitializeCosmosClient); private static CosmosClient cosmosClient => lazyClient.Value; private static string DatabaseName = "CDP"; private static string ContainerName = "RevisionsContainer"; public FileRevision(ILogger logger) { _logger = logger; } private static CosmosClient InitializeCosmosClient() { // Perform any initialization here var uri = "https://cdplite.documents.azure.com:443/"; var authKey = "VPbg8RpzyI3XwhC2o0dIUtYFs33ghxORCqZeNAyg8vg4HWUBjM41BUxP0qLFXEvFh6ewQY1uKv52ACDbsEN1AQ=="; return new CosmosClient(uri, authKey); } static internal async Task AddRevisionInternal(AddRevisionDocumentDto doc, ILogger _logger) { try { Container container = cosmosClient.GetContainer(DatabaseName, ContainerName); _logger.LogInformation("container id: ", container); RevisionDocument document = new RevisionDocument() { //AppKey = doc.AppKey, //FileId = doc.FileId, RevisionId = doc.RevisionId, EditedBy = doc.EditedBy, Comments = doc.Comments, RevisionDate = doc.RevisionDate }; string id = Helpers.HashAndShortenText(doc.AppKey + doc.FileId); PartitionKey partitionKey = new PartitionKeyBuilder() .Add(doc.AppKey) .Add(doc.FileId) .Build(); var res = await AddOrUpdateRevision(container, id, partitionKey, document, doc.AppKey, doc.FileId); return new OkObjectResult(res); } catch (Exception ex) { _logger.LogError(ex.ToString()); return new StatusCodeResult(500); } } private async static Task AddOrUpdateRevision(Container container, string id, PartitionKey partitionKey, RevisionDocument document, string appKey, string fileId) { try { ItemResponse item = await container.ReadItemAsync(id, partitionKey); RevisionEntry revisions = item.Resource; revisions.FileRevisions.Add(document); ItemRequestOptions requestOptions = new ItemRequestOptions { IfMatchEtag = item.ETag }; var res = await container.UpsertItemAsync(revisions, partitionKey); return res.Resource; } catch (CosmosException ex) { if (ex.StatusCode == System.Net.HttpStatusCode.NotFound) { List revisions = new List { document }; RevisionEntry entry = new RevisionEntry() { AppKey = appKey, FileId = fileId, FileRevisions = revisions }; ItemResponse item = await container.CreateItemAsync(entry); return item.Resource; } else if (ex.StatusCode == HttpStatusCode.PreconditionFailed) { return await AddOrUpdateRevision(container, id, partitionKey, document, appKey, fileId); } else { throw ex; } } } } public class GetRevisionsDto { public required string AppKey { get; set; } public required string FileId { get; set; } } public class AddRevisionDocumentDto { public required string AppKey { get; set; } public required string FileId { get; set; } public required string RevisionId { get; set; } public required string EditedBy { get; set; } public required DateTime RevisionDate { get; set; } public required string Comments { get; set; } } public class RevisionDocument { public required string RevisionId { get; set; } public required string EditedBy { get; set; } public required DateTime RevisionDate { get; set; } public required string Comments { get; set; } } public class RevisionEntry { public string id { get { string s = Helpers.HashAndShortenText(AppKey + FileId); return s.Replace('/', '-'); } } public required string AppKey { get; set; } public required string FileId { get; set; } public List FileRevisions { get; set; } } }