/*************************************************************************** * * 通过TTAPI发送 * * Author : Li Bo Feng * * Update History * DATE OWNER DESCRIPTION * ----------- ------------ ----------- * 2014-12-29 Li Bo Feng Generated * ***************************************************************************/ #include "dc.h" #include "dc_code.h" #include "dc_args.h" #include "ttapi.h" /** * TTAPI连接配置及缓存信息 */ static struct TTConnection { int is_configured; int initialized; tt_config_t config; } ttconn[2]; // ttconn[IDX_DOMESTIC] // ttconn[IDX_ABROAD] static tt_values_list_t vcontext[3]; //fixed variable for current system to set virtical context of TT static tt_values_list_t vcontext_dynamic[9]; //variable set to set other virtical context for every record line in log void _clear_ttapi(int serverid) { if (ttconn[serverid].initialized) { TT_shutdown(&(ttconn[serverid].config)); ttconn[serverid].initialized = 0; } } int _init_ttapi(int serverid) { ABLOG_Entry(Public, _init_ttapi); memset(&(ttconn[serverid]), 0x00, sizeof(struct TTConnection)); int iRtn; if (dc_args.ttapi[serverid].server_name != NULL && strlen(dc_args.ttapi[serverid].server_name) > 0 && dc_args.ttapi[serverid].server_addr != NULL && strlen(dc_args.ttapi[serverid].server_addr) > 0) { (ttconn[serverid].config).server = dc_args.ttapi[serverid].server_addr; //set vcontext value with stSys vcontext[0].name = "ServerName"; vcontext[0].value = dc_args.server_name; vcontext[0].size = strlen(vcontext[0].value); vcontext[1].name = "ComponentName"; vcontext[1].value = dc_args.instance_name; vcontext[1].size = strlen(vcontext[1].value); vcontext[2].name = "ApplicationName"; vcontext[2].value = dc_args.app_name; vcontext[2].size = strlen(vcontext[2].value); vcontext[0].next = &vcontext[1]; vcontext[1].next = &vcontext[2]; vcontext[2].next = &vcontext_dynamic[0]; //TTAPI check function iRtn = TT_check_version(); if (iRtn != 0) { ABLOG_Printf(Error, (ABLOG,"[E] TT_check_version failed, [%d]",iRtn)); ABLOG_Return_Code(DC_RET_TTAPI_VERSION_ERROR); } //TT_send initialization iRtn = TT_init(&(ttconn[serverid].config)); if (iRtn != 0) { ABLOG_Printf(Error, (ABLOG,"[E] TT_init failed: [%d]",iRtn)); ABLOG_Return_Code(DC_RET_TTAPI_INITIALIZE_ERROR); } ABLOG_Printf(Metrics, (ABLOG,"[I] ttapi initialization [%s] OK!", (ttconn[serverid].config).server)); ttconn[serverid].initialized = 1; ttconn[serverid].is_configured = 1; } else { ttconn[serverid].is_configured = 0; } ABLOG_Return_Code(DC_RET_OK); } int _ttSend(tt_config_t *config, tt_event_t *event) { ABLOG_Entry(Public, _ttSend); ABLOG_Printf(Detail, (ABLOG,"[D] TT_Track event, VID: [%s], HID: [%s]", event->vertical_id.link_id,event->horizontal_id.link_id)); int iRtn_tt_track = TT_track(config, event); if (iRtn_tt_track != 0) { ABLOG_Printf(Error, (ABLOG,"[E] TT_send event track error, returned:[%d,0x%08X]",iRtn_tt_track,iRtn_tt_track)); ABLOG_Return_Code(DC_RET_TTAPI_SEND_ERROR); } ABLOG_Return_Code(DC_RET_OK); } /*------- * funTT1 * Description : send event * parameter : tt_config_t *config, struct LogRecord *stLog, tt_event_t *event * * OUT : 0-DC_RET_OK;1-DC_RET_ABNORMAL *------ */ int funTT1(tt_config_t *config, struct LogRecord *stLog, tt_event_t *event) { ABLOG_Entry(Public, funTT1); char hlink[50 + 1]; char vlink[50 + 1]; int iRtn = 0; memset(hlink, 0x00, sizeof(hlink)); memset(vlink, 0x00, sizeof(vlink)); //memset (vcontext2,0x00,sizeof(vcontext2) ); /* clear vcontext[4],vcontext[5],vcontext[6] */ //fprintf(stdout, "Start to create a STARTED_INBOUND event.\n"); event->type = CYTA_STARTED_INBOUND_EVENT; //HID01=LinkSysName + FrontID sprintf(hlink, stLog->prepared.sLinkSys); strcat(hlink, stLog->received.sFrntID); //VID= SysName + FrontID sprintf(vlink, dc_args.sys_name); strcat(vlink, stLog->received.sFrntID); event->vertical_id.link_id = vlink; event->vertical_id.link_id_size = strlen(vlink); event->horizontal_id.link_id = hlink; event->horizontal_id.link_id_size = strlen(hlink); iRtn = _ttSend(config, event); ABLOG_Return_Code(iRtn); } /*------- * funTT2 * * OUT : 0-DC_RET_OK;1-DC_RET_ABNORMAL *------- */ int funTT2(tt_config_t *config, struct LogRecord *stLog, tt_event_t *event) { ABLOG_Entry(Public, funTT2); char hlink[50 + 1]; char vlink[50 + 1]; int iRtn = 0; memset(hlink, 0x00, sizeof(hlink)); memset(vlink, 0x00, sizeof(vlink)); //fprintf(stdout, "%s %d Start to create a OUTBOUND event.\n",__FILE__,__LINE__); event->type = CYTA_OUTBOUND_EVENT; //HID02=SysName + SendID sprintf(hlink, dc_args.sys_name); strcat(hlink, stLog->received.sSendID); //VID= SysName + FrontID sprintf(vlink, dc_args.sys_name); strcat(vlink, stLog->received.sFrntID); event->vertical_id.link_id = vlink; event->vertical_id.link_id_size = strlen(vlink); event->horizontal_id.link_id = hlink; event->horizontal_id.link_id_size = strlen(hlink); iRtn = _ttSend(config, event); ABLOG_Return_Code(iRtn); } /*------- * funTT3 * * OUT : 0-DC_RET_OK;1-DC_RET_ABNORMAL *------- */ int funTT3(tt_config_t *config, struct LogRecord *stLog, tt_event_t *event) { ABLOG_Entry(Public, funTT3); char hlink[50 + 1]; char vlink[50 + 1]; int iRtn = 0; memset(hlink, 0x00, sizeof(hlink)); memset(vlink, 0x00, sizeof(vlink)); //fprintf(stdout, "%s %d Start to create a INBOUND event.\n",__FILE__,__LINE__); event->type = CYTA_INBOUND_EVENT; //HID03=SysName + SendID + "R" sprintf(hlink, dc_args.sys_name); strcat(hlink, stLog->received.sSendID); strcat(hlink, "R"); //VID =SysName + FrontID sprintf(vlink, dc_args.sys_name); strcat(vlink, stLog->received.sFrntID); event->vertical_id.link_id = vlink; event->vertical_id.link_id_size = strlen(vlink); event->horizontal_id.link_id = hlink; event->horizontal_id.link_id_size = strlen(hlink); iRtn = _ttSend(config, event); ABLOG_Return_Code(iRtn); } /*------- * funTT4 * * OUT : 0-DC_RET_OK;1-DC_RET_ABNORMAL *------- */ int funTT4(tt_config_t *config, struct LogRecord *stLog, tt_event_t *event) { ABLOG_Entry(Public, funTT4); char hlink[50 + 1]; char vlink[50 + 1]; int iRtn = 0; memset(hlink, 0x00, sizeof(hlink)); memset(vlink, 0x00, sizeof(vlink)); //fprintf(stdout, "Start to create an OUTBOUND_FINISHED event.\n"); event->type = CYTA_OUTBOUND_FINISHED_EVENT; //HID04=LinkSys + FrontID + "R" sprintf(hlink, stLog->prepared.sLinkSys); strcat(hlink, stLog->received.sFrntID); strcat(hlink, "R"); //VID =SysName + FrontID sprintf(vlink, dc_args.sys_name); strcat(vlink, stLog->received.sFrntID); event->vertical_id.link_id = vlink; event->vertical_id.link_id_size = strlen(vlink); event->horizontal_id.link_id = hlink; event->horizontal_id.link_id_size = strlen(hlink); iRtn = _ttSend(config, event); ABLOG_Return_Code(iRtn); } /*------- * Function name: TT_send * Description : Send event by function TT_track * IN : 1 struct LogRecord *; 2 tt_config_t *; * OUT : Return value of function *------- */ int TT_send(int serverid, struct LogRecord *stLog) { ABLOG_Entry(Public, TT_send); int iRtn = 0; tt_event_t event; memset(&event, 0x00, sizeof(event)); ABLOG_Printf(Detail, (ABLOG,"[D] Create a TT_Event object with the connection string :[%s]", dc_args.ttapi[serverid].server_addr)); //set event timestamp value event.timestamp.sec = stLog->prepared.stTxnTime.tv_sec; event.timestamp.usec = stLog->prepared.stTxnTime.tv_usec; event.vertical_id.caller_type = TT_ANY_CALLER; event.horizontal_id.caller_type = TT_ANY_CALLER; event.instance_id.transaction_id = stLog->prepared.sTxnID; //2013-12-26 ADD event.instance_id.size = strlen(stLog->prepared.sTxnID); //2013-12-26 ADD //setting property of event event.vertical_context = vcontext; memset(vcontext_dynamic, 0x00, sizeof(vcontext_dynamic)); //clear vcontext[4],vcontext[5],vcontext[6] vcontext_dynamic[0].name = "TransactionName"; vcontext_dynamic[0].value = stLog->prepared.sTxnID; vcontext_dynamic[0].size = strlen(vcontext_dynamic[0].value); vcontext_dynamic[1].name = "BankID"; vcontext_dynamic[1].value = stLog->received.sBankID; vcontext_dynamic[1].size = strlen(vcontext_dynamic[1].value); vcontext_dynamic[2].name = "BranchID"; vcontext_dynamic[2].value = stLog->received.sBrchID; vcontext_dynamic[2].size = strlen(vcontext_dynamic[2].value); //ABLOG_Printf(Detail,(ABLOG,"[D] ------------> stLog RTNCODE:[%s] <--------------",stLog->sRtnCode)); vcontext_dynamic[3].name = "Status"; vcontext_dynamic[3].value = stLog->prepared.sStatus; vcontext_dynamic[3].size = strlen(vcontext_dynamic[3].value); vcontext_dynamic[4].name = "FrontID"; vcontext_dynamic[4].value = stLog->received.sFrntID; vcontext_dynamic[4].size = strlen(vcontext_dynamic[4].value); vcontext_dynamic[5].name = "SendID"; vcontext_dynamic[5].value = stLog->received.sSendID; vcontext_dynamic[5].size = strlen(vcontext_dynamic[5].value); vcontext_dynamic[6].name = "ReturnCode"; vcontext_dynamic[6].value = stLog->received.sRtnCode_orig; vcontext_dynamic[6].size = strlen(vcontext_dynamic[6].value); vcontext_dynamic[7].name = "TragetSystem"; vcontext_dynamic[7].value = stLog->prepared.for_ttapi.sTargetSystem; vcontext_dynamic[7].size = strlen(vcontext_dynamic[7].value); vcontext_dynamic[8].name = "ChannelID"; vcontext_dynamic[8].value = stLog->prepared.for_ttapi.sChannelID; vcontext_dynamic[8].size = strlen(vcontext_dynamic[8].value); vcontext_dynamic[0].next = &vcontext_dynamic[1]; vcontext_dynamic[1].next = &vcontext_dynamic[2]; vcontext_dynamic[2].next = &vcontext_dynamic[3]; vcontext_dynamic[3].next = &vcontext_dynamic[4]; vcontext_dynamic[4].next = &vcontext_dynamic[5]; vcontext_dynamic[5].next = &vcontext_dynamic[6]; vcontext_dynamic[6].next = &vcontext_dynamic[7]; vcontext_dynamic[7].next = &vcontext_dynamic[8]; //ABLOG_Printf(Detail,(ABLOG,"[D] event time - sec:[%ld] usec:[%ld]",stLog->stTxnTime.sec,stLog->stTxnTime.usec)); switch (atoi(stLog->received.sTimeType)) { case 1: iRtn = funTT1(&(ttconn[serverid].config), stLog, &event); break; case 2: iRtn = funTT2(&(ttconn[serverid].config), stLog, &event); break; case 3: iRtn = funTT3(&(ttconn[serverid].config), stLog, &event); break; case 4: iRtn = funTT4(&(ttconn[serverid].config), stLog, &event); break; default: ABLOG_Printf(Error, (ABLOG,"[E] TimeType of Event not in(01,02,03,04):[%s]",stLog->received.sTimeType)); ABLOG_Return_Code(DC_RET_UNSUPPORT); } ABLOG_Return_Code(iRtn); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 初始化TTAPI * 返回: * 正常返回 DC_RET_OK,否则返回错误码 */ int init_ttapi() { ABLOG_Entry(Public, init_ttapi); if (sizeof(ttconn) / sizeof(struct TTConnection) != sizeof(dc_args.ttapi) / sizeof(server_info)) { ABLOG_Printf(Error, (ABLOG, "[E] program error. length of config(%d) != length of dc_args.ttapi(%d).", sizeof(ttconn) / sizeof(struct TTConnection), sizeof(dc_args.ttapi)/sizeof(server_info))); ABLOG_Return_Code(DC_RET_PARAMS_ERROR); } int iRtn; iRtn = _init_ttapi(IDX_DOMESTIC); if (iRtn != DC_RET_OK) { return iRtn; } iRtn = _init_ttapi(IDX_ABROAD); if (iRtn != DC_RET_OK) { _clear_ttapi(IDX_DOMESTIC); return iRtn; } ABLOG_Return_Code(DC_RET_OK); } /** * 发送TTAPI信息 * 参数: * server_id ttas server标识 * stLog 交易日志记录 * 返回: * 正常返回 DC_RET_OK,否则返回错误码 */ int send_ttapi(int serverid, struct LogRecord *stLog) { ABLOG_Entry(Public, send_ttapi); int iRtn = DC_RET_TTAPI_NOT_INITIALIZED; if (!ttconn[serverid].is_configured) { ABLOG_Return_Code( DC_RET_TTAPI_NOT_CONFIGURED); } if (!ttconn[serverid].initialized) { iRtn = _init_ttapi(serverid); if (iRtn != DC_RET_OK) { ABLOG_Return_Code(iRtn); } } iRtn = TT_send(serverid, stLog); ABLOG_Return_Code(iRtn); } /** * 清除TTAPI */ int clear_ttapi() { ABLOG_Entry(Public, clear_ttapi); int iRtn = DC_RET_TTAPI_NOT_INITIALIZED; _clear_ttapi(IDX_DOMESTIC); _clear_ttapi(IDX_ABROAD); ABLOG_Return_Code(iRtn); }