mirror of
https://git.rwth-aachen.de/acs/public/villas/web-backend-go/
synced 2025-03-30 00:00:12 +01:00
Merge branch 'rework-demo-data-reading' into 'master'
Rework demo data reading See merge request acs/public/villas/web-backend-go!33
This commit is contained in:
commit
17fa67ae52
16 changed files with 286 additions and 169 deletions
|
@ -27,6 +27,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
@ -50,11 +51,11 @@ func InitConfig() error {
|
||||||
dbUser = flag.String("db-user", "", "Username of database connection (default is <empty>)")
|
dbUser = flag.String("db-user", "", "Username of database connection (default is <empty>)")
|
||||||
dbPass = flag.String("db-pass", "", "Password of database connection (default is <empty>)")
|
dbPass = flag.String("db-pass", "", "Password of database connection (default is <empty>)")
|
||||||
dbSSLMode = flag.String("db-ssl-mode", "disable", "SSL mode of DB (default is disable)") // TODO: change default for production
|
dbSSLMode = flag.String("db-ssl-mode", "disable", "SSL mode of DB (default is disable)") // TODO: change default for production
|
||||||
|
dbClear = flag.Bool("db-clear", false, "Set to true if you want to clear all DB tables upon startup. This parameter has to be used with great care, its effects cannot be reverted.")
|
||||||
amqpHost = flag.String("amqp-host", "", "If set, use this as host for AMQP broker (default is disabled)")
|
amqpHost = flag.String("amqp-host", "", "If set, use this as host for AMQP broker (default is disabled)")
|
||||||
amqpUser = flag.String("amqp-user", "", "Username for AMQP broker")
|
amqpUser = flag.String("amqp-user", "", "Username for AMQP broker")
|
||||||
amqpPass = flag.String("amqp-pass", "", "Password for AMQP broker")
|
amqpPass = flag.String("amqp-pass", "", "Password for AMQP broker")
|
||||||
configFile = flag.String("config", "", "Path to YAML configuration file")
|
configFile = flag.String("config", "", "Path to YAML configuration file")
|
||||||
mode = flag.String("mode", "release", "Select debug/release/test mode (default is release)")
|
|
||||||
port = flag.String("port", "4000", "Port of the backend (default is 4000)")
|
port = flag.String("port", "4000", "Port of the backend (default is 4000)")
|
||||||
adminUser = flag.String("admin-user", "", "Initial admin username")
|
adminUser = flag.String("admin-user", "", "Initial admin username")
|
||||||
adminPass = flag.String("admin-pass", "", "Initial admin password")
|
adminPass = flag.String("admin-pass", "", "Initial admin password")
|
||||||
|
@ -74,7 +75,7 @@ func InitConfig() error {
|
||||||
subTitle = flag.String("sub-title", "", "Sub-title shown in the frontend")
|
subTitle = flag.String("sub-title", "", "Sub-title shown in the frontend")
|
||||||
contactName = flag.String("contact-name", "Steffen Vogel", "Name of the administrative contact")
|
contactName = flag.String("contact-name", "Steffen Vogel", "Name of the administrative contact")
|
||||||
contactMail = flag.String("contact-mail", "svogel2@eonerc.rwth-aachen.de", "EMail of the administrative contact")
|
contactMail = flag.String("contact-mail", "svogel2@eonerc.rwth-aachen.de", "EMail of the administrative contact")
|
||||||
testDataPath = flag.String("test-data-path", "database/testdata.json", "The path to the test data json file (used in test mode)")
|
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")
|
groupsPath = flag.String("groups-path", "configuration/groups.yaml", "The path to a YAML file that maps user groups to scenario IDs")
|
||||||
)
|
)
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
@ -88,7 +89,6 @@ func InitConfig() error {
|
||||||
"amqp.host": *amqpHost,
|
"amqp.host": *amqpHost,
|
||||||
"amqp.user": *amqpUser,
|
"amqp.user": *amqpUser,
|
||||||
"amqp.pass": *amqpPass,
|
"amqp.pass": *amqpPass,
|
||||||
"mode": *mode,
|
|
||||||
"port": *port,
|
"port": *port,
|
||||||
"admin.user": *adminUser,
|
"admin.user": *adminUser,
|
||||||
"admin.pass": *adminPass,
|
"admin.pass": *adminPass,
|
||||||
|
@ -107,6 +107,13 @@ func InitConfig() error {
|
||||||
"contact.mail": *contactMail,
|
"contact.mail": *contactMail,
|
||||||
"test.datapath": *testDataPath,
|
"test.datapath": *testDataPath,
|
||||||
"groups.path": *groupsPath,
|
"groups.path": *groupsPath,
|
||||||
|
"config.file": *configFile,
|
||||||
|
}
|
||||||
|
|
||||||
|
if *dbClear == true {
|
||||||
|
static["db.clear"] = "true"
|
||||||
|
} else {
|
||||||
|
static["db.clear"] = "false"
|
||||||
}
|
}
|
||||||
|
|
||||||
if *s3NoSSL == true {
|
if *s3NoSSL == true {
|
||||||
|
@ -152,20 +159,20 @@ func InitConfig() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
m, err := GlobalConfig.String("mode")
|
settings, _ := GlobalConfig.Settings()
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if m != "test" {
|
keys := make([]string, 0, len(settings))
|
||||||
settings, _ := GlobalConfig.Settings()
|
for k := range settings {
|
||||||
log.Print("All settings:")
|
keys = append(keys, k)
|
||||||
for key, val := range settings {
|
}
|
||||||
// TODO password settings should be excluded!
|
sort.Strings(keys)
|
||||||
log.Printf(" %s = %s \n", key, val)
|
|
||||||
|
log.Print("All settings (except for PW and secrets):")
|
||||||
|
for _, k := range keys {
|
||||||
|
if !strings.Contains(k, "pass") && !strings.Contains(k, "secret") {
|
||||||
|
log.Printf(" %s = %s \n", k, settings[k])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/** Database package.
|
/** Package database
|
||||||
*
|
*
|
||||||
* @author Sonja Happ <sonja.happ@eonerc.rwth-aachen.de>
|
* @author Sonja Happ <sonja.happ@eonerc.rwth-aachen.de>
|
||||||
* @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC
|
* @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC
|
||||||
|
@ -36,8 +36,8 @@ import (
|
||||||
|
|
||||||
var DBpool *gorm.DB // database used by backend
|
var DBpool *gorm.DB // database used by backend
|
||||||
|
|
||||||
// Initialize connection to the database
|
// InitDB Initialize connection to the database
|
||||||
func InitDB(cfg *config.Config) error {
|
func InitDB(cfg *config.Config, dbClear string) error {
|
||||||
name, err := cfg.String("db.name")
|
name, err := cfg.String("db.name")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -73,20 +73,25 @@ func InitDB(cfg *config.Config) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
DBpool = db
|
DBpool = db
|
||||||
|
|
||||||
|
// drop tables if parameter set
|
||||||
|
if dbClear == "true" {
|
||||||
|
DropTables()
|
||||||
|
log.Println("Database tables dropped")
|
||||||
|
}
|
||||||
|
|
||||||
MigrateModels()
|
MigrateModels()
|
||||||
log.Println("Database connection established")
|
log.Println("Database connection established")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connection pool to already opened DB
|
// GetDB Connection pool to already opened DB
|
||||||
func GetDB() *gorm.DB {
|
func GetDB() *gorm.DB {
|
||||||
return DBpool
|
return DBpool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drop all the tables of the database
|
// DropTables drops all the tables of the database (use with care!)
|
||||||
// TODO: Remove that function from the codebase and substitute the body
|
|
||||||
// to the Dummy*() where it is called
|
|
||||||
func DropTables() {
|
func DropTables() {
|
||||||
DBpool.DropTableIfExists(&InfrastructureComponent{})
|
DBpool.DropTableIfExists(&InfrastructureComponent{})
|
||||||
DBpool.DropTableIfExists(&Signal{})
|
DBpool.DropTableIfExists(&Signal{})
|
||||||
|
@ -101,7 +106,7 @@ func DropTables() {
|
||||||
DBpool.DropTableIfExists("user_scenarios")
|
DBpool.DropTableIfExists("user_scenarios")
|
||||||
}
|
}
|
||||||
|
|
||||||
// AutoMigrate the models
|
// MigrateModels AutoMigrate the models
|
||||||
func MigrateModels() {
|
func MigrateModels() {
|
||||||
DBpool.AutoMigrate(&InfrastructureComponent{})
|
DBpool.AutoMigrate(&InfrastructureComponent{})
|
||||||
DBpool.AutoMigrate(&Signal{})
|
DBpool.AutoMigrate(&Signal{})
|
||||||
|
@ -122,19 +127,20 @@ func DBAddAdminUser(cfg *config.Config) (error, string) {
|
||||||
var users []User
|
var users []User
|
||||||
err := DBpool.Where("Role = ?", "Admin").Find(&users).Error
|
err := DBpool.Where("Role = ?", "Admin").Find(&users).Error
|
||||||
adminPW := ""
|
adminPW := ""
|
||||||
|
adminName := ""
|
||||||
|
|
||||||
if len(users) == 0 {
|
if len(users) == 0 {
|
||||||
fmt.Println("No admin user found in DB, adding default admin user.")
|
fmt.Println("No admin user found in DB, adding default admin user.")
|
||||||
|
|
||||||
name, err := cfg.String("admin.user")
|
adminName, err = cfg.String("admin.user")
|
||||||
if err != nil || name == "" {
|
if err != nil || adminName == "" {
|
||||||
name = "admin"
|
adminName = "admin"
|
||||||
}
|
}
|
||||||
|
|
||||||
adminPW, err = cfg.String("admin.pass")
|
adminPW, err = cfg.String("admin.pass")
|
||||||
if err != nil || adminPW == "" {
|
if err != nil || adminPW == "" {
|
||||||
adminPW = generatePassword(16)
|
adminPW = generatePassword(16)
|
||||||
fmt.Printf(" Generated admin password: %s\n", adminPW)
|
fmt.Printf(" Generated admin password: %s for admin user %s\n", adminPW, adminName)
|
||||||
}
|
}
|
||||||
|
|
||||||
mail, err := cfg.String("admin.mail")
|
mail, err := cfg.String("admin.mail")
|
||||||
|
@ -145,14 +151,16 @@ func DBAddAdminUser(cfg *config.Config) (error, string) {
|
||||||
pwEnc, _ := bcrypt.GenerateFromPassword([]byte(adminPW), 10)
|
pwEnc, _ := bcrypt.GenerateFromPassword([]byte(adminPW), 10)
|
||||||
|
|
||||||
// create a copy of global test data
|
// create a copy of global test data
|
||||||
user := User{Username: name, Password: string(pwEnc),
|
user := User{Username: adminName, Password: string(pwEnc),
|
||||||
Role: "Admin", Mail: mail, Active: true}
|
Role: "Admin", Mail: mail, Active: true}
|
||||||
|
|
||||||
// add admin user to DB
|
// add admin user to DB
|
||||||
err = DBpool.Create(&user).Error
|
err = DBpool.Create(&user).Error
|
||||||
|
if err != nil {
|
||||||
|
return err, ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return nil, adminPW
|
||||||
return err, adminPW
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func generatePassword(Len int) string {
|
func generatePassword(Len int) string {
|
||||||
|
|
|
@ -51,39 +51,39 @@ func TestInitDB(t *testing.T) {
|
||||||
|
|
||||||
ownconfig := config.NewConfig([]config.Provider{defaults, env})
|
ownconfig := config.NewConfig([]config.Provider{defaults, env})
|
||||||
|
|
||||||
err = InitDB(ownconfig)
|
err = InitDB(ownconfig, "true")
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
dbname, err := configuration.GlobalConfig.String("db.name")
|
dbname, err := configuration.GlobalConfig.String("db.name")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
static["db.name"] = dbname
|
static["db.name"] = dbname
|
||||||
ownconfig = config.NewConfig([]config.Provider{defaults, env})
|
ownconfig = config.NewConfig([]config.Provider{defaults, env})
|
||||||
err = InitDB(ownconfig)
|
err = InitDB(ownconfig, "true")
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
|
||||||
dbhost, err := configuration.GlobalConfig.String("db.host")
|
dbhost, err := configuration.GlobalConfig.String("db.host")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
static["db.host"] = dbhost
|
static["db.host"] = dbhost
|
||||||
ownconfig = config.NewConfig([]config.Provider{defaults, env})
|
ownconfig = config.NewConfig([]config.Provider{defaults, env})
|
||||||
err = InitDB(ownconfig)
|
err = InitDB(ownconfig, "true")
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
|
||||||
dbuser, err := configuration.GlobalConfig.String("db.user")
|
dbuser, err := configuration.GlobalConfig.String("db.user")
|
||||||
static["db.user"] = dbuser
|
static["db.user"] = dbuser
|
||||||
ownconfig = config.NewConfig([]config.Provider{defaults, env})
|
ownconfig = config.NewConfig([]config.Provider{defaults, env})
|
||||||
err = InitDB(ownconfig)
|
err = InitDB(ownconfig, "true")
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
|
||||||
dbpass, err := configuration.GlobalConfig.String("db.pass")
|
dbpass, err := configuration.GlobalConfig.String("db.pass")
|
||||||
static["db.pass"] = dbpass
|
static["db.pass"] = dbpass
|
||||||
ownconfig = config.NewConfig([]config.Provider{defaults, env})
|
ownconfig = config.NewConfig([]config.Provider{defaults, env})
|
||||||
err = InitDB(ownconfig)
|
err = InitDB(ownconfig, "true")
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
|
||||||
dbssl, err := configuration.GlobalConfig.String("db.ssl")
|
dbssl, err := configuration.GlobalConfig.String("db.ssl")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
static["db.ssl"] = dbssl
|
static["db.ssl"] = dbssl
|
||||||
ownconfig = config.NewConfig([]config.Provider{defaults, env})
|
ownconfig = config.NewConfig([]config.Provider{defaults, env})
|
||||||
err = InitDB(ownconfig)
|
err = InitDB(ownconfig, "true")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Verify that you can connect to the database
|
// Verify that you can connect to the database
|
||||||
|
|
|
@ -143,7 +143,7 @@ func TestMain(m *testing.M) {
|
||||||
panic(m)
|
panic(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = database.InitDB(configuration.GlobalConfig)
|
err = database.InitDB(configuration.GlobalConfig, "true")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(m)
|
panic(m)
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ func TestMain(m *testing.M) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(m)
|
panic(m)
|
||||||
}
|
}
|
||||||
err = database.InitDB(configuration.GlobalConfig)
|
err = database.InitDB(configuration.GlobalConfig, "true")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(m)
|
panic(m)
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ func TestMain(m *testing.M) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(m)
|
panic(m)
|
||||||
}
|
}
|
||||||
err = database.InitDB(configuration.GlobalConfig)
|
err = database.InitDB(configuration.GlobalConfig, "true")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(m)
|
panic(m)
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ func TestHealthz(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// connect DB
|
// connect DB
|
||||||
err = database.InitDB(configuration.GlobalConfig)
|
err = database.InitDB(configuration.GlobalConfig, "true")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
defer database.DBpool.Close()
|
defer database.DBpool.Close()
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ func TestHealthz(t *testing.T) {
|
||||||
assert.Equalf(t, 500, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 500, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// reconnect DB
|
// reconnect DB
|
||||||
err = database.InitDB(configuration.GlobalConfig)
|
err = database.InitDB(configuration.GlobalConfig, "true")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
defer database.DBpool.Close()
|
defer database.DBpool.Close()
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ func TestMain(m *testing.M) {
|
||||||
panic(m)
|
panic(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = database.InitDB(configuration.GlobalConfig)
|
err = database.InitDB(configuration.GlobalConfig, "true")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(m)
|
panic(m)
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,41 +102,58 @@ func RegisterEndpoints(router *gin.Engine, api *gin.RouterGroup) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read test data from JSON file (path set by ENV variable or command line param)
|
// ReadTestDataFromJson Reads test data from JSON file (path set by ENV variable or command line param)
|
||||||
func ReadTestDataFromJson(path string) error {
|
func ReadTestDataFromJson(path string) error {
|
||||||
|
|
||||||
jsonFile, err := os.Open(path)
|
_, err := os.Stat(path)
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error opening json file: %v", err)
|
|
||||||
}
|
|
||||||
log.Println("Successfully opened json data file", path)
|
|
||||||
|
|
||||||
defer jsonFile.Close()
|
if err == nil {
|
||||||
|
|
||||||
byteValue, _ := ioutil.ReadAll(jsonFile)
|
jsonFile, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error opening json file: %v", err)
|
||||||
|
}
|
||||||
|
log.Println("Successfully opened json data file", path)
|
||||||
|
|
||||||
err = json.Unmarshal(byteValue, &GlobalTestData)
|
defer jsonFile.Close()
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error unmarshalling json: %v", err)
|
byteValue, _ := ioutil.ReadAll(jsonFile)
|
||||||
|
|
||||||
|
err = json.Unmarshal(byteValue, &GlobalTestData)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error unmarshalling json: %v", err)
|
||||||
|
}
|
||||||
|
} else if os.IsNotExist(err) {
|
||||||
|
log.Println("Test data file does not exist, no test data added to DB:", path)
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
log.Println("Something is wrong with this file path:", path)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uses API endpoints to add test data to the backend; All endpoints have to be registered before invoking this function.
|
// AddTestData Uses API endpoints to add test data to the backend; All endpoints have to be registered before invoking this function.
|
||||||
func AddTestData(cfg *config.Config, router *gin.Engine) (*bytes.Buffer, error) {
|
func AddTestData(cfg *config.Config, router *gin.Engine) (*bytes.Buffer, error) {
|
||||||
database.MigrateModels()
|
|
||||||
|
|
||||||
// add Admin user (defaults to User_0, xyz789)
|
adminPW, errPW := cfg.String("admin.pass")
|
||||||
err, adminpw := database.DBAddAdminUser(cfg)
|
adminName, errName := cfg.String("admin.user")
|
||||||
|
if errPW != nil || errName != nil {
|
||||||
|
if errName != nil {
|
||||||
|
log.Println("WARNING:", errName)
|
||||||
|
}
|
||||||
|
if errPW != nil {
|
||||||
|
log.Println("WARNING:", errPW)
|
||||||
|
}
|
||||||
|
|
||||||
var Admin = helper.Credentials{
|
log.Println("WARNING: cannot add test data because of missing admin config, continue without it")
|
||||||
Username: "admin",
|
return nil, nil
|
||||||
Password: adminpw,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
var Admin = helper.Credentials{
|
||||||
return nil, err
|
Username: adminName,
|
||||||
|
Password: adminPW,
|
||||||
}
|
}
|
||||||
|
|
||||||
// authenticate as admin
|
// authenticate as admin
|
||||||
|
@ -147,11 +164,22 @@ func AddTestData(cfg *config.Config, router *gin.Engine) (*bytes.Buffer, error)
|
||||||
|
|
||||||
basePath := "/api/v2"
|
basePath := "/api/v2"
|
||||||
|
|
||||||
|
db := database.GetDB()
|
||||||
|
|
||||||
// add users
|
// add users
|
||||||
for _, u := range GlobalTestData.Users {
|
for _, u := range GlobalTestData.Users {
|
||||||
code, resp, err := helper.TestEndpoint(router, token, basePath+"/users", "POST", helper.KeyModels{"user": u})
|
|
||||||
if code != http.StatusOK {
|
var x []user.User
|
||||||
return resp, fmt.Errorf("error adding user %v: %v", u.Username, err)
|
err = db.Find(&x, "Username = ?", u.Username).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(x) == 0 {
|
||||||
|
code, resp, err := helper.TestEndpoint(router, token, basePath+"/users", "POST", helper.KeyModels{"user": u})
|
||||||
|
if code != http.StatusOK {
|
||||||
|
return resp, fmt.Errorf("error adding user %v: %v", u.Username, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,26 +189,44 @@ func AddTestData(cfg *config.Config, router *gin.Engine) (*bytes.Buffer, error)
|
||||||
for _, i := range GlobalTestData.ICs {
|
for _, i := range GlobalTestData.ICs {
|
||||||
|
|
||||||
if (i.ManagedExternally && amqphost != "") || !i.ManagedExternally {
|
if (i.ManagedExternally && amqphost != "") || !i.ManagedExternally {
|
||||||
code, resp, err := helper.TestEndpoint(router, token, basePath+"/ic", "POST", helper.KeyModels{"ic": i})
|
|
||||||
if code != http.StatusOK {
|
var x []infrastructure_component.InfrastructureComponent
|
||||||
return resp, fmt.Errorf("error adding IC %v: %v", i.Name, err)
|
err = db.Find(&x, "Name = ?", i.Name).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(x) == 0 {
|
||||||
|
code, resp, err := helper.TestEndpoint(router, token, basePath+"/ic", "POST", helper.KeyModels{"ic": i})
|
||||||
|
if code != http.StatusOK {
|
||||||
|
return resp, fmt.Errorf("error adding IC %v: %v", i.Name, err)
|
||||||
|
}
|
||||||
|
counterICs++
|
||||||
}
|
}
|
||||||
counterICs++
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add scenarios
|
// add scenarios
|
||||||
for _, s := range GlobalTestData.Scenarios {
|
for _, s := range GlobalTestData.Scenarios {
|
||||||
code, resp, err := helper.TestEndpoint(router, token, basePath+"/scenarios", "POST", helper.KeyModels{"scenario": s})
|
|
||||||
if code != http.StatusOK {
|
var x []scenario.Scenario
|
||||||
return resp, fmt.Errorf("error adding Scenario %v: %v", s.Name, err)
|
err = db.Find(&x, "Name = ?", s.Name).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// add all users to the scenario
|
if len(x) == 0 {
|
||||||
for _, u := range GlobalTestData.Users {
|
code, resp, err := helper.TestEndpoint(router, token, basePath+"/scenarios", "POST", helper.KeyModels{"scenario": s})
|
||||||
code, resp, err := helper.TestEndpoint(router, token, fmt.Sprintf("%v/scenarios/1/user?username="+u.Username, basePath), "PUT", nil)
|
|
||||||
if code != http.StatusOK {
|
if code != http.StatusOK {
|
||||||
return resp, fmt.Errorf("error adding user %v to scenario %v: %v", u.Username, s.Name, err)
|
return resp, fmt.Errorf("error adding Scenario %v: %v", s.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// add all users to the scenario
|
||||||
|
for _, u := range GlobalTestData.Users {
|
||||||
|
code, resp, err := helper.TestEndpoint(router, token, fmt.Sprintf("%v/scenarios/1/user?username="+u.Username, basePath), "PUT", nil)
|
||||||
|
if code != http.StatusOK {
|
||||||
|
return resp, fmt.Errorf("error adding user %v to scenario %v: %v", u.Username, s.Name, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,11 +236,20 @@ func AddTestData(cfg *config.Config, router *gin.Engine) (*bytes.Buffer, error)
|
||||||
if len(GlobalTestData.Scenarios) > 0 && counterICs > 0 {
|
if len(GlobalTestData.Scenarios) > 0 && counterICs > 0 {
|
||||||
|
|
||||||
for _, c := range GlobalTestData.Configs {
|
for _, c := range GlobalTestData.Configs {
|
||||||
c.ScenarioID = 1
|
|
||||||
c.ICID = 1
|
var x []component_configuration.ComponentConfiguration
|
||||||
code, resp, err := helper.TestEndpoint(router, token, basePath+"/configs", "POST", helper.KeyModels{"config": c})
|
err = db.Find(&x, "Name = ?", c.Name).Error
|
||||||
if code != http.StatusOK {
|
if err != nil {
|
||||||
return resp, fmt.Errorf("error adding Config %v: %v", c.Name, err)
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(x) == 0 {
|
||||||
|
c.ScenarioID = 1
|
||||||
|
c.ICID = 1
|
||||||
|
code, resp, err := helper.TestEndpoint(router, token, basePath+"/configs", "POST", helper.KeyModels{"config": c})
|
||||||
|
if code != http.StatusOK {
|
||||||
|
return resp, fmt.Errorf("error adding Config %v: %v", c.Name, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
configCounter++
|
configCounter++
|
||||||
}
|
}
|
||||||
|
@ -204,72 +259,114 @@ func AddTestData(cfg *config.Config, router *gin.Engine) (*bytes.Buffer, error)
|
||||||
dashboardCounter := 0
|
dashboardCounter := 0
|
||||||
if len(GlobalTestData.Scenarios) > 0 {
|
if len(GlobalTestData.Scenarios) > 0 {
|
||||||
for _, d := range GlobalTestData.Dashboards {
|
for _, d := range GlobalTestData.Dashboards {
|
||||||
d.ScenarioID = 1
|
|
||||||
code, resp, err := helper.TestEndpoint(router, token, basePath+"/dashboards", "POST", helper.KeyModels{"dashboard": d})
|
var x []dashboard.Dashboard
|
||||||
if code != http.StatusOK {
|
err = db.Find(&x, "Name = ?", d.Name).Error
|
||||||
return resp, fmt.Errorf("error adding Dashboard %v: %v", d.Name, err)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(x) == 0 {
|
||||||
|
d.ScenarioID = 1
|
||||||
|
code, resp, err := helper.TestEndpoint(router, token, basePath+"/dashboards", "POST", helper.KeyModels{"dashboard": d})
|
||||||
|
if code != http.StatusOK {
|
||||||
|
return resp, fmt.Errorf("error adding Dashboard %v: %v", d.Name, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dashboardCounter++
|
dashboardCounter++
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, r := range GlobalTestData.Results {
|
for _, r := range GlobalTestData.Results {
|
||||||
r.ScenarioID = 1
|
|
||||||
r.ResultFileIDs = []int64{}
|
var x []result.Result
|
||||||
code, resp, err := helper.TestEndpoint(router, token, basePath+"/results", "POST", helper.KeyModels{"result": r})
|
err = db.Find(&x, "Description = ?", r.Description).Error
|
||||||
if code != http.StatusOK {
|
if err != nil {
|
||||||
return resp, fmt.Errorf("error adding Result %v: %v", r.Description, err)
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(x) == 0 {
|
||||||
|
r.ScenarioID = 1
|
||||||
|
r.ResultFileIDs = []int64{}
|
||||||
|
code, resp, err := helper.TestEndpoint(router, token, basePath+"/results", "POST", helper.KeyModels{"result": r})
|
||||||
|
if code != http.StatusOK {
|
||||||
|
return resp, fmt.Errorf("error adding Result %v: %v", r.Description, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// upload files
|
// upload files
|
||||||
|
|
||||||
// upload readme file
|
var x []file.File
|
||||||
bodyBuf := &bytes.Buffer{}
|
err = db.Find(&x, "Name = ?", "Readme.md").Error
|
||||||
bodyWriter := multipart.NewWriter(bodyBuf)
|
if err != nil {
|
||||||
fileWriter, _ := bodyWriter.CreateFormFile("file", "Readme.md")
|
return nil, err
|
||||||
fh, _ := os.Open("README.md")
|
}
|
||||||
defer fh.Close()
|
|
||||||
|
|
||||||
// io copy
|
if len(x) == 0 {
|
||||||
_, err = io.Copy(fileWriter, fh)
|
// upload readme file
|
||||||
contentType := bodyWriter.FormDataContentType()
|
bodyBuf := &bytes.Buffer{}
|
||||||
bodyWriter.Close()
|
bodyWriter := multipart.NewWriter(bodyBuf)
|
||||||
|
fileWriter, _ := bodyWriter.CreateFormFile("file", "Readme.md")
|
||||||
|
fh, _ := os.Open("README.md")
|
||||||
|
defer fh.Close()
|
||||||
|
|
||||||
// Create the request and add file to scenario
|
// io copy
|
||||||
w1 := httptest.NewRecorder()
|
_, err = io.Copy(fileWriter, fh)
|
||||||
req1, _ := http.NewRequest("POST", basePath+"/files?scenarioID=1", bodyBuf)
|
contentType := bodyWriter.FormDataContentType()
|
||||||
req1.Header.Set("Content-Type", contentType)
|
bodyWriter.Close()
|
||||||
req1.Header.Add("Authorization", "Bearer "+token)
|
|
||||||
router.ServeHTTP(w1, req1)
|
|
||||||
|
|
||||||
// upload image file
|
// Create the request and add file to scenario
|
||||||
bodyBuf = &bytes.Buffer{}
|
w1 := httptest.NewRecorder()
|
||||||
bodyWriter = multipart.NewWriter(bodyBuf)
|
req1, _ := http.NewRequest("POST", basePath+"/files?scenarioID=1", bodyBuf)
|
||||||
fileWriter, _ = bodyWriter.CreateFormFile("file", "logo.png")
|
req1.Header.Set("Content-Type", contentType)
|
||||||
fh, _ = os.Open("doc/pictures/villas_web.png")
|
req1.Header.Add("Authorization", "Bearer "+token)
|
||||||
defer fh.Close()
|
router.ServeHTTP(w1, req1)
|
||||||
|
}
|
||||||
|
|
||||||
// io copy
|
var y []file.File
|
||||||
_, err = io.Copy(fileWriter, fh)
|
err = db.Find(&y, "Name = ?", "logo.png").Error
|
||||||
contentType = bodyWriter.FormDataContentType()
|
if err != nil {
|
||||||
bodyWriter.Close()
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// Create the request and add a second file to scenario
|
if len(y) == 0 {
|
||||||
w2 := httptest.NewRecorder()
|
// upload image file
|
||||||
req2, _ := http.NewRequest("POST", basePath+"/files?scenarioID=1", bodyBuf)
|
bodyBuf := &bytes.Buffer{}
|
||||||
req2.Header.Set("Content-Type", contentType)
|
bodyWriter := multipart.NewWriter(bodyBuf)
|
||||||
req2.Header.Add("Authorization", "Bearer "+token)
|
fileWriter, _ := bodyWriter.CreateFormFile("file", "logo.png")
|
||||||
router.ServeHTTP(w2, req2)
|
fh, _ := os.Open("doc/pictures/villas_web.png")
|
||||||
|
defer fh.Close()
|
||||||
|
|
||||||
|
// io copy
|
||||||
|
_, err = io.Copy(fileWriter, fh)
|
||||||
|
contentType := bodyWriter.FormDataContentType()
|
||||||
|
bodyWriter.Close()
|
||||||
|
|
||||||
|
// Create the request and add a second file to scenario
|
||||||
|
w2 := httptest.NewRecorder()
|
||||||
|
req2, _ := http.NewRequest("POST", basePath+"/files?scenarioID=1", bodyBuf)
|
||||||
|
req2.Header.Set("Content-Type", contentType)
|
||||||
|
req2.Header.Add("Authorization", "Bearer "+token)
|
||||||
|
router.ServeHTTP(w2, req2)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is at least one dashboard, add widgets
|
// If there is at least one dashboard, add widgets
|
||||||
if dashboardCounter > 0 {
|
if dashboardCounter > 0 {
|
||||||
for _, w := range GlobalTestData.Widgets {
|
for _, w := range GlobalTestData.Widgets {
|
||||||
w.DashboardID = 1
|
|
||||||
code, resp, err := helper.TestEndpoint(router, token, basePath+"/widgets", "POST", helper.KeyModels{"widget": w})
|
var x []widget.Widget
|
||||||
if code != http.StatusOK {
|
err = db.Find(&x, "Name = ?", w.Name).Error
|
||||||
return resp, fmt.Errorf("error adding Widget %v: %v", w.Name, err)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(x) == 0 {
|
||||||
|
w.DashboardID = 1
|
||||||
|
code, resp, err := helper.TestEndpoint(router, token, basePath+"/widgets", "POST", helper.KeyModels{"widget": w})
|
||||||
|
if code != http.StatusOK {
|
||||||
|
return resp, fmt.Errorf("error adding Widget %v: %v", w.Name, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -277,10 +374,19 @@ func AddTestData(cfg *config.Config, router *gin.Engine) (*bytes.Buffer, error)
|
||||||
// If there is at least one config, add signals
|
// If there is at least one config, add signals
|
||||||
if configCounter > 0 {
|
if configCounter > 0 {
|
||||||
for _, s := range GlobalTestData.Signals {
|
for _, s := range GlobalTestData.Signals {
|
||||||
s.ConfigID = 1
|
|
||||||
code, resp, err := helper.TestEndpoint(router, token, basePath+"/signals", "POST", helper.KeyModels{"signal": s})
|
var x []signal.Signal
|
||||||
if code != http.StatusOK {
|
err = db.Find(&x, "Name = ?", s.Name).Error
|
||||||
return resp, fmt.Errorf("error adding Signal %v: %v", s.Name, err)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(x) == 0 {
|
||||||
|
s.ConfigID = 1
|
||||||
|
code, resp, err := helper.TestEndpoint(router, token, basePath+"/signals", "POST", helper.KeyModels{"signal": s})
|
||||||
|
if code != http.StatusOK {
|
||||||
|
return resp, fmt.Errorf("error adding Signal %v: %v", s.Name, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ func TestMain(m *testing.M) {
|
||||||
panic(m)
|
panic(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = database.InitDB(configuration.GlobalConfig)
|
err = database.InitDB(configuration.GlobalConfig, "true")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(m)
|
panic(m)
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ func TestMain(m *testing.M) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(m)
|
panic(m)
|
||||||
}
|
}
|
||||||
err = database.InitDB(configuration.GlobalConfig)
|
err = database.InitDB(configuration.GlobalConfig, "true")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(m)
|
panic(m)
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ func TestMain(m *testing.M) {
|
||||||
panic(m)
|
panic(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = database.InitDB(configuration.GlobalConfig)
|
err = database.InitDB(configuration.GlobalConfig, "true")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(m)
|
panic(m)
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,7 +151,7 @@ func TestMain(m *testing.M) {
|
||||||
panic(m)
|
panic(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = database.InitDB(configuration.GlobalConfig)
|
err = database.InitDB(configuration.GlobalConfig, "true")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(m)
|
panic(m)
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ func TestMain(m *testing.M) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(m)
|
panic(m)
|
||||||
}
|
}
|
||||||
err = database.InitDB(configuration.GlobalConfig)
|
err = database.InitDB(configuration.GlobalConfig, "true")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(m)
|
panic(m)
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@ func TestMain(m *testing.M) {
|
||||||
panic(m)
|
panic(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = database.InitDB(configuration.GlobalConfig)
|
err = database.InitDB(configuration.GlobalConfig, "true")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(m)
|
panic(m)
|
||||||
}
|
}
|
||||||
|
|
64
start.go
64
start.go
|
@ -35,34 +35,24 @@ import (
|
||||||
|
|
||||||
func addData(router *gin.Engine, cfg *config.Config) error {
|
func addData(router *gin.Engine, cfg *config.Config) error {
|
||||||
|
|
||||||
if mode, err := cfg.String("mode"); err == nil && mode == "test" {
|
testDataPath, err := cfg.String("test.datapath")
|
||||||
// test mode: drop all tables and add test data to DB
|
if err != nil {
|
||||||
database.DropTables()
|
// if param is missing, no test data will be added
|
||||||
log.Println("Database tables dropped, using API to add test data")
|
return nil
|
||||||
|
|
||||||
testDataPath, err := cfg.String("test.datapath")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = routes.ReadTestDataFromJson(testDataPath)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("testdata could not be read from json")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := routes.AddTestData(cfg, router)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("error: testdata could not be added to DB:", err.Error(), "Response body: ", resp)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// release mode: make sure that at least one admin user exists in DB
|
|
||||||
err, _ := database.DBAddAdminUser(cfg)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("error: adding admin user failed:", err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = routes.ReadTestDataFromJson(testDataPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("WARNING: test data cannot not be read from file, continue without it: ", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := routes.AddTestData(cfg, router)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("ERROR: test data could not be added to DB:", err.Error(), "Response body: ", resp)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,9 +77,9 @@ func main() {
|
||||||
log.Fatalf("Error during initialization of global configuration: %s, aborting.", err)
|
log.Fatalf("Error during initialization of global configuration: %s, aborting.", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
mode, err := configuration.GlobalConfig.String("mode")
|
dbClear, err := configuration.GlobalConfig.String("db.clear")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error reading mode from global configuration: %s, aborting.", err)
|
log.Fatalf("Error reading db.clear parameter from global configuration: %s, aborting.", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
port, err := configuration.GlobalConfig.String("port")
|
port, err := configuration.GlobalConfig.String("port")
|
||||||
|
@ -110,16 +100,14 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init database
|
// Init database
|
||||||
err = database.InitDB(configuration.GlobalConfig)
|
err = database.InitDB(configuration.GlobalConfig, dbClear)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error during initialization of database: %s, aborting.", err)
|
log.Fatalf("Error during initialization of database: %s, aborting.", err)
|
||||||
}
|
}
|
||||||
defer database.DBpool.Close()
|
defer database.DBpool.Close()
|
||||||
|
|
||||||
// Init endpoints
|
// Init endpoints
|
||||||
if mode == "release" {
|
gin.SetMode(gin.ReleaseMode)
|
||||||
gin.SetMode(gin.ReleaseMode)
|
|
||||||
}
|
|
||||||
|
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
api := r.Group("/api/v2")
|
api := r.Group("/api/v2")
|
||||||
|
@ -139,12 +127,20 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add data to DB (if any)
|
// Make sure that at least one admin user exists in DB
|
||||||
|
err, _ = database.DBAddAdminUser(configuration.GlobalConfig)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("error: adding admin user failed:", err.Error())
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add test/demo data to DB (if any)
|
||||||
err = addData(r, configuration.GlobalConfig)
|
err = addData(r, configuration.GlobalConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Println("Running...")
|
||||||
// Server at port 4000 to match frontend's redirect path
|
// Server at port 4000 to match frontend's redirect path
|
||||||
r.Run(":" + port)
|
r.Run(":" + port)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue