mirror of
https://git.rwth-aachen.de/acs/public/villas/web-backend-go/
synced 2025-03-30 00:00:12 +01:00
query status of VILLASnode via VILLASnode API in parallel job #64
This commit is contained in:
parent
55fe91c5f4
commit
1b3e4e907c
5 changed files with 164 additions and 0 deletions
|
@ -77,6 +77,7 @@ func InitConfig() error {
|
|||
contactMail = flag.String("contact-mail", "svogel2@eonerc.rwth-aachen.de", "EMail of the administrative contact")
|
||||
testDataPath = flag.String("test-data-path", "", "The path to a test data json file")
|
||||
groupsPath = flag.String("groups-path", "configuration/groups.yaml", "The path to a YAML file that maps user groups to scenario IDs")
|
||||
apiUpdateInterval = flag.String("api-update-interval", "10s" /* 10 sec */, "Interval in which API URL is queried for status updates of ICs")
|
||||
)
|
||||
flag.Parse()
|
||||
|
||||
|
@ -108,6 +109,7 @@ func InitConfig() error {
|
|||
"test.datapath": *testDataPath,
|
||||
"groups.path": *groupsPath,
|
||||
"config.file": *configFile,
|
||||
"apiupdateinterval": *apiUpdateInterval,
|
||||
}
|
||||
|
||||
if *dbClear == true {
|
||||
|
|
1
go.mod
1
go.mod
|
@ -8,6 +8,7 @@ require (
|
|||
github.com/gin-gonic/gin v1.4.0
|
||||
github.com/go-ini/ini v1.51.0 // indirect
|
||||
github.com/go-playground/universal-translator v0.17.0 // indirect
|
||||
github.com/go-resty/resty/v2 v2.6.0
|
||||
github.com/google/uuid v1.1.2
|
||||
github.com/jinzhu/gorm v1.9.11
|
||||
github.com/kr/pretty v0.2.1 // indirect
|
||||
|
|
8
go.sum
8
go.sum
|
@ -69,6 +69,8 @@ github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8c
|
|||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-resty/resty/v2 v2.6.0 h1:joIR5PNLM2EFqqESUjCMGXrWmXNHEU9CEiK813oKYS4=
|
||||
github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q=
|
||||
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
|
@ -238,6 +240,8 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -259,6 +263,10 @@ golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/nt
|
|||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44 h1:Bli41pIlzTzf3KEY06n+xnzK/BESIg2ze4Pgfh/aI8c=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
|
|
147
routes/infrastructure-component/ic_apiquery.go
Normal file
147
routes/infrastructure-component/ic_apiquery.go
Normal file
|
@ -0,0 +1,147 @@
|
|||
/** infrastructure-component package, API queries.
|
||||
*
|
||||
* @author Sonja Happ <sonja.happ@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC
|
||||
* @license GNU General Public License (version 3)
|
||||
*
|
||||
* VILLASweb-backend-go
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************************/
|
||||
|
||||
package infrastructure_component
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/jinzhu/gorm/dialects/postgres"
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func QueryICAPIs(d time.Duration) {
|
||||
|
||||
client := resty.New()
|
||||
//client.SetDebug(true)
|
||||
|
||||
go func() {
|
||||
|
||||
for _ = range time.Tick(d) {
|
||||
//log.Println("Querying IC APIs at time:", x)
|
||||
var err error
|
||||
|
||||
db := database.GetDB()
|
||||
var ics []database.InfrastructureComponent
|
||||
err = db.Order("ID asc").Find(&ics).Error
|
||||
if err != nil {
|
||||
log.Println("Error getting ICs from DB:", err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
// iterate over ICs in DB
|
||||
for _, ic := range ics {
|
||||
|
||||
if ic.ManagedExternally {
|
||||
continue
|
||||
}
|
||||
|
||||
if ic.APIURL == "" || (!strings.HasPrefix(ic.APIURL, "http://") && !strings.HasPrefix(ic.APIURL, "https://")) {
|
||||
continue
|
||||
}
|
||||
|
||||
if ic.Category == "gateway" && ic.Type == "villas-node" {
|
||||
|
||||
log.Println("External API: checking for IC", ic.Name)
|
||||
statusResponse, err := client.R().SetHeader("Accept", "application/json").Get(ic.APIURL + "/status")
|
||||
if err != nil {
|
||||
log.Println("Error querying status of", ic.Name, err)
|
||||
continue
|
||||
}
|
||||
var status map[string]interface{}
|
||||
err = json.Unmarshal(statusResponse.Body(), &status)
|
||||
if err != nil {
|
||||
log.Println("Error unmarshalling status of", ic.Name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
parts := strings.Split(ic.WebsocketURL, "/")
|
||||
if len(parts) > 0 && parts[len(parts)-1] != "" {
|
||||
|
||||
configResponse, _ := client.R().SetHeader("Accept", "application/json").Get(ic.APIURL + "/node/" + parts[len(parts)-1])
|
||||
statsResponse, _ := client.R().SetHeader("Accept", "application/json").Get(ic.APIURL + "/node/" + parts[len(parts)-1] + "/stats")
|
||||
|
||||
var config map[string]interface{}
|
||||
err = json.Unmarshal(configResponse.Body(), &config)
|
||||
if err == nil {
|
||||
status["config"] = config
|
||||
}
|
||||
var stats map[string]interface{}
|
||||
err = json.Unmarshal(statsResponse.Body(), &stats)
|
||||
if err == nil {
|
||||
status["statistics"] = stats
|
||||
}
|
||||
}
|
||||
|
||||
var updatedIC UpdateICRequest
|
||||
statusRaw, _ := json.Marshal(status)
|
||||
updatedIC.InfrastructureComponent.StatusUpdateRaw = postgres.Jsonb{RawMessage: statusRaw}
|
||||
updatedIC.InfrastructureComponent.State = fmt.Sprintf("%v", status["state"])
|
||||
updatedIC.InfrastructureComponent.UUID = fmt.Sprintf("%v", status["uuid"])
|
||||
timeNow, myerr := strconv.ParseFloat(fmt.Sprintf("%v", status["time_now"]), 64)
|
||||
if myerr != nil {
|
||||
log.Println("Error parsing time_now to float", myerr.Error())
|
||||
continue
|
||||
}
|
||||
timeStarted, myerr := strconv.ParseFloat(fmt.Sprintf("%v", status["time_started"]), 64)
|
||||
if myerr != nil {
|
||||
log.Println("Error parsing time_started to float", myerr.Error())
|
||||
continue
|
||||
}
|
||||
uptime := timeNow - timeStarted
|
||||
updatedIC.InfrastructureComponent.Uptime = uptime
|
||||
|
||||
// validate the update
|
||||
err = updatedIC.validate()
|
||||
if err != nil {
|
||||
log.Println("Error validating updated IC", ic.Name, ic.UUID, err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
// create the update and update IC in DB
|
||||
var x InfrastructureComponent
|
||||
err = x.byID(ic.ID)
|
||||
if err != nil {
|
||||
log.Println("Error getting IC by ID", ic.Name, err)
|
||||
continue
|
||||
}
|
||||
u := updatedIC.updatedIC(x)
|
||||
err = x.update(u)
|
||||
if err != nil {
|
||||
log.Println("Error updating IC", ic.Name, ic.UUID, err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
} else if ic.Category == "manager" && ic.Type == "villas-relay" {
|
||||
|
||||
} else if ic.Category == "gateway" && ic.Type == "villas-relay" {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
6
start.go
6
start.go
|
@ -24,6 +24,7 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
|
||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
||||
|
@ -140,6 +141,11 @@ func main() {
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Update via external APIs of ICs (if not managed via AMQP)
|
||||
intervalStr, _ := configuration.GlobalConfig.String("apiupdateinterval")
|
||||
interval, _ := time.ParseDuration(intervalStr)
|
||||
infrastructure_component.QueryICAPIs(interval)
|
||||
|
||||
log.Println("Running...")
|
||||
// Server at port 4000 to match frontend's redirect path
|
||||
r.Run(":" + port)
|
||||
|
|
Loading…
Add table
Reference in a new issue