Loading go-packages/meep-vis-traffic-mgr/go.mod 0 → 100644 +7 −0 Original line number Diff line number Diff line module github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-vis-traffic-mgr go 1.16 require github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger v0.0.0 replace github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger => ../../go-packages/meep-logger go-packages/meep-vis-traffic-mgr/go.sum 0 → 100644 +13 −0 Original line number Diff line number Diff line github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= go-packages/meep-vis-traffic-mgr/traffic-mgr.go 0 → 100644 +426 −0 Original line number Diff line number Diff line /* * Copyright (c) 2022 InterDigital Communications, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package vistrafficmgr import ( "database/sql" "errors" "strings" "time" log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger" ) // DB Config const ( DbHost = "meep-postgis.default.svc.cluster.local" DbPort = "5432" DbUser = "" DbPassword = "" DbDefault = "postgres" DbMaxRetryCount int = 2 ) // Enable profiling const profiling = false var profilingTimers map[string]time.Time const ( FieldTime1 = "time1" FieldTime2 = "time2" FieldTime3 = "time3" FieldTime4 = "time4" // FieldPath = "path" // FieldMode = "mode" // FieldVelocity = "velocity" // FieldConnected = "connected" // FieldPriority = "priority" // FieldSubtype = "subtype" // FieldRadius = "radius" ) // DB Table Names const ( TrafficTable = "traffic_patterns" ) // Asset Types const ( TypePoa = "POA" ) // POA Types // const ( // PoaTypeGeneric = "POA" // PoaTypeCell4g = "POA-4G" // PoaTypeCell5g = "POA-5G" // PoaTypeWifi = "POA-WIFI" // PoaTypeDisconnected = "DISCONNECTED" // ) // VIS Traffic Manager type TrafficMgr struct { name string namespace string user string pwd string host string port string dbName string db *sql.DB connected bool // updateCb func(string, string) } type PoaTimes struct { Id string PoaName string Time1 int32 Time2 int32 Time3 int32 Time4 int32 } // Profiling init func init() { if profiling { profilingTimers = make(map[string]time.Time) } } // NewTrafficMgr - Creates and initializes a new VIS Traffic Manager func NewTrafficMgr(name, namespace, user, pwd, host, port string) (tm *TrafficMgr, err error) { if name == "" { err = errors.New("Missing connector name") return nil, err } // Create new Traffic Manager tm = new(TrafficMgr) tm.name = name if namespace != "" { tm.namespace = namespace } else { tm.namespace = "default" } tm.user = user tm.pwd = pwd tm.host = host tm.port = port // Connect to Postgis DB for retry := 0; retry <= DbMaxRetryCount; retry++ { tm.db, err = tm.connectDB("", tm.user, tm.pwd, tm.host, tm.port) if err == nil { break } } if err != nil { log.Error("Failed to connect to postgis DB with err: ", err.Error()) return nil, err } defer tm.db.Close() // Create sandbox DB if it does not exist // Use format: '<namespace>_<name>' & replace dashes with underscores tm.dbName = strings.ToLower(strings.Replace(namespace+"_"+name, "-", "_", -1)) // Ignore DB creation error in case it already exists. // Failure will occur at DB connection if DB was not successfully created. _ = tm.CreateDb(tm.dbName) // Close connection to postgis DB _ = tm.db.Close() // Connect with sandbox-specific DB tm.db, err = tm.connectDB(tm.dbName, user, pwd, host, port) if err != nil { log.Error("Failed to connect to sandbox DB with err: ", err.Error()) return nil, err } log.Info("Postgis Connector successfully created") tm.connected = true return tm, nil } func (tm *TrafficMgr) connectDB(dbName, user, pwd, host, port string) (db *sql.DB, err error) { // Set default values if none provided if dbName == "" { dbName = DbDefault } if host == "" { host = DbHost } if port == "" { port = DbPort } log.Debug("Connecting to Postgis DB [", dbName, "] at addr [", host, ":", port, "]") // Open postgis DB connStr := "user=" + user + " password=" + pwd + " dbname=" + dbName + " host=" + host + " port=" + port + " sslmode=disable" db, err = sql.Open("postgres", connStr) if err != nil { log.Warn("Failed to connect to Postgis DB with error: ", err.Error()) return nil, err } // Make sure connection is up err = db.Ping() if err != nil { log.Warn("Failed to ping Postgis DB with error: ", err.Error()) db.Close() return nil, err } log.Info("Connected to Postgis DB [", dbName, "]") return db, nil } // func (tm *TrafficMgr) SetListener(listener func(string, string)) error { // tm.updateCb = listener // return nil // } // func (tm *TrafficMgr) notifyListener(cbType string, assetName string) { // if tm.updateCb != nil { // go tm.updateCb(cbType, assetName) // } // } // DeleteTrafficMgr - func (tm *TrafficMgr) DeleteTrafficMgr() (err error) { if tm.db == nil { err = errors.New("Traffic Manager database not initialized") log.Error(err.Error()) return err } // Close connection to sandbox-specific DB _ = tm.db.Close() // Connect to Postgis DB tm.db, err = tm.connectDB("", tm.user, tm.pwd, tm.host, tm.port) if err != nil { log.Error("Failed to connect to postgis DB with err: ", err.Error()) return err } defer tm.db.Close() // Destroy sandbox database _ = tm.DestroyDb(tm.dbName) return nil } // CreateDb -- Create new DB with provided name func (tm *TrafficMgr) CreateDb(name string) (err error) { _, err = tm.db.Exec("CREATE DATABASE " + name) if err != nil { log.Error(err.Error()) return err } log.Info("Created database: " + name) return nil } // DestroyDb -- Destroy DB with provided name func (tm *TrafficMgr) DestroyDb(name string) (err error) { _, err = tm.db.Exec("DROP DATABASE " + name) if err != nil { log.Error(err.Error()) return err } log.Info("Destroyed database: " + name) return nil } func (tm *TrafficMgr) CreateTable() (err error) { _, err = tm.db.Exec("CREATE EXTENSION IF NOT EXISTS postgis") if err != nil { log.Error(err.Error()) return err } _, err = tm.db.Exec(`CREATE TABLE ` + TrafficTable + ` ( id varchar(36) NOT NULL, poaName varchar(100) NOT NULL UNIQUE, time1 integer NOT NULL DEFAULT '0', time2 integer NOT NULL DEFAULT '0', time3 integer NOT NULL DEFAULT '0', time4 integer NOT NULL DEFAULT '0', PRIMARY KEY (id) )`) if err != nil { log.Error(err.Error()) return err } log.Info("Created Traffic table: ", TrafficTable) return nil } // DeleteTables - Delete all postgis traffic tables func (tm *TrafficMgr) DeleteTables() (err error) { err = tm.DeleteTable(TrafficTable) if err != nil { log.Error(err.Error()) return err } return nil } // DeleteTable - Delete postgis table with provided name func (tm *TrafficMgr) DeleteTable(tableName string) (err error) { _, err = tm.db.Exec("DROP TABLE IF EXISTS " + tableName) if err != nil { log.Error(err.Error()) return err } log.Info("Deleted table: " + tableName) return nil } // CreatePoaLoad - Create new POA func (tm *TrafficMgr) CreatePoaLoad(id string, poaName string, data map[string]interface{}) (err error) { if profiling { profilingTimers["CreatePoaLoad"] = time.Now() } var time1 int32 var time2 int32 var time3 int32 var time4 int32 var ok bool // Validate input if id == "" { return errors.New("Missing ID") } if poaName == "" { return errors.New("Missing POA Name") } // Get time1 if dataTime1, found := data[FieldTime1]; !found { return errors.New("Missing subtype") } else if time1, ok = dataTime1.(int32); !ok { return errors.New("Invalid subtype data type") } else if time1 == 0 { return errors.New("Invalid time1") } // Get time2 if dataTime2, found := data[FieldTime2]; !found { return errors.New("Missing subtype") } else if time2, ok = dataTime2.(int32); !ok { return errors.New("Invalid subtype data type") } else if time2 == 0 { return errors.New("Invalid time2") } // Get time3 if dataTime3, found := data[FieldTime3]; !found { return errors.New("Missing subtype") } else if time3, ok = dataTime3.(int32); !ok { return errors.New("Invalid subtype data type") } else if time3 == 0 { return errors.New("Invalid time3") } // Get time4 if dataTime4, found := data[FieldTime4]; !found { return errors.New("Missing subtype") } else if time4, ok = dataTime4.(int32); !ok { return errors.New("Invalid subtype data type") } else if time4 == 0 { return errors.New("Invalid time4") } // Create Traffic Load entry query := `INSERT INTO ` + TrafficTable + ` (id, poaName, time1, time2, time3, time4) VALUES ($1, $2, $3, $4, $5, $6)` _, err = tm.db.Exec(query, id, poaName, time1, time2, time3, time4) if err != nil { log.Error(err.Error()) return err } // Notify listener // tm.notifyListener(TypePoa, name) if profiling { now := time.Now() log.Debug("CreatePoaLoad: ", now.Sub(profilingTimers["CreatePoaLoad"])) } return nil } // GetPoaLoad - Get POA Load information func (tm *TrafficMgr) GetPoaLoad(poaName string) (poaTimes *PoaTimes, err error) { if profiling { profilingTimers["GetPoaLoad"] = time.Now() } // Validate input if poaName == "" { err = errors.New("Missing POA Name") return nil, err } // Get Poa entry var rows *sql.Rows rows, err = tm.db.Query(` SELECT id, name, time1, time2, time3, time4 FROM `+TrafficTable+` WHERE name = ($1)`, poaName) if err != nil { log.Error(err.Error()) return nil, err } defer rows.Close() // Scan result for rows.Next() { poaTimes = new(PoaTimes) err = rows.Scan(&poaTimes.Id, &poaTimes.PoaName, &poaTimes.Time1, &poaTimes.Time2, &poaTimes.Time3, &poaTimes.Time4) if err != nil { log.Error(err.Error()) return nil, err } } err = rows.Err() if err != nil { log.Error(err) } // Return error if not found if poaTimes == nil { err = errors.New("POA not found: " + poaName) return nil, err } if profiling { now := time.Now() log.Debug("GetPoaLoad: ", now.Sub(profilingTimers["GetPoaLoad"])) } return poaTimes, nil } Loading
go-packages/meep-vis-traffic-mgr/go.mod 0 → 100644 +7 −0 Original line number Diff line number Diff line module github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-vis-traffic-mgr go 1.16 require github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger v0.0.0 replace github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger => ../../go-packages/meep-logger
go-packages/meep-vis-traffic-mgr/go.sum 0 → 100644 +13 −0 Original line number Diff line number Diff line github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
go-packages/meep-vis-traffic-mgr/traffic-mgr.go 0 → 100644 +426 −0 Original line number Diff line number Diff line /* * Copyright (c) 2022 InterDigital Communications, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package vistrafficmgr import ( "database/sql" "errors" "strings" "time" log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger" ) // DB Config const ( DbHost = "meep-postgis.default.svc.cluster.local" DbPort = "5432" DbUser = "" DbPassword = "" DbDefault = "postgres" DbMaxRetryCount int = 2 ) // Enable profiling const profiling = false var profilingTimers map[string]time.Time const ( FieldTime1 = "time1" FieldTime2 = "time2" FieldTime3 = "time3" FieldTime4 = "time4" // FieldPath = "path" // FieldMode = "mode" // FieldVelocity = "velocity" // FieldConnected = "connected" // FieldPriority = "priority" // FieldSubtype = "subtype" // FieldRadius = "radius" ) // DB Table Names const ( TrafficTable = "traffic_patterns" ) // Asset Types const ( TypePoa = "POA" ) // POA Types // const ( // PoaTypeGeneric = "POA" // PoaTypeCell4g = "POA-4G" // PoaTypeCell5g = "POA-5G" // PoaTypeWifi = "POA-WIFI" // PoaTypeDisconnected = "DISCONNECTED" // ) // VIS Traffic Manager type TrafficMgr struct { name string namespace string user string pwd string host string port string dbName string db *sql.DB connected bool // updateCb func(string, string) } type PoaTimes struct { Id string PoaName string Time1 int32 Time2 int32 Time3 int32 Time4 int32 } // Profiling init func init() { if profiling { profilingTimers = make(map[string]time.Time) } } // NewTrafficMgr - Creates and initializes a new VIS Traffic Manager func NewTrafficMgr(name, namespace, user, pwd, host, port string) (tm *TrafficMgr, err error) { if name == "" { err = errors.New("Missing connector name") return nil, err } // Create new Traffic Manager tm = new(TrafficMgr) tm.name = name if namespace != "" { tm.namespace = namespace } else { tm.namespace = "default" } tm.user = user tm.pwd = pwd tm.host = host tm.port = port // Connect to Postgis DB for retry := 0; retry <= DbMaxRetryCount; retry++ { tm.db, err = tm.connectDB("", tm.user, tm.pwd, tm.host, tm.port) if err == nil { break } } if err != nil { log.Error("Failed to connect to postgis DB with err: ", err.Error()) return nil, err } defer tm.db.Close() // Create sandbox DB if it does not exist // Use format: '<namespace>_<name>' & replace dashes with underscores tm.dbName = strings.ToLower(strings.Replace(namespace+"_"+name, "-", "_", -1)) // Ignore DB creation error in case it already exists. // Failure will occur at DB connection if DB was not successfully created. _ = tm.CreateDb(tm.dbName) // Close connection to postgis DB _ = tm.db.Close() // Connect with sandbox-specific DB tm.db, err = tm.connectDB(tm.dbName, user, pwd, host, port) if err != nil { log.Error("Failed to connect to sandbox DB with err: ", err.Error()) return nil, err } log.Info("Postgis Connector successfully created") tm.connected = true return tm, nil } func (tm *TrafficMgr) connectDB(dbName, user, pwd, host, port string) (db *sql.DB, err error) { // Set default values if none provided if dbName == "" { dbName = DbDefault } if host == "" { host = DbHost } if port == "" { port = DbPort } log.Debug("Connecting to Postgis DB [", dbName, "] at addr [", host, ":", port, "]") // Open postgis DB connStr := "user=" + user + " password=" + pwd + " dbname=" + dbName + " host=" + host + " port=" + port + " sslmode=disable" db, err = sql.Open("postgres", connStr) if err != nil { log.Warn("Failed to connect to Postgis DB with error: ", err.Error()) return nil, err } // Make sure connection is up err = db.Ping() if err != nil { log.Warn("Failed to ping Postgis DB with error: ", err.Error()) db.Close() return nil, err } log.Info("Connected to Postgis DB [", dbName, "]") return db, nil } // func (tm *TrafficMgr) SetListener(listener func(string, string)) error { // tm.updateCb = listener // return nil // } // func (tm *TrafficMgr) notifyListener(cbType string, assetName string) { // if tm.updateCb != nil { // go tm.updateCb(cbType, assetName) // } // } // DeleteTrafficMgr - func (tm *TrafficMgr) DeleteTrafficMgr() (err error) { if tm.db == nil { err = errors.New("Traffic Manager database not initialized") log.Error(err.Error()) return err } // Close connection to sandbox-specific DB _ = tm.db.Close() // Connect to Postgis DB tm.db, err = tm.connectDB("", tm.user, tm.pwd, tm.host, tm.port) if err != nil { log.Error("Failed to connect to postgis DB with err: ", err.Error()) return err } defer tm.db.Close() // Destroy sandbox database _ = tm.DestroyDb(tm.dbName) return nil } // CreateDb -- Create new DB with provided name func (tm *TrafficMgr) CreateDb(name string) (err error) { _, err = tm.db.Exec("CREATE DATABASE " + name) if err != nil { log.Error(err.Error()) return err } log.Info("Created database: " + name) return nil } // DestroyDb -- Destroy DB with provided name func (tm *TrafficMgr) DestroyDb(name string) (err error) { _, err = tm.db.Exec("DROP DATABASE " + name) if err != nil { log.Error(err.Error()) return err } log.Info("Destroyed database: " + name) return nil } func (tm *TrafficMgr) CreateTable() (err error) { _, err = tm.db.Exec("CREATE EXTENSION IF NOT EXISTS postgis") if err != nil { log.Error(err.Error()) return err } _, err = tm.db.Exec(`CREATE TABLE ` + TrafficTable + ` ( id varchar(36) NOT NULL, poaName varchar(100) NOT NULL UNIQUE, time1 integer NOT NULL DEFAULT '0', time2 integer NOT NULL DEFAULT '0', time3 integer NOT NULL DEFAULT '0', time4 integer NOT NULL DEFAULT '0', PRIMARY KEY (id) )`) if err != nil { log.Error(err.Error()) return err } log.Info("Created Traffic table: ", TrafficTable) return nil } // DeleteTables - Delete all postgis traffic tables func (tm *TrafficMgr) DeleteTables() (err error) { err = tm.DeleteTable(TrafficTable) if err != nil { log.Error(err.Error()) return err } return nil } // DeleteTable - Delete postgis table with provided name func (tm *TrafficMgr) DeleteTable(tableName string) (err error) { _, err = tm.db.Exec("DROP TABLE IF EXISTS " + tableName) if err != nil { log.Error(err.Error()) return err } log.Info("Deleted table: " + tableName) return nil } // CreatePoaLoad - Create new POA func (tm *TrafficMgr) CreatePoaLoad(id string, poaName string, data map[string]interface{}) (err error) { if profiling { profilingTimers["CreatePoaLoad"] = time.Now() } var time1 int32 var time2 int32 var time3 int32 var time4 int32 var ok bool // Validate input if id == "" { return errors.New("Missing ID") } if poaName == "" { return errors.New("Missing POA Name") } // Get time1 if dataTime1, found := data[FieldTime1]; !found { return errors.New("Missing subtype") } else if time1, ok = dataTime1.(int32); !ok { return errors.New("Invalid subtype data type") } else if time1 == 0 { return errors.New("Invalid time1") } // Get time2 if dataTime2, found := data[FieldTime2]; !found { return errors.New("Missing subtype") } else if time2, ok = dataTime2.(int32); !ok { return errors.New("Invalid subtype data type") } else if time2 == 0 { return errors.New("Invalid time2") } // Get time3 if dataTime3, found := data[FieldTime3]; !found { return errors.New("Missing subtype") } else if time3, ok = dataTime3.(int32); !ok { return errors.New("Invalid subtype data type") } else if time3 == 0 { return errors.New("Invalid time3") } // Get time4 if dataTime4, found := data[FieldTime4]; !found { return errors.New("Missing subtype") } else if time4, ok = dataTime4.(int32); !ok { return errors.New("Invalid subtype data type") } else if time4 == 0 { return errors.New("Invalid time4") } // Create Traffic Load entry query := `INSERT INTO ` + TrafficTable + ` (id, poaName, time1, time2, time3, time4) VALUES ($1, $2, $3, $4, $5, $6)` _, err = tm.db.Exec(query, id, poaName, time1, time2, time3, time4) if err != nil { log.Error(err.Error()) return err } // Notify listener // tm.notifyListener(TypePoa, name) if profiling { now := time.Now() log.Debug("CreatePoaLoad: ", now.Sub(profilingTimers["CreatePoaLoad"])) } return nil } // GetPoaLoad - Get POA Load information func (tm *TrafficMgr) GetPoaLoad(poaName string) (poaTimes *PoaTimes, err error) { if profiling { profilingTimers["GetPoaLoad"] = time.Now() } // Validate input if poaName == "" { err = errors.New("Missing POA Name") return nil, err } // Get Poa entry var rows *sql.Rows rows, err = tm.db.Query(` SELECT id, name, time1, time2, time3, time4 FROM `+TrafficTable+` WHERE name = ($1)`, poaName) if err != nil { log.Error(err.Error()) return nil, err } defer rows.Close() // Scan result for rows.Next() { poaTimes = new(PoaTimes) err = rows.Scan(&poaTimes.Id, &poaTimes.PoaName, &poaTimes.Time1, &poaTimes.Time2, &poaTimes.Time3, &poaTimes.Time4) if err != nil { log.Error(err.Error()) return nil, err } } err = rows.Err() if err != nil { log.Error(err) } // Return error if not found if poaTimes == nil { err = errors.New("POA not found: " + poaName) return nil, err } if profiling { now := time.Now() log.Debug("GetPoaLoad: ", now.Sub(profilingTimers["GetPoaLoad"])) } return poaTimes, nil }