package ews import ( "APIServer/cnf" "database/sql" "fmt" "log" "time" _ "github.com/go-sql-driver/mysql" ) type EWS struct{} type UutInfo struct { USN string MAC string IPAddr string Relay string Item string Status string Message string PartNO string MfgMO string MfgSKU string MfgLine string MfgStage string FirstAck string LastAck string LastChg string } type ReportInfo struct { USN string PartNO string MfgMO string SKU string Line string Location string Item string Status string Message string FirstAck string LastAck string LastChg string DiffMins string } func (e *EWS) SetUutInfo(cfg cnf.Cfg, logger *log.Logger, host string, addr string, uri string, params map[string]string) map[string]string { rst := map[string]string{"RESULT": ""} if params["USN"] == "" || params["MAC"] == "" { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, "Missing Parameter USN/MAC.") rst["RESULT"] = "NG" rst["ErrMsg"] = "Missing Parameter USN/MAC." return rst } dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", cfg.MySQL.User, cfg.MySQL.Password, cfg.MySQL.Server, cfg.MySQL.Port, cfg.MySQL.Database, ) dbo, err := sql.Open("mysql", dsn) if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } defer dbo.Close() err = dbo.Ping() if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } rec := dbo.QueryRow( fmt.Sprintf(`SELECT usn,mac,ipaddr,relay,item,status,message,partno,mo,sku,line,stage,first_ack,last_ack,last_change FROM uutinfo WHERE usn='%s';`, params["USN"])) ui := new(UutInfo) err = rec.Scan( &ui.USN, &ui.MAC, &ui.IPAddr, &ui.Relay, &ui.Item, &ui.Status, &ui.Message, &ui.PartNO, &ui.MfgMO, &ui.MfgSKU, &ui.MfgLine, &ui.MfgStage, &ui.FirstAck, &ui.LastAck, &ui.LastChg, ) //如果在uutinfo表中未查找到此USN的记录, 则新增一条此USN的记录 if err == sql.ErrNoRows { dmlInsert := fmt.Sprintf("INSERT INTO uutinfo (usn,mac,ipaddr,relay,item,status,message,partno,mo,sku,line,stage,first_ack,last_ack,last_change) VALUES ('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s',%s,%s,%s);", params["USN"], params["MAC"], addr, host, params["ITEM"], params["STATUS"], params["MESSAGE"], params["PARTNO"], params["MO"], params["SKU"], params["LINE"], params["STAGE"], "NOW()", "NOW()", "NOW()", ) _, err = dbo.Exec(dmlInsert) if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } rst["RESULT"] = "OK" rst["ErrMsg"] = "Inserted 1 new record." return rst } //如果此USN的记录存在与uutinfo表中, 且此USN的MAC/Item/Status/Message已变化, 则: //1. 备份此USN对应记录行到uutinfobkup表 //2. 删除uutinfo表中对应USN记录的MAC/Item/Status/Message/PartNO/MO/SKU/Line/Stage //3. 新增此USN的最新记录到uutinfo表 extFlag := false chgFlag := false _, extFlag = params["MAC"] if extFlag && params["MAC"] != ui.MAC { chgFlag = true } _, extFlag = params["ITEM"] if extFlag && params["ITEM"] != ui.Item { chgFlag = true } _, extFlag = params["STATUS"] if extFlag && params["STATUS"] != ui.Status { chgFlag = true } _, extFlag = params["MESSAGE"] if extFlag && params["MESSAGE"] != ui.Message { chgFlag = true } if chgFlag { tx, err := dbo.Begin() if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } stmt, err := tx.Prepare("INSERT INTO uutinfobkup (usn,mac,ipaddr,relay,item,status,message,partno,mo,sku,line,stage,first_ack,last_ack,last_change) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);") if err != nil { tx.Rollback() logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } defer stmt.Close() _, err = stmt.Exec( ui.USN, ui.MAC, addr, host, ui.Item, ui.Status, ui.Message, ui.PartNO, ui.MfgMO, ui.MfgSKU, ui.MfgLine, ui.MfgStage, ui.FirstAck, ui.LastAck, ui.LastChg, ) if err != nil { tx.Rollback() logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } // stmt, err = tx.Prepare("UPDATE uutinfo SET mac=?, ipaddr=?, relay=?, item=?, status=?, message=?, partno=?, mo=?, sku=?, line=?, stage=?, last_ack=NOW(), last_change=NOW() WHERE usn=?;") // if err != nil { // tx.Rollback() // logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) // rst["RESULT"] = "NG" // rst["ErrMsg"] = err.Error() // return rst // } // defer stmt.Close() // _, err = stmt.Exec( // params["MAC"], // addr, // host, // params["ITEM"], // params["STATUS"], // params["MESSAGE"], // params["PARTNO"], // params["MO"], // params["SKU"], // params["LINE"], // params["STAGE"], // params["USN"], // ) stmt, err = tx.Prepare("DELETE FROM uutinfo WHERE usn=?;") if err != nil { tx.Rollback() logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } defer stmt.Close() _, err = stmt.Exec(params["USN"]) if err != nil { tx.Rollback() logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } mac := params["MAC"] if mac == "" { mac = ui.MAC } stmt, err = tx.Prepare("INSERT INTO uutinfo (usn,mac,ipaddr,relay,item,status,message,partno,mo,sku,line,stage,first_ack,last_ack,last_change) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,NOW(),NOW());") if err != nil { tx.Rollback() logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } _, err = stmt.Exec( params["USN"], mac, addr, host, params["ITEM"], params["STATUS"], params["MESSAGE"], params["PARTNO"], params["MO"], params["SKU"], params["LINE"], params["STAGE"], ui.FirstAck, ) if err != nil { tx.Rollback() logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } err = tx.Commit() if err != nil { tx.Rollback() logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } rst["RESULT"] = "OK" rst["ErrMsg"] = "Updated and backed up 1 record." return rst } //如果此USN的记录存在与uutinfo表中, 且MAC/Item/Status/Message未变化, 则更新此USN记录的ipaddr,relay,stage, 并更新last_ack栏位为当前时间 dmlUpdate := fmt.Sprintf("UPDATE uutinfo SET ipaddr='%s', relay='%s', stage='%s', last_ack=NOW() WHERE usn='%s'", addr, host, params["STAGE"], params["USN"]) _, err = dbo.Exec(dmlUpdate) if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = err.Error() return rst } rst["RESULT"] = "OK" rst["ErrMsg"] = "Updated 1 record." return rst } func (e *EWS) GetUutInfo(cfg cnf.Cfg, logger *log.Logger, host string, addr string, uri string, params map[string]string) map[string]string { rst := map[string]string{"RESULT": ""} if params["KEY"] == "" || params["VALUE"] == "" { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, "Invalid Parameters !") rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", "Invalid Parameters !") return rst } dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", cfg.MySQL.User, cfg.MySQL.Password, cfg.MySQL.Server, cfg.MySQL.Port, cfg.MySQL.Database, ) dbo, err := sql.Open("mysql", dsn) if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", err.Error()) return rst } defer dbo.Close() err = dbo.Ping() if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", err.Error()) return rst } ul := new(UutInfo) partNO := "" mfgMO := "" mfgSKU := "" fstAck := "" lstAck := "" //Get Last Record last := "" curr, err := dbo.Query( fmt.Sprintf(`SELECT usn,mac,ipaddr,relay,item,status,message,partno,mo,sku,line,stage,first_ack,last_ack,last_change FROM uutinfo WHERE %s='%s' ORDER BY usn ASC, seqid ASC;`, params["KEY"], params["VALUE"])) if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", err.Error()) return rst } defer curr.Close() for curr.Next() { err := curr.Scan( &ul.USN, &ul.MAC, &ul.IPAddr, &ul.Relay, &ul.Item, &ul.Status, &ul.Message, &ul.PartNO, &ul.MfgMO, &ul.MfgSKU, &ul.MfgLine, &ul.MfgStage, &ul.FirstAck, &ul.LastAck, &ul.LastChg, ) if err != nil { break } last = last + fmt.Sprintf(` %s %s %s %s %s %s %s %s %s`, ul.USN, ul.MAC, ul.IPAddr, ul.Relay, ul.Item, ul.Status, ul.Message, ul.LastChg, "\r\n") if ul.PartNO != "" { partNO = ul.PartNO } if ul.MfgMO != "" { mfgMO = ul.MfgMO } if ul.MfgSKU != "" { mfgSKU = ul.MfgSKU } if ul.FirstAck != "" { fstAck = ul.FirstAck } if ul.LastAck != "" { lstAck = ul.LastAck } } //Get History Records uh := new(UutInfo) bkup := "" prev, err := dbo.Query( fmt.Sprintf(`SELECT usn,mac,ipaddr,relay,item,status,message,partno,mo,sku,line,stage,first_ack,last_ack,last_change FROM uutinfobkup WHERE %s='%s' ORDER BY usn ASC, seqid ASC;`, params["KEY"], params["VALUE"])) if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", err.Error()) return rst } defer prev.Close() for prev.Next() { err := prev.Scan( &uh.USN, &uh.MAC, &uh.IPAddr, &uh.Relay, &uh.Item, &uh.Status, &uh.Message, &uh.PartNO, &uh.MfgMO, &uh.MfgSKU, &uh.MfgLine, &uh.MfgStage, &uh.FirstAck, &uh.LastAck, &uh.LastChg, ) if err != nil { break } bkup = bkup + fmt.Sprintf(`%s%s%s%s%s%s%s%s%s`, uh.USN, uh.MAC, uh.IPAddr, uh.Relay, uh.Item, uh.Status, uh.Message, uh.LastChg, "\r\n") } //Get Location Information loc, locTime := "", "" var locStmp int64 = 0 if ul.MAC != "" { qry := dbo.QueryRow(fmt.Sprintf(`SELECT CONCAT_WS(' ', line, CONCAT_WS('-',col,row,num)) AS loc, update_time, update_stmp FROM locinfo WHERE mac='%s' ORDER BY seqid DESC;`, ul.MAC)) qry.Scan(&loc, &locTime, &locStmp) } else { qry := dbo.QueryRow(fmt.Sprintf(`SELECT CONCAT_WS(' ', line, CONCAT_WS('-',col,row,num)) AS loc, update_time, update_stmp FROM locinfo WHERE mac='%s' ORDER BY seqid DESC;`, uh.MAC)) qry.Scan(&loc, &locTime, &locStmp) } if loc == "" { loc = `Unknown` } else { loc = fmt.Sprintf(`%s`, loc) } if time.Now().Unix()-locStmp >= 3600 { locTime = fmt.Sprintf(`%s`, locTime) } else { locTime = fmt.Sprintf(`%s`, locTime) } //Get Misc. Info if partNO == "" { partNO = uh.PartNO } if mfgMO == "" { mfgMO = uh.MfgMO } if mfgSKU == "" { mfgSKU = uh.MfgSKU } if fstAck == "" { fstAck = uh.FirstAck } if lstAck == "" { lstAck = uh.LastAck } misc := "" misc = fmt.Sprintf("%s%s%s%s%s", partNO, mfgMO, mfgSKU, fstAck, lstAck) rst["RESULT"] = "OK" rst["ErrMsg"] = e.TemplateUutInfo(loc, locTime, misc, last, bkup) return rst } func (e *EWS) GetIssueReport(cfg cnf.Cfg, logger *log.Logger, host string, addr string, uri string, params map[string]string) map[string]string { rst := map[string]string{"RESULT": ""} dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", cfg.MySQL.User, cfg.MySQL.Password, cfg.MySQL.Server, cfg.MySQL.Port, cfg.MySQL.Database, ) dbo, err := sql.Open("mysql", dsn) if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", err.Error()) return rst } defer dbo.Close() err = dbo.Ping() if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", err.Error()) return rst } ri := new(ReportInfo) defect := "" rows, err := dbo.Query(fmt.Sprintf( `SELECT usn,partno,mo,sku,line,location,item,status,message,first_ack,last_ack,last_change,diffmins FROM %s ORDER BY diffmins ASC;`, cfg.MySQL.IssueTable)) if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", err.Error()) return rst } defer rows.Close() num := 1 for rows.Next() { err := rows.Scan( &ri.USN, &ri.PartNO, &ri.MfgMO, &ri.SKU, &ri.Line, &ri.Location, &ri.Item, &ri.Status, &ri.Message, &ri.FirstAck, &ri.LastAck, &ri.LastChg, &ri.DiffMins, ) if err != nil { break } temp := fmt.Sprintf(`%d%s%s%s%s%s%s%s%s%s%s%s%s%s%s`, num, ri.USN, ri.PartNO, ri.MfgMO, ri.SKU, ri.Line, ri.Location, ri.Item, ri.Status, ri.Message, ri.FirstAck, ri.LastAck, ri.LastChg, ri.DiffMins, "\r\n") defect = defect + temp num += 1 } rst["RESULT"] = "OK" rst["ErrMsg"] = e.TemplateDefectInfo(defect) return rst } func (e *EWS) GetOfflineReport(cfg cnf.Cfg, logger *log.Logger, host string, addr string, uri string, params map[string]string) map[string]string { rst := map[string]string{"RESULT": ""} dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", cfg.MySQL.User, cfg.MySQL.Password, cfg.MySQL.Server, cfg.MySQL.Port, cfg.MySQL.Database, ) dbo, err := sql.Open("mysql", dsn) if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", err.Error()) return rst } defer dbo.Close() err = dbo.Ping() if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", err.Error()) return rst } ri := new(ReportInfo) offline := "" rows, err := dbo.Query(fmt.Sprintf( `SELECT usn,partno,mo,sku,line,location,item,status,message,first_ack,last_ack,last_change,diffmins FROM %s ORDER BY diffmins DESC;`, cfg.MySQL.OfflineTable)) if err != nil { logger.Printf("[ERR] %s; %s; %#v; %s\r\n", addr, uri, params, err.Error()) rst["RESULT"] = "NG" rst["ErrMsg"] = e.SimpleMsgHTML("red", err.Error()) return rst } defer rows.Close() num := 1 for rows.Next() { err := rows.Scan( &ri.USN, &ri.PartNO, &ri.MfgMO, &ri.SKU, &ri.Line, &ri.Location, &ri.Item, &ri.Status, &ri.Message, &ri.FirstAck, &ri.LastAck, &ri.LastChg, &ri.DiffMins, ) if err != nil { break } temp := fmt.Sprintf(`%d%s%s%s%s%s%s%s%s%s%s%s%s%s%s`, num, ri.USN, ri.PartNO, ri.MfgMO, ri.SKU, ri.Line, ri.Location, ri.Item, ri.Status, ri.Message, ri.FirstAck, ri.LastAck, ri.LastChg, ri.DiffMins, "\r\n") offline = offline + temp num += 1 } rst["RESULT"] = "OK" rst["ErrMsg"] = e.TemplateDefectInfo(offline) return rst } func (e *EWS) SimpleMsgHTML(clr, msg string) string { now := time.Now().Format("2006-01-02 15:04:05") resp := fmt.Sprintf(`
[%s] %s
`, clr, now, msg) return resp } func (e *EWS) TemplateUutInfo(loc, locTime, misc, last, bkup string) string { now := time.Now().Format("2006-01-02 15:04:05") resp := fmt.Sprintf(` Test Records Response Time: %s

Location Info
Location Location Time
%s %s

Misc. Info
%s
PartNO. MO SKU First Ack Last Ack

测试记录
%s %s
USN MAC IP Address Server Test Item Status Message Last Change
`, now, loc, locTime, misc, last, bkup) return resp } func (e *EWS) TemplateDefectInfo(src string) string { now := time.Now().Format("2006-01-02 15:04:05") if src == "" { src = fmt.Sprintf(`[%s] NO Records !
`, now) } resp := fmt.Sprintf(` Test Records Response Time: %s
%s
NO. USN PartNO. MO SKU Line Location Item Status Message First Ack Last Ack Last Change Differ Time (Min)
`, now, src) return resp }