using Amazon.S3.Model; using Amazon.S3; using BMA.EHR.Application.Common.Interfaces; using BMA.EHR.Domain.Models.Organizations; using BMA.EHR.Domain.Shared; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using MimeTypes; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using BMA.EHR.Domain.Models.Documents; using Microsoft.EntityFrameworkCore; using System.Net.Http.Headers; namespace BMA.EHR.Application.Repositories { public class MinIOLeaveService { #region " Fields " private readonly ILeaveDbContext _dbContext; private readonly IConfiguration _configuration; private readonly AmazonS3Client _s3Client; private readonly IWebHostEnvironment _hostingEnvironment; private string _bucketName = string.Empty; #endregion #region " Constructors " public MinIOLeaveService(ILeaveDbContext dbContext, IConfiguration configuration, IWebHostEnvironment hostingEnvironment) { _dbContext = dbContext; _configuration = configuration; _hostingEnvironment = hostingEnvironment; var config = new AmazonS3Config { ServiceURL = _configuration["MinIO:Endpoint"], ForcePathStyle = true, SignatureVersion = "V4", // รองรับ MinIO AuthenticationRegion = "th-middle-rack-1" // บาง MinIO ใช้ region "us-east-1" โดย default }; _s3Client = new AmazonS3Client(_configuration["MinIO:AccessKey"], _configuration["MinIO:SecretKey"], config); this._bucketName = _configuration["MinIO:BucketName"] ?? "bma-recruit"; } #endregion #region " Methods " public async Task UploadFileAsync(IFormFile file, string newFileName = "") { var fileName = ""; var fileExt = Path.GetExtension(file.FileName); if (newFileName != "") fileName = $"{newFileName}"; else fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"'); var tmpDir = Path.Combine("tmp"); if (!Directory.Exists(tmpDir)) Directory.CreateDirectory(tmpDir); var tmpFile = Path.Combine(tmpDir, $"tmp_{DateTime.Now.ToString("ddMMyyyyHHmmss")}{fileExt}"); try { using (var ms = new MemoryStream()) { var id = Guid.NewGuid(); file.CopyTo(ms); var fileBytes = ms.ToArray(); System.IO.MemoryStream filestream = new System.IO.MemoryStream(fileBytes); var request = new PutObjectRequest { BucketName = _bucketName, Key = id.ToString("D"), InputStream = filestream, ContentType = file.ContentType, CannedACL = S3CannedACL.PublicRead }; await _s3Client.PutObjectAsync(request); // create document object var doc = new Document() { FileName = fileName, FileType = file.ContentType, FileSize = Convert.ToInt32(file.Length), ObjectRefId = id, CreatedDate = DateTime.Now }; await _dbContext.Set().AddAsync(doc); await _dbContext.SaveChangesAsync(); return doc; } } catch { throw; } finally { File.Delete(tmpFile); } } public async Task DownloadFileAsync(Guid fileId) { try { var doc = await _dbContext.Set().AsQueryable() .FirstOrDefaultAsync(x => x.Id == fileId); if (doc == null) throw new Exception(GlobalMessages.FileNotFoundOnServer); using (var memoryStream = new MemoryStream()) { GetObjectRequest request = new GetObjectRequest { BucketName = _bucketName, Key = doc.ObjectRefId.ToString("D") }; using (GetObjectResponse response = await _s3Client.GetObjectAsync(request)) { using (Stream responseStream = response.ResponseStream) { responseStream.CopyTo(memoryStream); } } var fileContent = memoryStream.ToArray(); return new FileDownloadResponse { FileName = doc.FileName, FileType = doc.FileType, FileContent = fileContent }; }; } catch { throw; } } public async Task DeleteFileAsync(Guid fileId) { try { var doc = await _dbContext.Set().AsQueryable() .FirstOrDefaultAsync(x => x.Id == fileId); if (doc == null) throw new Exception(GlobalMessages.FileNotFoundOnServer); else { DeleteObjectRequest request = new DeleteObjectRequest { BucketName = _bucketName, Key = doc?.ObjectRefId.ToString("D") }; // delete from minio await _s3Client.DeleteObjectAsync(request); _dbContext.Set().Remove(doc); await _dbContext.SaveChangesAsync(); } } catch { throw; } } public async Task ImagesPath(Guid? fileId) { if (fileId == null) return ""; var doc = await _dbContext.Set().AsQueryable() .FirstOrDefaultAsync(x => x.Id == fileId); if (doc == null) throw new Exception(GlobalMessages.FileNotFoundOnServer); var config = new AmazonS3Config { ServiceURL = _configuration["MinIO:Endpoint"], ForcePathStyle = true }; DateTime expires = DateTime.UtcNow.AddHours(6); var _protocol = _configuration["Protocol"]; GetPreSignedUrlRequest request = new GetPreSignedUrlRequest { BucketName = _bucketName, Key = doc?.ObjectRefId.ToString("D"), Expires = expires, Protocol = _protocol == "HTTPS" ? Protocol.HTTPS : Protocol.HTTP }; string path = _s3Client.GetPreSignedURL(request); return path; } public async Task ImagesPathByName(string fileName) { var config = new AmazonS3Config { ServiceURL = _configuration["MinIO:Endpoint"], ForcePathStyle = true }; DateTime expires = DateTime.UtcNow.AddHours(6); var _protocol = _configuration["Protocol"]; GetPreSignedUrlRequest request = new GetPreSignedUrlRequest { BucketName = _bucketName, Key = fileName, Expires = expires, Protocol = _protocol == "HTTPS" ? Protocol.HTTPS : Protocol.HTTP }; string path = _s3Client.GetPreSignedURL(request); return path; } #endregion private async Task IsExistBucketAsync(string bucketName) { try { var response = await _s3Client.ListObjectsV2Async(new ListObjectsV2Request { BucketName = bucketName }); return true; } catch { return false; } } private async Task CreateBucketAsync(string bucketName) { try { var request = new PutBucketRequest { BucketName = bucketName, UseClientRegion = true, }; var response = await _s3Client.PutBucketAsync(request); return response.HttpStatusCode == System.Net.HttpStatusCode.OK; } catch { return false; } } public List GetAllIdByRoot(Guid? id) { try { var ret = new List(); if (id == null) return ret; var oc = _dbContext.Set().FirstOrDefault(x => x.Id == id); if (oc != null) ret.Add(oc.Id); var child = _dbContext.Set().AsQueryable().Where(x => x.Parent != null && x.Parent.Id == id).ToList(); if (child.Any()) { foreach (var item in child) { ret.AddRange(GetAllIdByRoot(item.Id)); } } return ret; } catch { throw; } } public async Task UploadFileAsyncTemp(string fileName, string subFolder) { try { var fileContents = File.ReadAllBytes(fileName); System.IO.MemoryStream filestream = new System.IO.MemoryStream(fileContents); //var fileNameWithoutExt = Path.GetFileNameWithoutExtension(fileName); var fileExt = Path.GetExtension(fileName); var fileType = MimeTypeMap.GetMimeType(fileExt); var file_name = Path.GetFileName(fileName); Console.WriteLine($"{_bucketName}{subFolder}"); Console.WriteLine(fileName); Console.WriteLine(file_name); Console.WriteLine(filestream); Console.WriteLine(fileType); var request = new PutObjectRequest { BucketName = $"{_bucketName}", // BucketName = $"{_bucketName}{subFolder}", Key = file_name, InputStream = filestream, ContentType = fileType, CannedACL = S3CannedACL.PublicRead }; await _s3Client.PutObjectAsync(request); } catch { throw; } } public async Task UploadFileAsync(string fileName, MemoryStream fileStream) { try { //var fileTransferUtility = new TransferUtility(_s3Client); var fileExt = Path.GetExtension(fileName); var fileType = MimeTypeMap.GetMimeType(fileExt); //var file_name = Path.GetFileName(fileName); var request = new PutObjectRequest { BucketName = _bucketName, Key = fileName, InputStream = fileStream, ContentType = fileType, CannedACL = S3CannedACL.BucketOwnerFullControl }; await _s3Client.PutObjectAsync(request); } catch { throw; } } public async Task UploadFileAsync(string fileName, string subFolder) { try { var fileContents = File.ReadAllBytes(fileName); System.IO.MemoryStream filestream = new System.IO.MemoryStream(fileContents); //var fileNameWithoutExt = Path.GetFileNameWithoutExtension(fileName); var fileExt = Path.GetExtension(fileName); var fileType = MimeTypeMap.GetMimeType(fileExt); var file_name = Path.GetFileName(fileName); var request = new PutObjectRequest { //BucketName = $"{_bucketName}", BucketName = $"{_bucketName}{subFolder}", Key = file_name, InputStream = filestream, ContentType = fileType, CannedACL = S3CannedACL.PublicRead }; await _s3Client.PutObjectAsync(request); } catch { throw; } } public async Task GenerateJsonFile(string json, string path, string fileName) { var tmpDir = Path.Combine("tmp"); if (!Directory.Exists(tmpDir)) Directory.CreateDirectory(tmpDir); var tmpFile = Path.Combine(tmpDir, $"{fileName}.json"); try { SaveToJsonFile(tmpFile, json); await UploadFileAsyncTemp(tmpFile, path); } catch { throw; } finally { if (tmpFile != "") { if (System.IO.File.Exists(tmpFile)) System.IO.File.Delete(tmpFile); } } } private void SaveToJsonFile(string fileName, string data) { TextWriter writer = null; try { writer = new StreamWriter(fileName); writer.Write(data); } catch { throw; } finally { if (writer != null) writer.Close(); } } } }