using Aip.Service.Aip.Exceptions; using Aip.Service.Aip.Models; using Aip.Service.Aip.Serivces; using Aip.Service.Models.App; using Aip.Service.Models.Request; using Aip.Service.Models.Response; using Aip.Service.Services.Interfaces; using Aip.Service.Utils; using Microsoft.InformationProtection; using Newtonsoft.Json; using Serilog; using System.Diagnostics; using System.Text; using static System.Net.WebRequestMethods; namespace Aip.Service.Services; public class ApiFileService : BaseService, IApiFileService { private readonly ILogger _log; protected readonly AipFileService _aipFileService; private HttpClient _httpClient; public ApiFileService(ILogger log, IApiConfigService aipConfigService, AipFileService aipFileService) :base(aipConfigService) { _log = log; _aipFileService = aipFileService; _httpClient = new HttpClient(new HttpClientHandler { MaxConnectionsPerServer = int.MaxValue }); _httpClient.BaseAddress = new Uri("http://localhost:5050"); _httpClient.DefaultRequestHeaders.ConnectionClose = false; _httpClient.Timeout = TimeSpan.FromSeconds(20); } public async Task GetInfo(RequestFileInfo req) { string reqFileName = _aipConfigService.GetRequestFileName(req.file.realFileName); if (!FileUtils.IsExists(reqFileName)) { return new ResponseInfo { errorCode = 101, errorMessage = "파일이 존재하지 않습니다.", }; } string? newFileExt = _aipConfigService.GetSupportedFileType(reqFileName); if (newFileExt == null) { return new ResponseInfo { errorCode = 102, errorMessage = "지원하지 않는 파일형식 입니다.", }; } var task = Task.Run(() => { return ResponseGetFileInfo(_aipFileService.GetFileInfo(reqFileName), req.file.dispFileName); }); ResponseInfo result = await task; return result; } public async Task SetLabel(RequestFileSet req) { try { CheckAip check = CheckAipRequest(req.apiGuid, req.file.dispFileName, req.file.realFileName, false); if (check.errorCode != 0) { return new ResponseFile { errorCode = check.errorCode, errorMessage = check.errorMessage, dispFileName = check.dispFileName, realFileName = req.file.realFileName, actualFileName = check.actualFileName, }; } var task = Task.Run(() => { Stopwatch sw = new Stopwatch(); sw.Start(); _log.LogInformation("SetLabel: [{0}], AipFileService............Start: {1}", Task.CurrentId, req.file.dispFileName); SetFileInfo fileInfo = _aipFileService.SetLabel(check.reqFileName, check.actualFileName, req.email, req.aipGuid, "", req.comment); sw.Stop(); _log.LogInformation("SetLabel: [{0}], AipFileService..............End: {1,6} ms. actualFileName: {2}", Task.CurrentId, sw.ElapsedMilliseconds.ToString("#,##0"), req.file.dispFileName); return ResponseSetFile(fileInfo, req.file.dispFileName, req.file.realFileName, Path.GetFileName(fileInfo.newFileName)); }); ResponseFile result = await task; result.endDateTime = DateTime.Now; return result; } catch (AipFileException ex) { return ResponseFileException(ex, req.file.dispFileName); } catch (Exception e) { return ResponseFileException(e, req.file.dispFileName); } } public async Task> SetAipFileLabels(RequestMultiFileSet reqSet) { var startTotal = Stopwatch.GetTimestamp(); Log.Error("SetAipFileLabels Tatal {0} EA. Start.", reqSet.files.Count); List result = new List(); var tasks = new List>(); foreach (RequestFile req in reqSet.files) { CheckAip check = CheckAipRequest(reqSet.apiGuid, req.dispFileName, req.realFileName, false); if (check.errorCode != 0) { continue; } tasks.Add(Task.Run(() => { //Thread.Sleep(100); SetFileInfo fileInfo = _aipFileService.SetLabel(check.reqFileName, check.actualFileName, reqSet.email, reqSet.aipGuid, "", reqSet.comment); return fileInfo; })); } await Task.WhenAll(tasks); foreach (var task in tasks) { result.Add(task.Result); } Log.Error("====================== SetAipFileLabels Tatal {0} EA. ..Stop. {1} ms.", reqSet.files.Count, TimeUtils.GetElapsedMilliseconds(startTotal)); return result; } public async Task> SetLabels(RequestMultiFileSet reqSet) { List result = new List(); //var tasks = new List>(); try { var startTotal = Stopwatch.GetTimestamp(); int taskBatchSize = 40; for (int ii = 0; ii < reqSet.files.Count; ii += taskBatchSize) { var start = Stopwatch.GetTimestamp(); _log.LogInformation("{0} 작업 시작", ii); var batchFiles = reqSet.files.Skip(ii).Take(taskBatchSize).ToList(); var batchTasks = batchFiles.Select(req => Task.Run(() => { CheckAip check = CheckAipRequest(reqSet.apiGuid, req.dispFileName, req.realFileName, false); if (check.errorCode != 0) { return new ResponseFile { errorCode = check.errorCode, errorMessage = check.errorMessage, dispFileName = check.dispFileName, realFileName = req.realFileName, actualFileName = check.actualFileName, }; } Thread.Sleep(100); SetFileInfo fileInfo = _aipFileService.SetLabel(check.reqFileName, check.actualFileName, reqSet.email, reqSet.aipGuid, "", reqSet.comment); return ResponseSetFile(fileInfo, req.dispFileName, req.realFileName, Path.GetFileName(fileInfo.newFileName)); })); await Task.WhenAll(batchTasks); result.AddRange(await Task.WhenAll(batchTasks)); // 병렬로 결과를 가져오도록 수정 _log.LogInformation("{0} 작업 완료. {1} ms.", ii, TimeUtils.GetElapsedMilliseconds(start)); //result.AddRange(batchTasks.Select(t => t.Result)); } _log.LogInformation("{0} EA. 작업 완료. {1} ms.", reqSet.files.Count, TimeUtils.GetElapsedMilliseconds(startTotal)); } catch (AipFileException ex) { var exceptionResult = ResponseFileException(ex, reqSet.apiKey); result.Add(exceptionResult); } catch (Exception e) { var exceptionResult = ResponseFileException(e, reqSet.apiKey); result.Add(exceptionResult); } return result; } public async Task> SetLabels1(RequestMultiFileSet reqSet) { List result = new List(); var tasks = new List>(); try { //Label label = _aipFileService.GetLabelById(reqSet.apiGuid); //if (label == null) //{ // throw new AipFileException(101, "Label 정보를 찾을 수 없습니다."); //} foreach (RequestFile req in reqSet.files) { CheckAip check = CheckAipRequest(reqSet.apiGuid, req.dispFileName, req.realFileName, false); if (check.errorCode != 0) { result.Add(new ResponseFile { errorCode = check.errorCode, errorMessage = check.errorMessage, dispFileName = check.dispFileName, realFileName = req.realFileName, actualFileName = check.actualFileName, }); continue; } tasks.Add(Task.Run(() => { Thread.Sleep(100); SetFileInfo fileInfo = _aipFileService.SetLabel(check.reqFileName, check.actualFileName, reqSet.email, reqSet.aipGuid, "", reqSet.comment); return ResponseSetFile(fileInfo, req.dispFileName, req.realFileName, Path.GetFileName(fileInfo.newFileName)); })); } await Task.WhenAll(tasks); foreach (var task in tasks) { result.Add(task.Result); } } catch (AipFileException ex) { var exceptionResult = ResponseFileException(ex, reqSet.apiKey); result.Add(exceptionResult); } catch (Exception e) { var exceptionResult = ResponseFileException(e, reqSet.apiKey); result.Add(exceptionResult); } return result; } public async Task> SetLabels2(RequestMultiFileSet reqSet) { List result = new List(); var tasks = new List>(); try { //Label label = _aipFileService.GetLabelById(reqSet.apiGuid); //if (label == null) //{ // throw new AipFileException(101, "Label 정보를 찾을 수 없습니다."); //} foreach (RequestFile req in reqSet.files) { CheckAip check = CheckAipRequest(reqSet.apiGuid, req.dispFileName, req.realFileName, false); if (check.errorCode != 0) { result.Add(new ResponseFile { errorCode = check.errorCode, errorMessage = check.errorMessage, dispFileName = check.dispFileName, realFileName = req.realFileName, actualFileName = check.actualFileName, }); continue; } tasks.Add(Task.Run(() => { Thread.Sleep(100); SetFileInfo fileInfo = _aipFileService.SetLabel(check.reqFileName, check.actualFileName, reqSet.email, reqSet.aipGuid, "", reqSet.comment); return ResponseSetFile(fileInfo, req.dispFileName, req.realFileName, Path.GetFileName(fileInfo.newFileName)); })); } await Task.WhenAll(tasks); foreach (var task in tasks) { result.Add(task.Result); } } catch (AipFileException ex) { var exceptionResult = ResponseFileException(ex, reqSet.apiKey); result.Add(exceptionResult); } catch (Exception e) { var exceptionResult = ResponseFileException(e, reqSet.apiKey); result.Add(exceptionResult); } return result; } public async Task> SetLabels3(RequestMultiFileSet reqSet) { List result = new List(); try { _log.LogInformation("{0} EA. 작업 시작.", reqSet.files.Count); var startTotal = Stopwatch.GetTimestamp(); int ii = 0; foreach (RequestFile req in reqSet.files) { var start = Stopwatch.GetTimestamp(); //_log.LogInformation("{0} 작업 시작, {1}", ii, req.dispFileName); CheckAip check = CheckAipRequest(reqSet.apiGuid, req.dispFileName, req.realFileName, false); if (check.errorCode != 0) { result.Add(new ResponseFile { errorCode = check.errorCode, errorMessage = check.errorMessage, dispFileName = check.dispFileName, realFileName = req.realFileName, actualFileName = check.actualFileName, }); _log.LogError("{0} 작업 오류, {1}", ii, req.dispFileName); continue; } SetFileInfo fileInfo = _aipFileService.SetLabel(check.reqFileName, check.actualFileName, reqSet.email, reqSet.aipGuid, "", reqSet.comment); result.Add(ResponseSetFile(fileInfo, req.dispFileName, req.realFileName, Path.GetFileName(fileInfo.newFileName))); _log.LogInformation("{0} 작업 완료. {1},, {2} ms.", ii++, req.dispFileName, TimeUtils.GetElapsedMilliseconds(start)); } _log.LogInformation("{0} EA. 작업 완료. {1} ms.", reqSet.files.Count, TimeUtils.GetElapsedMilliseconds(startTotal)); } catch (AipFileException ex) { var exceptionResult = ResponseFileException(ex, reqSet.apiKey); result.Add(exceptionResult); } catch (Exception e) { var exceptionResult = ResponseFileException(e, reqSet.apiKey); result.Add(exceptionResult); } return result; } public async Task> SetLabels4(RequestMultiFileSet reqSet) { int Port = 7000; int seq = 0; List result = new List(); try { _log.LogInformation("{0} EA. 작업 시작.", reqSet.files.Count); var startTotal = Stopwatch.GetTimestamp(); var tasks = new List>(); foreach (RequestFile req in reqSet.files) { RequestFileSet reqFileSet = new RequestFileSet { apiKey = reqSet.apiKey, email = reqSet.email, aipGuid = reqSet.aipGuid, comment = reqSet.comment, file = new RequestFile { dispFileName = req.dispFileName, realFileName = req.realFileName, } }; var json = JsonConvert.SerializeObject(reqFileSet); var content = new StringContent(json, Encoding.UTF8, "application/json"); //string reqUri = $"http://localhost:{Port + seq++}/api/v1/file/set-label"; string reqUri = $"/api/v1/file/set-label"; if (seq >= 31) seq = 0; tasks.Add(Task.Run(() => { ApiResponseModel fileInfo = SendRequestsAsync( reqUri, reqFileSet).Result; return fileInfo.result!; })); } await Task.WhenAll(tasks); foreach (var task in tasks) { result.Add(task.Result); } _log.LogInformation("{0} EA. 작업 완료. {1} ms.", reqSet.files.Count, TimeUtils.GetElapsedMilliseconds(startTotal)); } catch (AipFileException ex) { var exceptionResult = ResponseFileException(ex, reqSet.apiKey); result.Add(exceptionResult); } catch (Exception e) { var exceptionResult = ResponseFileException(e, reqSet.apiKey); result.Add(exceptionResult); } return result; } private async Task> SendRequestsAsync(string reqUri, RequestFileSet reqFileSet) { var content = new StringContent(JsonConvert.SerializeObject(reqFileSet), Encoding.UTF8, "application/json"); try { var response = await _httpClient.PostAsync(reqUri, content);//.ConfigureAwait(false); if (response.IsSuccessStatusCode) { Log.Information($"Request successful for: {reqFileSet.file.dispFileName}"); } else { Log.Error($"Request failed for: {reqFileSet.file.dispFileName}. Status code: {response.StatusCode}"); } #pragma warning disable CS8603 // 가능한 null 참조 반환입니다. return JsonConvert.DeserializeObject>(await response.Content.ReadAsStringAsync()); #pragma warning restore CS8603 // 가능한 null 참조 반환입니다. } finally { content?.Dispose(); } } public async Task DelLabel(RequestFileDel req) { try { CheckAip check = CheckAipRequest(req.apiGuid, req.file.dispFileName, req.file.realFileName, false); if (check.errorCode != 0) { return new ResponseFile { errorCode = check.errorCode, errorMessage = check.errorMessage, dispFileName = check.dispFileName, }; } var task = Task.Run(() => { SetFileInfo fileInfo = _aipFileService.DeleteLabel(check.reqFileName, check.actualFileName, req.email, req.comment, false); return ResponseSetFile(fileInfo, req.file.dispFileName, req.file.realFileName, Path.GetFileName(fileInfo.newFileName)); }); ResponseFile result = await task; return result; } catch (Exception e) { return ResponseFileException(e, req.file.dispFileName); } } public async Task SetProtection(RequestFileSet req) { try { CheckAip check = CheckAipRequest(req.apiGuid, req.file.dispFileName, req.file.realFileName, false); if (check.errorCode != 0) { return new ResponseFile { errorCode = check.errorCode, errorMessage = check.errorMessage, dispFileName = check.dispFileName, }; } var task = Task.Run(() => { SetFileInfo fileInfo = _aipFileService.SetProtection(check.reqFileName, check.actualFileName, req.email, req.aipGuid, req.comment); return ResponseSetFile(fileInfo, req.file.dispFileName, req.file.realFileName, Path.GetFileName(fileInfo.newFileName)); }); ResponseFile result = await task; return result; } catch (Exception e) { return ResponseFileException(e, req.file.dispFileName); } } public async Task RemoveProtection(RequestFileDel req) { try { CheckAip check = CheckAipRequest(req.apiGuid, req.file.dispFileName, req.file.realFileName, false); if (check.errorCode != 0) { return new ResponseFile { errorCode = check.errorCode, errorMessage = check.errorMessage, dispFileName = check.dispFileName, }; } var task = Task.Run(() => { SetFileInfo fileInfo = _aipFileService.RemoveProtection(check.reqFileName, check.actualFileName, req.email, req.comment); return ResponseSetFile(fileInfo, req.file.dispFileName, req.file.realFileName, Path.GetFileName(fileInfo.newFileName)); }); ResponseFile result = await task; return result; } catch (Exception e) { return ResponseFileException(e, req.file.dispFileName); } } public async Task SetLabelProtection(RequestFileAllSet req) { try { CheckAip check = CheckAipRequest(req.apiGuid, req.file.dispFileName, req.file.realFileName, false); if (check.errorCode != 0) { return new ResponseFile { errorCode = check.errorCode, errorMessage = check.errorMessage, dispFileName = check.dispFileName, }; } var task = Task.Run(() => { SetFileInfo fileInfo = _aipFileService.SetLabel(check.reqFileName, check.actualFileName, req.email, req.aipGuid, req.templateGuid, req.comment); return ResponseSetFile(fileInfo, req.file.dispFileName, req.file.realFileName, Path.GetFileName(fileInfo.newFileName)); }); ResponseFile result = await task; return result; } catch (Exception e) { return ResponseFileException(e, req.file.dispFileName); } } public async Task RemoveLabelProtection(RequestFileDel req) { try { CheckAip check = CheckAipRequest(req.apiGuid, req.file.dispFileName, req.file.realFileName, false); if (check.errorCode != 0) { return new ResponseFile { errorCode = check.errorCode, errorMessage = check.errorMessage, dispFileName = check.dispFileName, }; } var task = Task.Run(() => { SetFileInfo fileInfo = _aipFileService.DeleteLabel(check.reqFileName, check.actualFileName, req.email, req.comment, true); return ResponseSetFile(fileInfo, req.file.dispFileName, req.file.realFileName, Path.GetFileName(fileInfo.newFileName)); }); ResponseFile result = await task; return result; } catch (Exception e) { return ResponseFileException(e, req.file.dispFileName); } } public async Task EncryptFile(IFormFile file, RequestBase baseReq) { CheckMultipartFile check = ValidateMultipartFile(file, baseReq.apiGuid); try { if (check.errorCode != 0) { return new ResponseFile { errorCode = check.errorCode, errorMessage = check.errorMessage, dispFileName = check.dispFileName, }; } RequestFileSet req = new RequestFileSet { apiKey = baseReq.apiKey, email = baseReq.email, apiGuid = baseReq.apiGuid, decryptKey = string.Empty, file = new RequestFile { dispFileName = check.dispFileName, realFileName = check.saveFileName, }, aipGuid = _aipConfigService.aipSetting.SetLabelId, comment = "EncryptFile" }; ResponseFile result = await SetLabel(req); return result; } catch (Exception e) { return ResponseFileException(e, file.FileName); } finally { FileUtils.DeleteFile(_aipConfigService.GetRequestFileName(check.saveFileName)); } } public async Task DecryptFile(IFormFile file, RequestBase baseReq) { CheckMultipartFile check = ValidateMultipartFile(file, baseReq.apiGuid); try { if (check.errorCode != 0) { return new ResponseFile { errorCode = check.errorCode, errorMessage = check.errorMessage, dispFileName = check.dispFileName, }; } RequestFileDel req = new RequestFileDel { apiKey = baseReq.apiKey, email = baseReq.email, apiGuid = baseReq.apiGuid, decryptKey = string.Empty, file = new RequestFile { dispFileName = check.dispFileName, realFileName = check.saveFileName, }, comment = "DecryptFile" }; ResponseFile result = await DelLabel(req); return result; } catch (Exception e) { return ResponseFileException(e, file.FileName); } finally { FileUtils.DeleteFile(_aipConfigService.GetRequestFileName(check.saveFileName)); } } }