350 lines
No EOL
12 KiB
C#
350 lines
No EOL
12 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Net.Http.Headers;
|
||
using System.Threading.Tasks;
|
||
using Amazon.S3;
|
||
using Amazon.S3.Model;
|
||
using BMA.EHR.Recurit.Exam.Service.Core;
|
||
using BMA.EHR.Recurit.Exam.Service.Data;
|
||
using BMA.EHR.Recurit.Exam.Service.Models.Documents;
|
||
using BMA.EHR.Recurit.Exam.Service.Responses.Document;
|
||
using Elasticsearch.Net;
|
||
using Microsoft.EntityFrameworkCore;
|
||
|
||
namespace BMA.EHR.Recurit.Exam.Service.Services
|
||
{
|
||
public class MinIOService
|
||
{
|
||
#region " Fields "
|
||
|
||
private readonly ApplicationDbContext _context;
|
||
private readonly MetadataDbContext _contextMetadata;
|
||
private readonly IConfiguration _configuration;
|
||
private readonly IWebHostEnvironment _webHostEnvironment;
|
||
private readonly AmazonS3Client _s3Client;
|
||
private string _bucketName = string.Empty;
|
||
|
||
#endregion
|
||
|
||
#region " Constructors "
|
||
|
||
public MinIOService(ApplicationDbContext context,
|
||
MetadataDbContext contextMetadata,
|
||
IConfiguration configuration,
|
||
IWebHostEnvironment webHostEnvironment)
|
||
{
|
||
_context = context;
|
||
_contextMetadata = contextMetadata;
|
||
_configuration = configuration;
|
||
_webHostEnvironment = webHostEnvironment;
|
||
|
||
var config = new AmazonS3Config
|
||
{
|
||
ServiceURL = _configuration["MinIO:Endpoint"],
|
||
ForcePathStyle = true
|
||
};
|
||
|
||
_s3Client = new AmazonS3Client(_configuration["MinIO:AccessKey"], _configuration["MinIO:SecretKey"], config);
|
||
this._bucketName = _configuration["MinIO:BucketName"] ?? "bma-recruit";
|
||
}
|
||
|
||
public static IConfigurationRoot Configuration
|
||
{
|
||
get
|
||
{
|
||
return new ConfigurationBuilder()
|
||
.SetBasePath(Directory.GetCurrentDirectory())
|
||
.AddJsonFile("appsettings.json")
|
||
.Build();
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region " Methods "
|
||
|
||
public async Task<Document> 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(_webHostEnvironment.ContentRootPath, "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 _context.Documents.AddAsync(doc);
|
||
await _context.SaveChangesAsync();
|
||
|
||
return doc;
|
||
}
|
||
}
|
||
catch
|
||
{
|
||
throw;
|
||
}
|
||
finally
|
||
{
|
||
File.Delete(tmpFile);
|
||
}
|
||
}
|
||
|
||
public async Task<FileDownloadResponse> DownloadFileAsync(Guid fileId)
|
||
{
|
||
try
|
||
{
|
||
var doc = await _context.Documents.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<Document> UploadImageFileAsync(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(_webHostEnvironment.ContentRootPath, "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
|
||
};
|
||
// <20><><EFBFBD> _contextMetadata <20><><EFBFBD><EFBFBD><EFBFBD> Save ŧ<><C5A7><EFBFBD><EFBFBD><EFBFBD>к<EFBFBD><D0BA><EFBFBD>è<EFBFBD>
|
||
await _contextMetadata.Documents.AddAsync(doc);
|
||
await _contextMetadata.SaveChangesAsync();
|
||
|
||
return doc;
|
||
}
|
||
}
|
||
catch
|
||
{
|
||
throw;
|
||
}
|
||
finally
|
||
{
|
||
File.Delete(tmpFile);
|
||
}
|
||
}
|
||
|
||
public async Task<FormFile> GetImageToFormFileAsync(string refId)
|
||
{
|
||
try
|
||
{
|
||
using var memoryStream = new MemoryStream();
|
||
var request = new GetObjectRequest
|
||
{
|
||
BucketName = _bucketName,
|
||
Key = refId
|
||
};
|
||
|
||
using var response = await _s3Client.GetObjectAsync(request);
|
||
using var responseStream = response.ResponseStream;
|
||
|
||
await responseStream.CopyToAsync(memoryStream);
|
||
|
||
var finalBytes = memoryStream.ToArray();
|
||
|
||
var finalStream = new MemoryStream(finalBytes);
|
||
var fileName = Path.GetFileName(refId);
|
||
var contentType = response.Headers.ContentType ?? "image/jpeg";
|
||
|
||
return new FormFile(finalStream, 0, finalStream.Length, "file", fileName)
|
||
{
|
||
Headers = new HeaderDictionary(),
|
||
ContentType = contentType
|
||
};
|
||
}
|
||
catch
|
||
{
|
||
throw;
|
||
}
|
||
}
|
||
|
||
public async Task DeleteFileAsync(Guid fileId)
|
||
{
|
||
try
|
||
{
|
||
var doc = await _context.Documents.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);
|
||
|
||
|
||
_context.Documents.Remove(doc);
|
||
await _context.SaveChangesAsync();
|
||
}
|
||
}
|
||
catch
|
||
{
|
||
throw;
|
||
}
|
||
}
|
||
|
||
public async Task<string> ImagesPath(Guid fileId)
|
||
{
|
||
if (fileId == null)
|
||
return "";
|
||
|
||
var doc = await _context.Documents.AsQueryable()
|
||
.FirstOrDefaultAsync(x => x.Id == fileId);
|
||
|
||
if (doc == null)
|
||
throw new Exception(GlobalMessages.FileNotFoundOnServer);
|
||
var config = new AmazonS3Config
|
||
{
|
||
ServiceURL = Configuration.GetValue<string>("MinIO:Endpoint"),
|
||
ForcePathStyle = true
|
||
};
|
||
|
||
DateTime expires = DateTime.UtcNow.AddHours(6);
|
||
GetPreSignedUrlRequest request = new GetPreSignedUrlRequest
|
||
{
|
||
BucketName = _bucketName,
|
||
Key = doc?.ObjectRefId.ToString("D"),
|
||
Expires = expires,
|
||
};
|
||
string path = _s3Client.GetPreSignedURL(request);
|
||
|
||
return path;
|
||
}
|
||
|
||
public async Task<string> ImagesPathString(string fileId)
|
||
{
|
||
if (fileId == null)
|
||
return "";
|
||
|
||
var config = new AmazonS3Config
|
||
{
|
||
ServiceURL = Configuration.GetValue<string>("MinIO:Endpoint"),
|
||
ForcePathStyle = true
|
||
};
|
||
|
||
DateTime expires = DateTime.UtcNow.AddHours(6);
|
||
GetPreSignedUrlRequest request = new GetPreSignedUrlRequest
|
||
{
|
||
BucketName = _bucketName,
|
||
Key = fileId,
|
||
Expires = expires,
|
||
};
|
||
string path = _s3Client.GetPreSignedURL(request);
|
||
|
||
return path;
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
} |