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

270 lines
16 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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");
}
}
}
}