You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
229 lines
8.9 KiB
229 lines
8.9 KiB
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Azure.Cosmos;
|
|
using Microsoft.Azure.Functions.Worker;
|
|
using Microsoft.Azure.Functions.Worker.Http;
|
|
using Microsoft.Extensions.Logging;
|
|
using Newtonsoft.Json;
|
|
using System.Net;
|
|
using FromBodyAttribute = Microsoft.Azure.Functions.Worker.Http.FromBodyAttribute;
|
|
|
|
namespace CDP
|
|
{
|
|
public class FileRevision
|
|
{
|
|
private readonly ILogger<FileRevision> _logger;
|
|
private static Lazy<CosmosClient> lazyClient = new Lazy<CosmosClient>(InitializeCosmosClient);
|
|
private static CosmosClient cosmosClient => lazyClient.Value;
|
|
private static string DatabaseName = "CDP";
|
|
private static string ContainerName = "RevisionsContainer";
|
|
|
|
public FileRevision(ILogger<FileRevision> 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);
|
|
}
|
|
|
|
public static async Task<RevisionEntry> GetFileRevisionInternal(string appKey, string fileId)
|
|
{
|
|
Container container = cosmosClient.GetContainer(DatabaseName, ContainerName);
|
|
string id = Helpers.HashAndShortenText(appKey + fileId);
|
|
PartitionKey key = new PartitionKeyBuilder().Add(appKey).Add(fileId).Build();
|
|
var item = await container.ReadItemAsync<RevisionEntry>(id, key);
|
|
return item.Resource;
|
|
}
|
|
|
|
static internal async Task<IActionResult> 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);
|
|
}
|
|
}
|
|
|
|
public async static Task<string> AddMailBodyRevision(RevisionDocument document, CompoundDocument compoundDocument, string AppKey, string FileId)
|
|
{
|
|
Container container = cosmosClient.GetContainer(DatabaseName, ContainerName);
|
|
List<RevisionDocument> documents = new List<RevisionDocument> { document };
|
|
RevisionEntry entry = new RevisionEntry
|
|
{
|
|
AppKey = AppKey,
|
|
FileId = FileId,
|
|
FileRevisions = documents,
|
|
CompoundDocument = compoundDocument
|
|
};
|
|
ItemResponse<RevisionEntry> item = await container.CreateItemAsync<RevisionEntry>(entry);
|
|
return item.Resource.id;
|
|
}
|
|
|
|
private async static Task<RevisionEntry> AddOrUpdateRevision(Container container, string id, PartitionKey partitionKey, RevisionDocument document, string appKey, string fileId)
|
|
{
|
|
try
|
|
{
|
|
ItemResponse<RevisionEntry> item = await container.ReadItemAsync<RevisionEntry>(id, partitionKey);
|
|
RevisionEntry revisions = item.Resource;
|
|
revisions.FileRevisions.Add(document);
|
|
ItemRequestOptions requestOptions = new ItemRequestOptions
|
|
{
|
|
IfMatchEtag = item.ETag
|
|
};
|
|
var res = await container.UpsertItemAsync<RevisionEntry>(revisions, partitionKey);
|
|
return res.Resource;
|
|
}
|
|
catch (CosmosException ex)
|
|
{
|
|
if (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
|
|
{
|
|
List<RevisionDocument> revisions = new List<RevisionDocument>
|
|
{
|
|
document
|
|
};
|
|
RevisionEntry entry = new RevisionEntry()
|
|
{
|
|
AppKey = appKey,
|
|
FileId = fileId,
|
|
FileRevisions = revisions
|
|
};
|
|
ItemResponse<RevisionEntry> item = await container.CreateItemAsync<RevisionEntry>(entry);
|
|
return item.Resource;
|
|
}
|
|
else if (ex.StatusCode == HttpStatusCode.PreconditionFailed)
|
|
{
|
|
return await AddOrUpdateRevision(container, id, partitionKey, document, appKey, fileId);
|
|
}
|
|
else
|
|
{
|
|
throw ex;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
#region Versioning Functions
|
|
|
|
[Function("AddRevisionDocument")]
|
|
public async Task<IActionResult> AddRevisionDocument([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req)
|
|
{
|
|
_logger.LogInformation("C# HTTP trigger function processed a request for update revision");
|
|
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
|
|
AddRevisionDocumentDto doc;
|
|
try
|
|
{
|
|
doc = JsonConvert.DeserializeObject<AddRevisionDocumentDto>(requestBody);
|
|
_logger.LogInformation(doc.RevisionId + doc.AppKey + doc.FileId);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex.ToString());
|
|
return new BadRequestObjectResult("Invalid request format");
|
|
}
|
|
|
|
return await AddRevisionInternal(doc, _logger);
|
|
}
|
|
|
|
[Function("GetFileRevisions")]
|
|
public async Task<IActionResult> GetFileRevisions([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req, [FromBody] GetRevisionsDto reqDto)
|
|
{
|
|
_logger.LogInformation("C# HTTP trigger function processed a request for update revision", JsonConvert.SerializeObject(reqDto));
|
|
|
|
try
|
|
{
|
|
|
|
var item = await GetFileRevisionInternal(reqDto.AppKey, reqDto.FileId);
|
|
if (item.CompoundDocument != null)
|
|
{
|
|
return new OkObjectResult(item);
|
|
}
|
|
List<RevisionDocument> revisions = item.FileRevisions;
|
|
//_logger.LogInformation("docs: {0}", JsonConvert.SerializeObject(revisions));
|
|
|
|
return new OkObjectResult(revisions);
|
|
}
|
|
catch (CosmosException ex) when (ex.StatusCode == HttpStatusCode.NotFound)
|
|
{
|
|
return new StatusCodeResult(404);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
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<RevisionDocument> FileRevisions { get; set; }
|
|
public CompoundDocument? CompoundDocument { get; set; }
|
|
}
|
|
public class CompoundDocument
|
|
{
|
|
public required string Id { get; set; }
|
|
public required string AppKey { get; set; }
|
|
public required string Contents { get; set; } //can be MailRecord below
|
|
public required string DocumentType { get; set; }
|
|
}
|
|
}
|