ibms-dome/Backend/Quartz/Jobs/DataDeliveryJob.cs

270 lines
16 KiB
C#
Raw Normal View History

using Backend.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using Quartz;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace Backend.Quartz.Jobs
{
[DisallowConcurrentExecution]
class DataDeliveryJob : IJob
{
private readonly ILogger<DataDeliveryJob> logger;
private readonly IBackgroundServiceRepository backgroundServiceRepository;
public DataDeliveryJob(
ILogger<DataDeliveryJob> logger,
IBackgroundServiceRepository backgroundServiceRepository)
{
this.logger = logger;
this.backgroundServiceRepository = backgroundServiceRepository;
}
public async Task Execute(IJobExecutionContext context)
{
Dictionary<string, object> insertLog = new Dictionary<string, object>()
{
{ "@task_id", 0 },
{ "@log_level", "" },
{ "@log_content", "" }
};
try
{
logger.LogInformation("【DataDeliveryJob】【任務開始】");
insertLog["@log_level"] = $@"INFO";
insertLog["@log_content"] = $@"【DataDeliveryJob】任務開始";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_task_log");
//找出所有要派送的資料
string sWhere = @"is_complete = 0 AND task_type = @Task_type AND repeat_times < 10";
var backgroundServiceTasks = await backgroundServiceRepository.GetAllAsync<BackgroundServiceTask>("background_service_task", sWhere, new { Task_type = BackgroundServiceTaskType.data_delivery });
if (backgroundServiceTasks.Count == 0)
{
logger.LogInformation("【DataDeliveryJob】【查無任務列表】");
insertLog["@log_level"] = $@"INFO";
insertLog["@log_content"] = $@"【DataDeliveryJob】查無任務列表";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_task_log");
}
else
{
List<Dictionary<string, object>> updateObjs = new List<Dictionary<string, object>>();
foreach (var task in backgroundServiceTasks)
{
var DateTimeNow = DateTime.Now;
Dictionary<string, object> updateObj = new Dictionary<string, object>()
{
{ "Id", task.Id },
{ "@repeat_times", 0 },
{ "@is_complete", 0 },
{ "@fail_reason", null },
{ "@complete_at", null },
{ "@updated_at", DateTimeNow }
};
insertLog["@task_id"] = task.Id;
//var parameters = JsonSerializer.Deserialize<Dictionary<string, object>>(task.Target_data);
try
{
logger.LogInformation("【DataDeliveryJob】【開始派送】[棟別IP]{0}", task.Target_ip);
insertLog["@log_level"] = $@"INFO";
insertLog["@log_content"] = $@"開始派送";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_task_log");
var boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
var boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
var endBoundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--");
HttpWebRequest Postrequest = (HttpWebRequest)WebRequest.Create($"http://{task.Target_ip}/api/ReceiveDataDelivery/GetData");
Postrequest.ContentType = "multipart/form-data; boundary=" + boundary;
Postrequest.Method = "POST";
if (!string.IsNullOrEmpty(task.Target_table))
{
using (Stream requestStream = Postrequest.GetRequestStream())
{
//Id
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
string task_id = "Content-Disposition: form-data; name=\"" + "Id" + "\"\r\n\r\n" + task.Id;
byte[] task_id_bytes = System.Text.Encoding.UTF8.GetBytes(task_id);
requestStream.Write(task_id_bytes, 0, task_id_bytes.Length);
//Target Table
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
string target_table = "Content-Disposition: form-data; name=\"" + "TargetTable" + "\"\r\n\r\n" + task.Target_table;
byte[] target_table_bytes = System.Text.Encoding.UTF8.GetBytes(target_table);
requestStream.Write(target_table_bytes, 0, target_table_bytes.Length);
//mode
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
string target_mode = "Content-Disposition: form-data; name=\"" + "mode" + "\"\r\n\r\n" + task.Mode;
byte[] target_mode_bytes = System.Text.Encoding.UTF8.GetBytes(target_mode);
requestStream.Write(target_mode_bytes, 0, target_mode_bytes.Length);
//Target data
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
string target_data = "Content-Disposition: form-data; name=\"" + "TargetData" + "\"\r\n\r\n" + task.Target_data;
byte[] target_data_bytes = System.Text.Encoding.UTF8.GetBytes(target_data);
requestStream.Write(target_data_bytes, 0, target_data_bytes.Length);
//解析Files
if (task.Target_files != null)
{
var target_files = JsonSerializer.Deserialize<List<Backend.Models.FileInfo>>(task.Target_files);
var file_index = 0;
foreach (var file in target_files)
{
//file Folder
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
string file_folder = "Content-Disposition: form-data; name=\"" + $"FileInfos[{file_index}].Folder" + "\"\r\n\r\n" + file.Folder;
byte[] file_folder_bytes = System.Text.Encoding.UTF8.GetBytes(file_folder);
requestStream.Write(file_folder_bytes, 0, file_folder_bytes.Length);
//file OriginalFileName
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
string orig_file_name = "Content-Disposition: form-data; name=\"" + $"FileInfos[{file_index}].OriginalFileName" + "\"\r\n\r\n" + file.OriginalFileName;
byte[] orig_file_name_bytes = System.Text.Encoding.UTF8.GetBytes(orig_file_name);
requestStream.Write(orig_file_name_bytes, 0, orig_file_name_bytes.Length);
//file FileName
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
string file_name = "Content-Disposition: form-data; name=\"" + $"FileInfos[{file_index}].FileName" + "\"\r\n\r\n" + file.FileName;
byte[] file_name_bytes = System.Text.Encoding.UTF8.GetBytes(file_name);
requestStream.Write(file_name_bytes, 0, file_name_bytes.Length);
//取得Content-Type
var content_type = string.Empty;
string ext = Path.GetExtension(file.File);
using (Microsoft.Win32.RegistryKey registryKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext))
{
if (registryKey != null)
{
var value = registryKey.GetValue("Content Type");
if (value != null)
{
content_type = value.ToString();
}
}
}
if (file.File != null)
{
string file_header = "Content-Disposition: form-data; name=\"" + $"FileInfos[{file_index}].File" + "\"; filename=\"" + file.FileName + "\"\r\nContent-Type: " + content_type + "\r\n\r\n";
byte[] file_header_bytes = System.Text.Encoding.UTF8.GetBytes(file_header);
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
requestStream.Write(file_header_bytes, 0, file_header_bytes.Length);
byte[] buffer = new byte[32768];
int bytesRead;
// upload from file
using (FileStream fileStream = File.OpenRead(file.File))
{
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
requestStream.Write(buffer, 0, bytesRead);
fileStream.Close();
}
}
}
}
requestStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
requestStream.Close();
}
}
HttpWebResponse response = (HttpWebResponse)Postrequest.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
var statusNumber = (int)response.StatusCode;
if (statusNumber != 200)
{
logger.LogError("【DataDeliveryJob】【派送失敗】[棟別IP]{0}", task.Target_ip);
logger.LogError("【DataDeliveryJob】【派送失敗】[response]{0}", responseString);
updateObj["@repeat_times"] = task.Repeat_times + 1;
updateObj["@fail_reason"] = responseString;
insertLog["@log_level"] = $@"ERR";
insertLog["@log_content"] = $@"派送失敗 - [失敗原因]{responseString}";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_task_log");
}
else
{
//解析回傳內容
var final = JObject.Parse(responseString);
var code = final["code"].ToString();
if (code == "0000")
{
logger.LogInformation("【DataDeliveryJob】【派送成功】[棟別IP]{0}", task.Target_ip);
updateObj["@repeat_times"] = task.Repeat_times;
updateObj["@is_complete"] = 1;
updateObj["@complete_at"] = DateTime.Now;
insertLog["@log_level"] = $@"INFO";
insertLog["@log_content"] = $@"派送成功";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_task_log");
}
else
{
logger.LogError("【DataDeliveryJob】【派送失敗】[棟別IP]{0}", task.Target_ip);
logger.LogError("【DataDeliveryJob】【派送失敗】[response]{0}", responseString);
updateObj["@repeat_times"] = task.Repeat_times + 1;
updateObj["@fail_reason"] = responseString;
insertLog["@log_level"] = $@"ERR";
insertLog["@log_content"] = $@"派送失敗 - [失敗原因]{responseString}";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_task_log");
}
}
}
catch (Exception exception)
{
logger.LogError("【DataDeliveryJob】【派送失敗】[棟別IP]{0}", task.Target_ip);
logger.LogError("【DataDeliveryJob】【派送失敗】[Exception]{0}", exception.ToString());
updateObj["@repeat_times"] = task.Repeat_times + 1;
updateObj["@fail_reason"] = exception.ToString();
insertLog["@log_level"] = $@"ERR";
insertLog["@log_content"] = $@"派送失敗 - [失敗原因(Exception)]{exception.ToString()}";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_task_log");
}
updateObjs.Add(updateObj);
}
await backgroundServiceRepository.UpdateListByCustomTable(updateObjs, "background_service_task", "id = @Id");
logger.LogInformation("【DataDeliveryJob】【任務完成】");
insertLog["@task_id"] = 0;
insertLog["@log_level"] = $@"INFO";
insertLog["@log_content"] = $@"任務完成";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_task_log");
}
}
catch (Exception exception)
{
logger.LogError("【DataDeliveryJob】【任務失敗】");
logger.LogError("【DataDeliveryJob】【任務失敗】[Exception]{0}", exception.ToString());
insertLog["@task_id"] = 0;
insertLog["@log_level"] = $@"ERR";
insertLog["@log_content"] = $@"任務失敗";
await backgroundServiceRepository.AddOneByCustomTable(insertLog, "background_service_task_log");
}
}
}
}