/// <summary> /// Reader出貨流程 -2016-02-23 /// 1.檢查ReaderId是否存在於Reader主檔 /// 2.更新或新增數據至Reader主檔(需自行設定顧客識別符號與卡機種別) /// 3.根據原來的SAM UID將SAM表格資料備份到SAMDIFF /// 4.刪除SAM表格原來UID的數據 /// 5.重新新增此UID的資料到SAM表格 /// </summary> /// <param name="obDB">DB模組</param> /// <param name="uid">SAM UID(OSN)14 hex string</param> /// <param name="deviceId">卡機DeviceId:32 hex string</param> /// <param name="reader_type">卡機種別, 00:沒卡機、01:NEC R6 卡機、02:MPG/CRF 卡機、03:CASTLES/V5s 卡機</param> /// <param name="merc_flg">顧客識別符號, ex:"SET"</param> public void Shipment_Reader(AL_DBModule obDB, string uid, string deviceId, string reader_type, string merc_flg) { string readerId = (Sql_Getter_Reader_D.Reader_Head + uid);//'86' + osn bool flag = false; //1.檢查ReaderId是否存在於Reader主檔 if (this.Check_ReaderId_FromReader_D(obDB, readerId)) { //更新Reader主檔 flag = this.Update_FromReader_D(obDB, uid, deviceId, reader_type, merc_flg); } else { //新增Reader主檔 flag = this.Insert_FromReader_D(obDB, uid, deviceId, reader_type, merc_flg); } if (flag) { TransactionOptions option = new TransactionOptions(); option.IsolationLevel = System.Transactions.IsolationLevel.RepeatableRead; option.Timeout = new TimeSpan(0, 0, 10);//10sec using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, option)) { //1.依據UID將SAM_D表格資料備份到SAMDIFF_D表格 this.Copy_SAM_D_To_SAMDIFF(obDB, uid); //2.依據UID刪除SAM_D資料 this.Delete_SAM_D(obDB, uid); //3.依據UID新增一筆資料到SAM_D this.Insert_SAM_D(obDB, uid); scope.Complete(); } } }
/// <summary> /// 依據uid(osn)將SAM主檔的Row data備份到SAMDIFF_D表格 /// </summary> /// <param name="obDB"></param> /// <param name="uid">SAM UID(14 hex string)</param> /// <returns>true:新增成功/false:新增數據無變動</returns> protected bool Copy_SAM_D_To_SAMDIFF(AL_DBModule obDB, string uid) { try { //判斷資料庫連線有無開啟 if (obDB != null && obDB.ALCon.State != ConnectionState.Open) { obDB.ALCon.Open(); } } catch (SqlException ex) { Debug.WriteLine(ex); throw ex; } catch (Exception ex) { throw ex; } //SqlMod_Chk_Bkl BkL = new SqlMod_Chk_Bkl();//產生sql指令 //Sql_Getter_SAM_D operate_SAM_D = new Sql_Getter_SAM_D(); SqlParameter[] SqlParamSet = null; String sSql; //查詢SQL try { //依據uid(osn)將SAM主檔的Row data備份到SAMDIFF_D表格 //operate_SAM_D.Insert_To_SAMDIFF_D(uid, out sSql, out SqlParamSet,"21"); this.Operate_SAM_D.Insert_To_SAMDIFF_D(uid, out sSql, out SqlParamSet, "21"); string result = obDB.SqlExec1(sSql, SqlParamSet); if (IsDebugWriteLine) { Debug.WriteLine("Result:" + ((result == "1") ? "Success" : "NoneChange")); } return((result == "1") ? true : false); } catch (SqlException sqlEx) { if (IsDebugWriteLine) { Debug.WriteLine("[Shipment][Copy_SAM_D_To_SADDIFF]Sql Error:" + sqlEx.Message); } throw sqlEx; } catch (Exception ex) { if (IsDebugWriteLine) { Debug.WriteLine("[Shipment][Copy_SAM_D_To_SADDIFF]Error:" + ex.Message); } throw ex; } finally { //operate_SAM_D = null; Array.Resize(ref SqlParamSet, 0); } }
/// <summary> /// 依據OSN來刪除SAM主檔一筆Row data /// </summary> /// <param name="obDB">DB連線模組</param> /// <param name="uid">SAM UID</param> protected void Delete_SAM_D(AL_DBModule obDB, string uid) { try { //判斷資料庫連線有無開啟 if (obDB != null && obDB.ALCon.State != ConnectionState.Open) { obDB.ALCon.Open(); } } catch (SqlException ex) { Debug.WriteLine(ex); throw ex; } catch (Exception ex) { throw ex; } //Sql_Getter_SAM_D operate_SAM_D = new Sql_Getter_SAM_D();//產生sql指令 SqlParameter[] SqlParamSet = null; String sSql; //查詢SQL try { //依據uid(osn)將SAM主檔的Row data刪除 //operate_SAM_D.Delete(uid, out sSql, out SqlParamSet); this.Operate_SAM_D.Delete(uid, out sSql, out SqlParamSet); string result = obDB.SqlExec1(sSql, SqlParamSet); if (IsDebugWriteLine) { Debug.WriteLine("Result:" + ((result == "1") ? "Success" : "NoneChange")); } //return (result == "1") ? true : false; } catch (SqlException sqlEx) { if (IsDebugWriteLine) { Debug.WriteLine("[Shipment][Delete_SAM_D]Sql Error:" + sqlEx.Message); } throw sqlEx; } catch (Exception ex) { if (IsDebugWriteLine) { Debug.WriteLine("[Shipment][Delete_SAM_D]Error:" + ex.Message); } throw ex; } finally { //operate_SAM_D = null; Array.Resize(ref SqlParamSet, 0); } }
/// <summary> /// 依據ReaderId 新增Reader主檔 /// SAM uid(14 hex string), deviceId(16 bytes) /// 取得更新Reader主檔的SQL參數和命令 /// </summary> /// <param name="obDB">DB連線模組</param> /// <param name="uid">SAM uid(14 hex string)</param> /// <param name="deviceId">deviceId(16 bytes)</param> /// <returns>true:新增成功/false:新增後數據無變動</returns> protected bool Insert_FromReader_D(AL_DBModule obDB, string uid, string deviceId) { try { //判斷資料庫連線有無開啟 if (obDB != null && obDB.ALCon.State != ConnectionState.Open) { obDB.ALCon.Open(); } } catch (SqlException ex) { Debug.WriteLine(ex); throw ex; } catch (Exception ex) { throw ex; } //Sql_Getter_Reader_D operate_Reader_D = new Sql_Getter_Reader_D();//產生sql指令 SqlParameter[] SqlParamSet = null; String sSql; //查詢SQL try { //依據ReaderId('86' + uid)新增Reader主檔 //operate_Reader_D.Insert(uid, deviceId, out sSql, out SqlParamSet); this.Operate_Reader_D.Insert(uid, deviceId, out sSql, out SqlParamSet); string result = obDB.SqlExec1(sSql, SqlParamSet); if (IsDebugWriteLine) { Debug.WriteLine("Result:" + ((result == "1") ? "Success" : "NoneChange")); } return((result == "1") ? true : false); } catch (SqlException sqlEx) { if (IsDebugWriteLine) { Debug.WriteLine("[Shipment][Insert_FromReader_D]Sql Error:" + sqlEx.Message); } throw sqlEx; } catch (Exception ex) { if (IsDebugWriteLine) { Debug.WriteLine("[Shipment][Insert_FromReader_D]Error:" + ex.Message); } throw ex; } finally { //operate_Reader_D = null; Array.Resize(ref SqlParamSet, 0); } }
/// <summary> /// 依據卡機UID和M_Kind檢查是否存在於SAM主檔 /// </summary> /// <param name="obDB">DB連線模組</param> /// <param name="uid">卡機UID(7 bytes=>14 hex string)</param> /// <param name="m_kind">卡片代別(default:21)</param> /// <returns>true:存在/false:不存在</returns> public bool Check_ReaderId_FromSAM_D(AL_DBModule obDB,string uid,string m_kind) { try { //判斷資料庫連線有無開啟 if (obDB != null && obDB.ALCon.State != ConnectionState.Open) { obDB.ALCon.Open(); } } catch (SqlException ex) { Console.WriteLine(ex); throw ex; } catch (Exception ex) { throw ex; } //SqlMod_Chk_Bkl BkL = new SqlMod_Chk_Bkl();//產生sql指令 //Sql_Getter_SAM_D operate_SAM_D = new Sql_Getter_SAM_D(); SqlParameter[] SqlParamSet = null; String sSql; //查詢SQL try { m_kind = String.IsNullOrEmpty(m_kind) ? "21" : m_kind; //檢查ReaderId('86' + uid)是否存在於SAM主檔 //operate_SAM_D.Exist_ReaderId(uid, out sSql, out SqlParamSet, m_kind); this.Operate_SAM_D.Exist_OSN(uid, out sSql, out SqlParamSet, m_kind); string result = obDB.SqlExecuteScalarHasParams(sSql, SqlParamSet); return (result == "0" || result == "") ? false : true; } catch (SqlException sqlEx) { if (IsDebugWriteLine) { Debug.WriteLine("[Shipment][Check_ReaderId_FromSAM_D]Sql Error:" + sqlEx.Message); } throw sqlEx; } catch (Exception ex) { if (IsDebugWriteLine) { Debug.WriteLine("[Shipment][Check_ReaderId_FromSAM_D]Error:" + ex.Message); } throw ex; } finally { //operate_SAM_D = null; Array.Resize(ref SqlParamSet, 0); } }
/// <summary> /// 依據卡機UID和M_Kind檢查是否存在於SAM主檔 /// </summary> /// <param name="obDB">DB連線模組</param> /// <param name="uid">卡機UID(7 bytes=>14 hex string)</param> /// <param name="m_kind">卡片代別(default:21)</param> /// <returns>true:存在/false:不存在</returns> public bool Check_ReaderId_FromSAM_D(AL_DBModule obDB, string uid, string m_kind) { try { //判斷資料庫連線有無開啟 if (obDB != null && obDB.ALCon.State != ConnectionState.Open) { obDB.ALCon.Open(); } } catch (SqlException ex) { Console.WriteLine(ex); throw ex; } catch (Exception ex) { throw ex; } //SqlMod_Chk_Bkl BkL = new SqlMod_Chk_Bkl();//產生sql指令 //Sql_Getter_SAM_D operate_SAM_D = new Sql_Getter_SAM_D(); SqlParameter[] SqlParamSet = null; String sSql; //查詢SQL try { m_kind = String.IsNullOrEmpty(m_kind) ? "21" : m_kind; //檢查ReaderId('86' + uid)是否存在於SAM主檔 //operate_SAM_D.Exist_ReaderId(uid, out sSql, out SqlParamSet, m_kind); this.Operate_SAM_D.Exist_OSN(uid, out sSql, out SqlParamSet, m_kind); string result = obDB.SqlExecuteScalarHasParams(sSql, SqlParamSet); return((result == "0" || result == "") ? false : true); } catch (SqlException sqlEx) { if (IsDebugWriteLine) { Debug.WriteLine("[Shipment][Check_ReaderId_FromSAM_D]Sql Error:" + sqlEx.Message); } throw sqlEx; } catch (Exception ex) { if (IsDebugWriteLine) { Debug.WriteLine("[Shipment][Check_ReaderId_FromSAM_D]Error:" + ex.Message); } throw ex; } finally { //operate_SAM_D = null; Array.Resize(ref SqlParamSet, 0); } }
/// <summary> /// 初始化靜態集合DicBanks,從DB取得銀行最後更新狀態 /// </summary> private bool InitDicBanks() { AL_DBModule obDB = null; try { log.Debug("開始初始化銀行狀態列表"); #region 1.取得資料物件列表 //建立DB模組 obDB = new AL_DBModule(); //建立Network_Msg模組 Network_Msg network_Msg_Module = new Network_Msg(); //開啟連線 obDB.OpenConnection(); //從DB取得銀行連線狀態的table DataTable dt = network_Msg_Module.Get_NetMsgAll(obDB); //建立對應用的字典集合key=物件屬性名稱/value=Row的Column名稱 //Dictionary<string,string> dic = new Dictionary<string,string>(); //dic.Add("","BANK_CODE"); //dic.Add("","STATUS"); //dic.Add("","INFO_CODE"); ////dic.Add("","REMARK"); //dic.Add("","MOD_TIME"); //將DataTable Mapping成List<NETWORK_MSG>資料物件列表 IList <NETWORK_MSG> bankStatus = Extensions.ToList <NETWORK_MSG>(dt); #endregion #region 2.初始化DicBanks內容 foreach (NETWORK_MSG item in bankStatus) { string key = item.BANK_CODE.PadLeft(4, '0');//key = 銀行代碼(3碼->4碼),Value = NETWORK_MSG Object this.DicBanks.Add(key, item); log.Debug(">> DicBanks[" + key + "] => \n" + item.ToString()); } //表示已初始化完畢 return(true); #endregion } catch (Exception ex) { log.Error(">> [AbsClientRequestHandler][InitDicBanks] Error:" + ex.ToString()); return(false); } finally { if (obDB != null) { obDB.CloseConnection();//關閉連線 } } }
/// <summary> /// 依據卡機ReaderId檢查是否存在於Reader主檔 /// </summary> /// <param name="obDB">DB連線模組</param> /// <param name="readerId">卡機ReaderId(14 hex string)</param> /// <returns>true:存在/false:不存在</returns> protected bool Check_ReaderId_FromReader_D(AL_DBModule obDB, string readerId) { try { //判斷資料庫連線有無開啟 if (obDB != null && obDB.ALCon.State != ConnectionState.Open) { obDB.ALCon.Open(); } } catch (SqlException ex) { Debug.WriteLine(ex); throw ex; } catch (Exception ex) { throw ex; } //Sql_Getter_Reader_D operate_Reader_D = new Sql_Getter_Reader_D();//產生sql指令 SqlParameter[] SqlParamSet = null; String sSql; //查詢SQL try { //檢查ReaderId('86' + uid)是否存在於SAM主檔 //operate_Reader_D.Exist_ReaderId(readerId, out sSql, out SqlParamSet); this.Operate_Reader_D.Exist_ReaderId(readerId, out sSql, out SqlParamSet); string result = obDB.SqlExecuteScalarHasParams(sSql, SqlParamSet); return((result == "0" || result == "") ? false : true); } catch (SqlException sqlEx) { if (IsDebugWriteLine) { Debug.WriteLine("[Shipment][Check_ReaderId_FromReader_D]Sql Error:" + sqlEx.Message); } throw sqlEx; } catch (Exception ex) { if (IsDebugWriteLine) { Debug.WriteLine("[Shipment][Check_ReaderId_FromReader_D]Error:" + ex.Message); } throw ex; } finally { //operate_Reader_D = null; Array.Resize(ref SqlParamSet, 0); } }
public void Handle(AbsClientRequestHandler absClientRequestHandler) { #region variable byte[] receiveBuffer = null; int readCount = 0; string requestJsonStr = null; string outputCmd = null; EskmsKeyTxLogPOCO_v2 request = null; EskmsKeyTxLogPOCO_v2 response = null; string requestCheckErrMsg = null; string responseJsonStr = null; byte[] responseBytes = null; int sendCount = -1; AL_DBModule obDB = null; Shipment shipment = null; string txLogReturnCode = String.Empty; #endregion try { receiveBuffer = new byte[0x1000];//4k readCount = absClientRequestHandler.ClientSocket.Receive(receiveBuffer, SocketFlags.None); if (readCount == 0) { return; } //command 輸出狀態 TODO... else if (readCount == 6 && Encoding.UTF8.GetString(receiveBuffer, 0, readCount).ToLower().Contains("status")) { outputCmd = "Hello"; receiveBuffer = Encoding.UTF8.GetBytes(outputCmd); absClientRequestHandler.ClientSocket.Send(receiveBuffer); return; } else { log.Debug(m => m(">> {0}: {1}", this.GetType().Name, absClientRequestHandler.ClientNo)); //resize buffer Array.Resize(ref receiveBuffer, readCount); //init obDB = new AL_DBModule(); shipment = new Shipment(); //casting jsonstring from buffer array requestJsonStr = Encoding.UTF8.GetString(receiveBuffer); log.Debug(m => m("[{0}]Request: {1}", this.GetType().Name, requestJsonStr)); request = JsonConvert.DeserializeObject<EskmsKeyTxLogPOCO_v2>(requestJsonStr); //檢查Request資料長度(Attribute) //request.CheckLength(true, out requestCheckErrMsg); //回應資料設定 response = new EskmsKeyTxLogPOCO_v2() { SAM_UID = request.SAM_UID, DeviceId = request.DeviceId, ReturnCode = "000001",//預設為fail }; txLogReturnCode = request.TestTxLog.Substring(16, 8);//取第16~23個字串 //簡易判斷:TxLog ReturnCode if (txLogReturnCode.Equals("00000000")) { log.Debug(m => m("1.Open DB Connection")); obDB.OpenConnection(); log.Debug(m => m("2.Run Shipment DB Operate SAM_UID:{0}, DeviceId:{1}", request.SAM_UID, request.DeviceId)); //若有輸入顧客識別符號和卡機種別則寫入時就依據此資料寫入,若無則使用預設値寫入(在DB_Operate.SQL.Sql_Getter_Reader_D裡) if (!String.IsNullOrEmpty(request.Merc_Flg) && !String.IsNullOrEmpty(request.Reader_Type)) { log.Debug(m => m("2-1. 自訂卡機格式與顧客識別[Reader_Type:{0}, Merc_Flg:{1}]", request.Reader_Type, request.Merc_Flg)); //執行Reader出貨的DB操作流程 shipment.Shipment_Reader(obDB, request.SAM_UID, request.DeviceId, request.Reader_Type, request.Merc_Flg);// } else { log.Debug(m => m("2-2.預設的卡機格式與顧客識別[Reader_Type:{0}, Merc_Flg:{1}]", "03", "ICA")); //執行Reader出貨的DB操作流程 shipment.Shipment_Reader(obDB, request.SAM_UID, request.DeviceId);// } response.ReturnCode = "000000"; log.Debug(m => m("3.Shipment DB Operate End ...")); } else { log.Error(m => m("UID:{0} DeviceId:{1} TxLog ReturnCode異常:{2}",request.SAM_UID, request.DeviceId, txLogReturnCode)); } responseJsonStr = JsonConvert.SerializeObject(response); responseBytes = Encoding.UTF8.GetBytes(responseJsonStr); log.Debug(m => m("[{0}] Response:{1}", this.GetType().Name, responseJsonStr)); sendCount = absClientRequestHandler.ClientSocket.Send(responseBytes); if (sendCount != responseBytes.Length) { log.Error(m => m("異常:送出資料(length:{0}不等於原始資料(length:{1}))", sendCount, responseBytes.Length)); } log.Debug(m => m("[{0}] Response End", this.GetType().Name)); } } catch (ArgumentOutOfRangeException ex) { log.Error(m => m("資料檢核失敗:{0}", ex.ToString())); } catch (JsonException ex) { log.Error(m => m("Request(JsonString) Parse Request(Object) Failed:{0}", ex.ToString())); } catch (Exception ex) { log.Error(m => m("[{0}] Error:{1} {2}", this.GetType().Name, ex.Message, ex.StackTrace)); } finally { if (obDB != null && obDB.ALCon != null) { obDB.CloseConnection(); shipment = null; } absClientRequestHandler.ServiceState = new State_Exit(); } }
public void RunBatch() { byte[] receiveBytes = null; SocketClient.Domain.SocketClient bankAgent = null; AutoloadRqt_2Bank requestToBank = null; AutoloadRqt_2Bank responseFormBank = null; //建立DB模組 AL_DBModule obDB = new AL_DBModule(); //交易log模組 LogModual logM = new LogModual(); try { //初始化DicBankAgents集合 this.InitBankAgentSetting(); //開啟連線 obDB.OpenConnection(); //-------------------------------------------------------------------------------------------- //從字典取出每個要傳批次的電文類型 foreach (BankAgent item in this.DicBankAgents.Keys) { log.Debug("開始檢查" + item.BankCode + "銀行的狀態與MQ存放的" + item.MessageType + "資料"); #region 1.當銀行狀態是連線的且MQ有傳資料(Ex:0120類型)回來(放在工作Queue) while (this.DicBanks[item.BankCode].STATUS == "0" && this.DicBankAgents[item].synTopicSubscriber.Process()) { if (this.waitForWork.Count == 0) { log.Error("待辦工作Queue[waitForWork]內無資料"); break; } DateTime dtrqt = DateTime.Now; DateTime dtrsp = DateTime.Now; string requestToBankJsonStr = this.waitForWork.Dequeue();//取得要傳送的字串 try { using (bankAgent = new SocketClient.Domain.SocketClient(item.IP, item.Port, item.SendTimeout, item.ReceiveTimeout)) { if (bankAgent.ConnectToServer()) { log.Debug("送到" + item.IP + ":" + item.Port + "的資料: " + requestToBankJsonStr); byte[] sendJsonBytes = Encoding.UTF8.GetBytes(requestToBankJsonStr); receiveBytes = bankAgent.SendAndReceive(sendJsonBytes);//送出資料並取得回應資料 if (receiveBytes == null) { log.Debug("接收資料為null,開始將資料加入異常Queue"); //要用Regex來比對嗎 Performance不知好不好//MESSAGE_TYPE:XXX0 --> XXX1 if (Regex.IsMatch(requestToBankJsonStr, "^{\"MESSAGE_TYPE\":\"[0-9]{3}0")) { string repeatRequest = Regex.Replace(requestToBankJsonStr, "^{\"MESSAGE_TYPE\":\"[0-9]{3}0", delegate(Match match) { string result = match.Value.Substring(0, match.Value.Length - 1) + "1"; //xxx0 --> xxx1 return(result); }); log.Debug("送出失敗: 修改MESSAGE_TYPE後的JSON =>" + repeatRequest); //轉型回物件改MESSAGE_TYPE屬性內的值 //AutoloadRqt_2Bank tmp = JsonConvert.DeserializeObject<AutoloadRqt_2Bank>(requestToBankJsonStr); //tmp.MESSAGE_TYPE = tmp.MESSAGE_TYPE.Substring(0, 3) + "1";// //string sendFailRequest = JsonConvert.SerializeObject(tmp); this.failed.Enqueue(repeatRequest); } else { //MESSAGE_TYPE:XXX1//格式已是重送的SPEC this.failed.Enqueue(requestToBankJsonStr);//加入異常列表 } continue; } } } } catch (Exception ex) { log.Error("連線BankAgent異常:" + ex.StackTrace); log.Error("連線異常,開始將資料加入異常Queue"); //只修改第一層message_type的data,第二層message_type的data不動(因為第二層為原始交易資訊) string repeatRequest = Regex.Replace(requestToBankJsonStr, "^{\"MESSAGE_TYPE\":\"[0-9]{3}0", delegate(Match match) { string result = match.Value.Substring(0, match.Value.Length - 1) + "1"; return(result); }); log.Debug("[Exception]: 修改MESSAGE_TYPE後的JSON =>" + repeatRequest); this.failed.Enqueue(repeatRequest);//加入異常列表 continue; } finally { //寫送出的Tans Log //轉型 requestToBank = JsonConvert.DeserializeObject <AutoloadRqt_2Bank>(requestToBankJsonStr); dtrsp = DateTime.Now; //給銀行需要12碼,給DB紀錄只能8碼,故金額切掉多餘的碼(剩8碼) requestToBank.AMOUNT = (requestToBank.AMOUNT.Length > 8) ? requestToBank.AMOUNT.Substring(requestToBank.AMOUNT.Length - 8, 8) : requestToBank.AMOUNT; //記錄此次交易 log.Debug("[紀錄]給銀行的JSON:" + requestToBankJsonStr); log.Debug("開始寫入Log傳給銀行的Request物件(類型:" + requestToBank.MESSAGE_TYPE + ")"); logM.SaveTransLog2Bank(requestToBank, obDB, dtrqt, dtrsp); } //回傳訊息不為空 if (receiveBytes != null) { try { //寫接收的Tans Log //轉型 string responseFormBankJsonStr = Encoding.UTF8.GetString(receiveBytes); responseFormBank = JsonConvert.DeserializeObject <AutoloadRqt_2Bank>(responseFormBankJsonStr); //記錄此次交易 log.Debug("[紀錄]銀行回來的的JSON:" + responseFormBankJsonStr); log.Debug("開始寫入Log銀行回傳的Response物件(類型:" + responseFormBank.MESSAGE_TYPE + ")"); //因為銀行回傳無Field 61,所以從給銀行的POCO取 responseFormBank.ICC_info = requestToBank.ICC_info; //截掉銀行的代碼(DB只能3碼)-DB可以容許5碼_2015-04-28 //rspFromBank.BANK_CODE = rspFromBank.BANK_CODE.Substring((rspFromBank.BANK_CODE.Length - 3), 3); //銀行回應的有12碼,給DB紀錄只能8碼,故金額切掉多餘的碼(剩8碼) responseFormBank.AMOUNT = (responseFormBank.AMOUNT.Length > 8) ? responseFormBank.AMOUNT.Substring(responseFormBank.AMOUNT.Length - 8, 8) : responseFormBank.AMOUNT; dtrsp = DateTime.Now; logM.SaveTransLog2Bank(responseFormBank, obDB, dtrqt, dtrsp); } catch (Exception ex2) { logM.SaveErrorLog(obDB, this.GetType().Name + ex2.Message, "BatchAP"); log.Error("[BatchAP][RunBatch] Save Bank Trans Log Failed: " + ex2.StackTrace); } } bankAgent = null; } #endregion #region 2.將異常列表的資料塞回MQ log.Debug("2.開始將異常列表的資料塞回MQ=>筆數:" + this.failed.Count); this.DicBankAgents[item].topicPublisher.Start(); int count = 1; while (this.failed.Count > 0) { //從異常Queue取出送到銀行端失敗的Json String string backToMQJsonStr = this.failed.Dequeue(); log.Debug("開始發佈第 " + (count++) + " 筆發送失敗的POCO到MQ: " + backToMQJsonStr); //發佈回MQ this.DicBankAgents[item].topicPublisher.SendMessage <string>(backToMQJsonStr); } #endregion #region 3.清空Queue log.Debug("開始檢查並清空" + item.MessageType + "格式的暫存Queue"); if (this.waitForWork.Count > 0 || this.failed.Count > 0) { log.Debug("見鬼了...(類型:" + item.MessageType + ")Queue還有東西:\n waitForWork:" + this.waitForWork.Count + " \nfailed:" + this.failed.Count); } this.waitForWork.Clear(); this.failed.Clear(); #endregion } } catch (Exception ex) { log.Error("[BatchAP][RunBatch] Error:" + ex.StackTrace); } finally { receiveBytes = null; requestToBank = null; responseFormBank = null; obDB.CloseConnection(); } }
public void Handle(AbsClientRequestHandler absClientRequestHandler) { #region variable byte[] receiveBuffer = null; int readCount = 0; string requestJsonStr = null; string outputCmd = null; EskmsKeyTxLogPOCO_v2 request = null; EskmsKeyTxLogPOCO_v2 response = null; string requestCheckErrMsg = null; string responseJsonStr = null; byte[] responseBytes = null; int sendCount = -1; AL_DBModule obDB = null; Shipment shipment = null; string txLogReturnCode = String.Empty; #endregion try { receiveBuffer = new byte[0x1000];//4k readCount = absClientRequestHandler.ClientSocket.Receive(receiveBuffer, SocketFlags.None); if (readCount == 0) { return; } //command 輸出狀態 TODO... else if (readCount == 6 && Encoding.UTF8.GetString(receiveBuffer, 0, readCount).ToLower().Contains("status")) { outputCmd = "Hello"; receiveBuffer = Encoding.UTF8.GetBytes(outputCmd); absClientRequestHandler.ClientSocket.Send(receiveBuffer); return; } else { log.Debug(m => m(">> {0}: {1}", this.GetType().Name, absClientRequestHandler.ClientNo)); //resize buffer Array.Resize(ref receiveBuffer, readCount); //init obDB = new AL_DBModule(); shipment = new Shipment(); //casting jsonstring from buffer array requestJsonStr = Encoding.UTF8.GetString(receiveBuffer); log.Debug(m => m("[{0}]Request: {1}", this.GetType().Name, requestJsonStr)); request = JsonConvert.DeserializeObject <EskmsKeyTxLogPOCO_v2>(requestJsonStr); //檢查Request資料長度(Attribute) //request.CheckLength(true, out requestCheckErrMsg); //回應資料設定 response = new EskmsKeyTxLogPOCO_v2() { SAM_UID = request.SAM_UID, DeviceId = request.DeviceId, ReturnCode = "000001",//預設為fail }; txLogReturnCode = request.TestTxLog.Substring(16, 8);//取第16~23個字串 //簡易判斷:TxLog ReturnCode if (txLogReturnCode.Equals("00000000")) { log.Debug(m => m("1.Open DB Connection")); obDB.OpenConnection(); log.Debug(m => m("2.Run Shipment DB Operate SAM_UID:{0}, DeviceId:{1}", request.SAM_UID, request.DeviceId)); //若有輸入顧客識別符號和卡機種別則寫入時就依據此資料寫入,若無則使用預設値寫入(在DB_Operate.SQL.Sql_Getter_Reader_D裡) if (!String.IsNullOrEmpty(request.Merc_Flg) && !String.IsNullOrEmpty(request.Reader_Type)) { log.Debug(m => m("2-1. 自訂卡機格式與顧客識別[Reader_Type:{0}, Merc_Flg:{1}]", request.Reader_Type, request.Merc_Flg)); //執行Reader出貨的DB操作流程 shipment.Shipment_Reader(obDB, request.SAM_UID, request.DeviceId, request.Reader_Type, request.Merc_Flg);// } else { log.Debug(m => m("2-2.預設的卡機格式與顧客識別[Reader_Type:{0}, Merc_Flg:{1}]", "03", "ICA")); //執行Reader出貨的DB操作流程 shipment.Shipment_Reader(obDB, request.SAM_UID, request.DeviceId);// } response.ReturnCode = "000000"; log.Debug(m => m("3.Shipment DB Operate End ...")); } else { log.Error(m => m("UID:{0} DeviceId:{1} TxLog ReturnCode異常:{2}", request.SAM_UID, request.DeviceId, txLogReturnCode)); } responseJsonStr = JsonConvert.SerializeObject(response); responseBytes = Encoding.UTF8.GetBytes(responseJsonStr); log.Debug(m => m("[{0}] Response:{1}", this.GetType().Name, responseJsonStr)); sendCount = absClientRequestHandler.ClientSocket.Send(responseBytes); if (sendCount != responseBytes.Length) { log.Error(m => m("異常:送出資料(length:{0}不等於原始資料(length:{1}))", sendCount, responseBytes.Length)); } log.Debug(m => m("[{0}] Response End", this.GetType().Name)); } } catch (ArgumentOutOfRangeException ex) { log.Error(m => m("資料檢核失敗:{0}", ex.ToString())); } catch (JsonException ex) { log.Error(m => m("Request(JsonString) Parse Request(Object) Failed:{0}", ex.ToString())); } catch (Exception ex) { log.Error(m => m("[{0}] Error:{1} {2}", this.GetType().Name, ex.Message, ex.StackTrace)); } finally { if (obDB != null && obDB.ALCon != null) { obDB.CloseConnection(); shipment = null; } absClientRequestHandler.ServiceState = new State_Exit(); } }
public void Init() { this.shipment = new Shipment(); this.shipment.IsDebugWriteLine = true; this.obDb = new AL_DBModule(); }
/// <summary> /// /// </summary> /// <param name="absClientRequestHandler"></param> public void Handle(AbsClientRequestHandler absClientRequestHandler) { #region variable byte[] receiveBuffer = null; int readCount = 0; string requestJsonStr = null; string outputCmd = null; IKMSGetter kmsGetter = null; IList <EskmsKeyPOCO> request_list = null; IList <EskmsKeyPOCO> response_list = null; EskmsKeyPOCO response = null; IList <string> UID_Failed_List; Stopwatch timer; //string requestCheckErrMsg = null; string responseJsonStr = null; string failed_list = null; byte[] responseBytes = null; byte[] diversKey = null; int sendCount = -1; AL_DBModule obDB = null; Shipment shipment = null; bool hasReaderId = false; #endregion try { receiveBuffer = new byte[0x4000];//4k readCount = absClientRequestHandler.ClientSocket.Receive(receiveBuffer, SocketFlags.None); if (readCount == 0) { return; } //command 輸出狀態 TODO... else if (readCount == 6 && Encoding.UTF8.GetString(receiveBuffer, 0, readCount).ToLower().Contains("status")) { outputCmd = "Hello"; receiveBuffer = Encoding.UTF8.GetBytes(outputCmd); absClientRequestHandler.ClientSocket.Send(receiveBuffer); return; } else { log.Debug(m => m(">> {0}: {1}", this.GetType().Name, absClientRequestHandler.ClientNo)); //resize buffer Array.Resize(ref receiveBuffer, readCount); //init obDB = new AL_DBModule(); shipment = new Shipment(); UID_Failed_List = new List <string>(); response_list = new List <EskmsKeyPOCO>(); timer = new Stopwatch(); timer.Start(); //casting jsonstring from buffer array requestJsonStr = Encoding.UTF8.GetString(receiveBuffer); log.Debug(m => m("[{0}]Request: {1}", this.GetType().Name, requestJsonStr)); request_list = JsonConvert.DeserializeObject <IList <EskmsKeyPOCO> >(requestJsonStr); //檢查Request資料長度(Attribute) //不能檢查 因為沒有DeviceID //poco.CheckLength(true, out requestCheckErrMsg); log.Debug(m => m("1.Open DB Connection")); obDB.OpenConnection(); log.Debug(m => m("2.Run DB Command")); foreach (EskmsKeyPOCO request in request_list) { hasReaderId = shipment.Check_ReaderId_FromSAM_D(obDB, request.Input_UID, "21"); if (hasReaderId) { //設定Authenticate參數 kmsGetter = new KMSGetter() { Input_KeyLabel = request.Input_KeyLabel, Input_KeyVersion = request.Input_KeyVersion, Input_UID = request.Input_UID, Input_DeviceID = request.Input_DeviceID }; log.Debug(m => m("3.開始取Divers Key")); diversKey = kmsGetter.GetDiversKey();//會傳送數據到KMS並取回DiverseKey後做運算並將結果寫入Output屬性中 if (diversKey == null) { UID_Failed_List.Add(request.Input_UID); } else { //回應資料設定 response = new EskmsKeyPOCO() { Input_KeyLabel = request.Input_KeyLabel, Input_KeyVersion = request.Input_KeyVersion, Input_UID = request.Input_UID, Output_DiversKey = diversKey }; response_list.Add(response); } } else { UID_Failed_List.Add(request.Input_UID); } } if (UID_Failed_List.Count > 0) { failed_list = JsonConvert.SerializeObject(UID_Failed_List); log.Debug(m => m("[{0}] 取Key失敗的UID列表:{1}", this.GetType().Name, failed_list)); } responseJsonStr = JsonConvert.SerializeObject(response_list); responseBytes = Encoding.UTF8.GetBytes(responseJsonStr); log.Debug(m => m("[{0}] Response:{1}", this.GetType().Name, responseJsonStr)); sendCount = absClientRequestHandler.ClientSocket.Send(responseBytes); if (sendCount != responseBytes.Length) { log.Error(m => m("異常:送出資料(length:{0}不等於原始資料(length:{1}))", sendCount, responseBytes.Length)); } timer.Stop(); log.Debug(m => m("[{0}] Response End TimeSpend:{1}ms", this.GetType().Name, timer.ElapsedMilliseconds)); } } catch (ArgumentOutOfRangeException ex) { log.Error(m => m("資料檢核失敗:{0}", ex.ToString())); } catch (System.Data.SqlClient.SqlException sqlEx) { log.Error(m => m("DB Operate Failed:{0}", sqlEx.ToString())); } catch (JsonException ex) { log.Error(m => m("Request(JsonString) Parse Request(Object) Failed:{0}", ex.ToString())); } catch (Exception ex) { log.Error(m => m("[{0}] Error:{1} {2}", this.GetType().Name, ex.Message, ex.StackTrace)); } finally { if (obDB != null) { obDB.CloseConnection(); shipment = null; } absClientRequestHandler.ServiceState = new State_Exit(); } }
/// <summary> /// 依據卡機ReaderId檢查是否存在於Reader主檔 /// </summary> /// <param name="obDB">DB連線模組</param> /// <param name="readerId">卡機ReaderId(14 hex string)</param> /// <returns>true:存在/false:不存在</returns> protected bool Check_ReaderId_FromReader_D(AL_DBModule obDB, string readerId) { try { //判斷資料庫連線有無開啟 if (obDB != null && obDB.ALCon.State != ConnectionState.Open) { obDB.ALCon.Open(); } } catch (SqlException ex) { Debug.WriteLine(ex); throw ex; } catch (Exception ex) { throw ex; } //Sql_Getter_Reader_D operate_Reader_D = new Sql_Getter_Reader_D();//產生sql指令 SqlParameter[] SqlParamSet = null; String sSql; //查詢SQL try { //檢查ReaderId('86' + uid)是否存在於SAM主檔 //operate_Reader_D.Exist_ReaderId(readerId, out sSql, out SqlParamSet); this.Operate_Reader_D.Exist_ReaderId(readerId, out sSql, out SqlParamSet); string result = obDB.SqlExecuteScalarHasParams(sSql, SqlParamSet); return (result == "0" || result == "") ? false : true; } catch (SqlException sqlEx) { if (IsDebugWriteLine) { Debug.WriteLine("[Shipment][Check_ReaderId_FromReader_D]Sql Error:" + sqlEx.Message); } throw sqlEx; } catch (Exception ex) { if (IsDebugWriteLine) { Debug.WriteLine("[Shipment][Check_ReaderId_FromReader_D]Error:" + ex.Message); } throw ex; } finally { //operate_Reader_D = null; Array.Resize(ref SqlParamSet, 0); } }
/// <summary> /// 依據uid來新增一筆資料到SAM_D表格 /// </summary> /// <param name="obDB">DB模組</param> /// <param name="uid">SAM UID(OSN)7 bytes</param> protected void Insert_SAM_D(AL_DBModule obDB, string uid) { try { //判斷資料庫連線有無開啟 if (obDB != null && obDB.ALCon.State != ConnectionState.Open) { obDB.ALCon.Open(); } } catch (SqlException ex) { Debug.WriteLine(ex); throw ex; } catch (Exception ex) { throw ex; } //Sql_Getter_SAM_D operate_SAM_D = new Sql_Getter_SAM_D();//產生sql指令 SqlParameter[] SqlParamSet = null; String sSql; //查詢SQL try { //依據uid(osn)將SAM主檔的Row data刪除 //operate_SAM_D.Insert(uid, out sSql, out SqlParamSet); this.Operate_SAM_D.Insert(uid, out sSql, out SqlParamSet); string result = obDB.SqlExec1(sSql, SqlParamSet); if (IsDebugWriteLine) { Debug.WriteLine("Result:" + ((result == "1") ? "Success" : "NoneChange")); } //return (result == "1") ? true : false; } catch (SqlException sqlEx) { if (IsDebugWriteLine) { Debug.WriteLine("[Shipment][Insert_SAM_D]Sql Error:" + sqlEx.Message); } throw sqlEx; } catch (Exception ex) { if (IsDebugWriteLine) { Debug.WriteLine("[Shipment][Insert_SAM_D]Error:" + ex.Message); } throw ex; } finally { //operate_SAM_D = null; Array.Resize(ref SqlParamSet, 0); } }
/// <summary> /// 依據ReaderId 更新Reader主檔(需有顧客識別符號與reader_type, null=>default value) /// 資料物件必須有資料的欄位(READER_ID,READER_TYPE,READER_STS,TERMINAL_PSN,SAM_ID,SH_DATE,UPT_DATE,UPT_TIME,READER_ID) /// 取得更新Reader主檔的SQL參數和命令 /// </summary> /// <param name="obDB">DB連線模組</param> /// <param name="uid">SAM uid(14 hex string)</param> /// <param name="deviceId">deviceId(16 bytes)</param> /// <param name="reader_type">卡機種別, 00:沒卡機、01:NEC R6 卡機、02:MPG/CRF 卡機、03:CASTLES/V5s 卡機</param> /// <param name="merc_flg">顧客識別符號, ex:"SET"</param> /// <returns>true:更新成功/false:更新後數據無變動</returns> protected bool Update_FromReader_D(AL_DBModule obDB, string uid, string deviceId, string reader_type, string merc_flg) { try { //判斷資料庫連線有無開啟 if (obDB != null && obDB.ALCon.State != ConnectionState.Open) { obDB.ALCon.Open(); } } catch (SqlException ex) { Debug.WriteLine(ex); throw ex; } catch (Exception ex) { throw ex; } //Sql_Getter_Reader_D operate_Reader_D = new Sql_Getter_Reader_D();//產生sql指令 SqlParameter[] SqlParamSet = null; String sSql; //查詢SQL try { //依據ReaderId('86' + uid)更新Reader主檔 this.Operate_Reader_D.Update(uid, deviceId, out sSql, out SqlParamSet, reader_type, merc_flg); string result = obDB.SqlExec1(sSql, SqlParamSet); //if (IsDebugWriteLine) //{ // Debug.WriteLine("Result:" + ((result == "1") ? "Success" : "NoneChange")); //} return (result == "1") ? true : false; } catch (SqlException sqlEx) { if (IsDebugWriteLine) { Debug.WriteLine("[Shipment][Update_FromReader_D]Sql Error:" + sqlEx.Message); } throw sqlEx; } catch (Exception ex) { if (IsDebugWriteLine) { Debug.WriteLine("[Shipment][Update_FromReader_D]Error:" + ex.Message); } throw ex; } finally { //operate_Reader_D = null; Array.Resize(ref SqlParamSet, 0); } }
/// <summary> /// /// </summary> /// <param name="absClientRequestHandler"></param> public void Handle(AbsClientRequestHandler absClientRequestHandler) { #region variable byte[] receiveBuffer = null; int readCount = 0; string requestJsonStr = null; string outputCmd = null; IKMSGetter kmsGetter = null; IList<EskmsKeyPOCO> request_list = null; IList<EskmsKeyPOCO> response_list = null; EskmsKeyPOCO response = null; IList<string> UID_Failed_List; Stopwatch timer; //string requestCheckErrMsg = null; string responseJsonStr = null; string failed_list = null; byte[] responseBytes = null; byte[] diversKey = null; int sendCount = -1; AL_DBModule obDB = null; Shipment shipment = null; bool hasReaderId = false; #endregion try { receiveBuffer = new byte[0x4000];//4k readCount = absClientRequestHandler.ClientSocket.Receive(receiveBuffer, SocketFlags.None); if (readCount == 0) { return; } //command 輸出狀態 TODO... else if (readCount == 6 && Encoding.UTF8.GetString(receiveBuffer, 0, readCount).ToLower().Contains("status")) { outputCmd = "Hello"; receiveBuffer = Encoding.UTF8.GetBytes(outputCmd); absClientRequestHandler.ClientSocket.Send(receiveBuffer); return; } else { log.Debug(m => m(">> {0}: {1}", this.GetType().Name, absClientRequestHandler.ClientNo)); //resize buffer Array.Resize(ref receiveBuffer, readCount); //init obDB = new AL_DBModule(); shipment = new Shipment(); UID_Failed_List = new List<string>(); response_list = new List<EskmsKeyPOCO>(); timer = new Stopwatch(); timer.Start(); //casting jsonstring from buffer array requestJsonStr = Encoding.UTF8.GetString(receiveBuffer); log.Debug(m => m("[{0}]Request: {1}", this.GetType().Name, requestJsonStr)); request_list = JsonConvert.DeserializeObject<IList<EskmsKeyPOCO>>(requestJsonStr); //檢查Request資料長度(Attribute) //不能檢查 因為沒有DeviceID //poco.CheckLength(true, out requestCheckErrMsg); log.Debug(m => m("1.Open DB Connection")); obDB.OpenConnection(); log.Debug(m => m("2.Run DB Command")); foreach (EskmsKeyPOCO request in request_list) { hasReaderId = shipment.Check_ReaderId_FromSAM_D(obDB, request.Input_UID, "21"); if (hasReaderId) { //設定Authenticate參數 kmsGetter = new KMSGetter() { Input_KeyLabel = request.Input_KeyLabel, Input_KeyVersion = request.Input_KeyVersion, Input_UID = request.Input_UID, Input_DeviceID = request.Input_DeviceID }; log.Debug(m => m("3.開始取Divers Key")); diversKey = kmsGetter.GetDiversKey();//會傳送數據到KMS並取回DiverseKey後做運算並將結果寫入Output屬性中 if (diversKey == null) { UID_Failed_List.Add(request.Input_UID); } else { //回應資料設定 response = new EskmsKeyPOCO() { Input_KeyLabel = request.Input_KeyLabel, Input_KeyVersion = request.Input_KeyVersion, Input_UID = request.Input_UID, Output_DiversKey = diversKey }; response_list.Add(response); } } else { UID_Failed_List.Add(request.Input_UID); } } if (UID_Failed_List.Count > 0) { failed_list = JsonConvert.SerializeObject(UID_Failed_List); log.Debug(m => m("[{0}] 取Key失敗的UID列表:{1}", this.GetType().Name, failed_list)); } responseJsonStr = JsonConvert.SerializeObject(response_list); responseBytes = Encoding.UTF8.GetBytes(responseJsonStr); log.Debug(m => m("[{0}] Response:{1}", this.GetType().Name, responseJsonStr)); sendCount = absClientRequestHandler.ClientSocket.Send(responseBytes); if (sendCount != responseBytes.Length) { log.Error(m => m("異常:送出資料(length:{0}不等於原始資料(length:{1}))", sendCount, responseBytes.Length)); } timer.Stop(); log.Debug(m => m("[{0}] Response End TimeSpend:{1}ms", this.GetType().Name, timer.ElapsedMilliseconds)); } } catch (ArgumentOutOfRangeException ex) { log.Error(m => m("資料檢核失敗:{0}", ex.ToString())); } catch (System.Data.SqlClient.SqlException sqlEx) { log.Error(m => m("DB Operate Failed:{0}", sqlEx.ToString())); } catch (JsonException ex) { log.Error(m => m("Request(JsonString) Parse Request(Object) Failed:{0}", ex.ToString())); } catch (Exception ex) { log.Error(m => m("[{0}] Error:{1} {2}", this.GetType().Name, ex.Message, ex.StackTrace)); } finally { if (obDB != null) { obDB.CloseConnection(); shipment = null; } absClientRequestHandler.ServiceState = new State_Exit(); } }