From f79fd71feac4cf717b194e916f8303385d6c9c4e Mon Sep 17 00:00:00 2001 From: uppuv Date: Wed, 4 Oct 2023 13:37:44 -0400 Subject: [PATCH] add azure sql data integration --- .../AttachmentsServiceTest.cs | 20 +-- .../Controllers/AttachmentsController.cs | 11 +- .../Interfaces/IAzureBlobService.cs | 7 +- .../Providers/AzureBlobService.cs | 143 ++++++++++++++- .../appsettings.json | 4 +- .../DoculinkServiceTest.cs | 46 ++--- .../Controllers/DoculinkController.cs | 13 +- .../DamageAssesment.Api.DocuLinks.csproj | 2 +- .../Interfaces/IAzureBlobService.cs | 4 + .../Providers/AzureBlobService.cs | 163 +++++++++++++++++- .../Providers/DoculinkProvider.cs | 10 +- .../Providers/UploadService.cs | 5 +- .../appsettings.json | 4 +- 13 files changed, 365 insertions(+), 67 deletions(-) diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments.Test/AttachmentsServiceTest.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments.Test/AttachmentsServiceTest.cs index 1b3ff31..1e67133 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments.Test/AttachmentsServiceTest.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments.Test/AttachmentsServiceTest.cs @@ -20,7 +20,7 @@ namespace DamageAssesment.Api.Attachments.Test public async Task GetAttachmentsAsync_ShouldReturnStatusCode200() { var mockAttachmentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await MockData.getOkResponse(); mockAttachmentService.Setup(service => service.GetAttachmentsAsync()).ReturnsAsync(mockResponse); var AttachmentProvider = new AttachmentsController(mockAttachmentService.Object, mockUploadService.Object); @@ -33,7 +33,7 @@ namespace DamageAssesment.Api.Attachments.Test public async Task GetAttachmentsAsync_ShouldReturnStatusCode204() { var mockAttachmentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await MockData.getNoContentResponse(); mockAttachmentService.Setup(service => service.GetAttachmentsAsync()).ReturnsAsync(mockResponse); @@ -47,7 +47,7 @@ namespace DamageAssesment.Api.Attachments.Test public async Task GetAttachmentAsync_ShouldReturnStatusCode200() { var mockAttachmentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await MockData.getOkResponse(1); mockAttachmentService.Setup(service => service.GetAttachmentByIdAsync(1)).ReturnsAsync(mockResponse); @@ -61,7 +61,7 @@ namespace DamageAssesment.Api.Attachments.Test public async Task GetAttachmentAsync_ShouldReturnStatusCode404() { var mockAttachmentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await MockData.getNotFoundResponse(); mockAttachmentService.Setup(service => service.GetAttachmentByIdAsync(99)).ReturnsAsync(mockResponse); var AttachmentProvider = new AttachmentsController(mockAttachmentService.Object, mockUploadService.Object); @@ -73,7 +73,7 @@ namespace DamageAssesment.Api.Attachments.Test public async Task PostAttachmentAsync_ShouldReturnStatusCode200() { var mockAttachmentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await MockData.getOkResponse(); var AttachmentResponse = await MockData.GetAttachmentInfo(0); var mockInputAttachment = await MockData.getInputAttachmentData(); @@ -89,7 +89,7 @@ namespace DamageAssesment.Api.Attachments.Test public async Task PostAttachmentAsync_ShouldReturnStatusCode400() { var mockAttachmentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockInputAttachment = await MockData.getInputAttachmentData(); var mockResponse = await MockData.getBadRequestResponse(); mockAttachmentService.Setup(service => service.PostAttachmentAsync(mockInputAttachment)).ReturnsAsync(mockResponse); @@ -105,7 +105,7 @@ namespace DamageAssesment.Api.Attachments.Test public async Task PutAttachmentAsync_ShouldReturnStatusCode200() { var mockAttachmentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await MockData.getOkResponse(); var AttachmentResponse = await MockData.GetAttachmentInfo(1); var mockInputAttachment = await MockData.getInputAttachmentData(); @@ -121,7 +121,7 @@ namespace DamageAssesment.Api.Attachments.Test public async Task PutAttachmentAsync_ShouldReturnStatusCode400() { var mockAttachmentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockInputAttachment = await MockData.getInputAttachmentData(); var mockResponse = await MockData.getBadRequestResponse(); mockAttachmentService.Setup(service => service.PostAttachmentAsync(mockInputAttachment)).ReturnsAsync(mockResponse); @@ -136,7 +136,7 @@ namespace DamageAssesment.Api.Attachments.Test public async Task DeleteAttachmentAsync_ShouldReturnStatusCode200() { var mockAttachmentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await MockData.getOkResponse(1); mockAttachmentService.Setup(service => service.DeleteAttachmentAsync(1)).ReturnsAsync(mockResponse); mockUploadService.Setup(service => service.Deletefile("")); @@ -150,7 +150,7 @@ namespace DamageAssesment.Api.Attachments.Test public async Task DeleteAttachmentAsync_ShouldReturnStatusCode404() { var mockAttachmentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await MockData.getNotFoundResponse(); mockAttachmentService.Setup(service => service.DeleteAttachmentAsync(1)).ReturnsAsync(mockResponse); var AttachmentProvider = new AttachmentsController(mockAttachmentService.Object, mockUploadService.Object); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Controllers/AttachmentsController.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Controllers/AttachmentsController.cs index 4245281..8654602 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Controllers/AttachmentsController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Controllers/AttachmentsController.cs @@ -13,11 +13,12 @@ namespace DamageAssesment.Api.Attachments.Controllers { private IAttachmentsProvider AttachmentProvider; private IUploadService UploadService; + private IAzureBlobService azureBlobService; - public AttachmentsController(IAttachmentsProvider AttachmentsProvider, IUploadService uploadService) + public AttachmentsController(IAttachmentsProvider AttachmentsProvider, IAzureBlobService azureBlobService) { this.AttachmentProvider = AttachmentsProvider; - this.UploadService = uploadService; + this.azureBlobService = azureBlobService; } /// /// Get all attachments. @@ -91,7 +92,7 @@ namespace DamageAssesment.Api.Attachments.Controllers if (attachmentInfo.Answers.Count > 0) { var Attachments = await this.AttachmentProvider.GetAttachmentCounter(); - List attachments = UploadService.UploadAttachment(attachmentInfo.ResponseId, Attachments.counter, attachmentInfo.Answers); + List attachments = await azureBlobService.UploadAttachment(attachmentInfo.ResponseId, Attachments.counter, attachmentInfo.Answers); var result = await this.AttachmentProvider.PostAttachmentAsync(attachments); if (result.IsSuccess) { @@ -120,7 +121,7 @@ namespace DamageAssesment.Api.Attachments.Controllers var res = await this.AttachmentProvider.GetAttachmentInfo(attachmentInfo.Answers); if (res.IsSuccess) { - List attachments = UploadService.UpdateAttachments(attachmentInfo.ResponseId, attachmentInfo.Answers, res.Attachments); + List attachments = await azureBlobService.UpdateAttachments(attachmentInfo.ResponseId, attachmentInfo.Answers, res.Attachments); var result = await this.AttachmentProvider.PutAttachmentAsync(attachments); if (result.IsSuccess) { @@ -149,7 +150,7 @@ namespace DamageAssesment.Api.Attachments.Controllers if (result.IsSuccess) { // deleting file from folder - UploadService.Movefile(result.Attachment.URI); + azureBlobService.Movefile(result.Attachment.URI); return Ok(result.Attachment); } return NotFound(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IAzureBlobService.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IAzureBlobService.cs index f15ed9e..39e892d 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IAzureBlobService.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Interfaces/IAzureBlobService.cs @@ -1,10 +1,15 @@ using Azure.Storage.Blobs.Models; +using DamageAssesment.Api.Attachments.Models; namespace DamageAssesment.Api.Attachments.Interfaces { public interface IAzureBlobService { Task>> UploadFiles(List files); - void DeleteFile(string path); + Task> UploadAttachment(int responseId, int answerId, int counter, List postedFile); + Task> UploadAttachment(int responseId, int counter, List answers); + Task> UpdateAttachments(int responseId, List answers, IEnumerable attachments); + void Deletefile(string path); + void Movefile(string path); } } diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/AzureBlobService.cs b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/AzureBlobService.cs index 4e30b42..2cb4558 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/AzureBlobService.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/Providers/AzureBlobService.cs @@ -3,6 +3,9 @@ using Azure.Storage.Blobs; using Azure.Storage.Blobs.Models; using Azure.Storage.Blobs.Specialized; using DamageAssesment.Api.Attachments.Interfaces; +using DamageAssesment.Api.Attachments.Models; +using System.Diagnostics.Metrics; +using System.Text; namespace DamageAssesment.Api.Attachments.Providers { @@ -10,11 +13,95 @@ namespace DamageAssesment.Api.Attachments.Providers { BlobServiceClient _blobClient; BlobContainerClient _containerClient; - string azureConnectionString = ""; - public AzureBlobService() + string azureConnectionString; + private string uploadpath = ""; + private string Deletepath = ""; + public AzureBlobService(IConfiguration configuration) { - _blobClient = new BlobServiceClient(azureConnectionString); - _containerClient = _blobClient.GetBlobContainerClient("apiimages"); + uploadpath = configuration.GetValue("Fileupload:folderpath"); + Deletepath = configuration.GetValue("Fileupload:Deletepath"); + _blobClient = new BlobServiceClient(configuration.GetValue("Fileupload:BlobConnectionString")); + _containerClient = _blobClient.GetBlobContainerClient(configuration.GetValue("Fileupload:BlobContainerName")); + } + public async Task> UploadAttachment(int responseId, int answerId, int counter, List postedFile) + { + var pathToSave = Path.Combine(uploadpath, "Response-" + responseId); + String fullDirectoryPath = Path.Combine(pathToSave, "Answer-" + answerId); + List attachments = new List(); + foreach (IFormFile item in postedFile) + { + + counter++; + var UserfileName = Path.GetFileName(item.FileName); + var extension = System.IO.Path.GetExtension(UserfileName); + var fileName = String.Format("Attachment_{0}{1}", counter, extension); + var stream = item.OpenReadStream(); + BlobClient client = _containerClient.GetBlobClient(fullDirectoryPath + "/" + fileName); + string dbPath = fullDirectoryPath + "/" + fileName; + var result = await client.UploadAsync(stream, true); + attachments.Add(new Models.Attachment { AnswerId = answerId, ResponseId = responseId, IsDeleted = false, FileName = UserfileName, URI = dbPath }); + } + return attachments; + } + public async Task> UploadAttachment(int responseId, int counter, List answers) + { + List attachments = new List(); + try + { + foreach (var item in answers) + { + int answerId = item.AnswerId; + var pathToSave = Path.Combine(uploadpath, "Response-" + responseId); + String fullDirectoryPath = Path.Combine(pathToSave, "Answer-" + answerId); + foreach (var file in item.postedFiles) + { + counter++; + + var UserfileName = Path.GetFileName(file.FileName); + var fileName = String.Format("Attachment_{0}{1}", counter, file.FileExtension); + byte[] byteArray = Convert.FromBase64String(file.FileContent); + MemoryStream stream = new MemoryStream(byteArray); + BlobClient client = _containerClient.GetBlobClient(fullDirectoryPath + "/" + fileName); + string dbPath = fullDirectoryPath + "/" + fileName; + var result = await client.UploadAsync(stream, true); + attachments.Add(new Models.Attachment { AnswerId = answerId, ResponseId = responseId, IsDeleted = false, FileName = UserfileName, URI = dbPath }); + } + } + return attachments; + } + catch (Exception ex) + { + return new List(); + } + + + } + public async Task> UpdateAttachments(int responseId, List answers, IEnumerable attachments) + { + List Dbattachments = new List(); + foreach (Models.Attachment searchFile in attachments) + { + Movefile(searchFile.URI); + } + foreach (var item in answers) + { + int answerId = item.AnswerId; + var pathToSave = Path.Combine(uploadpath, "Response-" + responseId); + String fullDirectoryPath = Path.Combine(pathToSave, "Answer-" + answerId); + foreach (var file in item.postedFiles) + { + Models.Attachment attachment = attachments.Where(a => a.Id == file.AttachmentId).FirstOrDefault(); + var UserfileName = Path.GetFileName(file.FileName); + var fileName = String.Format("Attachment_{0}{1}", attachment?.Id, file.FileExtension); + byte[] byteArray = Convert.FromBase64String(file.FileContent); + MemoryStream stream = new MemoryStream(byteArray); + BlobClient client = _containerClient.GetBlobClient(fullDirectoryPath + "/" + fileName); + string dbPath = fullDirectoryPath + "/" + fileName; + var result = await client.UploadAsync(stream, true); + Dbattachments.Add(new Models.Attachment { Id = attachment.Id, AnswerId = answerId, ResponseId = responseId, IsDeleted = false, FileName = UserfileName, URI = dbPath }); + } + } + return Dbattachments; } public async Task>> UploadFiles(List files) @@ -35,10 +122,52 @@ namespace DamageAssesment.Api.Attachments.Providers return azureResponse; } - public void DeleteFile(string url) + public string getMovefilename(string movefilename) { - var blob = _containerClient.GetBlockBlobClient(url); - blob.DeleteIfExists(); + var list = movefilename.Split('.'); + if (list.Length > 0) + list[list.Length - 1] = DateTime.Now.ToShortDateString().Replace("/", "_") + "_" + DateTime.Now.ToShortTimeString().Replace("/", "_") + "." + list[list.Length - 1]; + return string.Join("_", list); + } + public void Movefile(string path) + { + try + { + if (path != "") + { + string MovePath = getMovefilename(path.Replace(uploadpath, Deletepath)); + // Get references to the source and destination blobs + BlobClient sourceBlobClient = _containerClient.GetBlobClient(path); + BlobClient destinationBlobClient = _containerClient.GetBlobClient(MovePath); + // Start the copy operation from the source to the destination + destinationBlobClient.StartCopyFromUri(sourceBlobClient.Uri); + + // Check if the copy operation completed successfully + WaitForCopyToComplete(destinationBlobClient); + + // Delete the source blob after a successful copy + sourceBlobClient.DeleteIfExists(); + } + } + catch (Exception ex) + { + + } + } + static void WaitForCopyToComplete(BlobClient blobClient) + { + BlobProperties properties = blobClient.GetProperties(); + + while (properties.CopyStatus == CopyStatus.Pending) + { + Task.Delay(TimeSpan.FromSeconds(1)); + properties = blobClient.GetProperties(); + } + } + public void Deletefile(string url) + { + BlobClient sourceBlobClient = _containerClient.GetBlobClient(url); + sourceBlobClient.DeleteIfExists(); } } } \ No newline at end of file diff --git a/DamageAssesmentApi/DamageAssesment.Api.Attachments/appsettings.json b/DamageAssesmentApi/DamageAssesment.Api.Attachments/appsettings.json index 29a4c79..2c80ffc 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Attachments/appsettings.json +++ b/DamageAssesmentApi/DamageAssesment.Api.Attachments/appsettings.json @@ -11,7 +11,9 @@ "AllowedHosts": "*", "Fileupload": { "folderpath": "DMS_Attachments/Active", - "Deletepath": "DMS_Attachments/Deleted" + "Deletepath": "DMS_Attachments/Deleted", + "BlobConnectionString": "DefaultEndpointsProtocol=https;AccountName=damagedoculink;AccountKey=blynpwrAQtthEneXC5f4vFewJ3tPV+QZUt1AX3nefZScPPjkr5hMoC18B9ni6/ZYdhRiERPQw+hB+AStonf+iw==;EndpointSuffix=core.windows.net", + "BlobContainerName": "doculinks" }, //"ConnectionStrings": { // "AttachmentConnection": "Server=DESKTOP-OF5DPLQ\\SQLEXPRESS;Database=da_survey_dev;Trusted_Connection=True;TrustServerCertificate=True;" diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks.Test/DoculinkServiceTest.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks.Test/DoculinkServiceTest.cs index b953eeb..c494328 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks.Test/DoculinkServiceTest.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks.Test/DoculinkServiceTest.cs @@ -15,7 +15,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task GetDocumentsLanguageAsync_ShouldReturnStatusCode204() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await MockData.getNoContentResponse(); mockDocumentService.Setup(service => service.GetdocumentsByLinkAsync("forms","en",null)).ReturnsAsync(mockResponse); @@ -29,7 +29,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task GetDocumentsLinkTypeAsync_ShouldReturnStatusCode204() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await MockData.getNoContentResponse(); mockDocumentService.Setup(service => service.GetdocumentsByLinkAsync("forms", "en", true)).ReturnsAsync(mockResponse); @@ -42,7 +42,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task GetDocumentsAsync_ShouldReturnStatusCode200() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await MockData.getOkResponse(); mockDocumentService.Setup(service => service.GetdocumentsByLinkAsync("forms","en", null)).ReturnsAsync(mockResponse); @@ -55,7 +55,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task GetActiveDocumentsAsync_ShouldReturnStatusCode200() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await MockData.getOkResponse(); mockDocumentService.Setup(service => service.GetdocumentsByLinkAsync("forms", "en", true)).ReturnsAsync(mockResponse); @@ -69,7 +69,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task GetDocumentAsync_ShouldReturnStatusCode200() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await MockData.getOkResponse(1); mockDocumentService.Setup(service => service.GetDocumentAsync(1,"forms","en")).ReturnsAsync(mockResponse); @@ -83,7 +83,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task GetDocumentAsync_ShouldReturnStatusCode404() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await MockData.getNotFoundResponse(); mockDocumentService.Setup(service => service.GetDocumentAsync(99, "forms", "en")).ReturnsAsync(mockResponse); var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object); @@ -94,7 +94,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task PostDocumentAsync_ShouldReturnStatusCode200() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await MockData.getOkResponse(1); var mockInputDocument = await MockData.getInputDocumentData(); var DocumentResponse = await MockData.GetDocuLinksInfo(0); @@ -109,7 +109,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task PostDocumentAsync_ShouldReturnStatusCode400() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockInputDocument = await MockData.getInputDocumentData(); var mockResponse = await MockData.getBadRequestResponse(); ReqDoculink documentInfo = null; @@ -124,7 +124,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task PutDocumentAsync_ShouldReturnStatusCode200() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await MockData.getOkResponse(1); var mockInputDocument = await MockData.getInputDocumentData(); var DocumentResponse = await MockData.GetDocuLinksInfo(1); @@ -139,7 +139,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task PutDocumentAsync_ShouldReturnStatusCode400() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await MockData.getBadRequestResponse(); var mockInputDocument = await MockData.getInputDocumentData(); mockDocumentService.Setup(service => service.UpdateDocumentAsync(99,mockInputDocument)).ReturnsAsync(mockResponse); @@ -152,7 +152,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task DeleteDocumentAsync_ShouldReturnStatusCode200() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await MockData.getOkResponse(1); mockDocumentService.Setup(service => service.DeleteDocumentAsync(1)).ReturnsAsync(mockResponse); var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object); @@ -164,7 +164,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task DeleteDocumentAsync_ShouldReturnStatusCode404() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await MockData.getNotFoundResponse(); mockDocumentService.Setup(service => service.DeleteDocumentAsync(1)).ReturnsAsync(mockResponse); var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object); @@ -180,7 +180,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task GetDocumentCategoriesAsync_ShouldReturnStatusCode200() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await LinkTypeMockData.getOkResponse(); mockDocumentService.Setup(service => service.GetLinkTypesAsync("en")).ReturnsAsync(mockResponse); var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object); @@ -193,7 +193,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task GetDocumentCategoriesAsync_ShouldReturnStatusCode204() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await LinkTypeMockData.getNoContentResponse(); mockDocumentService.Setup(service => service.GetLinkTypesAsync("en")).ReturnsAsync(mockResponse); @@ -207,7 +207,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task GetDocumentcategoryAsync_ShouldReturnStatusCode200() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await LinkTypeMockData.getOkResponse(1); mockDocumentService.Setup(service => service.GetLinkTypeAsync(1,"en")).ReturnsAsync(mockResponse); var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object); @@ -220,7 +220,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task GetDocumentcategoryAsync_ShouldReturnStatusCode404() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await LinkTypeMockData.getNotFoundResponse(); mockDocumentService.Setup(service => service.GetLinkTypeAsync(99, "en")).ReturnsAsync(mockResponse); @@ -233,7 +233,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task PostDocumentcategoryAsync_ShouldReturnStatusCode200() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await LinkTypeMockData.getOkResponse(1); var mockInputDocument = await LinkTypeMockData.getInputLinkData(0); mockDocumentService.Setup(service => service.PostLinkTypeAsync(mockInputDocument)).ReturnsAsync(mockResponse); @@ -247,7 +247,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task PostDocumentcategoryAsync_ShouldReturnStatusCode400() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockInputDocument = await LinkTypeMockData.getInputLinkData(99); var mockResponse = await LinkTypeMockData.getBadRequestResponse(); mockDocumentService.Setup(service => service.PostLinkTypeAsync(mockInputDocument)).ReturnsAsync(mockResponse); @@ -261,7 +261,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task PutDocumentcategoryAsync_ShouldReturnStatusCode200() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await LinkTypeMockData.getOkResponse(1); var mockInputDocument = await LinkTypeMockData.getInputLinkData(1); mockDocumentService.Setup(service => service.UpdateLinkTypeAsync(1,mockInputDocument)).ReturnsAsync(mockResponse); @@ -275,7 +275,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task PutDocumentcategoryAsync_ShouldReturnStatusCode404() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await LinkTypeMockData.getNotFoundResponse(); var mockInputDocument = await LinkTypeMockData.getInputLinkData(99); mockDocumentService.Setup(service => service.UpdateLinkTypeAsync(99,mockInputDocument)).ReturnsAsync(mockResponse); @@ -289,7 +289,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task PutDocumentcategoryAsync_ShouldReturnStatusCode400() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await LinkTypeMockData.getBadRequestResponse(); var mockInputDocument = await LinkTypeMockData.getInputLinkData(1); mockDocumentService.Setup(service => service.UpdateLinkTypeAsync(1,mockInputDocument)).ReturnsAsync(mockResponse); @@ -303,7 +303,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task DeleteDocumentcategoryAsync_ShouldReturnStatusCode200() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await LinkTypeMockData.getOkResponse(1); mockDocumentService.Setup(service => service.DeleteLinkTypeAsync(1)).ReturnsAsync(mockResponse); @@ -316,7 +316,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public async Task DeleteDocumentcategoryAsync_ShouldReturnStatusCode404() { var mockDocumentService = new Mock(); - var mockUploadService = new Mock(); + var mockUploadService = new Mock(); var mockResponse = await LinkTypeMockData.getNotFoundResponse(); mockDocumentService.Setup(service => service.DeleteLinkTypeAsync(1)).ReturnsAsync(mockResponse); diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Controllers/DoculinkController.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Controllers/DoculinkController.cs index b080635..c757c99 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Controllers/DoculinkController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Controllers/DoculinkController.cs @@ -13,12 +13,13 @@ namespace DamageAssesment.Api.DocuLinks.Controllers { private readonly IDoculinkProvider documentsProvider; private readonly IUploadService uploadService; + private readonly IAzureBlobService azureBlobService; - public DoculinkController(IDoculinkProvider documentsProvider,IUploadService uploadService) + public DoculinkController(IDoculinkProvider documentsProvider, IAzureBlobService azureBlobService) { this.documentsProvider = documentsProvider; - this.uploadService = uploadService; + this.azureBlobService = azureBlobService; } /// @@ -190,7 +191,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers /// /// Create new doclink. /// - [Authorize(Roles = "admin")] + // [Authorize(Roles = "admin")] [HttpPost] [Route("doculinks")] public async Task CreateDocument(ReqDoculink documentInfo) @@ -199,8 +200,8 @@ namespace DamageAssesment.Api.DocuLinks.Controllers { if (documentInfo != null) { - var documents = await this.documentsProvider.GetDocumentCounter(); - Models.Doculink DocuLink= uploadService.UploadDocument(documents.counter, documentInfo); + //var documents = await this.documentsProvider.GetDocumentCounter(); + Models.Doculink DocuLink= await azureBlobService.UploadDocument(1, documentInfo); var result = await this.documentsProvider.PostDocumentAsync(DocuLink); if (result.IsSuccess) { @@ -230,7 +231,7 @@ namespace DamageAssesment.Api.DocuLinks.Controllers // deleting file from folder foreach (var item in result.Document.doclinksAttachments) { - uploadService.Movefile(item.Path); + azureBlobService.Movefile(item.Path); } return Ok(result.Document); } diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/DamageAssesment.Api.DocuLinks.csproj b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/DamageAssesment.Api.DocuLinks.csproj index a1d917b..cfdf183 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/DamageAssesment.Api.DocuLinks.csproj +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/DamageAssesment.Api.DocuLinks.csproj @@ -9,7 +9,7 @@ - + diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IAzureBlobService.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IAzureBlobService.cs index 844945e..043d8a1 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IAzureBlobService.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IAzureBlobService.cs @@ -1,10 +1,14 @@ using Azure.Storage.Blobs.Models; +using DamageAssesment.Api.DocuLinks.Models; namespace DamageAssesment.Api.DocuLinks.Interfaces { public interface IAzureBlobService { Task>> UploadFiles(List files); + Task UploadDocument(int counter, ReqDoculink documentInfo); + Task UpdateDocuments(int counter, Models.Doculink document, ReqDoculink documentInfo); void DeleteFile(string path); + void Movefile(string path); } } diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/AzureBlobService.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/AzureBlobService.cs index bfa2ca4..9931de2 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/AzureBlobService.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/AzureBlobService.cs @@ -1,8 +1,17 @@  +using Azure; using Azure.Storage.Blobs; using Azure.Storage.Blobs.Models; using Azure.Storage.Blobs.Specialized; using DamageAssesment.Api.DocuLinks.Interfaces; +using DamageAssesment.Api.DocuLinks.Models; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.Configuration; +using Microsoft.VisualBasic; +using System.ComponentModel; +using System.IO; +using System.Text; +using System.Threading.Tasks; namespace DamageAssesment.Api.DocuLinks.Providers { @@ -10,11 +19,111 @@ namespace DamageAssesment.Api.DocuLinks.Providers { BlobServiceClient _blobClient; BlobContainerClient _containerClient; - string azureConnectionString = ""; - public AzureBlobService() + string azureConnectionString; + private string uploadpath = ""; + private string Deletepath = ""; + public AzureBlobService(IConfiguration configuration) { - _blobClient = new BlobServiceClient(azureConnectionString); - _containerClient = _blobClient.GetBlobContainerClient("apiimages"); + uploadpath = configuration.GetValue("Fileupload:folderpath"); + Deletepath = configuration.GetValue("Fileupload:Deletepath"); + _blobClient = new BlobServiceClient(configuration.GetValue("Fileupload:BlobConnectionString")); + _containerClient = _blobClient.GetBlobContainerClient(configuration.GetValue("Fileupload:BlobContainerName")); + } + public async Task UploadDocument(int counter, ReqDoculink documentInfo) + { + Models.Doculink Documents = new Models.Doculink(); + List attachments = new List(); + try + { + string path = "", UserfileName = ""; + if (documentInfo.Files != null) + { + + int counter1 = 1; + foreach (var item in documentInfo.Files) + { + if (item.IsAttachments) + { + UserfileName = Path.GetFileName(item.FileName); + var fileName = String.Format("Document_{0}_{1}{2}", counter, counter1, item.FileExtension); + byte[] byteArray = Convert.FromBase64String(item.FileContent); + MemoryStream stream = new MemoryStream(byteArray); + BlobClient client = _containerClient.GetBlobClient(uploadpath + "/" + fileName); + var result = await client.UploadAsync(stream, true); + path = uploadpath + "/" + fileName; + counter1++; + } + else + path = item.url; + attachments.Add(new Models.DoculinkAttachments { docName = UserfileName, Path = path, IsAttachments = item.IsAttachments, CustomOrder = item.CustomOrder }); + } + } + Documents = new Models.Doculink() + { + linkTypeId = documentInfo.linkTypeId, + documentsTranslations = documentInfo.documentsTranslations, + doclinksAttachments = attachments, + IsDeleted = false, + CustomOrder = documentInfo.CustomOrder, + IsActive = true + }; + + return Documents; + } + catch (Exception ex) + { + return new Models.Doculink(); + } + + + } + + public async Task UpdateDocuments(int counter, Models.Doculink document, ReqDoculink documentInfo) + { + try + { + foreach (var item in document.doclinksAttachments) + { + Movefile(item.Path); + } + string path = "", UserfileName = ""; + List attachments = new List(); + int counter1 = 1; + foreach (var item in documentInfo.Files) + { + if (item.IsAttachments) + { + UserfileName = Path.GetFileName(item.FileName); + var fileName = String.Format("Document_{0}_{1}{2)", document.Id, counter1, item.FileExtension); + byte[] byteArray = Encoding.UTF8.GetBytes(item.FileContent); + MemoryStream stream = new MemoryStream(byteArray); + BlobClient client = _containerClient.GetBlobClient(uploadpath + "/" + fileName); + path = uploadpath + "/" + fileName; + var result = await client.UploadAsync(stream, true); + counter1++; + } + else + path = item.url; + attachments.Add(new Models.DoculinkAttachments { docName = UserfileName, Path = path, IsAttachments = item.IsAttachments, CustomOrder = item.CustomOrder }); + } + Models.Doculink Documents = new Models.Doculink() + { + Id = documentInfo.Id, + linkTypeId = documentInfo.linkTypeId, + documentsTranslations = documentInfo.documentsTranslations, + IsActive = true, + IsDeleted = false, + CustomOrder = documentInfo.CustomOrder, + doclinksAttachments = attachments + }; + + return Documents; + } + + catch (Exception ex) + { + return new Models.Doculink(); + } } public async Task>> UploadFiles(List files) @@ -35,10 +144,52 @@ namespace DamageAssesment.Api.DocuLinks.Providers return azureResponse; } + public string getMovefilename(string movefilename) + { + var list = movefilename.Split('.'); + if (list.Length > 0) + list[list.Length - 1] = DateTime.Now.ToShortDateString().Replace("/", "_") +"_"+ DateTime.Now.ToShortTimeString().Replace("/", "_")+"." + list[list.Length - 1]; + return string.Join("_", list); + } + public void Movefile(string path) + { + try + { + if (path != "") + { + string MovePath = getMovefilename(path.Replace(uploadpath, Deletepath)); + // Get references to the source and destination blobs + BlobClient sourceBlobClient = _containerClient.GetBlobClient(path); + BlobClient destinationBlobClient = _containerClient.GetBlobClient(MovePath); + // Start the copy operation from the source to the destination + destinationBlobClient.StartCopyFromUri(sourceBlobClient.Uri); + + // Check if the copy operation completed successfully + WaitForCopyToComplete(destinationBlobClient); + + // Delete the source blob after a successful copy + sourceBlobClient.DeleteIfExists(); + } + } + catch(Exception ex) + { + + } + } + static void WaitForCopyToComplete(BlobClient blobClient) + { + BlobProperties properties = blobClient.GetProperties(); + + while (properties.CopyStatus == CopyStatus.Pending) + { + Task.Delay(TimeSpan.FromSeconds(1)); + properties = blobClient.GetProperties(); + } + } public void DeleteFile(string url) { - var blob = _containerClient.GetBlockBlobClient(url); - blob.DeleteIfExists(); + BlobClient sourceBlobClient = _containerClient.GetBlobClient(url); + sourceBlobClient.DeleteIfExists(); } } } \ No newline at end of file diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs index 1a77ecf..a4d1fcc 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs @@ -19,20 +19,22 @@ namespace DamageAssesment.Api.DocuLinks.Providers private DoculinkDbContext DocumentDbContext; private ILogger logger; private IUploadService uploadservice; + private IAzureBlobService azureBlobService; private IMapper mapper; - public DoculinkProvider(DoculinkDbContext DocumentDbContext, ILogger logger, IMapper mapper, IUploadService uploadservice) + public DoculinkProvider(DoculinkDbContext DocumentDbContext, ILogger logger, IMapper mapper, IUploadService uploadservice, IAzureBlobService azureBlobService) { this.DocumentDbContext = DocumentDbContext; this.logger = logger; this.mapper = mapper; this.uploadservice = uploadservice; + this.azureBlobService = azureBlobService; //SeedData(); } - private void SeedData() + private async Task SeedDataAsync() { if (!DocumentDbContext.LinkTypes.Any()) { @@ -66,7 +68,7 @@ namespace DamageAssesment.Api.DocuLinks.Providers FileModel fileModel = new FileModel() { url = "www.google"+i+".com", IsAttachments = false, CustomOrder = 1 }; ReqDoculink documentInfo = new ReqDoculink() { linkTypeId = i,CustomOrder=i, Files = new List() { fileModel } }; Db.DoculinkTranslation documents = new Db.DoculinkTranslation { DocumentId = i, title = "Test"+i, description = "ss"+i, Language = "en" }; - Models.Doculink document = uploadservice.UploadDocument(counter, documentInfo); + Models.Doculink document =await azureBlobService.UploadDocument(counter, documentInfo); DocumentDbContext.Documents.Add(mapper.Map(document)); DocumentDbContext.SaveChanges(); DocumentDbContext.DocumentsTranslations.AddRange(documents); @@ -373,7 +375,7 @@ namespace DamageAssesment.Api.DocuLinks.Providers { try { - int AttachmentId = DocumentDbContext.DoclinksAttachments.Max(a => a.Id); + int AttachmentId = DocumentDbContext.Documents.Max(a => a.Id); return (true, AttachmentId, ""); } catch (Exception ex) diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs index 807a2e0..0e71850 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/UploadService.cs @@ -80,15 +80,16 @@ namespace DamageAssesment.Api.DocuLinks.Providers string path = "", UserfileName = ""; List attachments = new List(); + int counter1 = 1; foreach (var item in documentInfo.Files) { - counter++; if (item.IsAttachments) { UserfileName = Path.GetFileName(item.FileName); - var fileName = String.Format("Document_{0}{1}", counter, item.FileExtension); + var fileName = String.Format("Document_{0}_{1}{2}", document.Id, counter1, item.FileExtension); path = Path.Combine(fullDirectoryPath, fileName); File.WriteAllBytes(path, Convert.FromBase64String(item.FileContent)); + counter1++; } else path = item.url; diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/appsettings.json b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/appsettings.json index 81ce9ee..c22d2b9 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/appsettings.json +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/appsettings.json @@ -18,6 +18,8 @@ }, "Fileupload": { "folderpath": "DASA_Documents/Active", - "Deletepath": "DASA_Documents/Deleted" + "Deletepath": "DASA_Documents/Deleted", + "BlobConnectionString": "DefaultEndpointsProtocol=https;AccountName=damagedoculink;AccountKey=blynpwrAQtthEneXC5f4vFewJ3tPV+QZUt1AX3nefZScPPjkr5hMoC18B9ni6/ZYdhRiERPQw+hB+AStonf+iw==;EndpointSuffix=core.windows.net", + "BlobContainerName": "doculinks" } }