mirror of
https://git.rwth-aachen.de/acs/public/villas/web-backend-go/
synced 2025-03-30 00:00:12 +01:00
Merge branch 'renaming-simulator-simmodel' into 'master'
Renaming simulator and simmodel See merge request acs/public/villas/web-backend-go!14
This commit is contained in:
commit
361121434b
37 changed files with 3484 additions and 3409 deletions
|
@ -95,10 +95,10 @@ test:scenario:
|
||||||
variables:
|
variables:
|
||||||
TEST_FOLDER: routes/scenario
|
TEST_FOLDER: routes/scenario
|
||||||
|
|
||||||
test:simulationmodel:
|
test:component-configuration:
|
||||||
extends: test:scenario
|
extends: test:database
|
||||||
variables:
|
variables:
|
||||||
TEST_FOLDER: routes/simulationmodel
|
TEST_FOLDER: routes/component-configuration
|
||||||
|
|
||||||
test:signal:
|
test:signal:
|
||||||
extends: test:database
|
extends: test:database
|
||||||
|
@ -115,10 +115,10 @@ test:widget:
|
||||||
variables:
|
variables:
|
||||||
TEST_FOLDER: routes/widget
|
TEST_FOLDER: routes/widget
|
||||||
|
|
||||||
test:simulator:
|
test:infrastructure-component:
|
||||||
extends: test:database
|
extends: test:database
|
||||||
variables:
|
variables:
|
||||||
TEST_FOLDER: routes/simulator
|
TEST_FOLDER: routes/infrastructure-component
|
||||||
|
|
||||||
test:file:
|
test:file:
|
||||||
extends: test:database
|
extends: test:database
|
||||||
|
|
|
@ -24,32 +24,32 @@ package amqp
|
||||||
import (
|
import (
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/simulator"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/infrastructure-component"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RegisterAMQPEndpoint(r *gin.RouterGroup) {
|
func RegisterAMQPEndpoint(r *gin.RouterGroup) {
|
||||||
r.POST("/:simulatorID/action", sendActionToSimulator)
|
r.POST("/ICID/action", sendActionToIC)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendActionToSimulator godoc
|
// sendActionToIC godoc
|
||||||
// @Summary Send an action to simulator (only available if backend server is started with -amqp parameter)
|
// @Summary Send an action to IC (only available if backend server is started with -amqp parameter)
|
||||||
// @ID sendActionToSimulator
|
// @ID sendActionToIC
|
||||||
// @Tags AMQP
|
// @Tags AMQP
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param inputAction query string true "Action for simulator"
|
// @Param inputAction query string true "Action for IC"
|
||||||
// @Success 200 {object} docs.ResponseError "Action sent successfully"
|
// @Success 200 {object} docs.ResponseError "Action sent successfully"
|
||||||
// @Failure 400 {object} docs.ResponseError "Bad request"
|
// @Failure 400 {object} docs.ResponseError "Bad request"
|
||||||
// @Failure 404 {object} docs.ResponseError "Not found"
|
// @Failure 404 {object} docs.ResponseError "Not found"
|
||||||
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
||||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
||||||
// @Param simulatorID path int true "Simulator ID"
|
// @Param ICID path int true "InfrastructureComponent ID"
|
||||||
// @Router /simulators/{simulatorID}/action [post]
|
// @Router /ic/{ICID}/action [post]
|
||||||
func sendActionToSimulator(c *gin.Context) {
|
func sendActionToIC(c *gin.Context) {
|
||||||
|
|
||||||
ok, s := simulator.CheckPermissions(c, database.ModelSimulatorAction, database.Update, true)
|
ok, s := infrastructure_component.CheckPermissions(c, database.ModelInfrastructureComponentAction, database.Update, true)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ func sendActionToSimulator(c *gin.Context) {
|
||||||
|
|
||||||
err = SendActionAMQP(action, s.UUID)
|
err = SendActionAMQP(action, s.UUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.InternalServerError(c, "Unable to send actions to simulator: "+err.Error())
|
helper.InternalServerError(c, "Unable to send actions to IC: "+err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,8 +77,8 @@ func ConnectAMQP(uri string) error {
|
||||||
return fmt.Errorf("AMQP: failed to declare the exchange")
|
return fmt.Errorf("AMQP: failed to declare the exchange")
|
||||||
}
|
}
|
||||||
|
|
||||||
// add a queue for the simulators
|
// add a queue for the ICs
|
||||||
simulatorQueue, err := client.channel.QueueDeclare("simulators",
|
ICQueue, err := client.channel.QueueDeclare("infrastructure_components",
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
@ -88,13 +88,13 @@ func ConnectAMQP(uri string) error {
|
||||||
return fmt.Errorf("AMQP: failed to declare the queue")
|
return fmt.Errorf("AMQP: failed to declare the queue")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = client.channel.QueueBind(simulatorQueue.Name, "", VILLAS_EXCHANGE, false, nil)
|
err = client.channel.QueueBind(ICQueue.Name, "", VILLAS_EXCHANGE, false, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("AMQP: failed to bind the queue")
|
return fmt.Errorf("AMQP: failed to bind the queue")
|
||||||
}
|
}
|
||||||
|
|
||||||
// consume deliveries
|
// consume deliveries
|
||||||
client.replies, err = client.channel.Consume(simulatorQueue.Name,
|
client.replies, err = client.channel.Consume(ICQueue.Name,
|
||||||
"",
|
"",
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
@ -120,15 +120,15 @@ func ConnectAMQP(uri string) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
var sToBeUpdated database.Simulator
|
var sToBeUpdated database.InfrastructureComponent
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
simulatorUUID := gjson.Get(content, "properties.uuid").String()
|
ICUUID := gjson.Get(content, "properties.uuid").String()
|
||||||
if simulatorUUID == "" {
|
if ICUUID == "" {
|
||||||
log.Println("AMQP: Could not extract UUID of simulator from content of received message, SIMULATOR NOT UPDATED")
|
log.Println("AMQP: Could not extract UUID of IC from content of received message, COMPONENT NOT UPDATED")
|
||||||
} else {
|
} else {
|
||||||
err = db.Where("UUID = ?", simulatorUUID).Find(sToBeUpdated).Error
|
err = db.Where("UUID = ?", ICUUID).Find(sToBeUpdated).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("AMQP: Unable to find simulator with UUID: ", gjson.Get(content, "properties.uuid"), " DB error message: ", err)
|
log.Println("AMQP: Unable to find IC with UUID: ", gjson.Get(content, "properties.uuid"), " DB error message: ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = db.Model(&sToBeUpdated).Updates(map[string]interface{}{
|
err = db.Model(&sToBeUpdated).Updates(map[string]interface{}{
|
||||||
|
@ -140,10 +140,10 @@ func ConnectAMQP(uri string) error {
|
||||||
"RawProperties": gjson.Get(content, "properties"),
|
"RawProperties": gjson.Get(content, "properties"),
|
||||||
}).Error
|
}).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("AMQP: Unable to update simulator in DB: ", err)
|
log.Println("AMQP: Unable to update IC in DB: ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("AMQP: Updated simulator with UUID ", gjson.Get(content, "properties.uuid"))
|
log.Println("AMQP: Updated IC with UUID ", gjson.Get(content, "properties.uuid"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -182,7 +182,7 @@ func SendActionAMQP(action Action, uuid string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func PingAMQP() error {
|
func PingAMQP() error {
|
||||||
log.Println("AMQP: sending ping command to all simulators")
|
log.Println("AMQP: sending ping command to all ICs")
|
||||||
|
|
||||||
var a Action
|
var a Action
|
||||||
a.Act = "ping"
|
a.Act = "ping"
|
||||||
|
|
|
@ -55,9 +55,9 @@ read_users () {
|
||||||
-X GET | jq '.' && printf '\n'
|
-X GET | jq '.' && printf '\n'
|
||||||
}
|
}
|
||||||
|
|
||||||
read_simulators () {
|
read_infrastructure_components () {
|
||||||
printf "> GET "$apiBase"/simulators\n"
|
printf "> GET "$apiBase"/ic\n"
|
||||||
curl "$apiBase"/simulators -s \
|
curl "$apiBase"/ic -s \
|
||||||
-H "Contet-Type: application/json" \
|
-H "Contet-Type: application/json" \
|
||||||
-H "Authorization: Bearer $(< auth.jwt)" \
|
-H "Authorization: Bearer $(< auth.jwt)" \
|
||||||
-X GET | jq '.' && printf '\n'
|
-X GET | jq '.' && printf '\n'
|
||||||
|
@ -114,7 +114,7 @@ login "$admin"
|
||||||
#create_user "$userC"
|
#create_user "$userC"
|
||||||
#read_users
|
#read_users
|
||||||
#read_user 1
|
#read_user 1
|
||||||
#read_simulators
|
#read_infrastructure_components
|
||||||
create_user "$newUserW"
|
create_user "$newUserW"
|
||||||
#read_users
|
#read_users
|
||||||
read_user 4
|
read_user 4
|
||||||
|
|
|
@ -102,9 +102,9 @@ func GetDB() *gorm.DB {
|
||||||
// TODO: Remove that function from the codebase and substitute the body
|
// TODO: Remove that function from the codebase and substitute the body
|
||||||
// to the Dummy*() where it is called
|
// to the Dummy*() where it is called
|
||||||
func DropTables(db *gorm.DB) {
|
func DropTables(db *gorm.DB) {
|
||||||
db.DropTableIfExists(&Simulator{})
|
db.DropTableIfExists(&InfrastructureComponent{})
|
||||||
db.DropTableIfExists(&Signal{})
|
db.DropTableIfExists(&Signal{})
|
||||||
db.DropTableIfExists(&SimulationModel{})
|
db.DropTableIfExists(&ComponentConfiguration{})
|
||||||
db.DropTableIfExists(&File{})
|
db.DropTableIfExists(&File{})
|
||||||
db.DropTableIfExists(&Scenario{})
|
db.DropTableIfExists(&Scenario{})
|
||||||
db.DropTableIfExists(&User{})
|
db.DropTableIfExists(&User{})
|
||||||
|
@ -116,9 +116,9 @@ func DropTables(db *gorm.DB) {
|
||||||
|
|
||||||
// AutoMigrate the models
|
// AutoMigrate the models
|
||||||
func MigrateModels(db *gorm.DB) {
|
func MigrateModels(db *gorm.DB) {
|
||||||
db.AutoMigrate(&Simulator{})
|
db.AutoMigrate(&InfrastructureComponent{})
|
||||||
db.AutoMigrate(&Signal{})
|
db.AutoMigrate(&Signal{})
|
||||||
db.AutoMigrate(&SimulationModel{})
|
db.AutoMigrate(&ComponentConfiguration{})
|
||||||
db.AutoMigrate(&File{})
|
db.AutoMigrate(&File{})
|
||||||
db.AutoMigrate(&Scenario{})
|
db.AutoMigrate(&Scenario{})
|
||||||
db.AutoMigrate(&User{})
|
db.AutoMigrate(&User{})
|
||||||
|
|
|
@ -107,8 +107,8 @@ func TestScenarioAssociations(t *testing.T) {
|
||||||
user0 := User0
|
user0 := User0
|
||||||
userA := UserA
|
userA := UserA
|
||||||
userB := UserB
|
userB := UserB
|
||||||
modelA := SimulationModelA
|
configA := ConfigA
|
||||||
modelB := SimulationModelB
|
configB := ConfigB
|
||||||
dashboardA := DashboardA
|
dashboardA := DashboardA
|
||||||
dashboardB := DashboardB
|
dashboardB := DashboardB
|
||||||
|
|
||||||
|
@ -121,9 +121,9 @@ func TestScenarioAssociations(t *testing.T) {
|
||||||
assert.NoError(t, db.Create(&userA).Error) // Normal User
|
assert.NoError(t, db.Create(&userA).Error) // Normal User
|
||||||
assert.NoError(t, db.Create(&userB).Error) // Normal User
|
assert.NoError(t, db.Create(&userB).Error) // Normal User
|
||||||
|
|
||||||
// add simulation models to DB
|
// add component configurations to DB
|
||||||
assert.NoError(t, db.Create(&modelA).Error)
|
assert.NoError(t, db.Create(&configA).Error)
|
||||||
assert.NoError(t, db.Create(&modelB).Error)
|
assert.NoError(t, db.Create(&configB).Error)
|
||||||
|
|
||||||
// add dashboards to DB
|
// add dashboards to DB
|
||||||
assert.NoError(t, db.Create(&dashboardA).Error)
|
assert.NoError(t, db.Create(&dashboardA).Error)
|
||||||
|
@ -136,9 +136,9 @@ func TestScenarioAssociations(t *testing.T) {
|
||||||
assert.NoError(t, db.Model(&scenarioB).Association("Users").Append(&userA).Error)
|
assert.NoError(t, db.Model(&scenarioB).Association("Users").Append(&userA).Error)
|
||||||
assert.NoError(t, db.Model(&scenarioB).Association("Users").Append(&userB).Error)
|
assert.NoError(t, db.Model(&scenarioB).Association("Users").Append(&userB).Error)
|
||||||
|
|
||||||
// add scenario has many simulation models associations
|
// add scenario has many component configurations associations
|
||||||
assert.NoError(t, db.Model(&scenarioA).Association("SimulationModels").Append(&modelA).Error)
|
assert.NoError(t, db.Model(&scenarioA).Association("ComponentConfigurations").Append(&configA).Error)
|
||||||
assert.NoError(t, db.Model(&scenarioA).Association("SimulationModels").Append(&modelB).Error)
|
assert.NoError(t, db.Model(&scenarioA).Association("ComponentConfigurations").Append(&configB).Error)
|
||||||
|
|
||||||
// Scenario HM Dashboards
|
// Scenario HM Dashboards
|
||||||
assert.NoError(t, db.Model(&scenarioA).Association("Dashboards").Append(&dashboardA).Error)
|
assert.NoError(t, db.Model(&scenarioA).Association("Dashboards").Append(&dashboardA).Error)
|
||||||
|
@ -156,12 +156,12 @@ func TestScenarioAssociations(t *testing.T) {
|
||||||
"Expected to have %v Users. Has %v.", 2, len(users))
|
"Expected to have %v Users. Has %v.", 2, len(users))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get simulation models of scenario1
|
// Get component configurations of scenario1
|
||||||
var models []SimulationModel
|
var configs []ComponentConfiguration
|
||||||
assert.NoError(t, db.Model(&scenario1).Related(&models, "SimulationModels").Error)
|
assert.NoError(t, db.Model(&scenario1).Related(&configs, "ComponentConfigurations").Error)
|
||||||
if len(models) != 2 {
|
if len(configs) != 2 {
|
||||||
assert.Fail(t, "Scenario Associations",
|
assert.Fail(t, "Scenario Associations",
|
||||||
"Expected to have %v simulation models. Has %v.", 2, len(models))
|
"Expected to have %v component configs. Has %v.", 2, len(configs))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get dashboards of scenario1
|
// Get dashboards of scenario1
|
||||||
|
@ -173,50 +173,50 @@ func TestScenarioAssociations(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSimulatorAssociations(t *testing.T) {
|
func TestICAssociations(t *testing.T) {
|
||||||
|
|
||||||
DropTables(db)
|
DropTables(db)
|
||||||
MigrateModels(db)
|
MigrateModels(db)
|
||||||
|
|
||||||
// create copies of global test data
|
// create copies of global test data
|
||||||
simulatorA := SimulatorA
|
icA := ICA
|
||||||
simulatorB := SimulatorB
|
icB := ICB
|
||||||
modelA := SimulationModelA
|
configA := ConfigA
|
||||||
modelB := SimulationModelB
|
configB := ConfigB
|
||||||
|
|
||||||
// add simulators to DB
|
// add ICs to DB
|
||||||
assert.NoError(t, db.Create(&simulatorA).Error)
|
assert.NoError(t, db.Create(&icA).Error)
|
||||||
assert.NoError(t, db.Create(&simulatorB).Error)
|
assert.NoError(t, db.Create(&icB).Error)
|
||||||
|
|
||||||
// add simulation models to DB
|
// add component configurations to DB
|
||||||
assert.NoError(t, db.Create(&modelA).Error)
|
assert.NoError(t, db.Create(&configA).Error)
|
||||||
assert.NoError(t, db.Create(&modelB).Error)
|
assert.NoError(t, db.Create(&configB).Error)
|
||||||
|
|
||||||
// add simulator has many simulation models association to DB
|
// add IC has many component configurations association to DB
|
||||||
assert.NoError(t, db.Model(&simulatorA).Association("SimulationModels").Append(&modelA).Error)
|
assert.NoError(t, db.Model(&icA).Association("ComponentConfigurations").Append(&configA).Error)
|
||||||
assert.NoError(t, db.Model(&simulatorA).Association("SimulationModels").Append(&modelB).Error)
|
assert.NoError(t, db.Model(&icA).Association("ComponentConfigurations").Append(&configB).Error)
|
||||||
|
|
||||||
var simulator1 Simulator
|
var ic1 InfrastructureComponent
|
||||||
assert.NoError(t, db.Find(&simulator1, 1).Error, fmt.Sprintf("Find Simulator with ID=1"))
|
assert.NoError(t, db.Find(&ic1, 1).Error, fmt.Sprintf("Find InfrastructureComponent with ID=1"))
|
||||||
assert.EqualValues(t, "Host_A", simulator1.Host)
|
assert.EqualValues(t, "Host_A", ic1.Host)
|
||||||
|
|
||||||
// Get simulation models of simulator1
|
// Get Component Configurations of ic1
|
||||||
var models []SimulationModel
|
var configs []ComponentConfiguration
|
||||||
assert.NoError(t, db.Model(&simulator1).Association("SimulationModels").Find(&models).Error)
|
assert.NoError(t, db.Model(&ic1).Association("ComponentConfigurations").Find(&configs).Error)
|
||||||
if len(models) != 2 {
|
if len(configs) != 2 {
|
||||||
assert.Fail(t, "Simulator Associations",
|
assert.Fail(t, "InfrastructureComponent Associations",
|
||||||
"Expected to have %v SimulationModels. Has %v.", 2, len(models))
|
"Expected to have %v Component Configurations. Has %v.", 2, len(configs))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSimulationModelAssociations(t *testing.T) {
|
func TestComponentConfigurationAssociations(t *testing.T) {
|
||||||
|
|
||||||
DropTables(db)
|
DropTables(db)
|
||||||
MigrateModels(db)
|
MigrateModels(db)
|
||||||
|
|
||||||
// create copies of global test data
|
// create copies of global test data
|
||||||
modelA := SimulationModelA
|
configA := ConfigA
|
||||||
modelB := SimulationModelB
|
configB := ConfigB
|
||||||
outSignalA := OutSignalA
|
outSignalA := OutSignalA
|
||||||
outSignalB := OutSignalB
|
outSignalB := OutSignalB
|
||||||
inSignalA := InSignalA
|
inSignalA := InSignalA
|
||||||
|
@ -225,12 +225,12 @@ func TestSimulationModelAssociations(t *testing.T) {
|
||||||
fileB := FileB
|
fileB := FileB
|
||||||
fileC := FileC
|
fileC := FileC
|
||||||
fileD := FileD
|
fileD := FileD
|
||||||
simulatorA := SimulatorA
|
icA := ICA
|
||||||
simulatorB := SimulatorB
|
icB := ICB
|
||||||
|
|
||||||
// add simulation models to DB
|
// add Component Configurations to DB
|
||||||
assert.NoError(t, db.Create(&modelA).Error)
|
assert.NoError(t, db.Create(&configA).Error)
|
||||||
assert.NoError(t, db.Create(&modelB).Error)
|
assert.NoError(t, db.Create(&configB).Error)
|
||||||
|
|
||||||
// add signals to DB
|
// add signals to DB
|
||||||
assert.NoError(t, db.Create(&outSignalA).Error)
|
assert.NoError(t, db.Create(&outSignalA).Error)
|
||||||
|
@ -244,46 +244,46 @@ func TestSimulationModelAssociations(t *testing.T) {
|
||||||
assert.NoError(t, db.Create(&fileC).Error)
|
assert.NoError(t, db.Create(&fileC).Error)
|
||||||
assert.NoError(t, db.Create(&fileD).Error)
|
assert.NoError(t, db.Create(&fileD).Error)
|
||||||
|
|
||||||
// add simulators to DB
|
// add ICs to DB
|
||||||
assert.NoError(t, db.Create(&simulatorA).Error)
|
assert.NoError(t, db.Create(&icA).Error)
|
||||||
assert.NoError(t, db.Create(&simulatorB).Error)
|
assert.NoError(t, db.Create(&icB).Error)
|
||||||
|
|
||||||
// add simulation model has many signals associations
|
// add Component Configuration has many signals associations
|
||||||
assert.NoError(t, db.Model(&modelA).Association("InputMapping").Append(&inSignalA).Error)
|
assert.NoError(t, db.Model(&configA).Association("InputMapping").Append(&inSignalA).Error)
|
||||||
assert.NoError(t, db.Model(&modelA).Association("InputMapping").Append(&inSignalB).Error)
|
assert.NoError(t, db.Model(&configA).Association("InputMapping").Append(&inSignalB).Error)
|
||||||
assert.NoError(t, db.Model(&modelA).Association("OutputMapping").Append(&outSignalA).Error)
|
assert.NoError(t, db.Model(&configA).Association("OutputMapping").Append(&outSignalA).Error)
|
||||||
assert.NoError(t, db.Model(&modelA).Association("OutputMapping").Append(&outSignalB).Error)
|
assert.NoError(t, db.Model(&configA).Association("OutputMapping").Append(&outSignalB).Error)
|
||||||
|
|
||||||
// add simulation model has many files associations
|
// add Component Configuration has many files associations
|
||||||
assert.NoError(t, db.Model(&modelA).Association("Files").Append(&fileC).Error)
|
assert.NoError(t, db.Model(&configA).Association("Files").Append(&fileC).Error)
|
||||||
assert.NoError(t, db.Model(&modelA).Association("Files").Append(&fileD).Error)
|
assert.NoError(t, db.Model(&configA).Association("Files").Append(&fileD).Error)
|
||||||
|
|
||||||
// associate simulation models with simulators
|
// associate Component Configurations with IC
|
||||||
assert.NoError(t, db.Model(&simulatorA).Association("SimulationModels").Append(&modelA).Error)
|
assert.NoError(t, db.Model(&icA).Association("ComponentConfigurations").Append(&configA).Error)
|
||||||
assert.NoError(t, db.Model(&simulatorA).Association("SimulationModels").Append(&modelB).Error)
|
assert.NoError(t, db.Model(&icA).Association("ComponentConfigurations").Append(&configB).Error)
|
||||||
|
|
||||||
var model1 SimulationModel
|
var config1 ComponentConfiguration
|
||||||
assert.NoError(t, db.Find(&model1, 1).Error, fmt.Sprintf("Find SimulationModel with ID=1"))
|
assert.NoError(t, db.Find(&config1, 1).Error, fmt.Sprintf("Find ComponentConfiguration with ID=1"))
|
||||||
assert.EqualValues(t, "SimulationModel_A", model1.Name)
|
assert.EqualValues(t, ConfigA.Name, config1.Name)
|
||||||
|
|
||||||
// Check simulator ID
|
// Check IC ID
|
||||||
if model1.SimulatorID != 1 {
|
if config1.ICID != 1 {
|
||||||
assert.Fail(t, "Simulation Model expected to have Simulator ID 1, but is %v", model1.SimulatorID)
|
assert.Fail(t, "Component Configurations expected to have Infrastructure Component ID 1, but is %v", config1.ICID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get OutputMapping signals of model1
|
// Get OutputMapping signals of config1
|
||||||
var signals []Signal
|
var signals []Signal
|
||||||
assert.NoError(t, db.Model(&model1).Where("Direction = ?", "out").Related(&signals, "OutputMapping").Error)
|
assert.NoError(t, db.Model(&config1).Where("Direction = ?", "out").Related(&signals, "OutputMapping").Error)
|
||||||
if len(signals) != 2 {
|
if len(signals) != 2 {
|
||||||
assert.Fail(t, "SimulationModel Associations",
|
assert.Fail(t, "ComponentConfiguration Associations",
|
||||||
"Expected to have %v Output Signals. Has %v.", 2, len(signals))
|
"Expected to have %v Output Signals. Has %v.", 2, len(signals))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get files of model1
|
// Get files of config1
|
||||||
var files []File
|
var files []File
|
||||||
assert.NoError(t, db.Model(&model1).Related(&files, "Files").Error)
|
assert.NoError(t, db.Model(&config1).Related(&files, "Files").Error)
|
||||||
if len(files) != 2 {
|
if len(files) != 2 {
|
||||||
assert.Fail(t, "SimulationModel Associations",
|
assert.Fail(t, "ComponentConfiguration Associations",
|
||||||
"Expected to have %v Files. Has %v.", 2, len(files))
|
"Expected to have %v Files. Has %v.", 2, len(files))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,35 +65,35 @@ type Scenario struct {
|
||||||
StartParameters postgres.Jsonb `json:"startParameters"`
|
StartParameters postgres.Jsonb `json:"startParameters"`
|
||||||
// Users that have access to the scenario
|
// Users that have access to the scenario
|
||||||
Users []*User `json:"-" gorm:"many2many:user_scenarios;"`
|
Users []*User `json:"-" gorm:"many2many:user_scenarios;"`
|
||||||
// SimulationModels that belong to the scenario
|
// ComponentConfigurations that belong to the scenario
|
||||||
SimulationModels []SimulationModel `json:"-" gorm:"foreignkey:ScenarioID" `
|
ComponentConfigurations []ComponentConfiguration `json:"-" gorm:"foreignkey:ScenarioID" `
|
||||||
// Dashboards that belong to the Scenario
|
// Dashboards that belong to the Scenario
|
||||||
Dashboards []Dashboard `json:"-" gorm:"foreignkey:ScenarioID" `
|
Dashboards []Dashboard `json:"-" gorm:"foreignkey:ScenarioID" `
|
||||||
}
|
}
|
||||||
|
|
||||||
// SimulationModel data model
|
// ComponentConfiguration data model
|
||||||
type SimulationModel struct {
|
type ComponentConfiguration struct {
|
||||||
Model
|
Model
|
||||||
// Name of simulation model
|
// Name of Component Configuration
|
||||||
Name string `json:"name" gorm:"not null"`
|
Name string `json:"name" gorm:"not null"`
|
||||||
// Number of output signals
|
// Number of output signals
|
||||||
OutputLength int `json:"outputLength" gorm:"default:0"`
|
OutputLength int `json:"outputLength" gorm:"default:0"`
|
||||||
// Number of input signals
|
// Number of input signals
|
||||||
InputLength int `json:"inputLength" gorm:"default:0"`
|
InputLength int `json:"inputLength" gorm:"default:0"`
|
||||||
// Start parameters of simulation model as JSON
|
// Start parameters of Component Configuration as JSON
|
||||||
StartParameters postgres.Jsonb `json:"startParameters"`
|
StartParameters postgres.Jsonb `json:"startParameters"`
|
||||||
// ID of Scenario to which simulation model belongs
|
// ID of Scenario to which Component Configuration belongs
|
||||||
ScenarioID uint `json:"scenarioID"`
|
ScenarioID uint `json:"scenarioID"`
|
||||||
// ID of simulator associated with simulation model
|
// ID of IC associated with Component Configuration
|
||||||
SimulatorID uint `json:"simulatorID"`
|
ICID uint `json:"icID"`
|
||||||
// Mapping of output signals of the simulation model, order of signals is important
|
// Mapping of output signals of the ComponentConfiguration, order of signals is important
|
||||||
OutputMapping []Signal `json:"-" gorm:"foreignkey:SimulationModelID"`
|
OutputMapping []Signal `json:"-" gorm:"foreignkey:ConfigID"`
|
||||||
// Mapping of input signals of the simulation model, order of signals is important
|
// Mapping of input signals of the Component Configuration, order of signals is important
|
||||||
InputMapping []Signal `json:"-" gorm:"foreignkey:SimulationModelID"`
|
InputMapping []Signal `json:"-" gorm:"foreignkey:ConfigID"`
|
||||||
// Files of simulation model (can be CIM and other simulation model file formats)
|
// Files of Component Configuration (can be CIM and other ComponentConfiguration file formats)
|
||||||
Files []File `json:"-" gorm:"foreignkey:SimulationModelID"`
|
Files []File `json:"-" gorm:"foreignkey:ConfigID"`
|
||||||
// Currently selected simulation model FileID
|
// Currently selected FileID
|
||||||
SelectedModelFileID uint `json:"selectedModelFileID" gorm:"default:0"`
|
SelectedFileID uint `json:"selectedFileID" gorm:"default:0"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signal data model
|
// Signal data model
|
||||||
|
@ -107,31 +107,31 @@ type Signal struct {
|
||||||
Index uint `json:"index"`
|
Index uint `json:"index"`
|
||||||
// Direction of the signal (in or out)
|
// Direction of the signal (in or out)
|
||||||
Direction string `json:"direction"`
|
Direction string `json:"direction"`
|
||||||
// ID of simulation model
|
// ID of Component Configuration
|
||||||
SimulationModelID uint `json:"simulationModelID"`
|
ConfigID uint `json:"configID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simulator data model
|
// InfrastructureComponent data model
|
||||||
type Simulator struct {
|
type InfrastructureComponent struct {
|
||||||
Model
|
Model
|
||||||
// UUID of the simulator
|
// UUID of the IC
|
||||||
UUID string `json:"uuid" gorm:"not null"`
|
UUID string `json:"uuid" gorm:"not null"`
|
||||||
// Host if the simulator
|
// Host if the IC
|
||||||
Host string `json:"host" gorm:"default:''"`
|
Host string `json:"host" gorm:"default:''"`
|
||||||
// Model type supported by the simulator
|
// Model type supported by the IC
|
||||||
Modeltype string `json:"modelType" gorm:"default:''"`
|
Modeltype string `json:"modelType" gorm:"default:''"`
|
||||||
// Uptime of the simulator
|
// Uptime of the IC
|
||||||
Uptime int `json:"uptime" gorm:"default:0"`
|
Uptime int `json:"uptime" gorm:"default:0"`
|
||||||
// State of the simulator
|
// State of the IC
|
||||||
State string `json:"state" gorm:"default:''"`
|
State string `json:"state" gorm:"default:''"`
|
||||||
// Time of last state update
|
// Time of last state update
|
||||||
StateUpdateAt string `json:"stateUpdateAt" gorm:"default:''"`
|
StateUpdateAt string `json:"stateUpdateAt" gorm:"default:''"`
|
||||||
// Properties of simulator as JSON string
|
// Properties of IC as JSON string
|
||||||
Properties postgres.Jsonb `json:"properties"`
|
Properties postgres.Jsonb `json:"properties"`
|
||||||
// Raw properties of simulator as JSON string
|
// Raw properties of IC as JSON string
|
||||||
RawProperties postgres.Jsonb `json:"rawProperties"`
|
RawProperties postgres.Jsonb `json:"rawProperties"`
|
||||||
// SimulationModels in which the simulator is used
|
// ComponentConfigurations in which the IC is used
|
||||||
SimulationModels []SimulationModel `json:"-" gorm:"foreignkey:SimulatorID"`
|
ComponentConfigurations []ComponentConfiguration `json:"-" gorm:"foreignkey:ICID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dashboard data model
|
// Dashboard data model
|
||||||
|
@ -195,8 +195,8 @@ type File struct {
|
||||||
ImageWidth uint `json:"imageWidth"`
|
ImageWidth uint `json:"imageWidth"`
|
||||||
// Last modification time of file
|
// Last modification time of file
|
||||||
Date string `json:"date"`
|
Date string `json:"date"`
|
||||||
// ID of model to which file belongs
|
// ID of Component Configuration to which file belongs
|
||||||
SimulationModelID uint `json:"simulationModelID"`
|
ConfigID uint `json:"configID"`
|
||||||
// ID of widget to which file belongs
|
// ID of widget to which file belongs
|
||||||
WidgetID uint `json:"widgetID"`
|
WidgetID uint `json:"widgetID"`
|
||||||
// File itself
|
// File itself
|
||||||
|
|
|
@ -38,11 +38,11 @@ type ModelName string
|
||||||
const ModelUser = ModelName("user")
|
const ModelUser = ModelName("user")
|
||||||
const ModelUsers = ModelName("users")
|
const ModelUsers = ModelName("users")
|
||||||
const ModelScenario = ModelName("scenario")
|
const ModelScenario = ModelName("scenario")
|
||||||
const ModelSimulator = ModelName("simulator")
|
const ModelInfrastructureComponent = ModelName("ic")
|
||||||
const ModelSimulatorAction = ModelName("simulatoraction")
|
const ModelInfrastructureComponentAction = ModelName("icaction")
|
||||||
const ModelDashboard = ModelName("dashboard")
|
const ModelDashboard = ModelName("dashboard")
|
||||||
const ModelWidget = ModelName("widget")
|
const ModelWidget = ModelName("widget")
|
||||||
const ModelSimulationModel = ModelName("simulationmodel")
|
const ModelComponentConfiguration = ModelName("component-configuration")
|
||||||
const ModelSignal = ModelName("signal")
|
const ModelSignal = ModelName("signal")
|
||||||
const ModelFile = ModelName("file")
|
const ModelFile = ModelName("file")
|
||||||
|
|
||||||
|
@ -76,9 +76,9 @@ var Roles = RoleActions{
|
||||||
ModelUser: crud,
|
ModelUser: crud,
|
||||||
ModelUsers: crud,
|
ModelUsers: crud,
|
||||||
ModelScenario: crud,
|
ModelScenario: crud,
|
||||||
ModelSimulationModel: crud,
|
ModelComponentConfiguration: crud,
|
||||||
ModelSimulator: crud,
|
ModelInfrastructureComponent: crud,
|
||||||
ModelSimulatorAction: crud,
|
ModelInfrastructureComponentAction: crud,
|
||||||
ModelWidget: crud,
|
ModelWidget: crud,
|
||||||
ModelDashboard: crud,
|
ModelDashboard: crud,
|
||||||
ModelSignal: crud,
|
ModelSignal: crud,
|
||||||
|
@ -88,9 +88,9 @@ var Roles = RoleActions{
|
||||||
ModelUser: _ru_,
|
ModelUser: _ru_,
|
||||||
ModelUsers: none,
|
ModelUsers: none,
|
||||||
ModelScenario: crud,
|
ModelScenario: crud,
|
||||||
ModelSimulationModel: crud,
|
ModelComponentConfiguration: crud,
|
||||||
ModelSimulator: _r__,
|
ModelInfrastructureComponent: _r__,
|
||||||
ModelSimulatorAction: _ru_,
|
ModelInfrastructureComponentAction: _ru_,
|
||||||
ModelWidget: crud,
|
ModelWidget: crud,
|
||||||
ModelDashboard: crud,
|
ModelDashboard: crud,
|
||||||
ModelSignal: crud,
|
ModelSignal: crud,
|
||||||
|
@ -98,11 +98,11 @@ var Roles = RoleActions{
|
||||||
},
|
},
|
||||||
"Guest": {
|
"Guest": {
|
||||||
ModelScenario: _r__,
|
ModelScenario: _r__,
|
||||||
ModelSimulationModel: _r__,
|
ModelComponentConfiguration: _r__,
|
||||||
ModelDashboard: _r__,
|
ModelDashboard: _r__,
|
||||||
ModelWidget: _r__,
|
ModelWidget: _r__,
|
||||||
ModelSimulator: _r__,
|
ModelInfrastructureComponent: _r__,
|
||||||
ModelSimulatorAction: _r__,
|
ModelInfrastructureComponentAction: _r__,
|
||||||
ModelUser: _ru_,
|
ModelUser: _ru_,
|
||||||
ModelUsers: none,
|
ModelUsers: none,
|
||||||
ModelSignal: _r__,
|
ModelSignal: _r__,
|
||||||
|
|
|
@ -55,12 +55,12 @@ var UserB = User{Username: "User_B", Password: string(pwB),
|
||||||
var UserC = User{Username: "User_C", Password: string(pwC),
|
var UserC = User{Username: "User_C", Password: string(pwC),
|
||||||
Role: "Guest", Mail: "User_C@example.com", Active: true}
|
Role: "Guest", Mail: "User_C@example.com", Active: true}
|
||||||
|
|
||||||
// Simulators
|
// Infrastructure components
|
||||||
|
|
||||||
var propertiesA = json.RawMessage(`{"name" : "TestNameA", "category" : "CategoryA", "location" : "anywhere on earth", "type": "dummy"}`)
|
var propertiesA = json.RawMessage(`{"name" : "DPsim simulator", "category" : "Simulator", "location" : "ACSlab", "type": "DPsim"}`)
|
||||||
var propertiesB = json.RawMessage(`{"name" : "TestNameB", "category" : "CategoryB", "location" : "where ever you want", "type": "generic"}`)
|
var propertiesB = json.RawMessage(`{"name" : "VILLASnode gateway", "category" : "Gateway", "location" : "ACSlab", "type": "VILLASnode"}`)
|
||||||
|
|
||||||
var SimulatorA = Simulator{
|
var ICA = InfrastructureComponent{
|
||||||
UUID: "4854af30-325f-44a5-ad59-b67b2597de68",
|
UUID: "4854af30-325f-44a5-ad59-b67b2597de68",
|
||||||
Host: "Host_A",
|
Host: "Host_A",
|
||||||
Modeltype: "ModelTypeA",
|
Modeltype: "ModelTypeA",
|
||||||
|
@ -71,7 +71,7 @@ var SimulatorA = Simulator{
|
||||||
RawProperties: postgres.Jsonb{propertiesA},
|
RawProperties: postgres.Jsonb{propertiesA},
|
||||||
}
|
}
|
||||||
|
|
||||||
var SimulatorB = Simulator{
|
var ICB = InfrastructureComponent{
|
||||||
UUID: "7be0322d-354e-431e-84bd-ae4c9633138b",
|
UUID: "7be0322d-354e-431e-84bd-ae4c9633138b",
|
||||||
Host: "Host_B",
|
Host: "Host_B",
|
||||||
Modeltype: "ModelTypeB",
|
Modeltype: "ModelTypeB",
|
||||||
|
@ -98,18 +98,18 @@ var ScenarioB = Scenario{
|
||||||
StartParameters: postgres.Jsonb{startParametersB},
|
StartParameters: postgres.Jsonb{startParametersB},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simulation Models
|
// Component Configuration
|
||||||
|
|
||||||
var SimulationModelA = SimulationModel{
|
var ConfigA = ComponentConfiguration{
|
||||||
Name: "SimulationModel_A",
|
Name: "Example simulation",
|
||||||
StartParameters: postgres.Jsonb{startParametersA},
|
StartParameters: postgres.Jsonb{startParametersA},
|
||||||
SelectedModelFileID: 3,
|
SelectedFileID: 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
var SimulationModelB = SimulationModel{
|
var ConfigB = ComponentConfiguration{
|
||||||
Name: "SimulationModel_B",
|
Name: "VILLASnode gateway X",
|
||||||
StartParameters: postgres.Jsonb{startParametersB},
|
StartParameters: postgres.Jsonb{startParametersB},
|
||||||
SelectedModelFileID: 4,
|
SelectedFileID: 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signals
|
// Signals
|
||||||
|
@ -198,7 +198,7 @@ var customPropertiesLabel = json.RawMessage(`{"textSize" : "20", "fontColor" : 5
|
||||||
var customPropertiesButton = json.RawMessage(`{"toggle" : "Value1", "on_value" : "Value2", "off_value" : Value3}`)
|
var customPropertiesButton = json.RawMessage(`{"toggle" : "Value1", "on_value" : "Value2", "off_value" : Value3}`)
|
||||||
var customPropertiesCustomActions = json.RawMessage(`{"actions" : "Value1", "icon" : "Value2"}`)
|
var customPropertiesCustomActions = json.RawMessage(`{"actions" : "Value1", "icon" : "Value2"}`)
|
||||||
var customPropertiesGauge = json.RawMessage(`{ "valueMin": 0, "valueMax": 1}`)
|
var customPropertiesGauge = json.RawMessage(`{ "valueMin": 0, "valueMax": 1}`)
|
||||||
var customPropertiesLamp = json.RawMessage(`{"simulationModel" : "null", "signal" : 0, "on_color" : 4, "off_color": 2 , "threshold" : 0.5}`)
|
var customPropertiesLamp = json.RawMessage(`{"signal" : 0, "on_color" : 4, "off_color": 2 , "threshold" : 0.5}`)
|
||||||
|
|
||||||
var WidgetA = Widget{
|
var WidgetA = Widget{
|
||||||
Name: "Label",
|
Name: "Label",
|
||||||
|
@ -316,8 +316,8 @@ func DBAddTestData(db *gorm.DB) error {
|
||||||
userB := UserB
|
userB := UserB
|
||||||
userC := UserC
|
userC := UserC
|
||||||
|
|
||||||
simulatorA := SimulatorA
|
ICA := ICA
|
||||||
simulatorB := SimulatorB
|
ICB := ICB
|
||||||
|
|
||||||
scenarioA := ScenarioA
|
scenarioA := ScenarioA
|
||||||
scenarioB := ScenarioB
|
scenarioB := ScenarioB
|
||||||
|
@ -327,8 +327,8 @@ func DBAddTestData(db *gorm.DB) error {
|
||||||
inSignalA := InSignalA
|
inSignalA := InSignalA
|
||||||
inSignalB := InSignalB
|
inSignalB := InSignalB
|
||||||
|
|
||||||
modelA := SimulationModelA
|
configA := ConfigA
|
||||||
modelB := SimulationModelB
|
configB := ConfigB
|
||||||
|
|
||||||
dashboardA := DashboardA
|
dashboardA := DashboardA
|
||||||
dashboardB := DashboardB
|
dashboardB := DashboardB
|
||||||
|
@ -354,9 +354,9 @@ func DBAddTestData(db *gorm.DB) error {
|
||||||
// add Guest user to DB
|
// add Guest user to DB
|
||||||
err = db.Create(&userC).Error
|
err = db.Create(&userC).Error
|
||||||
|
|
||||||
// Simulators
|
// ICs
|
||||||
err = db.Create(&simulatorA).Error
|
err = db.Create(&ICA).Error
|
||||||
err = db.Create(&simulatorB).Error
|
err = db.Create(&ICB).Error
|
||||||
|
|
||||||
// Scenarios
|
// Scenarios
|
||||||
err = db.Create(&scenarioA).Error
|
err = db.Create(&scenarioA).Error
|
||||||
|
@ -368,9 +368,9 @@ func DBAddTestData(db *gorm.DB) error {
|
||||||
err = db.Create(&outSignalA).Error
|
err = db.Create(&outSignalA).Error
|
||||||
err = db.Create(&outSignalB).Error
|
err = db.Create(&outSignalB).Error
|
||||||
|
|
||||||
// Simulation Models
|
// Component Configuration
|
||||||
err = db.Create(&modelA).Error
|
err = db.Create(&configA).Error
|
||||||
err = db.Create(&modelB).Error
|
err = db.Create(&configB).Error
|
||||||
|
|
||||||
// Dashboards
|
// Dashboards
|
||||||
err = db.Create(&dashboardA).Error
|
err = db.Create(&dashboardA).Error
|
||||||
|
@ -400,9 +400,9 @@ func DBAddTestData(db *gorm.DB) error {
|
||||||
err = db.Model(&scenarioA).Association("Users").Append(&userC).Error
|
err = db.Model(&scenarioA).Association("Users").Append(&userC).Error
|
||||||
err = db.Model(&scenarioA).Association("Users").Append(&user0).Error
|
err = db.Model(&scenarioA).Association("Users").Append(&user0).Error
|
||||||
|
|
||||||
// Scenario HM SimulationModels
|
// Scenario HM Component Configurations
|
||||||
err = db.Model(&scenarioA).Association("SimulationModels").Append(&modelA).Error
|
err = db.Model(&scenarioA).Association("ComponentConfigurations").Append(&configA).Error
|
||||||
err = db.Model(&scenarioA).Association("SimulationModels").Append(&modelB).Error
|
err = db.Model(&scenarioA).Association("ComponentConfigurations").Append(&configB).Error
|
||||||
|
|
||||||
// Scenario HM Dashboards
|
// Scenario HM Dashboards
|
||||||
err = db.Model(&scenarioA).Association("Dashboards").Append(&dashboardA).Error
|
err = db.Model(&scenarioA).Association("Dashboards").Append(&dashboardA).Error
|
||||||
|
@ -415,19 +415,19 @@ func DBAddTestData(db *gorm.DB) error {
|
||||||
err = db.Model(&dashboardA).Association("Widgets").Append(&widgetD).Error
|
err = db.Model(&dashboardA).Association("Widgets").Append(&widgetD).Error
|
||||||
err = db.Model(&dashboardA).Association("Widgets").Append(&widgetE).Error
|
err = db.Model(&dashboardA).Association("Widgets").Append(&widgetE).Error
|
||||||
|
|
||||||
// SimulationModel HM Signals
|
// ComponentConfiguration HM Signals
|
||||||
err = db.Model(&modelA).Association("InputMapping").Append(&inSignalA).Error
|
err = db.Model(&configA).Association("InputMapping").Append(&inSignalA).Error
|
||||||
err = db.Model(&modelA).Association("InputMapping").Append(&inSignalB).Error
|
err = db.Model(&configA).Association("InputMapping").Append(&inSignalB).Error
|
||||||
err = db.Model(&modelA).Association("InputMapping").Append(&outSignalA).Error
|
err = db.Model(&configA).Association("InputMapping").Append(&outSignalA).Error
|
||||||
err = db.Model(&modelA).Association("InputMapping").Append(&outSignalB).Error
|
err = db.Model(&configA).Association("InputMapping").Append(&outSignalB).Error
|
||||||
|
|
||||||
// SimulationModel HM Files
|
// ComponentConfiguration HM Files
|
||||||
err = db.Model(&modelA).Association("Files").Append(&fileC).Error
|
err = db.Model(&configA).Association("Files").Append(&fileC).Error
|
||||||
err = db.Model(&modelA).Association("Files").Append(&fileD).Error
|
err = db.Model(&configA).Association("Files").Append(&fileD).Error
|
||||||
|
|
||||||
// Simulator HM SimulationModels
|
// InfrastructureComponent HM ComponentConfigurations
|
||||||
err = db.Model(&simulatorA).Association("SimulationModels").Append(&modelA).Error
|
err = db.Model(&ICA).Association("ComponentConfigurations").Append(&configA).Error
|
||||||
err = db.Model(&simulatorA).Association("SimulationModels").Append(&modelB).Error
|
err = db.Model(&ICA).Association("ComponentConfigurations").Append(&configB).Error
|
||||||
|
|
||||||
// Widget HM Files
|
// Widget HM Files
|
||||||
err = db.Model(&widgetA).Association("Files").Append(&fileA).Error
|
err = db.Model(&widgetA).Association("Files").Append(&fileA).Error
|
||||||
|
|
1574
doc/api/docs.go
1574
doc/api/docs.go
File diff suppressed because it is too large
Load diff
|
@ -46,12 +46,12 @@ type ResponseUser struct {
|
||||||
user database.User
|
user database.User
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResponseSimulators struct {
|
type ResponseICs struct {
|
||||||
simulators []database.Simulator
|
ics []database.InfrastructureComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResponseSimulator struct {
|
type ResponseIC struct {
|
||||||
simulator database.Simulator
|
ic database.InfrastructureComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResponseScenarios struct {
|
type ResponseScenarios struct {
|
||||||
|
@ -62,12 +62,12 @@ type ResponseScenario struct {
|
||||||
scenario database.Scenario
|
scenario database.Scenario
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResponseSimulationModels struct {
|
type ResponseConfigs struct {
|
||||||
simulationModels []database.SimulationModel
|
configs []database.ComponentConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResponseSimulationModel struct {
|
type ResponseConfig struct {
|
||||||
simulationModel database.SimulationModel
|
config database.ComponentConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResponseDashboards struct {
|
type ResponseDashboards struct {
|
||||||
|
|
1572
doc/api/swagger.json
1572
doc/api/swagger.json
File diff suppressed because it is too large
Load diff
1473
doc/api/swagger.yaml
1473
doc/api/swagger.yaml
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,4 @@
|
||||||
/** Simulationmodel package, endpoints.
|
/** component_configuration package, endpoints.
|
||||||
*
|
*
|
||||||
* @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
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*********************************************************************************/
|
*********************************************************************************/
|
||||||
package simulationmodel
|
package component_configuration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
|
||||||
|
@ -31,27 +31,27 @@ import (
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RegisterSimulationModelEndpoints(r *gin.RouterGroup) {
|
func RegisterComponentConfigurationEndpoints(r *gin.RouterGroup) {
|
||||||
r.GET("", getSimulationModels)
|
r.GET("", getConfigs)
|
||||||
r.POST("", addSimulationModel)
|
r.POST("", addConfig)
|
||||||
r.PUT("/:modelID", updateSimulationModel)
|
r.PUT("/:configID", updateConfig)
|
||||||
r.GET("/:modelID", getSimulationModel)
|
r.GET("/:configID", getConfig)
|
||||||
r.DELETE("/:modelID", deleteSimulationModel)
|
r.DELETE("/:configID", deleteConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getSimulationModels godoc
|
// getConfigs godoc
|
||||||
// @Summary Get all simulation models of scenario
|
// @Summary Get all component configurations of scenario
|
||||||
// @ID getSimulationModels
|
// @ID getConfigs
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Tags simulationModels
|
// @Tags component-configurations
|
||||||
// @Success 200 {object} docs.ResponseSimulationModels "Simulation models which belong to scenario"
|
// @Success 200 {object} docs.ResponseConfigs "Component configurations which belong to scenario"
|
||||||
// @Failure 404 {object} docs.ResponseError "Not found"
|
// @Failure 404 {object} docs.ResponseError "Not found"
|
||||||
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
||||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
||||||
// @Param Authorization header string true "Authorization token"
|
// @Param Authorization header string true "Authorization token"
|
||||||
// @Param scenarioID query int true "Scenario ID"
|
// @Param scenarioID query int true "Scenario ID"
|
||||||
// @Router /models [get]
|
// @Router /configs [get]
|
||||||
func getSimulationModels(c *gin.Context) {
|
func getConfigs(c *gin.Context) {
|
||||||
|
|
||||||
ok, so := scenario.CheckPermissions(c, database.Read, "query", -1)
|
ok, so := scenario.CheckPermissions(c, database.Read, "query", -1)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -59,32 +59,32 @@ func getSimulationModels(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
var models []database.SimulationModel
|
var configs []database.ComponentConfiguration
|
||||||
err := db.Order("ID asc").Model(so).Related(&models, "Models").Error
|
err := db.Order("ID asc").Model(so).Related(&configs, "ComponentConfigurations").Error
|
||||||
if !helper.DBError(c, err) {
|
if !helper.DBError(c, err) {
|
||||||
c.JSON(http.StatusOK, gin.H{"simulationModels": models})
|
c.JSON(http.StatusOK, gin.H{"configs": configs})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// addSimulationModel godoc
|
// addConfig godoc
|
||||||
// @Summary Add a simulation model to a scenario
|
// @Summary Add a component configuration to a scenario
|
||||||
// @ID addSimulationModel
|
// @ID addConfig
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Tags simulationModels
|
// @Tags component-configurations
|
||||||
// @Success 200 {object} docs.ResponseSimulationModel "simulation model that was added"
|
// @Success 200 {object} docs.ResponseConfig "Component configuration that was added"
|
||||||
// @Failure 400 {object} docs.ResponseError "Bad request"
|
// @Failure 400 {object} docs.ResponseError "Bad request"
|
||||||
// @Failure 404 {object} docs.ResponseError "Not found"
|
// @Failure 404 {object} docs.ResponseError "Not found"
|
||||||
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
||||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
||||||
// @Param Authorization header string true "Authorization token"
|
// @Param Authorization header string true "Authorization token"
|
||||||
// @Param inputSimulationModel body simulationmodel.addSimulationModelRequest true "Simulation model to be added incl. IDs of scenario and simulator"
|
// @Param inputConfig body component_configuration.addConfigRequest true "component configuration to be added incl. IDs of scenario and IC"
|
||||||
// @Router /models [post]
|
// @Router /configs [post]
|
||||||
func addSimulationModel(c *gin.Context) {
|
func addConfig(c *gin.Context) {
|
||||||
|
|
||||||
// Bind the request to JSON
|
// Bind the request to JSON
|
||||||
var req addSimulationModelRequest
|
var req addConfigRequest
|
||||||
err := c.ShouldBindJSON(&req)
|
err := c.ShouldBindJSON(&req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.BadRequestError(c, "Bad request. Error binding form data to JSON: "+err.Error())
|
helper.BadRequestError(c, "Bad request. Error binding form data to JSON: "+err.Error())
|
||||||
|
@ -97,46 +97,46 @@ func addSimulationModel(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the new simulation model from the request
|
// Create the new Component Configuration from the request
|
||||||
newSimulationModel := req.createSimulationModel()
|
newConfig := req.createConfig()
|
||||||
|
|
||||||
// check access to the scenario
|
// check access to the scenario
|
||||||
ok, _ := scenario.CheckPermissions(c, database.Update, "body", int(newSimulationModel.ScenarioID))
|
ok, _ := scenario.CheckPermissions(c, database.Update, "body", int(newConfig.ScenarioID))
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the new simulation model to the scenario
|
// add the new Component Configuration to the scenario
|
||||||
err = newSimulationModel.addToScenario()
|
err = newConfig.addToScenario()
|
||||||
if !helper.DBError(c, err) {
|
if !helper.DBError(c, err) {
|
||||||
c.JSON(http.StatusOK, gin.H{"simulationModel": newSimulationModel.SimulationModel})
|
c.JSON(http.StatusOK, gin.H{"config": newConfig.ComponentConfiguration})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateSimulationModel godoc
|
// updateConfig godoc
|
||||||
// @Summary Update a simulation model
|
// @Summary Update a component configuration
|
||||||
// @ID updateSimulationModel
|
// @ID updateConfig
|
||||||
// @Tags simulationModels
|
// @Tags component-configurations
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} docs.ResponseSimulationModel "simulation model that was added"
|
// @Success 200 {object} docs.ResponseConfig "Component configuration that was added"
|
||||||
// @Failure 400 {object} docs.ResponseError "Bad request"
|
// @Failure 400 {object} docs.ResponseError "Bad request"
|
||||||
// @Failure 404 {object} docs.ResponseError "Not found"
|
// @Failure 404 {object} docs.ResponseError "Not found"
|
||||||
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
||||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
||||||
// @Param Authorization header string true "Authorization token"
|
// @Param Authorization header string true "Authorization token"
|
||||||
// @Param inputSimulationModel body simulationmodel.updateSimulationModelRequest true "Simulation model to be updated"
|
// @Param inputConfig body component_configuration.updateConfigRequest true "component configuration to be updated"
|
||||||
// @Param modelID path int true "Model ID"
|
// @Param configID path int true "Config ID"
|
||||||
// @Router /models/{modelID} [put]
|
// @Router /configs/{configID} [put]
|
||||||
func updateSimulationModel(c *gin.Context) {
|
func updateConfig(c *gin.Context) {
|
||||||
|
|
||||||
ok, oldSimulationModel := CheckPermissions(c, database.Update, "path", -1)
|
ok, oldConfig := CheckPermissions(c, database.Update, "path", -1)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var req updateSimulationModelRequest
|
var req updateConfigRequest
|
||||||
err := c.BindJSON(&req)
|
err := c.BindJSON(&req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.BadRequestError(c, "Error binding form data to JSON: "+err.Error())
|
helper.BadRequestError(c, "Error binding form data to JSON: "+err.Error())
|
||||||
|
@ -144,59 +144,59 @@ func updateSimulationModel(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the request
|
// Validate the request
|
||||||
if err := req.SimulationModel.validate(); err != nil {
|
if err := req.Config.validate(); err != nil {
|
||||||
helper.BadRequestError(c, err.Error())
|
helper.BadRequestError(c, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the updatedSimulationModel from oldSimulationModel
|
// Create the updateConfig from oldConfig
|
||||||
updatedSimulationModel := req.updatedSimulationModel(oldSimulationModel)
|
updatedConfig := req.updateConfig(oldConfig)
|
||||||
|
|
||||||
// Finally, update the simulation model
|
// Finally, update the Component Configuration
|
||||||
err = oldSimulationModel.Update(updatedSimulationModel)
|
err = oldConfig.Update(updatedConfig)
|
||||||
if !helper.DBError(c, err) {
|
if !helper.DBError(c, err) {
|
||||||
c.JSON(http.StatusOK, gin.H{"simulationModel": updatedSimulationModel.SimulationModel})
|
c.JSON(http.StatusOK, gin.H{"config": updatedConfig.ComponentConfiguration})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// getSimulationModel godoc
|
// getConfig godoc
|
||||||
// @Summary Get a simulation model
|
// @Summary Get a component configuration
|
||||||
// @ID getSimulationModel
|
// @ID getConfig
|
||||||
// @Tags simulationModels
|
// @Tags component-configurations
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} docs.ResponseSimulationModel "simulation model that was requested"
|
// @Success 200 {object} docs.ResponseConfig "component configuration that was requested"
|
||||||
// @Failure 400 {object} docs.ResponseError "Bad request"
|
// @Failure 400 {object} docs.ResponseError "Bad request"
|
||||||
// @Failure 404 {object} docs.ResponseError "Not found"
|
// @Failure 404 {object} docs.ResponseError "Not found"
|
||||||
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
||||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
||||||
// @Param Authorization header string true "Authorization token"
|
// @Param Authorization header string true "Authorization token"
|
||||||
// @Param modelID path int true "Model ID"
|
// @Param configID path int true "Config ID"
|
||||||
// @Router /models/{modelID} [get]
|
// @Router /configs/{configID} [get]
|
||||||
func getSimulationModel(c *gin.Context) {
|
func getConfig(c *gin.Context) {
|
||||||
|
|
||||||
ok, m := CheckPermissions(c, database.Read, "path", -1)
|
ok, m := CheckPermissions(c, database.Read, "path", -1)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{"simulationModel": m.SimulationModel})
|
c.JSON(http.StatusOK, gin.H{"config": m.ComponentConfiguration})
|
||||||
}
|
}
|
||||||
|
|
||||||
// deleteSimulationModel godoc
|
// deleteConfig godoc
|
||||||
// @Summary Delete a simulation model
|
// @Summary Delete a component configuration
|
||||||
// @ID deleteSimulationModel
|
// @ID deleteConfig
|
||||||
// @Tags simulationModels
|
// @Tags component-configurations
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} docs.ResponseSimulationModel "simulation model that was deleted"
|
// @Success 200 {object} docs.ResponseConfig "component configuration that was deleted"
|
||||||
// @Failure 400 {object} docs.ResponseError "Bad request"
|
// @Failure 400 {object} docs.ResponseError "Bad request"
|
||||||
// @Failure 404 {object} docs.ResponseError "Not found"
|
// @Failure 404 {object} docs.ResponseError "Not found"
|
||||||
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
||||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
||||||
// @Param Authorization header string true "Authorization token"
|
// @Param Authorization header string true "Authorization token"
|
||||||
// @Param modelID path int true "Model ID"
|
// @Param configID path int true "Config ID"
|
||||||
// @Router /models/{modelID} [delete]
|
// @Router /configs/{configID} [delete]
|
||||||
func deleteSimulationModel(c *gin.Context) {
|
func deleteConfig(c *gin.Context) {
|
||||||
|
|
||||||
ok, m := CheckPermissions(c, database.Delete, "path", -1)
|
ok, m := CheckPermissions(c, database.Delete, "path", -1)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -205,6 +205,6 @@ func deleteSimulationModel(c *gin.Context) {
|
||||||
|
|
||||||
err := m.delete()
|
err := m.delete()
|
||||||
if !helper.DBError(c, err) {
|
if !helper.DBError(c, err) {
|
||||||
c.JSON(http.StatusOK, gin.H{"simulationModel": m.SimulationModel})
|
c.JSON(http.StatusOK, gin.H{"config": m.ComponentConfiguration})
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
/** Simulationmodel package, methods.
|
/** component_configuration package, methods.
|
||||||
*
|
*
|
||||||
* @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
|
||||||
|
@ -19,25 +19,25 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*********************************************************************************/
|
*********************************************************************************/
|
||||||
package simulationmodel
|
package component_configuration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
||||||
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/infrastructure-component"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/simulator"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SimulationModel struct {
|
type ComponentConfiguration struct {
|
||||||
database.SimulationModel
|
database.ComponentConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SimulationModel) save() error {
|
func (m *ComponentConfiguration) save() error {
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
err := db.Create(m).Error
|
err := db.Create(m).Error
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SimulationModel) ByID(id uint) error {
|
func (m *ComponentConfiguration) ByID(id uint) error {
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
err := db.Find(m, id).Error
|
err := db.Find(m, id).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -46,7 +46,7 @@ func (m *SimulationModel) ByID(id uint) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SimulationModel) addToScenario() error {
|
func (m *ComponentConfiguration) addToScenario() error {
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
var so scenario.Scenario
|
var so scenario.Scenario
|
||||||
err := so.ByID(m.ScenarioID)
|
err := so.ByID(m.ScenarioID)
|
||||||
|
@ -54,65 +54,65 @@ func (m *SimulationModel) addToScenario() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// save simulation model to DB
|
// save component configuration to DB
|
||||||
err = m.save()
|
err = m.save()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// associate simulator with simulation model
|
// associate IC with component configuration
|
||||||
var simltr simulator.Simulator
|
var ic infrastructure_component.InfrastructureComponent
|
||||||
err = simltr.ByID(m.SimulatorID)
|
err = ic.ByID(m.ICID)
|
||||||
err = db.Model(&simltr).Association("SimulationModels").Append(m).Error
|
err = db.Model(&ic).Association("ComponentConfigurations").Append(m).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// associate simulation model with scenario
|
// associate component configuration with scenario
|
||||||
err = db.Model(&so).Association("SimulationModels").Append(m).Error
|
err = db.Model(&so).Association("ComponentConfigurations").Append(m).Error
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SimulationModel) Update(modifiedSimulationModel SimulationModel) error {
|
func (m *ComponentConfiguration) Update(modifiedConfig ComponentConfiguration) error {
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
|
|
||||||
// check if simulator has been updated
|
// check if IC has been updated
|
||||||
if m.SimulatorID != modifiedSimulationModel.SimulatorID {
|
if m.ICID != modifiedConfig.ICID {
|
||||||
// update simulator
|
// update IC
|
||||||
var s simulator.Simulator
|
var s infrastructure_component.InfrastructureComponent
|
||||||
var s_old simulator.Simulator
|
var s_old infrastructure_component.InfrastructureComponent
|
||||||
err := s.ByID(modifiedSimulationModel.SimulatorID)
|
err := s.ByID(modifiedConfig.ICID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = s_old.ByID(m.SimulatorID)
|
err = s_old.ByID(m.ICID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// remove simulation model from old simulator
|
// remove component configuration from old IC
|
||||||
err = db.Model(&s_old).Association("SimulationModels").Delete(m).Error
|
err = db.Model(&s_old).Association("ComponentConfigurations").Delete(m).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// add simulation model to new simulator
|
// add component configuration to new IC
|
||||||
err = db.Model(&s).Association("SimulationModels").Append(m).Error
|
err = db.Model(&s).Association("ComponentConfigurations").Append(m).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err := db.Model(m).Updates(map[string]interface{}{
|
err := db.Model(m).Updates(map[string]interface{}{
|
||||||
"Name": modifiedSimulationModel.Name,
|
"Name": modifiedConfig.Name,
|
||||||
"StartParameters": modifiedSimulationModel.StartParameters,
|
"StartParameters": modifiedConfig.StartParameters,
|
||||||
"SimulatorID": modifiedSimulationModel.SimulatorID,
|
"ICID": modifiedConfig.ICID,
|
||||||
"SelectedModelFileID": modifiedSimulationModel.SelectedModelFileID,
|
"SelectedFileID": modifiedConfig.SelectedFileID,
|
||||||
}).Error
|
}).Error
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SimulationModel) delete() error {
|
func (m *ComponentConfiguration) delete() error {
|
||||||
|
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
var so scenario.Scenario
|
var so scenario.Scenario
|
||||||
|
@ -121,9 +121,9 @@ func (m *SimulationModel) delete() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove association between SimulationModel and Scenario
|
// remove association between ComponentConfiguration and Scenario
|
||||||
// SimulationModel itself is not deleted from DB, it remains as "dangling"
|
// ComponentConfiguration itself is not deleted from DB, it remains as "dangling"
|
||||||
err = db.Model(&so).Association("SimulationModels").Delete(m).Error
|
err = db.Model(&so).Association("ComponentConfigurations").Delete(m).Error
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
/** Simulationmodel package, middleware.
|
/** component_configuration package, middleware.
|
||||||
*
|
*
|
||||||
* @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
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*********************************************************************************/
|
*********************************************************************************/
|
||||||
package simulationmodel
|
package component_configuration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -30,22 +30,22 @@ import (
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CheckPermissions(c *gin.Context, operation database.CRUD, modelIDSource string, modelIDBody int) (bool, SimulationModel) {
|
func CheckPermissions(c *gin.Context, operation database.CRUD, configIDSource string, configIDBody int) (bool, ComponentConfiguration) {
|
||||||
|
|
||||||
var m SimulationModel
|
var m ComponentConfiguration
|
||||||
|
|
||||||
err := database.ValidateRole(c, database.ModelSimulationModel, operation)
|
err := database.ValidateRole(c, database.ModelComponentConfiguration, operation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.UnprocessableEntityError(c, fmt.Sprintf("Access denied (role validation of simulation model failed): %v", err.Error()))
|
helper.UnprocessableEntityError(c, fmt.Sprintf("Access denied (role validation of Component Configuration failed): %v", err.Error()))
|
||||||
return false, m
|
return false, m
|
||||||
}
|
}
|
||||||
|
|
||||||
modelID, err := helper.GetIDOfElement(c, "modelID", modelIDSource, modelIDBody)
|
configID, err := helper.GetIDOfElement(c, "configID", configIDSource, configIDBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, m
|
return false, m
|
||||||
}
|
}
|
||||||
|
|
||||||
err = m.ByID(uint(modelID))
|
err = m.ByID(uint(configID))
|
||||||
if helper.DBError(c, err) {
|
if helper.DBError(c, err) {
|
||||||
return false, m
|
return false, m
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
/** Simulationmodel package, testing.
|
/** component_configuration package, testing.
|
||||||
*
|
*
|
||||||
* @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
|
||||||
|
@ -19,15 +19,15 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*********************************************************************************/
|
*********************************************************************************/
|
||||||
package simulationmodel
|
package component_configuration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
|
||||||
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/infrastructure-component"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/simulator"
|
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/user"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/user"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
|
@ -39,16 +39,18 @@ import (
|
||||||
|
|
||||||
var router *gin.Engine
|
var router *gin.Engine
|
||||||
var db *gorm.DB
|
var db *gorm.DB
|
||||||
|
var base_api_configs = "/api/configs"
|
||||||
|
var base_api_auth = "/api/authenticate"
|
||||||
|
|
||||||
type SimulationModelRequest struct {
|
type ConfigRequest struct {
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
ScenarioID uint `json:"scenarioID,omitempty"`
|
ScenarioID uint `json:"scenarioID,omitempty"`
|
||||||
SimulatorID uint `json:"simulatorID,omitempty"`
|
ICID uint `json:"icID,omitempty"`
|
||||||
StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
|
StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
|
||||||
SelectedModelFileID uint `json:"selectedModelFileID,omitempty"`
|
SelectedFileID uint `json:"selectedFileID,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SimulatorRequest struct {
|
type ICRequest struct {
|
||||||
UUID string `json:"uuid,omitempty"`
|
UUID string `json:"uuid,omitempty"`
|
||||||
Host string `json:"host,omitempty"`
|
Host string `json:"host,omitempty"`
|
||||||
Modeltype string `json:"modelType,omitempty"`
|
Modeltype string `json:"modelType,omitempty"`
|
||||||
|
@ -62,40 +64,40 @@ type ScenarioRequest struct {
|
||||||
StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
|
StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func addScenarioAndSimulator() (scenarioID uint, simulatorID uint) {
|
func addScenarioAndIC() (scenarioID uint, ICID uint) {
|
||||||
|
|
||||||
// authenticate as admin
|
// authenticate as admin
|
||||||
token, _ := helper.AuthenticateForTest(router,
|
token, _ := helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.AdminCredentials)
|
base_api_auth, "POST", helper.AdminCredentials)
|
||||||
|
|
||||||
// POST $newSimulatorA
|
// POST $newICA
|
||||||
newSimulatorA := SimulatorRequest{
|
newICA := ICRequest{
|
||||||
UUID: database.SimulatorA.UUID,
|
UUID: database.ICA.UUID,
|
||||||
Host: database.SimulatorA.Host,
|
Host: database.ICA.Host,
|
||||||
Modeltype: database.SimulatorA.Modeltype,
|
Modeltype: database.ICA.Modeltype,
|
||||||
State: database.SimulatorA.State,
|
State: database.ICA.State,
|
||||||
Properties: database.SimulatorA.Properties,
|
Properties: database.ICA.Properties,
|
||||||
}
|
}
|
||||||
_, resp, _ := helper.TestEndpoint(router, token,
|
_, resp, _ := helper.TestEndpoint(router, token,
|
||||||
"/api/simulators", "POST", helper.KeyModels{"simulator": newSimulatorA})
|
"/api/ic", "POST", helper.KeyModels{"ic": newICA})
|
||||||
|
|
||||||
// Read newSimulator's ID from the response
|
// Read newIC's ID from the response
|
||||||
newSimulatorID, _ := helper.GetResponseID(resp)
|
newICID, _ := helper.GetResponseID(resp)
|
||||||
|
|
||||||
// POST a second simulator to change to that simulator during testing
|
// POST a second IC to change to that IC during testing
|
||||||
newSimulatorB := SimulatorRequest{
|
newICB := ICRequest{
|
||||||
UUID: database.SimulatorB.UUID,
|
UUID: database.ICB.UUID,
|
||||||
Host: database.SimulatorB.Host,
|
Host: database.ICB.Host,
|
||||||
Modeltype: database.SimulatorB.Modeltype,
|
Modeltype: database.ICB.Modeltype,
|
||||||
State: database.SimulatorB.State,
|
State: database.ICB.State,
|
||||||
Properties: database.SimulatorB.Properties,
|
Properties: database.ICB.Properties,
|
||||||
}
|
}
|
||||||
_, resp, _ = helper.TestEndpoint(router, token,
|
_, resp, _ = helper.TestEndpoint(router, token,
|
||||||
"/api/simulators", "POST", helper.KeyModels{"simulator": newSimulatorB})
|
"/api/ic", "POST", helper.KeyModels{"ic": newICB})
|
||||||
|
|
||||||
// authenticate as normal user
|
// authenticate as normal user
|
||||||
token, _ = helper.AuthenticateForTest(router,
|
token, _ = helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.UserACredentials)
|
base_api_auth, "POST", helper.UserACredentials)
|
||||||
|
|
||||||
// POST $newScenario
|
// POST $newScenario
|
||||||
newScenario := ScenarioRequest{
|
newScenario := ScenarioRequest{
|
||||||
|
@ -113,7 +115,7 @@ func addScenarioAndSimulator() (scenarioID uint, simulatorID uint) {
|
||||||
_, resp, _ = helper.TestEndpoint(router, token,
|
_, resp, _ = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/scenarios/%v/user?username=User_C", newScenarioID), "PUT", nil)
|
fmt.Sprintf("/api/scenarios/%v/user?username=User_C", newScenarioID), "PUT", nil)
|
||||||
|
|
||||||
return uint(newScenarioID), uint(newSimulatorID)
|
return uint(newScenarioID), uint(newICID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
|
@ -133,342 +135,342 @@ func TestMain(m *testing.M) {
|
||||||
|
|
||||||
user.RegisterAuthenticate(api.Group("/authenticate"))
|
user.RegisterAuthenticate(api.Group("/authenticate"))
|
||||||
api.Use(user.Authentication(true))
|
api.Use(user.Authentication(true))
|
||||||
RegisterSimulationModelEndpoints(api.Group("/models"))
|
RegisterComponentConfigurationEndpoints(api.Group("/configs"))
|
||||||
// scenario endpoints required here to first add a scenario to the DB
|
// scenario endpoints required here to first add a scenario to the DB
|
||||||
// that can be associated with a new simulation model
|
// that can be associated with a new component configuration
|
||||||
scenario.RegisterScenarioEndpoints(api.Group("/scenarios"))
|
scenario.RegisterScenarioEndpoints(api.Group("/scenarios"))
|
||||||
// simulator endpoints required here to first add a simulator to the DB
|
// IC endpoints required here to first add a IC to the DB
|
||||||
// that can be associated with a new simulation model
|
// that can be associated with a new component configuration
|
||||||
simulator.RegisterSimulatorEndpoints(api.Group("/simulators"))
|
infrastructure_component.RegisterICEndpoints(api.Group("/ic"))
|
||||||
|
|
||||||
os.Exit(m.Run())
|
os.Exit(m.Run())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddSimulationModel(t *testing.T) {
|
func TestAddConfig(t *testing.T) {
|
||||||
database.DropTables(db)
|
database.DropTables(db)
|
||||||
database.MigrateModels(db)
|
database.MigrateModels(db)
|
||||||
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
||||||
|
|
||||||
// prepare the content of the DB for testing
|
// prepare the content of the DB for testing
|
||||||
// by adding a scenario and a simulator to the DB
|
// by adding a scenario and a IC to the DB
|
||||||
// using the respective endpoints of the API
|
// using the respective endpoints of the API
|
||||||
scenarioID, simulatorID := addScenarioAndSimulator()
|
scenarioID, ICID := addScenarioAndIC()
|
||||||
|
|
||||||
newSimulationModel := SimulationModelRequest{
|
newConfig := ConfigRequest{
|
||||||
Name: database.SimulationModelA.Name,
|
Name: database.ConfigA.Name,
|
||||||
ScenarioID: scenarioID,
|
ScenarioID: scenarioID,
|
||||||
SimulatorID: simulatorID,
|
ICID: ICID,
|
||||||
StartParameters: database.SimulationModelA.StartParameters,
|
StartParameters: database.ConfigA.StartParameters,
|
||||||
SelectedModelFileID: database.SimulationModelA.SelectedModelFileID,
|
SelectedFileID: database.ConfigA.SelectedFileID,
|
||||||
}
|
}
|
||||||
|
|
||||||
// authenticate as normal userB who has no access to new scenario
|
// authenticate as normal userB who has no access to new scenario
|
||||||
token, err := helper.AuthenticateForTest(router,
|
token, err := helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.UserBCredentials)
|
base_api_auth, "POST", helper.UserBCredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// try to POST with no access
|
// try to POST with no access
|
||||||
// should result in unprocessable entity
|
// should result in unprocessable entity
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/models", "POST", helper.KeyModels{"simulationModel": newSimulationModel})
|
base_api_configs, "POST", helper.KeyModels{"config": newConfig})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// authenticate as normal user
|
// authenticate as normal user
|
||||||
token, err = helper.AuthenticateForTest(router,
|
token, err = helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.UserACredentials)
|
base_api_auth, "POST", helper.UserACredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// try to POST non JSON body
|
// try to POST non JSON body
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
"/api/models", "POST", "this is not JSON")
|
base_api_configs, "POST", "this is not JSON")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 400, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 400, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// authenticate as normal user
|
// authenticate as normal user
|
||||||
token, err = helper.AuthenticateForTest(router,
|
token, err = helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.UserACredentials)
|
base_api_auth, "POST", helper.UserACredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// test POST models/ $newSimulationModel
|
// test POST newConfig
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
"/api/models", "POST", helper.KeyModels{"simulationModel": newSimulationModel})
|
base_api_configs, "POST", helper.KeyModels{"config": newConfig})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Compare POST's response with the newSimulationModel
|
// Compare POST's response with the newConfig
|
||||||
err = helper.CompareResponse(resp, helper.KeyModels{"simulationModel": newSimulationModel})
|
err = helper.CompareResponse(resp, helper.KeyModels{"config": newConfig})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Read newSimulationModel's ID from the response
|
// Read newConfig's ID from the response
|
||||||
newSimulationModelID, err := helper.GetResponseID(resp)
|
newConfigID, err := helper.GetResponseID(resp)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Get the newSimulationModel
|
// Get the newConfig
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/models/%v", newSimulationModelID), "GET", nil)
|
fmt.Sprintf("%v/%v", base_api_configs, newConfigID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Compare GET's response with the newSimulationModel
|
// Compare GET's response with the newConfig
|
||||||
err = helper.CompareResponse(resp, helper.KeyModels{"simulationModel": newSimulationModel})
|
err = helper.CompareResponse(resp, helper.KeyModels{"config": newConfig})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// try to POST a malformed simulation model
|
// try to POST a malformed component config
|
||||||
// Required fields are missing
|
// Required fields are missing
|
||||||
malformedNewSimulationModel := SimulationModelRequest{
|
malformedNewConfig := ConfigRequest{
|
||||||
Name: "ThisIsAMalformedRequest",
|
Name: "ThisIsAMalformedRequest",
|
||||||
}
|
}
|
||||||
// this should NOT work and return a unprocessable entity 442 status code
|
// this should NOT work and return a unprocessable entity 442 status code
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
"/api/models", "POST", helper.KeyModels{"simulationModel": malformedNewSimulationModel})
|
base_api_configs, "POST", helper.KeyModels{"config": malformedNewConfig})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// authenticate as normal userB who has no access to new scenario
|
// authenticate as normal userB who has no access to new scenario
|
||||||
token, err = helper.AuthenticateForTest(router,
|
token, err = helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.UserBCredentials)
|
base_api_auth, "POST", helper.UserBCredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Try to GET the newSimulationModel with no access
|
// Try to GET the newConfig with no access
|
||||||
// Should result in unprocessable entity
|
// Should result in unprocessable entity
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/models/%v", newSimulationModelID), "GET", nil)
|
fmt.Sprintf("%v/%v", base_api_configs, newConfigID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateSimulationModel(t *testing.T) {
|
func TestUpdateConfig(t *testing.T) {
|
||||||
|
|
||||||
database.DropTables(db)
|
database.DropTables(db)
|
||||||
database.MigrateModels(db)
|
database.MigrateModels(db)
|
||||||
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
||||||
|
|
||||||
// prepare the content of the DB for testing
|
// prepare the content of the DB for testing
|
||||||
// by adding a scenario and a simulator to the DB
|
// by adding a scenario and a IC to the DB
|
||||||
// using the respective endpoints of the API
|
// using the respective endpoints of the API
|
||||||
scenarioID, simulatorID := addScenarioAndSimulator()
|
scenarioID, ICID := addScenarioAndIC()
|
||||||
|
|
||||||
// authenticate as normal user
|
// authenticate as normal user
|
||||||
token, err := helper.AuthenticateForTest(router,
|
token, err := helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.UserACredentials)
|
base_api_auth, "POST", helper.UserACredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// test POST models/ $newSimulationModel
|
// test POST newConfig
|
||||||
newSimulationModel := SimulationModelRequest{
|
newConfig := ConfigRequest{
|
||||||
Name: database.SimulationModelA.Name,
|
Name: database.ConfigA.Name,
|
||||||
ScenarioID: scenarioID,
|
ScenarioID: scenarioID,
|
||||||
SimulatorID: simulatorID,
|
ICID: ICID,
|
||||||
StartParameters: database.SimulationModelA.StartParameters,
|
StartParameters: database.ConfigA.StartParameters,
|
||||||
SelectedModelFileID: database.SimulationModelA.SelectedModelFileID,
|
SelectedFileID: database.ConfigA.SelectedFileID,
|
||||||
}
|
}
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/models", "POST", helper.KeyModels{"simulationModel": newSimulationModel})
|
base_api_configs, "POST", helper.KeyModels{"config": newConfig})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Read newSimulationModel's ID from the response
|
// Read newConfig's ID from the response
|
||||||
newSimulationModelID, err := helper.GetResponseID(resp)
|
newConfigID, err := helper.GetResponseID(resp)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
updatedSimulationModel := SimulationModelRequest{
|
updatedConfig := ConfigRequest{
|
||||||
Name: database.SimulationModelB.Name,
|
Name: database.ConfigB.Name,
|
||||||
StartParameters: database.SimulationModelB.StartParameters,
|
StartParameters: database.ConfigB.StartParameters,
|
||||||
}
|
}
|
||||||
|
|
||||||
// authenticate as normal userB who has no access to new scenario
|
// authenticate as normal userB who has no access to new scenario
|
||||||
token, err = helper.AuthenticateForTest(router,
|
token, err = helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.UserBCredentials)
|
base_api_auth, "POST", helper.UserBCredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// try to PUT with no access
|
// try to PUT with no access
|
||||||
// should result in unprocessable entity
|
// should result in unprocessable entity
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/models/%v", newSimulationModelID), "PUT", helper.KeyModels{"simulationModel": updatedSimulationModel})
|
fmt.Sprintf("%v/%v", base_api_configs, newConfigID), "PUT", helper.KeyModels{"config": updatedConfig})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// authenticate as guest user who has access to simulation model
|
// authenticate as guest user who has access to component config
|
||||||
token, err = helper.AuthenticateForTest(router,
|
token, err = helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.GuestCredentials)
|
base_api_auth, "POST", helper.GuestCredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// try to PUT as guest
|
// try to PUT as guest
|
||||||
// should NOT work and result in unprocessable entity
|
// should NOT work and result in unprocessable entity
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/models/%v", newSimulationModelID), "PUT", helper.KeyModels{"simulationModel": updatedSimulationModel})
|
fmt.Sprintf("%v/%v", base_api_configs, newConfigID), "PUT", helper.KeyModels{"config": updatedConfig})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// authenticate as normal user
|
// authenticate as normal user
|
||||||
token, err = helper.AuthenticateForTest(router,
|
token, err = helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.UserACredentials)
|
base_api_auth, "POST", helper.UserACredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// try to PUT a non JSON body
|
// try to PUT a non JSON body
|
||||||
// should result in a bad request
|
// should result in a bad request
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/models/%v", newSimulationModelID), "PUT", "This is not JSON")
|
fmt.Sprintf("%v/%v", base_api_configs, newConfigID), "PUT", "This is not JSON")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 400, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 400, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// test PUT
|
// test PUT
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/models/%v", newSimulationModelID), "PUT", helper.KeyModels{"simulationModel": updatedSimulationModel})
|
fmt.Sprintf("%v/%v", base_api_configs, newConfigID), "PUT", helper.KeyModels{"config": updatedConfig})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Compare PUT's response with the updatedSimulationModel
|
// Compare PUT's response with the updateConfig
|
||||||
err = helper.CompareResponse(resp, helper.KeyModels{"simulationModel": updatedSimulationModel})
|
err = helper.CompareResponse(resp, helper.KeyModels{"config": updatedConfig})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
//Change simulator ID to use second simulator available in DB
|
//Change IC ID to use second IC available in DB
|
||||||
updatedSimulationModel.SimulatorID = simulatorID + 1
|
updatedConfig.ICID = ICID + 1
|
||||||
// test PUT again
|
// test PUT again
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/models/%v", newSimulationModelID), "PUT", helper.KeyModels{"simulationModel": updatedSimulationModel})
|
fmt.Sprintf("%v/%v", base_api_configs, newConfigID), "PUT", helper.KeyModels{"config": updatedConfig})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Compare PUT's response with the updatedSimulationModel
|
// Compare PUT's response with the updateConfig
|
||||||
err = helper.CompareResponse(resp, helper.KeyModels{"simulationModel": updatedSimulationModel})
|
err = helper.CompareResponse(resp, helper.KeyModels{"config": updatedConfig})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Get the updatedSimulationModel
|
// Get the updateConfig
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/models/%v", newSimulationModelID), "GET", nil)
|
fmt.Sprintf("%v/%v", base_api_configs, newConfigID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Compare GET's response with the updatedSimulationModel
|
// Compare GET's response with the updateConfig
|
||||||
err = helper.CompareResponse(resp, helper.KeyModels{"simulationModel": updatedSimulationModel})
|
err = helper.CompareResponse(resp, helper.KeyModels{"config": updatedConfig})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// try to update a simulation model that does not exist (should return not found 404 status code)
|
// try to update a component config that does not exist (should return not found 404 status code)
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/models/%v", newSimulationModelID+1), "PUT", helper.KeyModels{"simulationModel": updatedSimulationModel})
|
fmt.Sprintf("%v/%v", base_api_configs, newConfigID+1), "PUT", helper.KeyModels{"config": updatedConfig})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 404, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 404, code, "Response body: \n%v\n", resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteSimulationModel(t *testing.T) {
|
func TestDeleteConfig(t *testing.T) {
|
||||||
database.DropTables(db)
|
database.DropTables(db)
|
||||||
database.MigrateModels(db)
|
database.MigrateModels(db)
|
||||||
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
||||||
|
|
||||||
// prepare the content of the DB for testing
|
// prepare the content of the DB for testing
|
||||||
// by adding a scenario and a simulator to the DB
|
// by adding a scenario and a IC to the DB
|
||||||
// using the respective endpoints of the API
|
// using the respective endpoints of the API
|
||||||
scenarioID, simulatorID := addScenarioAndSimulator()
|
scenarioID, ICID := addScenarioAndIC()
|
||||||
|
|
||||||
newSimulationModel := SimulationModelRequest{
|
newConfig := ConfigRequest{
|
||||||
Name: database.SimulationModelA.Name,
|
Name: database.ConfigA.Name,
|
||||||
ScenarioID: scenarioID,
|
ScenarioID: scenarioID,
|
||||||
SimulatorID: simulatorID,
|
ICID: ICID,
|
||||||
StartParameters: database.SimulationModelA.StartParameters,
|
StartParameters: database.ConfigA.StartParameters,
|
||||||
SelectedModelFileID: database.SimulationModelA.SelectedModelFileID,
|
SelectedFileID: database.ConfigA.SelectedFileID,
|
||||||
}
|
}
|
||||||
|
|
||||||
// authenticate as normal user
|
// authenticate as normal user
|
||||||
token, err := helper.AuthenticateForTest(router,
|
token, err := helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.UserACredentials)
|
base_api_auth, "POST", helper.UserACredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// test POST models/ $newSimulationModel
|
// test POST newConfig
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/models", "POST", helper.KeyModels{"simulationModel": newSimulationModel})
|
base_api_configs, "POST", helper.KeyModels{"config": newConfig})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Read newSimulationModel's ID from the response
|
// Read newConfig's ID from the response
|
||||||
newSimulationModelID, err := helper.GetResponseID(resp)
|
newConfigID, err := helper.GetResponseID(resp)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// authenticate as normal userB who has no access to new scenario
|
// authenticate as normal userB who has no access to new scenario
|
||||||
token, err = helper.AuthenticateForTest(router,
|
token, err = helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.UserBCredentials)
|
base_api_auth, "POST", helper.UserBCredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// try to DELETE with no access
|
// try to DELETE with no access
|
||||||
// should result in unprocessable entity
|
// should result in unprocessable entity
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/models/%v", newSimulationModelID), "DELETE", nil)
|
fmt.Sprintf("%v/%v", base_api_configs, newConfigID), "DELETE", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// authenticate as normal user
|
// authenticate as normal user
|
||||||
token, err = helper.AuthenticateForTest(router,
|
token, err = helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.UserACredentials)
|
base_api_auth, "POST", helper.UserACredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Count the number of all the simulation models returned for scenario
|
// Count the number of all the component config returned for scenario
|
||||||
initialNumber, err := helper.LengthOfResponse(router, token,
|
initialNumber, err := helper.LengthOfResponse(router, token,
|
||||||
fmt.Sprintf("/api/models?scenarioID=%v", scenarioID), "GET", nil)
|
fmt.Sprintf("%v?scenarioID=%v", base_api_configs, scenarioID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Delete the added newSimulationModel
|
// Delete the added newConfig
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/models/%v", newSimulationModelID), "DELETE", nil)
|
fmt.Sprintf("%v/%v", base_api_configs, newConfigID), "DELETE", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Compare DELETE's response with the newSimulationModel
|
// Compare DELETE's response with the newConfig
|
||||||
err = helper.CompareResponse(resp, helper.KeyModels{"simulationModel": newSimulationModel})
|
err = helper.CompareResponse(resp, helper.KeyModels{"config": newConfig})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Again count the number of all the simulation models returned
|
// Again count the number of all the component configs returned
|
||||||
finalNumber, err := helper.LengthOfResponse(router, token,
|
finalNumber, err := helper.LengthOfResponse(router, token,
|
||||||
fmt.Sprintf("/api/models?scenarioID=%v", scenarioID), "GET", nil)
|
fmt.Sprintf("%v?scenarioID=%v", base_api_configs, scenarioID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, initialNumber-1, finalNumber)
|
assert.Equal(t, initialNumber-1, finalNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetAllSimulationModelsOfScenario(t *testing.T) {
|
func TestGetAllConfigsOfScenario(t *testing.T) {
|
||||||
database.DropTables(db)
|
database.DropTables(db)
|
||||||
database.MigrateModels(db)
|
database.MigrateModels(db)
|
||||||
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
||||||
|
|
||||||
// prepare the content of the DB for testing
|
// prepare the content of the DB for testing
|
||||||
// by adding a scenario and a simulator to the DB
|
// by adding a scenario and a IC to the DB
|
||||||
// using the respective endpoints of the API
|
// using the respective endpoints of the API
|
||||||
scenarioID, simulatorID := addScenarioAndSimulator()
|
scenarioID, ICID := addScenarioAndIC()
|
||||||
|
|
||||||
// authenticate as normal user
|
// authenticate as normal user
|
||||||
token, err := helper.AuthenticateForTest(router,
|
token, err := helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.UserACredentials)
|
base_api_auth, "POST", helper.UserACredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// test POST models/ $newSimulationModel
|
// test POST newConfig
|
||||||
newSimulationModel := SimulationModelRequest{
|
newConfig := ConfigRequest{
|
||||||
Name: database.SimulationModelA.Name,
|
Name: database.ConfigA.Name,
|
||||||
ScenarioID: scenarioID,
|
ScenarioID: scenarioID,
|
||||||
SimulatorID: simulatorID,
|
ICID: ICID,
|
||||||
StartParameters: database.SimulationModelA.StartParameters,
|
StartParameters: database.ConfigA.StartParameters,
|
||||||
SelectedModelFileID: database.SimulationModelA.SelectedModelFileID,
|
SelectedFileID: database.ConfigA.SelectedFileID,
|
||||||
}
|
}
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/models", "POST", helper.KeyModels{"simulationModel": newSimulationModel})
|
base_api_configs, "POST", helper.KeyModels{"config": newConfig})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Count the number of all the simulation models returned for scenario
|
// Count the number of all the component config returned for scenario
|
||||||
NumberOfSimulationModels, err := helper.LengthOfResponse(router, token,
|
NumberOfConfigs, err := helper.LengthOfResponse(router, token,
|
||||||
fmt.Sprintf("/api/models?scenarioID=%v", scenarioID), "GET", nil)
|
fmt.Sprintf("%v?scenarioID=%v", base_api_configs, scenarioID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, 1, NumberOfSimulationModels)
|
assert.Equal(t, 1, NumberOfConfigs)
|
||||||
|
|
||||||
// authenticate as normal userB who has no access to scenario
|
// authenticate as normal userB who has no access to scenario
|
||||||
token, err = helper.AuthenticateForTest(router,
|
token, err = helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.UserBCredentials)
|
base_api_auth, "POST", helper.UserBCredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// try to get models without access
|
// try to get configs without access
|
||||||
// should result in unprocessable entity
|
// should result in unprocessable entity
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/models?scenarioID=%v", scenarioID), "GET", nil)
|
fmt.Sprintf("%v?scenarioID=%v", base_api_configs, scenarioID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
||||||
|
|
108
routes/component-configuration/config_validators.go
Normal file
108
routes/component-configuration/config_validators.go
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
/** component_configuration package, validators.
|
||||||
|
*
|
||||||
|
* @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 component_configuration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/jinzhu/gorm/dialects/postgres"
|
||||||
|
"github.com/nsf/jsondiff"
|
||||||
|
"gopkg.in/go-playground/validator.v9"
|
||||||
|
)
|
||||||
|
|
||||||
|
var validate *validator.Validate
|
||||||
|
|
||||||
|
type validNewConfig struct {
|
||||||
|
Name string `form:"Name" validate:"required"`
|
||||||
|
ScenarioID uint `form:"ScenarioID" validate:"required"`
|
||||||
|
ICID uint `form:"ICID" validate:"required"`
|
||||||
|
StartParameters postgres.Jsonb `form:"StartParameters" validate:"required"`
|
||||||
|
SelectedFileID uint `form:"SelectedFileID" validate:"omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type validUpdatedConfig struct {
|
||||||
|
Name string `form:"Name" validate:"omitempty"`
|
||||||
|
ICID uint `form:"ICID" validate:"omitempty"`
|
||||||
|
StartParameters postgres.Jsonb `form:"StartParameters" validate:"omitempty"`
|
||||||
|
SelectedFileID uint `form:"SelectedFileID" validate:"omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type addConfigRequest struct {
|
||||||
|
Config validNewConfig `json:"config"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type updateConfigRequest struct {
|
||||||
|
Config validUpdatedConfig `json:"config"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *addConfigRequest) validate() error {
|
||||||
|
validate = validator.New()
|
||||||
|
errs := validate.Struct(r)
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *validUpdatedConfig) validate() error {
|
||||||
|
validate = validator.New()
|
||||||
|
errs := validate.Struct(r)
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *addConfigRequest) createConfig() ComponentConfiguration {
|
||||||
|
var s ComponentConfiguration
|
||||||
|
|
||||||
|
s.Name = r.Config.Name
|
||||||
|
s.ScenarioID = r.Config.ScenarioID
|
||||||
|
s.ICID = r.Config.ICID
|
||||||
|
s.StartParameters = r.Config.StartParameters
|
||||||
|
s.SelectedFileID = r.Config.SelectedFileID
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *updateConfigRequest) updateConfig(oldConfig ComponentConfiguration) ComponentConfiguration {
|
||||||
|
// Use the old ComponentConfiguration as a basis for the updated config
|
||||||
|
s := oldConfig
|
||||||
|
|
||||||
|
if r.Config.Name != "" {
|
||||||
|
s.Name = r.Config.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.Config.ICID != 0 {
|
||||||
|
s.ICID = r.Config.ICID
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.Config.SelectedFileID != 0 {
|
||||||
|
s.SelectedFileID = r.Config.SelectedFileID
|
||||||
|
}
|
||||||
|
|
||||||
|
// only update Params if not empty
|
||||||
|
var emptyJson postgres.Jsonb
|
||||||
|
// Serialize empty json and params
|
||||||
|
emptyJson_ser, _ := json.Marshal(emptyJson)
|
||||||
|
startParams_ser, _ := json.Marshal(r.Config.StartParameters)
|
||||||
|
opts := jsondiff.DefaultConsoleOptions()
|
||||||
|
diff, _ := jsondiff.Compare(emptyJson_ser, startParams_ser, &opts)
|
||||||
|
if diff.String() != "FullMatch" {
|
||||||
|
s.StartParameters = r.Config.StartParameters
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
|
@ -30,7 +30,7 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/simulationmodel"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/component-configuration"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/widget"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/widget"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -43,23 +43,23 @@ func RegisterFileEndpoints(r *gin.RouterGroup) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// getFiles godoc
|
// getFiles godoc
|
||||||
// @Summary Get all files of a specific model or widget
|
// @Summary Get all files of a specific component configuration or widget
|
||||||
// @ID getFiles
|
// @ID getFiles
|
||||||
// @Tags files
|
// @Tags files
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} docs.ResponseFiles "Files which belong to simulation model or widget"
|
// @Success 200 {object} docs.ResponseFiles "Files which belong to config or widget"
|
||||||
// @Failure 404 {object} docs.ResponseError "Not found"
|
// @Failure 404 {object} docs.ResponseError "Not found"
|
||||||
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
||||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
||||||
// @Param Authorization header string true "Authorization token"
|
// @Param Authorization header string true "Authorization token"
|
||||||
// @Param objectType query string true "Set to model for files of model, set to widget for files of widget"
|
// @Param objectType query string true "Set to config for files of component configuration, set to widget for files of widget"
|
||||||
// @Param objectID query int true "ID of either model or widget of which files are requested"
|
// @Param objectID query int true "ID of either config or widget of which files are requested"
|
||||||
// @Router /files [get]
|
// @Router /files [get]
|
||||||
func getFiles(c *gin.Context) {
|
func getFiles(c *gin.Context) {
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
objectType := c.Request.URL.Query().Get("objectType")
|
objectType := c.Request.URL.Query().Get("objectType")
|
||||||
if objectType != "model" && objectType != "widget" {
|
if objectType != "config" && objectType != "widget" {
|
||||||
helper.BadRequestError(c, fmt.Sprintf("Object type not supported for files: %s", objectType))
|
helper.BadRequestError(c, fmt.Sprintf("Object type not supported for files: %s", objectType))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -72,10 +72,10 @@ func getFiles(c *gin.Context) {
|
||||||
|
|
||||||
//Check access
|
//Check access
|
||||||
var ok bool
|
var ok bool
|
||||||
var m simulationmodel.SimulationModel
|
var m component_configuration.ComponentConfiguration
|
||||||
var w widget.Widget
|
var w widget.Widget
|
||||||
if objectType == "model" {
|
if objectType == "config" {
|
||||||
ok, m = simulationmodel.CheckPermissions(c, database.Read, "body", objectID)
|
ok, m = component_configuration.CheckPermissions(c, database.Read, "body", objectID)
|
||||||
} else {
|
} else {
|
||||||
ok, w = widget.CheckPermissions(c, database.Read, objectID)
|
ok, w = widget.CheckPermissions(c, database.Read, objectID)
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ func getFiles(c *gin.Context) {
|
||||||
|
|
||||||
var files []database.File
|
var files []database.File
|
||||||
|
|
||||||
if objectType == "model" {
|
if objectType == "config" {
|
||||||
err = db.Order("ID asc").Model(&m).Related(&files, "Files").Error
|
err = db.Order("ID asc").Model(&m).Related(&files, "Files").Error
|
||||||
} else {
|
} else {
|
||||||
err = db.Order("ID asc").Model(&w).Related(&files, "Files").Error
|
err = db.Order("ID asc").Model(&w).Related(&files, "Files").Error
|
||||||
|
@ -101,7 +101,7 @@ func getFiles(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// addFile godoc
|
// addFile godoc
|
||||||
// @Summary Add a file to a specific model or widget
|
// @Summary Add a file to a specific component config or widget
|
||||||
// @ID addFile
|
// @ID addFile
|
||||||
// @Tags files
|
// @Tags files
|
||||||
// @Produce json
|
// @Produce json
|
||||||
|
@ -118,13 +118,13 @@ func getFiles(c *gin.Context) {
|
||||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
||||||
// @Param Authorization header string true "Authorization token"
|
// @Param Authorization header string true "Authorization token"
|
||||||
// @Param inputFile formData file true "File to be uploaded"
|
// @Param inputFile formData file true "File to be uploaded"
|
||||||
// @Param objectType query string true "Set to model for files of model, set to widget for files of widget"
|
// @Param objectType query string true "Set to config for files of component config, set to widget for files of widget"
|
||||||
// @Param objectID query int true "ID of either model or widget of which files are requested"
|
// @Param objectID query int true "ID of either config or widget of which files are requested"
|
||||||
// @Router /files [post]
|
// @Router /files [post]
|
||||||
func addFile(c *gin.Context) {
|
func addFile(c *gin.Context) {
|
||||||
|
|
||||||
objectType := c.Request.URL.Query().Get("objectType")
|
objectType := c.Request.URL.Query().Get("objectType")
|
||||||
if objectType != "model" && objectType != "widget" {
|
if objectType != "config" && objectType != "widget" {
|
||||||
helper.BadRequestError(c, fmt.Sprintf("Object type not supported for files: %s", objectType))
|
helper.BadRequestError(c, fmt.Sprintf("Object type not supported for files: %s", objectType))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -137,8 +137,8 @@ func addFile(c *gin.Context) {
|
||||||
|
|
||||||
// Check access
|
// Check access
|
||||||
var ok bool
|
var ok bool
|
||||||
if objectType == "model" {
|
if objectType == "config" {
|
||||||
ok, _ = simulationmodel.CheckPermissions(c, database.Update, "body", objectID)
|
ok, _ = component_configuration.CheckPermissions(c, database.Update, "body", objectID)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/simulationmodel"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/component-configuration"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/widget"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/widget"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -84,14 +84,14 @@ func (f *File) register(fileHeader *multipart.FileHeader, objectType string, obj
|
||||||
f.ImageWidth = 0 // TODO: do we need this?
|
f.ImageWidth = 0 // TODO: do we need this?
|
||||||
f.ImageHeight = 0 // TODO: do we need this?
|
f.ImageHeight = 0 // TODO: do we need this?
|
||||||
|
|
||||||
var m simulationmodel.SimulationModel
|
var m component_configuration.ComponentConfiguration
|
||||||
var w widget.Widget
|
var w widget.Widget
|
||||||
var err error
|
var err error
|
||||||
if objectType == "model" {
|
if objectType == "config" {
|
||||||
// check if model exists
|
// check if config exists
|
||||||
err = m.ByID(objectID)
|
err = m.ByID(objectID)
|
||||||
f.WidgetID = 0
|
f.WidgetID = 0
|
||||||
f.SimulationModelID = objectID
|
f.ConfigID = objectID
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ func (f *File) register(fileHeader *multipart.FileHeader, objectType string, obj
|
||||||
} else {
|
} else {
|
||||||
// check if widget exists
|
// check if widget exists
|
||||||
f.WidgetID = objectID
|
f.WidgetID = objectID
|
||||||
f.SimulationModelID = 0
|
f.ConfigID = 0
|
||||||
err = w.ByID(uint(objectID))
|
err = w.ByID(uint(objectID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -122,8 +122,8 @@ func (f *File) register(fileHeader *multipart.FileHeader, objectType string, obj
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create association to model or widget
|
// Create association to config or widget
|
||||||
if objectType == "model" {
|
if objectType == "config" {
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
err := db.Model(&m).Association("Files").Append(f).Error
|
err := db.Model(&m).Association("Files").Append(f).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -174,9 +174,9 @@ func (f *File) delete() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// remove association between file and simulation model
|
// remove association between file and config
|
||||||
var m simulationmodel.SimulationModel
|
var m component_configuration.ComponentConfiguration
|
||||||
err := m.ByID(f.SimulationModelID)
|
err := m.ByID(f.ConfigID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/simulationmodel"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/component-configuration"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/widget"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/widget"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
@ -50,8 +50,8 @@ func checkPermissions(c *gin.Context, operation database.CRUD) (bool, File) {
|
||||||
return false, f
|
return false, f
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.SimulationModelID > 0 {
|
if f.ConfigID > 0 {
|
||||||
ok, _ := simulationmodel.CheckPermissions(c, operation, "body", int(f.SimulationModelID))
|
ok, _ := component_configuration.CheckPermissions(c, operation, "body", int(f.ConfigID))
|
||||||
if !ok {
|
if !ok {
|
||||||
return false, f
|
return false, f
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,10 +27,10 @@ import (
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
|
||||||
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/component-configuration"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/dashboard"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/dashboard"
|
||||||
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/infrastructure-component"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/simulationmodel"
|
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/simulator"
|
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/user"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/user"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/widget"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/widget"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
@ -49,14 +49,14 @@ import (
|
||||||
var router *gin.Engine
|
var router *gin.Engine
|
||||||
var db *gorm.DB
|
var db *gorm.DB
|
||||||
|
|
||||||
type SimulationModelRequest struct {
|
type ConfigRequest struct {
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
ScenarioID uint `json:"scenarioID,omitempty"`
|
ScenarioID uint `json:"scenarioID,omitempty"`
|
||||||
SimulatorID uint `json:"simulatorID,omitempty"`
|
ICID uint `json:"icID,omitempty"`
|
||||||
StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
|
StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SimulatorRequest struct {
|
type ICRequest struct {
|
||||||
UUID string `json:"uuid,omitempty"`
|
UUID string `json:"uuid,omitempty"`
|
||||||
Host string `json:"host,omitempty"`
|
Host string `json:"host,omitempty"`
|
||||||
Modeltype string `json:"modelType,omitempty"`
|
Modeltype string `json:"modelType,omitempty"`
|
||||||
|
@ -91,25 +91,25 @@ type WidgetRequest struct {
|
||||||
CustomProperties postgres.Jsonb `json:"customProperties,omitempty"`
|
CustomProperties postgres.Jsonb `json:"customProperties,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func addScenarioAndSimulatorAndSimulationModelAndDashboardAndWidget() (scenarioID uint, simulatorID uint, simulationModelID uint, dashboardID uint, widgetID uint) {
|
func addScenarioAndICAndConfigAndDashboardAndWidget() (scenarioID uint, ICID uint, configID uint, dashboardID uint, widgetID uint) {
|
||||||
|
|
||||||
// authenticate as admin
|
// authenticate as admin
|
||||||
token, _ := helper.AuthenticateForTest(router,
|
token, _ := helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.AdminCredentials)
|
"/api/authenticate", "POST", helper.AdminCredentials)
|
||||||
|
|
||||||
// POST $newSimulatorA
|
// POST $newICA
|
||||||
newSimulatorA := SimulatorRequest{
|
newICA := ICRequest{
|
||||||
UUID: database.SimulatorA.UUID,
|
UUID: database.ICA.UUID,
|
||||||
Host: database.SimulatorA.Host,
|
Host: database.ICA.Host,
|
||||||
Modeltype: database.SimulatorA.Modeltype,
|
Modeltype: database.ICA.Modeltype,
|
||||||
State: database.SimulatorA.State,
|
State: database.ICA.State,
|
||||||
Properties: database.SimulatorA.Properties,
|
Properties: database.ICA.Properties,
|
||||||
}
|
}
|
||||||
_, resp, _ := helper.TestEndpoint(router, token,
|
_, resp, _ := helper.TestEndpoint(router, token,
|
||||||
"/api/simulators", "POST", helper.KeyModels{"simulator": newSimulatorA})
|
"/api/ic", "POST", helper.KeyModels{"ic": newICA})
|
||||||
|
|
||||||
// Read newSimulator's ID from the response
|
// Read newIC's ID from the response
|
||||||
newSimulatorID, _ := helper.GetResponseID(resp)
|
newICID, _ := helper.GetResponseID(resp)
|
||||||
|
|
||||||
// authenticate as normal user
|
// authenticate as normal user
|
||||||
token, _ = helper.AuthenticateForTest(router,
|
token, _ = helper.AuthenticateForTest(router,
|
||||||
|
@ -127,18 +127,18 @@ func addScenarioAndSimulatorAndSimulationModelAndDashboardAndWidget() (scenarioI
|
||||||
// Read newScenario's ID from the response
|
// Read newScenario's ID from the response
|
||||||
newScenarioID, _ := helper.GetResponseID(resp)
|
newScenarioID, _ := helper.GetResponseID(resp)
|
||||||
|
|
||||||
// POST new simulation model
|
// POST new component config
|
||||||
newSimulationModel := SimulationModelRequest{
|
newConfig := ConfigRequest{
|
||||||
Name: database.SimulationModelA.Name,
|
Name: database.ConfigA.Name,
|
||||||
ScenarioID: uint(newScenarioID),
|
ScenarioID: uint(newScenarioID),
|
||||||
SimulatorID: uint(newSimulatorID),
|
ICID: uint(newICID),
|
||||||
StartParameters: database.SimulationModelA.StartParameters,
|
StartParameters: database.ConfigA.StartParameters,
|
||||||
}
|
}
|
||||||
_, resp, _ = helper.TestEndpoint(router, token,
|
_, resp, _ = helper.TestEndpoint(router, token,
|
||||||
"/api/models", "POST", helper.KeyModels{"simulationModel": newSimulationModel})
|
"/api/configs", "POST", helper.KeyModels{"config": newConfig})
|
||||||
|
|
||||||
// Read newSimulationModel's ID from the response
|
// Read newConfig's ID from the response
|
||||||
newSimulationModelID, _ := helper.GetResponseID(resp)
|
newConfigID, _ := helper.GetResponseID(resp)
|
||||||
|
|
||||||
// POST new dashboard
|
// POST new dashboard
|
||||||
newDashboard := DashboardRequest{
|
newDashboard := DashboardRequest{
|
||||||
|
@ -177,7 +177,7 @@ func addScenarioAndSimulatorAndSimulationModelAndDashboardAndWidget() (scenarioI
|
||||||
_, resp, _ = helper.TestEndpoint(router, token,
|
_, resp, _ = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/scenarios/%v/user?username=User_C", newScenarioID), "PUT", nil)
|
fmt.Sprintf("/api/scenarios/%v/user?username=User_C", newScenarioID), "PUT", nil)
|
||||||
|
|
||||||
return uint(newScenarioID), uint(newSimulatorID), uint(newSimulationModelID), uint(newDashboardID), uint(newWidgetID)
|
return uint(newScenarioID), uint(newICID), uint(newConfigID), uint(newDashboardID), uint(newWidgetID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
|
@ -196,15 +196,15 @@ func TestMain(m *testing.M) {
|
||||||
|
|
||||||
user.RegisterAuthenticate(api.Group("/authenticate"))
|
user.RegisterAuthenticate(api.Group("/authenticate"))
|
||||||
api.Use(user.Authentication(true))
|
api.Use(user.Authentication(true))
|
||||||
// simulationmodel endpoints required here to first add a simulation to the DB
|
// component-configuration endpoints required here to first add a config to the DB
|
||||||
// that can be associated with a new file
|
// that can be associated with a new file
|
||||||
simulationmodel.RegisterSimulationModelEndpoints(api.Group("/models"))
|
component_configuration.RegisterComponentConfigurationEndpoints(api.Group("/configs"))
|
||||||
// scenario endpoints required here to first add a scenario to the DB
|
// scenario endpoints required here to first add a scenario to the DB
|
||||||
// that can be associated with a new simulation model
|
// that can be associated with a new component config
|
||||||
scenario.RegisterScenarioEndpoints(api.Group("/scenarios"))
|
scenario.RegisterScenarioEndpoints(api.Group("/scenarios"))
|
||||||
// simulator endpoints required here to first add a simulator to the DB
|
// IC endpoints required here to first add a IC to the DB
|
||||||
// that can be associated with a new simulation model
|
// that can be associated with a new component config
|
||||||
simulator.RegisterSimulatorEndpoints(api.Group("/simulators"))
|
infrastructure_component.RegisterICEndpoints(api.Group("/ic"))
|
||||||
// dashboard endpoints required here to first add a dashboard to the DB
|
// dashboard endpoints required here to first add a dashboard to the DB
|
||||||
// that can be associated with a new widget
|
// that can be associated with a new widget
|
||||||
dashboard.RegisterDashboardEndpoints(api.Group("/dashboards"))
|
dashboard.RegisterDashboardEndpoints(api.Group("/dashboards"))
|
||||||
|
@ -224,7 +224,7 @@ func TestAddFile(t *testing.T) {
|
||||||
|
|
||||||
// prepare the content of the DB for testing
|
// prepare the content of the DB for testing
|
||||||
// using the respective endpoints of the API
|
// using the respective endpoints of the API
|
||||||
_, _, simulationModelID, _, widgetID := addScenarioAndSimulatorAndSimulationModelAndDashboardAndWidget()
|
_, _, configID, _, widgetID := addScenarioAndICAndConfigAndDashboardAndWidget()
|
||||||
|
|
||||||
// authenticate as userB who has no access to the elements in the DB
|
// authenticate as userB who has no access to the elements in the DB
|
||||||
token, err := helper.AuthenticateForTest(router,
|
token, err := helper.AuthenticateForTest(router,
|
||||||
|
@ -233,10 +233,10 @@ func TestAddFile(t *testing.T) {
|
||||||
|
|
||||||
emptyBuf := &bytes.Buffer{}
|
emptyBuf := &bytes.Buffer{}
|
||||||
|
|
||||||
// try to POST to a simulation model to which UserB has no access
|
// try to POST to a component config to which UserB has no access
|
||||||
// should return a 422 unprocessable entity error
|
// should return a 422 unprocessable entity error
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/files?objectID=%v&objectType=model", simulationModelID), "POST", emptyBuf)
|
fmt.Sprintf("/api/files?objectID=%v&objectType=config", configID), "POST", emptyBuf)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
|
@ -262,14 +262,14 @@ func TestAddFile(t *testing.T) {
|
||||||
// try to POST without an object ID
|
// try to POST without an object ID
|
||||||
// should return a bad request error
|
// should return a bad request error
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/files?objectType=model"), "POST", emptyBuf)
|
fmt.Sprintf("/api/files?objectType=config"), "POST", emptyBuf)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 400, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 400, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// try to POST an invalid file
|
// try to POST an invalid file
|
||||||
// should return a bad request
|
// should return a bad request
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/files?objectID=%v&objectType=model", simulationModelID), "POST", emptyBuf)
|
fmt.Sprintf("/api/files?objectID=%v&objectType=config", configID), "POST", emptyBuf)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 400, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 400, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
|
@ -299,7 +299,7 @@ func TestAddFile(t *testing.T) {
|
||||||
|
|
||||||
// Create the request
|
// Create the request
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
req, err := http.NewRequest("POST", fmt.Sprintf("/api/files?objectID=%v&objectType=model", simulationModelID), bodyBuf)
|
req, err := http.NewRequest("POST", fmt.Sprintf("/api/files?objectID=%v&objectType=config", configID), bodyBuf)
|
||||||
assert.NoError(t, err, "create request")
|
assert.NoError(t, err, "create request")
|
||||||
|
|
||||||
req.Header.Set("Content-Type", contentType)
|
req.Header.Set("Content-Type", contentType)
|
||||||
|
@ -340,7 +340,7 @@ func TestUpdateFile(t *testing.T) {
|
||||||
|
|
||||||
// prepare the content of the DB for testing
|
// prepare the content of the DB for testing
|
||||||
// using the respective endpoints of the API
|
// using the respective endpoints of the API
|
||||||
_, _, simulationModelID, _, _ := addScenarioAndSimulatorAndSimulationModelAndDashboardAndWidget()
|
_, _, configID, _, _ := addScenarioAndICAndConfigAndDashboardAndWidget()
|
||||||
|
|
||||||
// authenticate as normal user
|
// authenticate as normal user
|
||||||
token, err := helper.AuthenticateForTest(router,
|
token, err := helper.AuthenticateForTest(router,
|
||||||
|
@ -372,7 +372,7 @@ func TestUpdateFile(t *testing.T) {
|
||||||
|
|
||||||
// Create the POST request
|
// Create the POST request
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
req, err := http.NewRequest("POST", fmt.Sprintf("/api/files?objectID=%v&objectType=model", simulationModelID), bodyBuf)
|
req, err := http.NewRequest("POST", fmt.Sprintf("/api/files?objectID=%v&objectType=config", configID), bodyBuf)
|
||||||
assert.NoError(t, err, "create request")
|
assert.NoError(t, err, "create request")
|
||||||
|
|
||||||
req.Header.Set("Content-Type", contentType)
|
req.Header.Set("Content-Type", contentType)
|
||||||
|
@ -474,7 +474,7 @@ func TestDeleteFile(t *testing.T) {
|
||||||
|
|
||||||
// prepare the content of the DB for testing
|
// prepare the content of the DB for testing
|
||||||
// using the respective endpoints of the API
|
// using the respective endpoints of the API
|
||||||
_, _, simulationModelID, _, widgetID := addScenarioAndSimulatorAndSimulationModelAndDashboardAndWidget()
|
_, _, configID, _, widgetID := addScenarioAndICAndConfigAndDashboardAndWidget()
|
||||||
|
|
||||||
// authenticate as normal user
|
// authenticate as normal user
|
||||||
token, err := helper.AuthenticateForTest(router,
|
token, err := helper.AuthenticateForTest(router,
|
||||||
|
@ -504,7 +504,7 @@ func TestDeleteFile(t *testing.T) {
|
||||||
|
|
||||||
// Create the request
|
// Create the request
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
req, err := http.NewRequest("POST", fmt.Sprintf("/api/files?objectID=%v&objectType=model", simulationModelID), bodyBuf)
|
req, err := http.NewRequest("POST", fmt.Sprintf("/api/files?objectID=%v&objectType=config", configID), bodyBuf)
|
||||||
assert.NoError(t, err, "create request")
|
assert.NoError(t, err, "create request")
|
||||||
req.Header.Set("Content-Type", contentType)
|
req.Header.Set("Content-Type", contentType)
|
||||||
req.Header.Add("Authorization", "Bearer "+token)
|
req.Header.Add("Authorization", "Bearer "+token)
|
||||||
|
@ -542,7 +542,7 @@ func TestDeleteFile(t *testing.T) {
|
||||||
"/api/authenticate", "POST", helper.UserBCredentials)
|
"/api/authenticate", "POST", helper.UserBCredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// try to DELETE file of simulation model to which userB has no access
|
// try to DELETE file of component config to which userB has no access
|
||||||
// should return an unprocessable entity error
|
// should return an unprocessable entity error
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/files/%v", newFileID), "DELETE", nil)
|
fmt.Sprintf("/api/files/%v", newFileID), "DELETE", nil)
|
||||||
|
@ -561,9 +561,9 @@ func TestDeleteFile(t *testing.T) {
|
||||||
"/api/authenticate", "POST", helper.UserACredentials)
|
"/api/authenticate", "POST", helper.UserACredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Count the number of all files returned for simulation model
|
// Count the number of all files returned for component config
|
||||||
initialNumber, err := helper.LengthOfResponse(router, token,
|
initialNumber, err := helper.LengthOfResponse(router, token,
|
||||||
fmt.Sprintf("/api/files?objectID=%v&objectType=model", simulationModelID), "GET", nil)
|
fmt.Sprintf("/api/files?objectID=%v&objectType=config", configID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// try to DELETE non-existing fileID
|
// try to DELETE non-existing fileID
|
||||||
|
@ -578,7 +578,7 @@ func TestDeleteFile(t *testing.T) {
|
||||||
"/api/authenticate", "POST", helper.GuestCredentials)
|
"/api/authenticate", "POST", helper.GuestCredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// try to DELETE file of simulation model as guest
|
// try to DELETE file of component config as guest
|
||||||
// should return an unprocessable entity error
|
// should return an unprocessable entity error
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/files/%v", newFileID), "DELETE", nil)
|
fmt.Sprintf("/api/files/%v", newFileID), "DELETE", nil)
|
||||||
|
@ -609,15 +609,15 @@ func TestDeleteFile(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Again count the number of all the files returned for simulation model
|
// Again count the number of all the files returned for component config
|
||||||
finalNumber, err := helper.LengthOfResponse(router, token,
|
finalNumber, err := helper.LengthOfResponse(router, token,
|
||||||
fmt.Sprintf("/api/files?objectID=%v&objectType=model", simulationModelID), "GET", nil)
|
fmt.Sprintf("/api/files?objectID=%v&objectType=config", configID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, initialNumber-1, finalNumber)
|
assert.Equal(t, initialNumber-1, finalNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetAllFilesOfSimulationModel(t *testing.T) {
|
func TestGetAllFilesOfConfig(t *testing.T) {
|
||||||
|
|
||||||
database.DropTables(db)
|
database.DropTables(db)
|
||||||
database.MigrateModels(db)
|
database.MigrateModels(db)
|
||||||
|
@ -625,17 +625,17 @@ func TestGetAllFilesOfSimulationModel(t *testing.T) {
|
||||||
|
|
||||||
// prepare the content of the DB for testing
|
// prepare the content of the DB for testing
|
||||||
// using the respective endpoints of the API
|
// using the respective endpoints of the API
|
||||||
_, _, simulationModelID, _, widgetID := addScenarioAndSimulatorAndSimulationModelAndDashboardAndWidget()
|
_, _, ConfigID, _, widgetID := addScenarioAndICAndConfigAndDashboardAndWidget()
|
||||||
|
|
||||||
// authenticate as userB who has no access to the elements in the DB
|
// authenticate as userB who has no access to the elements in the DB
|
||||||
token, err := helper.AuthenticateForTest(router,
|
token, err := helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.UserBCredentials)
|
"/api/authenticate", "POST", helper.UserBCredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// try to get all files for simulation model to which userB has not access
|
// try to get all files for component config to which userB has not access
|
||||||
// should return unprocessable entity error
|
// should return unprocessable entity error
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/files?objectID=%v&objectType=model", simulationModelID), "GET", nil)
|
fmt.Sprintf("/api/files?objectID=%v&objectType=config", ConfigID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
|
@ -653,19 +653,19 @@ func TestGetAllFilesOfSimulationModel(t *testing.T) {
|
||||||
|
|
||||||
//try to get all files for unsupported object type; should return a bad request error
|
//try to get all files for unsupported object type; should return a bad request error
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/files?objectID=%v&objectType=wrongtype", simulationModelID), "GET", nil)
|
fmt.Sprintf("/api/files?objectID=%v&objectType=wrongtype", ConfigID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 400, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 400, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
//try to get all files with missing object ID; should return a bad request error
|
//try to get all files with missing object ID; should return a bad request error
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/files?objectType=model"), "GET", nil)
|
fmt.Sprintf("/api/files?objectType=config"), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 400, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 400, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Count the number of all files returned for simulation model
|
// Count the number of all files returned for component config
|
||||||
initialNumberModel, err := helper.LengthOfResponse(router, token,
|
initialNumberConfig, err := helper.LengthOfResponse(router, token,
|
||||||
fmt.Sprintf("/api/files?objectID=%v&objectType=model", simulationModelID), "GET", nil)
|
fmt.Sprintf("/api/files?objectID=%v&objectType=config", ConfigID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Count the number of all files returned for widget
|
// Count the number of all files returned for widget
|
||||||
|
@ -683,30 +683,30 @@ func TestGetAllFilesOfSimulationModel(t *testing.T) {
|
||||||
assert.NoError(t, err, "opening file")
|
assert.NoError(t, err, "opening file")
|
||||||
defer fh.Close()
|
defer fh.Close()
|
||||||
|
|
||||||
// test POST a file to simulation model and widget
|
// test POST a file to component config and widget
|
||||||
bodyBufModel1 := &bytes.Buffer{}
|
bodyBufConfig1 := &bytes.Buffer{}
|
||||||
bodyBufWidget1 := &bytes.Buffer{}
|
bodyBufWidget1 := &bytes.Buffer{}
|
||||||
bodyWriterModel1 := multipart.NewWriter(bodyBufModel1)
|
bodyWriterConfig1 := multipart.NewWriter(bodyBufConfig1)
|
||||||
bodyWriterWidget1 := multipart.NewWriter(bodyBufWidget1)
|
bodyWriterWidget1 := multipart.NewWriter(bodyBufWidget1)
|
||||||
fileWriterModel1, err := bodyWriterModel1.CreateFormFile("file", "testuploadfile.txt")
|
fileWriterConfig1, err := bodyWriterConfig1.CreateFormFile("file", "testuploadfile.txt")
|
||||||
assert.NoError(t, err, "writing to buffer")
|
assert.NoError(t, err, "writing to buffer")
|
||||||
fileWriterWidget1, err := bodyWriterWidget1.CreateFormFile("file", "testuploadfile.txt")
|
fileWriterWidget1, err := bodyWriterWidget1.CreateFormFile("file", "testuploadfile.txt")
|
||||||
assert.NoError(t, err, "writing to buffer")
|
assert.NoError(t, err, "writing to buffer")
|
||||||
// io copy
|
// io copy
|
||||||
_, err = io.Copy(fileWriterModel1, fh)
|
_, err = io.Copy(fileWriterConfig1, fh)
|
||||||
assert.NoError(t, err, "IO copy")
|
assert.NoError(t, err, "IO copy")
|
||||||
_, err = io.Copy(fileWriterWidget1, fh)
|
_, err = io.Copy(fileWriterWidget1, fh)
|
||||||
assert.NoError(t, err, "IO copy")
|
assert.NoError(t, err, "IO copy")
|
||||||
contentTypeModel1 := bodyWriterModel1.FormDataContentType()
|
contentTypeConfig1 := bodyWriterConfig1.FormDataContentType()
|
||||||
contentTypeWidget1 := bodyWriterWidget1.FormDataContentType()
|
contentTypeWidget1 := bodyWriterWidget1.FormDataContentType()
|
||||||
bodyWriterModel1.Close()
|
bodyWriterConfig1.Close()
|
||||||
bodyWriterWidget1.Close()
|
bodyWriterWidget1.Close()
|
||||||
|
|
||||||
// Create the request for simulation model
|
// Create the request for component config
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
req, err := http.NewRequest("POST", fmt.Sprintf("/api/files?objectID=%v&objectType=model", simulationModelID), bodyBufModel1)
|
req, err := http.NewRequest("POST", fmt.Sprintf("/api/files?objectID=%v&objectType=config", ConfigID), bodyBufConfig1)
|
||||||
assert.NoError(t, err, "create request")
|
assert.NoError(t, err, "create request")
|
||||||
req.Header.Set("Content-Type", contentTypeModel1)
|
req.Header.Set("Content-Type", contentTypeConfig1)
|
||||||
req.Header.Add("Authorization", "Bearer "+token)
|
req.Header.Add("Authorization", "Bearer "+token)
|
||||||
router.ServeHTTP(w, req)
|
router.ServeHTTP(w, req)
|
||||||
assert.Equalf(t, 200, w.Code, "Response body: \n%v\n", w.Body)
|
assert.Equalf(t, 200, w.Code, "Response body: \n%v\n", w.Body)
|
||||||
|
@ -720,36 +720,36 @@ func TestGetAllFilesOfSimulationModel(t *testing.T) {
|
||||||
router.ServeHTTP(w2, req2)
|
router.ServeHTTP(w2, req2)
|
||||||
assert.Equalf(t, 200, w2.Code, "Response body: \n%v\n", w2.Body)
|
assert.Equalf(t, 200, w2.Code, "Response body: \n%v\n", w2.Body)
|
||||||
|
|
||||||
// POST a second file to simulation model and widget
|
// POST a second file to component config and widget
|
||||||
|
|
||||||
// open a second file handle
|
// open a second file handle
|
||||||
fh2, err := os.Open("testfile.txt")
|
fh2, err := os.Open("testfile.txt")
|
||||||
assert.NoError(t, err, "opening file")
|
assert.NoError(t, err, "opening file")
|
||||||
defer fh2.Close()
|
defer fh2.Close()
|
||||||
|
|
||||||
bodyBufModel2 := &bytes.Buffer{}
|
bodyBufConfig2 := &bytes.Buffer{}
|
||||||
bodyBufWidget2 := &bytes.Buffer{}
|
bodyBufWidget2 := &bytes.Buffer{}
|
||||||
bodyWriterModel2 := multipart.NewWriter(bodyBufModel2)
|
bodyWriterConfig2 := multipart.NewWriter(bodyBufConfig2)
|
||||||
bodyWriterWidget2 := multipart.NewWriter(bodyBufWidget2)
|
bodyWriterWidget2 := multipart.NewWriter(bodyBufWidget2)
|
||||||
fileWriterModel2, err := bodyWriterModel2.CreateFormFile("file", "testuploadfile2.txt")
|
fileWriterConfig2, err := bodyWriterConfig2.CreateFormFile("file", "testuploadfile2.txt")
|
||||||
assert.NoError(t, err, "writing to buffer")
|
assert.NoError(t, err, "writing to buffer")
|
||||||
fileWriterWidget2, err := bodyWriterWidget2.CreateFormFile("file", "testuploadfile2.txt")
|
fileWriterWidget2, err := bodyWriterWidget2.CreateFormFile("file", "testuploadfile2.txt")
|
||||||
assert.NoError(t, err, "writing to buffer")
|
assert.NoError(t, err, "writing to buffer")
|
||||||
|
|
||||||
// io copy
|
// io copy
|
||||||
_, err = io.Copy(fileWriterModel2, fh2)
|
_, err = io.Copy(fileWriterConfig2, fh2)
|
||||||
assert.NoError(t, err, "IO copy")
|
assert.NoError(t, err, "IO copy")
|
||||||
_, err = io.Copy(fileWriterWidget2, fh2)
|
_, err = io.Copy(fileWriterWidget2, fh2)
|
||||||
assert.NoError(t, err, "IO copy")
|
assert.NoError(t, err, "IO copy")
|
||||||
contentTypeModel2 := bodyWriterModel2.FormDataContentType()
|
contentTypeConfig2 := bodyWriterConfig2.FormDataContentType()
|
||||||
contentTypeWidget2 := bodyWriterWidget2.FormDataContentType()
|
contentTypeWidget2 := bodyWriterWidget2.FormDataContentType()
|
||||||
bodyWriterModel2.Close()
|
bodyWriterConfig2.Close()
|
||||||
bodyWriterWidget2.Close()
|
bodyWriterWidget2.Close()
|
||||||
|
|
||||||
w3 := httptest.NewRecorder()
|
w3 := httptest.NewRecorder()
|
||||||
req3, err := http.NewRequest("POST", fmt.Sprintf("/api/files?objectID=%v&objectType=model", simulationModelID), bodyBufModel2)
|
req3, err := http.NewRequest("POST", fmt.Sprintf("/api/files?objectID=%v&objectType=config", ConfigID), bodyBufConfig2)
|
||||||
assert.NoError(t, err, "create request")
|
assert.NoError(t, err, "create request")
|
||||||
req3.Header.Set("Content-Type", contentTypeModel2)
|
req3.Header.Set("Content-Type", contentTypeConfig2)
|
||||||
req3.Header.Add("Authorization", "Bearer "+token)
|
req3.Header.Add("Authorization", "Bearer "+token)
|
||||||
router.ServeHTTP(w3, req3)
|
router.ServeHTTP(w3, req3)
|
||||||
assert.Equalf(t, 200, w3.Code, "Response body: \n%v\n", w3.Body)
|
assert.Equalf(t, 200, w3.Code, "Response body: \n%v\n", w3.Body)
|
||||||
|
@ -762,11 +762,11 @@ func TestGetAllFilesOfSimulationModel(t *testing.T) {
|
||||||
router.ServeHTTP(w4, req4)
|
router.ServeHTTP(w4, req4)
|
||||||
assert.Equalf(t, 200, w4.Code, "Response body: \n%v\n", w4.Body)
|
assert.Equalf(t, 200, w4.Code, "Response body: \n%v\n", w4.Body)
|
||||||
|
|
||||||
// Again count the number of all the files returned for simulation model
|
// Again count the number of all the files returned for component config
|
||||||
finalNumberModel, err := helper.LengthOfResponse(router, token,
|
finalNumberConfig, err := helper.LengthOfResponse(router, token,
|
||||||
fmt.Sprintf("/api/files?objectID=%v&objectType=model", simulationModelID), "GET", nil)
|
fmt.Sprintf("/api/files?objectID=%v&objectType=config", ConfigID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, initialNumberModel+2, finalNumberModel)
|
assert.Equal(t, initialNumberConfig+2, finalNumberConfig)
|
||||||
|
|
||||||
// Again count the number of all the files returned for widget
|
// Again count the number of all the files returned for widget
|
||||||
finalNumberWidget, err := helper.LengthOfResponse(router, token,
|
finalNumberWidget, err := helper.LengthOfResponse(router, token,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/** Simulator package, endpoints.
|
/** InfrastructureComponent package, endpoints.
|
||||||
*
|
*
|
||||||
* @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
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*********************************************************************************/
|
*********************************************************************************/
|
||||||
package simulator
|
package infrastructure_component
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
|
||||||
|
@ -29,61 +29,61 @@ import (
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RegisterSimulatorEndpoints(r *gin.RouterGroup) {
|
func RegisterICEndpoints(r *gin.RouterGroup) {
|
||||||
r.GET("", getSimulators)
|
r.GET("", getICs)
|
||||||
r.POST("", addSimulator)
|
r.POST("", addIC)
|
||||||
r.PUT("/:simulatorID", updateSimulator)
|
r.PUT("/:ICID", updateIC)
|
||||||
r.GET("/:simulatorID", getSimulator)
|
r.GET("/:ICID", getIC)
|
||||||
r.DELETE("/:simulatorID", deleteSimulator)
|
r.DELETE("/:ICID", deleteIC)
|
||||||
r.GET("/:simulatorID/models", getModelsOfSimulator)
|
r.GET("/:ICID/configs", getConfigsOfIC)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getSimulators godoc
|
// getICs godoc
|
||||||
// @Summary Get all simulators
|
// @Summary Get all infrastructure components
|
||||||
// @ID getSimulators
|
// @ID getICs
|
||||||
// @Tags simulators
|
// @Tags infrastructure-components
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} docs.ResponseSimulators "Simulators requested"
|
// @Success 200 {object} docs.ResponseICs "ICs requested"
|
||||||
// @Failure 404 {object} docs.ResponseError "Not found"
|
// @Failure 404 {object} docs.ResponseError "Not found"
|
||||||
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
||||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
||||||
// @Param Authorization header string true "Authorization token"
|
// @Param Authorization header string true "Authorization token"
|
||||||
// @Router /simulators [get]
|
// @Router /ic [get]
|
||||||
func getSimulators(c *gin.Context) {
|
func getICs(c *gin.Context) {
|
||||||
|
|
||||||
// Checking permission is not required here since READ access is independent of user's role
|
// Checking permission is not required here since READ access is independent of user's role
|
||||||
|
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
var simulators []database.Simulator
|
var ics []database.InfrastructureComponent
|
||||||
err := db.Order("ID asc").Find(&simulators).Error
|
err := db.Order("ID asc").Find(&ics).Error
|
||||||
if !helper.DBError(c, err) {
|
if !helper.DBError(c, err) {
|
||||||
c.JSON(http.StatusOK, gin.H{"simulators": simulators})
|
c.JSON(http.StatusOK, gin.H{"ics": ics})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// addSimulator godoc
|
// addIC godoc
|
||||||
// @Summary Add a simulator
|
// @Summary Add an infrastructure component
|
||||||
// @ID addSimulator
|
// @ID addIC
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Tags simulators
|
// @Tags infrastructure-components
|
||||||
// @Success 200 {object} docs.ResponseSimulator "Simulator that was added"
|
// @Success 200 {object} docs.ResponseIC "Infrastructure Component that was added"
|
||||||
// @Failure 400 {object} docs.ResponseError "Bad request"
|
// @Failure 400 {object} docs.ResponseError "Bad request"
|
||||||
// @Failure 404 {object} docs.ResponseError "Not found"
|
// @Failure 404 {object} docs.ResponseError "Not found"
|
||||||
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
||||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
||||||
// @Param Authorization header string true "Authorization token"
|
// @Param Authorization header string true "Authorization token"
|
||||||
// @Param inputSimulator body simulator.addSimulatorRequest true "Simulator to be added"
|
// @Param inputIC body infrastructure_component.addICRequest true "Infrastructure Component to be added"
|
||||||
// @Router /simulators [post]
|
// @Router /ic [post]
|
||||||
func addSimulator(c *gin.Context) {
|
func addIC(c *gin.Context) {
|
||||||
|
|
||||||
ok, _ := CheckPermissions(c, database.ModelSimulator, database.Create, false)
|
ok, _ := CheckPermissions(c, database.ModelInfrastructureComponent, database.Create, false)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var req addSimulatorRequest
|
var req addICRequest
|
||||||
err := c.BindJSON(&req)
|
err := c.BindJSON(&req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.BadRequestError(c, "Error binding form data to JSON: "+err.Error())
|
helper.BadRequestError(c, "Error binding form data to JSON: "+err.Error())
|
||||||
|
@ -96,40 +96,40 @@ func addSimulator(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the new simulator from the request
|
// Create the new IC from the request
|
||||||
newSimulator := req.createSimulator()
|
newIC := req.createIC()
|
||||||
|
|
||||||
// Save new simulator to DB
|
// Save new IC to DB
|
||||||
err = newSimulator.save()
|
err = newIC.save()
|
||||||
if !helper.DBError(c, err) {
|
if !helper.DBError(c, err) {
|
||||||
c.JSON(http.StatusOK, gin.H{"simulator": newSimulator.Simulator})
|
c.JSON(http.StatusOK, gin.H{"ic": newIC.InfrastructureComponent})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateSimulator godoc
|
// updateIC godoc
|
||||||
// @Summary Update a simulator
|
// @Summary Update an infrastructure component
|
||||||
// @ID updateSimulator
|
// @ID updateIC
|
||||||
// @Tags simulators
|
// @Tags infrastructure-components
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} docs.ResponseSimulator "Simulator that was updated"
|
// @Success 200 {object} docs.ResponseIC "Infrastructure Component that was updated"
|
||||||
// @Failure 400 {object} docs.ResponseError "Bad request"
|
// @Failure 400 {object} docs.ResponseError "Bad request"
|
||||||
// @Failure 404 {object} docs.ResponseError "Not found"
|
// @Failure 404 {object} docs.ResponseError "Not found"
|
||||||
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
||||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
||||||
// @Param Authorization header string true "Authorization token"
|
// @Param Authorization header string true "Authorization token"
|
||||||
// @Param inputSimulator body simulator.updateSimulatorRequest true "Simulator to be updated"
|
// @Param inputIC body infrastructure_component.updateICRequest true "InfrastructureComponent to be updated"
|
||||||
// @Param simulatorID path int true "Simulator ID"
|
// @Param ICID path int true "InfrastructureComponent ID"
|
||||||
// @Router /simulators/{simulatorID} [put]
|
// @Router /ic/{ICID} [put]
|
||||||
func updateSimulator(c *gin.Context) {
|
func updateIC(c *gin.Context) {
|
||||||
|
|
||||||
ok, oldSimulator := CheckPermissions(c, database.ModelSimulator, database.Update, true)
|
ok, oldIC := CheckPermissions(c, database.ModelInfrastructureComponent, database.Update, true)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var req updateSimulatorRequest
|
var req updateICRequest
|
||||||
err := c.BindJSON(&req)
|
err := c.BindJSON(&req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.BadRequestError(c, "Error binding form data to JSON: "+err.Error())
|
helper.BadRequestError(c, "Error binding form data to JSON: "+err.Error())
|
||||||
|
@ -137,97 +137,97 @@ func updateSimulator(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the request
|
// Validate the request
|
||||||
if err = req.Simulator.validate(); err != nil {
|
if err = req.InfrastructureComponent.validate(); err != nil {
|
||||||
helper.UnprocessableEntityError(c, err.Error())
|
helper.UnprocessableEntityError(c, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the updatedSimulator from oldSimulator
|
// Create the updatedIC from oldIC
|
||||||
updatedSimulator := req.updatedSimulator(oldSimulator)
|
updatedIC := req.updatedIC(oldIC)
|
||||||
|
|
||||||
// Finally update the simulator in the DB
|
// Finally update the IC in the DB
|
||||||
err = oldSimulator.update(updatedSimulator)
|
err = oldIC.update(updatedIC)
|
||||||
if !helper.DBError(c, err) {
|
if !helper.DBError(c, err) {
|
||||||
c.JSON(http.StatusOK, gin.H{"simulator": updatedSimulator.Simulator})
|
c.JSON(http.StatusOK, gin.H{"ic": updatedIC.InfrastructureComponent})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// getSimulator godoc
|
// getIC godoc
|
||||||
// @Summary Get simulator
|
// @Summary Get infrastructure component
|
||||||
// @ID getSimulator
|
// @ID getIC
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Tags simulators
|
// @Tags infrastructure-components
|
||||||
// @Success 200 {object} docs.ResponseSimulator "Simulator that was requested"
|
// @Success 200 {object} docs.ResponseIC "Infrastructure Component that was requested"
|
||||||
// @Failure 400 {object} docs.ResponseError "Bad request"
|
// @Failure 400 {object} docs.ResponseError "Bad request"
|
||||||
// @Failure 404 {object} docs.ResponseError "Not found"
|
// @Failure 404 {object} docs.ResponseError "Not found"
|
||||||
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
||||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
||||||
// @Param Authorization header string true "Authorization token"
|
// @Param Authorization header string true "Authorization token"
|
||||||
// @Param simulatorID path int true "Simulator ID"
|
// @Param ICID path int true "Infrastructure Component ID"
|
||||||
// @Router /simulators/{simulatorID} [get]
|
// @Router /ic/{ICID} [get]
|
||||||
func getSimulator(c *gin.Context) {
|
func getIC(c *gin.Context) {
|
||||||
|
|
||||||
ok, s := CheckPermissions(c, database.ModelSimulator, database.Read, true)
|
ok, s := CheckPermissions(c, database.ModelInfrastructureComponent, database.Read, true)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{"simulator": s.Simulator})
|
c.JSON(http.StatusOK, gin.H{"ic": s.InfrastructureComponent})
|
||||||
}
|
}
|
||||||
|
|
||||||
// deleteSimulator godoc
|
// deleteIC godoc
|
||||||
// @Summary Delete a simulator
|
// @Summary Delete an infrastructure component
|
||||||
// @ID deleteSimulator
|
// @ID deleteIC
|
||||||
// @Tags simulators
|
// @Tags infrastructure-components
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} docs.ResponseSimulator "Simulator that was deleted"
|
// @Success 200 {object} docs.ResponseIC "Infrastructure Component that was deleted"
|
||||||
// @Failure 400 {object} docs.ResponseError "Bad request"
|
// @Failure 400 {object} docs.ResponseError "Bad request"
|
||||||
// @Failure 404 {object} docs.ResponseError "Not found"
|
// @Failure 404 {object} docs.ResponseError "Not found"
|
||||||
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
||||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
||||||
// @Param Authorization header string true "Authorization token"
|
// @Param Authorization header string true "Authorization token"
|
||||||
// @Param simulatorID path int true "Simulator ID"
|
// @Param ICID path int true "Infrastructure Component ID"
|
||||||
// @Router /simulators/{simulatorID} [delete]
|
// @Router /ic/{ICID} [delete]
|
||||||
func deleteSimulator(c *gin.Context) {
|
func deleteIC(c *gin.Context) {
|
||||||
|
|
||||||
ok, s := CheckPermissions(c, database.ModelSimulator, database.Delete, true)
|
ok, s := CheckPermissions(c, database.ModelInfrastructureComponent, database.Delete, true)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the simulator
|
// Delete the IC
|
||||||
err := s.delete()
|
err := s.delete()
|
||||||
if !helper.DBError(c, err) {
|
if !helper.DBError(c, err) {
|
||||||
c.JSON(http.StatusOK, gin.H{"simulator": s.Simulator})
|
c.JSON(http.StatusOK, gin.H{"ic": s.InfrastructureComponent})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// getModelsOfSimulator godoc
|
// getConfigsOfIC godoc
|
||||||
// @Summary Get all simulation models in which the simulator is used
|
// @Summary Get all configurations of the infrastructure component
|
||||||
// @ID getModelsOfSimulator
|
// @ID getConfigsOfIC
|
||||||
// @Tags simulators
|
// @Tags infrastructure-components
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} docs.ResponseSimulationModels "Simulation models requested by user"
|
// @Success 200 {object} docs.ResponseConfigs "Configs requested by user"
|
||||||
// @Failure 400 {object} docs.ResponseError "Bad request"
|
// @Failure 400 {object} docs.ResponseError "Bad request"
|
||||||
// @Failure 404 {object} docs.ResponseError "Not found"
|
// @Failure 404 {object} docs.ResponseError "Not found"
|
||||||
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
||||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
||||||
// @Param Authorization header string true "Authorization token"
|
// @Param Authorization header string true "Authorization token"
|
||||||
// @Param simulatorID path int true "Simulator ID"
|
// @Param ICID path int true "Infrastructure Component ID"
|
||||||
// @Router /simulators/{simulatorID}/models [get]
|
// @Router /ic/{ICID}/configs [get]
|
||||||
func getModelsOfSimulator(c *gin.Context) {
|
func getConfigsOfIC(c *gin.Context) {
|
||||||
|
|
||||||
ok, s := CheckPermissions(c, database.ModelSimulator, database.Read, true)
|
ok, s := CheckPermissions(c, database.ModelInfrastructureComponent, database.Read, true)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// get all associated simulation models
|
// get all associated configurations
|
||||||
allModels, _, err := s.getModels()
|
allConfigs, _, err := s.getConfigs()
|
||||||
if !helper.DBError(c, err) {
|
if !helper.DBError(c, err) {
|
||||||
c.JSON(http.StatusOK, gin.H{"simulationModels": allModels})
|
c.JSON(http.StatusOK, gin.H{"configs": allConfigs})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
/** Simulator package, methods.
|
/** InfrastructureComponent package, methods.
|
||||||
*
|
*
|
||||||
* @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
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*********************************************************************************/
|
*********************************************************************************/
|
||||||
package simulator
|
package infrastructure_component
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -27,47 +27,47 @@ import (
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Simulator struct {
|
type InfrastructureComponent struct {
|
||||||
database.Simulator
|
database.InfrastructureComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Simulator) save() error {
|
func (s *InfrastructureComponent) save() error {
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
err := db.Create(s).Error
|
err := db.Create(s).Error
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Simulator) ByID(id uint) error {
|
func (s *InfrastructureComponent) ByID(id uint) error {
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
err := db.Find(s, id).Error
|
err := db.Find(s, id).Error
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Simulator) update(updatedSimulator Simulator) error {
|
func (s *InfrastructureComponent) update(updatedIC InfrastructureComponent) error {
|
||||||
|
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
err := db.Model(s).Updates(updatedSimulator).Error
|
err := db.Model(s).Updates(updatedIC).Error
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Simulator) delete() error {
|
func (s *InfrastructureComponent) delete() error {
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
|
|
||||||
no_simulationmodels := db.Model(s).Association("SimulationModels").Count()
|
no_configs := db.Model(s).Association("ComponentConfigurations").Count()
|
||||||
|
|
||||||
if no_simulationmodels > 0 {
|
if no_configs > 0 {
|
||||||
return fmt.Errorf("Simulator cannot be deleted as it is still used in SimulationModels (active or dangling)")
|
return fmt.Errorf("Infrastructure Component cannot be deleted as it is still used in configurations (active or dangling)")
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete Simulator from DB (does NOT remain as dangling)
|
// delete InfrastructureComponent from DB (does NOT remain as dangling)
|
||||||
err := db.Delete(s).Error
|
err := db.Delete(s).Error
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Simulator) getModels() ([]database.SimulationModel, int, error) {
|
func (s *InfrastructureComponent) getConfigs() ([]database.ComponentConfiguration, int, error) {
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
var models []database.SimulationModel
|
var configs []database.ComponentConfiguration
|
||||||
err := db.Order("ID asc").Model(s).Related(&models, "SimulationModels").Error
|
err := db.Order("ID asc").Model(s).Related(&configs, "ComponentConfigurations").Error
|
||||||
return models, len(models), err
|
return configs, len(configs), err
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
/** Simulator package, middleware.
|
/** InfrastructureComponent package, middleware.
|
||||||
*
|
*
|
||||||
* @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
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*********************************************************************************/
|
*********************************************************************************/
|
||||||
package simulator
|
package infrastructure_component
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -28,24 +28,24 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CheckPermissions(c *gin.Context, modeltype database.ModelName, operation database.CRUD, hasID bool) (bool, Simulator) {
|
func CheckPermissions(c *gin.Context, modeltype database.ModelName, operation database.CRUD, hasID bool) (bool, InfrastructureComponent) {
|
||||||
|
|
||||||
var s Simulator
|
var s InfrastructureComponent
|
||||||
|
|
||||||
err := database.ValidateRole(c, modeltype, operation)
|
err := database.ValidateRole(c, modeltype, operation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.UnprocessableEntityError(c, fmt.Sprintf("Access denied (role validation of simulator failed): %v", err.Error()))
|
helper.UnprocessableEntityError(c, fmt.Sprintf("Access denied (role validation of infrastructure component failed): %v", err.Error()))
|
||||||
return false, s
|
return false, s
|
||||||
}
|
}
|
||||||
|
|
||||||
if hasID {
|
if hasID {
|
||||||
// Get the ID of the simulator from the context
|
// Get the ID of the infrastructure component from the context
|
||||||
simulatorID, err := helper.GetIDOfElement(c, "simulatorID", "path", -1)
|
ICID, err := helper.GetIDOfElement(c, "ICID", "path", -1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, s
|
return false, s
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.ByID(uint(simulatorID))
|
err = s.ByID(uint(ICID))
|
||||||
if helper.DBError(c, err) {
|
if helper.DBError(c, err) {
|
||||||
return false, s
|
return false, s
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
/** Simulator package, testing.
|
/** InfrastructureComponent package, testing.
|
||||||
*
|
*
|
||||||
* @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
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*********************************************************************************/
|
*********************************************************************************/
|
||||||
package simulator
|
package infrastructure_component
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -40,7 +40,7 @@ import (
|
||||||
var router *gin.Engine
|
var router *gin.Engine
|
||||||
var db *gorm.DB
|
var db *gorm.DB
|
||||||
|
|
||||||
type SimulatorRequest struct {
|
type ICRequest struct {
|
||||||
UUID string `json:"uuid,omitempty"`
|
UUID string `json:"uuid,omitempty"`
|
||||||
Host string `json:"host,omitempty"`
|
Host string `json:"host,omitempty"`
|
||||||
Modeltype string `json:"modelType,omitempty"`
|
Modeltype string `json:"modelType,omitempty"`
|
||||||
|
@ -65,12 +65,12 @@ func TestMain(m *testing.M) {
|
||||||
|
|
||||||
user.RegisterAuthenticate(api.Group("/authenticate"))
|
user.RegisterAuthenticate(api.Group("/authenticate"))
|
||||||
api.Use(user.Authentication(true))
|
api.Use(user.Authentication(true))
|
||||||
RegisterSimulatorEndpoints(api.Group("/simulators"))
|
RegisterICEndpoints(api.Group("/ic"))
|
||||||
|
|
||||||
os.Exit(m.Run())
|
os.Exit(m.Run())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddSimulatorAsAdmin(t *testing.T) {
|
func TestAddICAsAdmin(t *testing.T) {
|
||||||
database.DropTables(db)
|
database.DropTables(db)
|
||||||
database.MigrateModels(db)
|
database.MigrateModels(db)
|
||||||
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
||||||
|
@ -83,61 +83,61 @@ func TestAddSimulatorAsAdmin(t *testing.T) {
|
||||||
// try to POST with non JSON body
|
// try to POST with non JSON body
|
||||||
// should result in bad request
|
// should result in bad request
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/simulators", "POST", "This is no JSON")
|
"/api/ic", "POST", "This is no JSON")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 400, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 400, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// try to POST malformed simulator (required fields missing, validation should fail)
|
// try to POST malformed IC (required fields missing, validation should fail)
|
||||||
// should result in an unprocessable entity
|
// should result in an unprocessable entity
|
||||||
newMalformedSimulator := SimulatorRequest{
|
newMalformedIC := ICRequest{
|
||||||
UUID: database.SimulatorB.UUID,
|
UUID: database.ICB.UUID,
|
||||||
}
|
}
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
"/api/simulators", "POST", helper.KeyModels{"simulator": newMalformedSimulator})
|
"/api/ic", "POST", helper.KeyModels{"ic": newMalformedIC})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// test POST simulators/ $newSimulator
|
// test POST ic/ $newIC
|
||||||
newSimulator := SimulatorRequest{
|
newIC := ICRequest{
|
||||||
UUID: database.SimulatorA.UUID,
|
UUID: database.ICA.UUID,
|
||||||
Host: database.SimulatorA.Host,
|
Host: database.ICA.Host,
|
||||||
Modeltype: database.SimulatorA.Modeltype,
|
Modeltype: database.ICA.Modeltype,
|
||||||
State: database.SimulatorA.State,
|
State: database.ICA.State,
|
||||||
Properties: database.SimulatorA.Properties,
|
Properties: database.ICA.Properties,
|
||||||
}
|
}
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
"/api/simulators", "POST", helper.KeyModels{"simulator": newSimulator})
|
"/api/ic", "POST", helper.KeyModels{"ic": newIC})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Compare POST's response with the newSimulator
|
// Compare POST's response with the newIC
|
||||||
err = helper.CompareResponse(resp, helper.KeyModels{"simulator": newSimulator})
|
err = helper.CompareResponse(resp, helper.KeyModels{"ic": newIC})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Read newSimulator's ID from the response
|
// Read newIC's ID from the response
|
||||||
newSimulatorID, err := helper.GetResponseID(resp)
|
newICID, err := helper.GetResponseID(resp)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Get the newSimulator
|
// Get the newIC
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/simulators/%v", newSimulatorID), "GET", nil)
|
fmt.Sprintf("/api/ic/%v", newICID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Compare GET's response with the newSimulator
|
// Compare GET's response with the newIC
|
||||||
err = helper.CompareResponse(resp, helper.KeyModels{"simulator": newSimulator})
|
err = helper.CompareResponse(resp, helper.KeyModels{"ic": newIC})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Try to GET a simulator that does not exist
|
// Try to GET a IC that does not exist
|
||||||
// should result in not found
|
// should result in not found
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/simulators/%v", newSimulatorID+1), "GET", nil)
|
fmt.Sprintf("/api/ic/%v", newICID+1), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 404, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 404, code, "Response body: \n%v\n", resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddSimulatorAsUser(t *testing.T) {
|
func TestAddICAsUser(t *testing.T) {
|
||||||
database.DropTables(db)
|
database.DropTables(db)
|
||||||
database.MigrateModels(db)
|
database.MigrateModels(db)
|
||||||
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
||||||
|
@ -147,24 +147,24 @@ func TestAddSimulatorAsUser(t *testing.T) {
|
||||||
"/api/authenticate", "POST", helper.UserACredentials)
|
"/api/authenticate", "POST", helper.UserACredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// test POST simulators/ $newSimulator
|
// test POST ic/ $newIC
|
||||||
newSimulator := SimulatorRequest{
|
newIC := ICRequest{
|
||||||
UUID: database.SimulatorA.UUID,
|
UUID: database.ICA.UUID,
|
||||||
Host: database.SimulatorA.Host,
|
Host: database.ICA.Host,
|
||||||
Modeltype: database.SimulatorA.Modeltype,
|
Modeltype: database.ICA.Modeltype,
|
||||||
State: database.SimulatorA.State,
|
State: database.ICA.State,
|
||||||
Properties: database.SimulatorA.Properties,
|
Properties: database.ICA.Properties,
|
||||||
}
|
}
|
||||||
|
|
||||||
// This should fail with unprocessable entity 422 error code
|
// This should fail with unprocessable entity 422 error code
|
||||||
// Normal users are not allowed to add simulators
|
// Normal users are not allowed to add ICs
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/simulators", "POST", helper.KeyModels{"simulator": newSimulator})
|
"/api/ic", "POST", helper.KeyModels{"ic": newIC})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateSimulatorAsAdmin(t *testing.T) {
|
func TestUpdateICAsAdmin(t *testing.T) {
|
||||||
database.DropTables(db)
|
database.DropTables(db)
|
||||||
database.MigrateModels(db)
|
database.MigrateModels(db)
|
||||||
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
||||||
|
@ -174,59 +174,59 @@ func TestUpdateSimulatorAsAdmin(t *testing.T) {
|
||||||
"/api/authenticate", "POST", helper.AdminCredentials)
|
"/api/authenticate", "POST", helper.AdminCredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// test POST simulators/ $newSimulator
|
// test POST ic/ $newIC
|
||||||
newSimulator := SimulatorRequest{
|
newIC := ICRequest{
|
||||||
UUID: database.SimulatorA.UUID,
|
UUID: database.ICA.UUID,
|
||||||
Host: database.SimulatorA.Host,
|
Host: database.ICA.Host,
|
||||||
Modeltype: database.SimulatorA.Modeltype,
|
Modeltype: database.ICA.Modeltype,
|
||||||
State: database.SimulatorA.State,
|
State: database.ICA.State,
|
||||||
Properties: database.SimulatorA.Properties,
|
Properties: database.ICA.Properties,
|
||||||
}
|
}
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/simulators", "POST", helper.KeyModels{"simulator": newSimulator})
|
"/api/ic", "POST", helper.KeyModels{"ic": newIC})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Compare POST's response with the newSimulator
|
// Compare POST's response with the newIC
|
||||||
err = helper.CompareResponse(resp, helper.KeyModels{"simulator": newSimulator})
|
err = helper.CompareResponse(resp, helper.KeyModels{"ic": newIC})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Read newSimulator's ID from the response
|
// Read newIC's ID from the response
|
||||||
newSimulatorID, err := helper.GetResponseID(resp)
|
newICID, err := helper.GetResponseID(resp)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// try to PUT with non JSON body
|
// try to PUT with non JSON body
|
||||||
// should result in bad request
|
// should result in bad request
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/simulators/%v", newSimulatorID), "PUT", "This is no JSON")
|
fmt.Sprintf("/api/ic/%v", newICID), "PUT", "This is no JSON")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 400, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 400, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Test PUT simulators
|
// Test PUT IC
|
||||||
newSimulator.Host = "ThisIsMyNewHost"
|
newIC.Host = "ThisIsMyNewHost"
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/simulators/%v", newSimulatorID), "PUT", helper.KeyModels{"simulator": newSimulator})
|
fmt.Sprintf("/api/ic/%v", newICID), "PUT", helper.KeyModels{"ic": newIC})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Compare PUT's response with the updated newSimulator
|
// Compare PUT's response with the updated newIC
|
||||||
err = helper.CompareResponse(resp, helper.KeyModels{"simulator": newSimulator})
|
err = helper.CompareResponse(resp, helper.KeyModels{"ic": newIC})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Get the updated newSimulator
|
// Get the updated newIC
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/simulators/%v", newSimulatorID), "GET", nil)
|
fmt.Sprintf("/api/ic/%v", newICID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Compare GET's response with the updated newSimulator
|
// Compare GET's response with the updated newIC
|
||||||
err = helper.CompareResponse(resp, helper.KeyModels{"simulator": newSimulator})
|
err = helper.CompareResponse(resp, helper.KeyModels{"ic": newIC})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateSimulatorAsUser(t *testing.T) {
|
func TestUpdateICAsUser(t *testing.T) {
|
||||||
database.DropTables(db)
|
database.DropTables(db)
|
||||||
database.MigrateModels(db)
|
database.MigrateModels(db)
|
||||||
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
||||||
|
@ -236,21 +236,21 @@ func TestUpdateSimulatorAsUser(t *testing.T) {
|
||||||
"/api/authenticate", "POST", helper.AdminCredentials)
|
"/api/authenticate", "POST", helper.AdminCredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// test POST simulators/ $newSimulator
|
// test POST ic/ $newIC
|
||||||
newSimulator := SimulatorRequest{
|
newIC := ICRequest{
|
||||||
UUID: database.SimulatorA.UUID,
|
UUID: database.ICA.UUID,
|
||||||
Host: database.SimulatorA.Host,
|
Host: database.ICA.Host,
|
||||||
Modeltype: database.SimulatorA.Modeltype,
|
Modeltype: database.ICA.Modeltype,
|
||||||
State: database.SimulatorA.State,
|
State: database.ICA.State,
|
||||||
Properties: database.SimulatorA.Properties,
|
Properties: database.ICA.Properties,
|
||||||
}
|
}
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/simulators", "POST", helper.KeyModels{"simulator": newSimulator})
|
"/api/ic", "POST", helper.KeyModels{"ic": newIC})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Read newSimulator's ID from the response
|
// Read newIC's ID from the response
|
||||||
newSimulatorID, err := helper.GetResponseID(resp)
|
newICID, err := helper.GetResponseID(resp)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// authenticate as user
|
// authenticate as user
|
||||||
|
@ -258,17 +258,17 @@ func TestUpdateSimulatorAsUser(t *testing.T) {
|
||||||
"/api/authenticate", "POST", helper.UserACredentials)
|
"/api/authenticate", "POST", helper.UserACredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Test PUT simulators
|
// Test PUT IC
|
||||||
// This should fail with unprocessable entity status code 422
|
// This should fail with unprocessable entity status code 422
|
||||||
newSimulator.Host = "ThisIsMyNewHost"
|
newIC.Host = "ThisIsMyNewHost"
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/simulators/%v", newSimulatorID), "PUT", helper.KeyModels{"simulator": newSimulator})
|
fmt.Sprintf("/api/ic/%v", newICID), "PUT", helper.KeyModels{"ic": newIC})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteSimulatorAsAdmin(t *testing.T) {
|
func TestDeleteICAsAdmin(t *testing.T) {
|
||||||
database.DropTables(db)
|
database.DropTables(db)
|
||||||
database.MigrateModels(db)
|
database.MigrateModels(db)
|
||||||
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
||||||
|
@ -278,47 +278,47 @@ func TestDeleteSimulatorAsAdmin(t *testing.T) {
|
||||||
"/api/authenticate", "POST", helper.AdminCredentials)
|
"/api/authenticate", "POST", helper.AdminCredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// test POST simulators/ $newSimulator
|
// test POST ic/ $newIC
|
||||||
newSimulator := SimulatorRequest{
|
newIC := ICRequest{
|
||||||
UUID: database.SimulatorA.UUID,
|
UUID: database.ICA.UUID,
|
||||||
Host: database.SimulatorA.Host,
|
Host: database.ICA.Host,
|
||||||
Modeltype: database.SimulatorA.Modeltype,
|
Modeltype: database.ICA.Modeltype,
|
||||||
State: database.SimulatorA.State,
|
State: database.ICA.State,
|
||||||
Properties: database.SimulatorA.Properties,
|
Properties: database.ICA.Properties,
|
||||||
}
|
}
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/simulators", "POST", helper.KeyModels{"simulator": newSimulator})
|
"/api/ic", "POST", helper.KeyModels{"ic": newIC})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Read newSimulator's ID from the response
|
// Read newIC's ID from the response
|
||||||
newSimulatorID, err := helper.GetResponseID(resp)
|
newICID, err := helper.GetResponseID(resp)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Count the number of all the simulators returned for admin
|
// Count the number of all the ICs returned for admin
|
||||||
initialNumber, err := helper.LengthOfResponse(router, token,
|
initialNumber, err := helper.LengthOfResponse(router, token,
|
||||||
"/api/simulators", "GET", nil)
|
"/api/ic", "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Delete the added newSimulator
|
// Delete the added newIC
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/simulators/%v", newSimulatorID), "DELETE", nil)
|
fmt.Sprintf("/api/ic/%v", newICID), "DELETE", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Compare DELETE's response with the newSimulator
|
// Compare DELETE's response with the newIC
|
||||||
err = helper.CompareResponse(resp, helper.KeyModels{"simulator": newSimulator})
|
err = helper.CompareResponse(resp, helper.KeyModels{"ic": newIC})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Again count the number of all the simulators returned
|
// Again count the number of all the ICs returned
|
||||||
finalNumber, err := helper.LengthOfResponse(router, token,
|
finalNumber, err := helper.LengthOfResponse(router, token,
|
||||||
"/api/simulators", "GET", nil)
|
"/api/ic", "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, finalNumber, initialNumber-1)
|
assert.Equal(t, finalNumber, initialNumber-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteSimulatorAsUser(t *testing.T) {
|
func TestDeleteICAsUser(t *testing.T) {
|
||||||
database.DropTables(db)
|
database.DropTables(db)
|
||||||
database.MigrateModels(db)
|
database.MigrateModels(db)
|
||||||
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
||||||
|
@ -328,21 +328,21 @@ func TestDeleteSimulatorAsUser(t *testing.T) {
|
||||||
"/api/authenticate", "POST", helper.AdminCredentials)
|
"/api/authenticate", "POST", helper.AdminCredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// test POST simulators/ $newSimulator
|
// test POST ic/ $newIC
|
||||||
newSimulator := SimulatorRequest{
|
newIC := ICRequest{
|
||||||
UUID: database.SimulatorA.UUID,
|
UUID: database.ICA.UUID,
|
||||||
Host: database.SimulatorA.Host,
|
Host: database.ICA.Host,
|
||||||
Modeltype: database.SimulatorA.Modeltype,
|
Modeltype: database.ICA.Modeltype,
|
||||||
State: database.SimulatorA.State,
|
State: database.ICA.State,
|
||||||
Properties: database.SimulatorA.Properties,
|
Properties: database.ICA.Properties,
|
||||||
}
|
}
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/simulators", "POST", helper.KeyModels{"simulator": newSimulator})
|
"/api/ic", "POST", helper.KeyModels{"ic": newIC})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Read newSimulator's ID from the response
|
// Read newIC's ID from the response
|
||||||
newSimulatorID, err := helper.GetResponseID(resp)
|
newICID, err := helper.GetResponseID(resp)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// authenticate as user
|
// authenticate as user
|
||||||
|
@ -350,16 +350,16 @@ func TestDeleteSimulatorAsUser(t *testing.T) {
|
||||||
"/api/authenticate", "POST", helper.UserACredentials)
|
"/api/authenticate", "POST", helper.UserACredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Test DELETE simulators
|
// Test DELETE ICs
|
||||||
// This should fail with unprocessable entity status code 422
|
// This should fail with unprocessable entity status code 422
|
||||||
newSimulator.Host = "ThisIsMyNewHost"
|
newIC.Host = "ThisIsMyNewHost"
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/simulators/%v", newSimulatorID), "DELETE", nil)
|
fmt.Sprintf("/api/ic/%v", newICID), "DELETE", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetAllSimulators(t *testing.T) {
|
func TestGetAllICs(t *testing.T) {
|
||||||
database.DropTables(db)
|
database.DropTables(db)
|
||||||
database.MigrateModels(db)
|
database.MigrateModels(db)
|
||||||
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
||||||
|
@ -369,40 +369,40 @@ func TestGetAllSimulators(t *testing.T) {
|
||||||
"/api/authenticate", "POST", helper.AdminCredentials)
|
"/api/authenticate", "POST", helper.AdminCredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// get the length of the GET all simulators response for user
|
// get the length of the GET all ICs response for user
|
||||||
initialNumber, err := helper.LengthOfResponse(router, token,
|
initialNumber, err := helper.LengthOfResponse(router, token,
|
||||||
"/api/simulators", "GET", nil)
|
"/api/ic", "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// test POST simulators/ $newSimulatorA
|
// test POST ic/ $newICA
|
||||||
newSimulatorA := SimulatorRequest{
|
newICA := ICRequest{
|
||||||
UUID: database.SimulatorA.UUID,
|
UUID: database.ICA.UUID,
|
||||||
Host: database.SimulatorA.Host,
|
Host: database.ICA.Host,
|
||||||
Modeltype: database.SimulatorA.Modeltype,
|
Modeltype: database.ICA.Modeltype,
|
||||||
State: database.SimulatorA.State,
|
State: database.ICA.State,
|
||||||
Properties: database.SimulatorA.Properties,
|
Properties: database.ICA.Properties,
|
||||||
}
|
}
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/simulators", "POST", helper.KeyModels{"simulator": newSimulatorA})
|
"/api/ic", "POST", helper.KeyModels{"ic": newICA})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// test POST simulators/ $newSimulatorB
|
// test POST ic/ $newICB
|
||||||
newSimulatorB := SimulatorRequest{
|
newICB := ICRequest{
|
||||||
UUID: database.SimulatorB.UUID,
|
UUID: database.ICB.UUID,
|
||||||
Host: database.SimulatorB.Host,
|
Host: database.ICB.Host,
|
||||||
Modeltype: database.SimulatorB.Modeltype,
|
Modeltype: database.ICB.Modeltype,
|
||||||
State: database.SimulatorB.State,
|
State: database.ICB.State,
|
||||||
Properties: database.SimulatorB.Properties,
|
Properties: database.ICB.Properties,
|
||||||
}
|
}
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
"/api/simulators", "POST", helper.KeyModels{"simulator": newSimulatorB})
|
"/api/ic", "POST", helper.KeyModels{"ic": newICB})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// get the length of the GET all simulators response again
|
// get the length of the GET all ICs response again
|
||||||
finalNumber, err := helper.LengthOfResponse(router, token,
|
finalNumber, err := helper.LengthOfResponse(router, token,
|
||||||
"/api/simulators", "GET", nil)
|
"/api/ic", "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, finalNumber, initialNumber+2)
|
assert.Equal(t, finalNumber, initialNumber+2)
|
||||||
|
@ -412,15 +412,15 @@ func TestGetAllSimulators(t *testing.T) {
|
||||||
"/api/authenticate", "POST", helper.UserACredentials)
|
"/api/authenticate", "POST", helper.UserACredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// get the length of the GET all simulators response again
|
// get the length of the GET all ICs response again
|
||||||
finalNumber2, err := helper.LengthOfResponse(router, token,
|
finalNumber2, err := helper.LengthOfResponse(router, token,
|
||||||
"/api/simulators", "GET", nil)
|
"/api/ic", "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, finalNumber2, initialNumber+2)
|
assert.Equal(t, finalNumber2, initialNumber+2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetSimulationModelsOfSimulator(t *testing.T) {
|
func TestGetConfigsOfIC(t *testing.T) {
|
||||||
database.DropTables(db)
|
database.DropTables(db)
|
||||||
database.MigrateModels(db)
|
database.MigrateModels(db)
|
||||||
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
||||||
|
@ -430,50 +430,50 @@ func TestGetSimulationModelsOfSimulator(t *testing.T) {
|
||||||
"/api/authenticate", "POST", helper.AdminCredentials)
|
"/api/authenticate", "POST", helper.AdminCredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// test POST simulators/ $newSimulatorA
|
// test POST ic/ $newICA
|
||||||
newSimulatorA := SimulatorRequest{
|
newICA := ICRequest{
|
||||||
UUID: database.SimulatorA.UUID,
|
UUID: database.ICA.UUID,
|
||||||
Host: database.SimulatorA.Host,
|
Host: database.ICA.Host,
|
||||||
Modeltype: database.SimulatorA.Modeltype,
|
Modeltype: database.ICA.Modeltype,
|
||||||
State: database.SimulatorA.State,
|
State: database.ICA.State,
|
||||||
Properties: database.SimulatorA.Properties,
|
Properties: database.ICA.Properties,
|
||||||
}
|
}
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/simulators", "POST", helper.KeyModels{"simulator": newSimulatorA})
|
"/api/ic", "POST", helper.KeyModels{"ic": newICA})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Read newSimulator's ID from the response
|
// Read newIC's ID from the response
|
||||||
newSimulatorID, err := helper.GetResponseID(resp)
|
newICID, err := helper.GetResponseID(resp)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// test GET simulators/ID/models
|
// test GET ic/ID/confis
|
||||||
// TODO how to properly test this without using simulation model endpoints?
|
// TODO how to properly test this without using component configuration endpoints?
|
||||||
numberOfModels, err := helper.LengthOfResponse(router, token,
|
numberOfConfigs, err := helper.LengthOfResponse(router, token,
|
||||||
fmt.Sprintf("/api/simulators/%v/models", newSimulatorID), "GET", nil)
|
fmt.Sprintf("/api/ic/%v/configs", newICID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
assert.Equal(t, 0, numberOfModels)
|
assert.Equal(t, 0, numberOfConfigs)
|
||||||
|
|
||||||
// authenticate as normal user
|
// authenticate as normal user
|
||||||
token, err = helper.AuthenticateForTest(router,
|
token, err = helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.UserACredentials)
|
"/api/authenticate", "POST", helper.UserACredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// test GET simulators/ID/models
|
// test GET ic/ID/configs
|
||||||
// TODO how to properly test this without using simulation model endpoints?
|
// TODO how to properly test this without using component configuration endpoints?
|
||||||
numberOfModels, err = helper.LengthOfResponse(router, token,
|
numberOfConfigs, err = helper.LengthOfResponse(router, token,
|
||||||
fmt.Sprintf("/api/simulators/%v/models", newSimulatorID), "GET", nil)
|
fmt.Sprintf("/api/ic/%v/configs", newICID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
assert.Equal(t, 0, numberOfModels)
|
assert.Equal(t, 0, numberOfConfigs)
|
||||||
|
|
||||||
// Try to get models of simulator that does not exist
|
// Try to get configs of IC that does not exist
|
||||||
// should result in not found
|
// should result in not found
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/simulators/%v/models", newSimulatorID+1), "GET", nil)
|
fmt.Sprintf("/api/ic/%v/configs", newICID+1), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 404, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 404, code, "Response body: \n%v\n", resp)
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
/** Simulator package, validators.
|
/** InfrastructureComponent package, validators.
|
||||||
*
|
*
|
||||||
* @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
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*********************************************************************************/
|
*********************************************************************************/
|
||||||
package simulator
|
package infrastructure_component
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
@ -30,7 +30,7 @@ import (
|
||||||
|
|
||||||
var validate *validator.Validate
|
var validate *validator.Validate
|
||||||
|
|
||||||
type validNewSimulator struct {
|
type validNewIC struct {
|
||||||
UUID string `form:"UUID" validate:"required"`
|
UUID string `form:"UUID" validate:"required"`
|
||||||
Host string `form:"Host" validate:"required"`
|
Host string `form:"Host" validate:"required"`
|
||||||
Modeltype string `form:"Modeltype" validate:"required"`
|
Modeltype string `form:"Modeltype" validate:"required"`
|
||||||
|
@ -38,7 +38,7 @@ type validNewSimulator struct {
|
||||||
State string `form:"State"`
|
State string `form:"State"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type validUpdatedSimulator struct {
|
type validUpdatedIC struct {
|
||||||
UUID string `form:"UUID" validate:"omitempty"`
|
UUID string `form:"UUID" validate:"omitempty"`
|
||||||
Host string `form:"Host" validate:"omitempty"`
|
Host string `form:"Host" validate:"omitempty"`
|
||||||
Modeltype string `form:"Modeltype" validate:"omitempty"`
|
Modeltype string `form:"Modeltype" validate:"omitempty"`
|
||||||
|
@ -46,68 +46,68 @@ type validUpdatedSimulator struct {
|
||||||
State string `form:"State" validate:"omitempty"`
|
State string `form:"State" validate:"omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type addSimulatorRequest struct {
|
type addICRequest struct {
|
||||||
Simulator validNewSimulator `json:"simulator"`
|
InfrastructureComponent validNewIC `json:"ic"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type updateSimulatorRequest struct {
|
type updateICRequest struct {
|
||||||
Simulator validUpdatedSimulator `json:"simulator"`
|
InfrastructureComponent validUpdatedIC `json:"ic"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *addSimulatorRequest) validate() error {
|
func (r *addICRequest) validate() error {
|
||||||
validate = validator.New()
|
validate = validator.New()
|
||||||
errs := validate.Struct(r)
|
errs := validate.Struct(r)
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *validUpdatedSimulator) validate() error {
|
func (r *validUpdatedIC) validate() error {
|
||||||
validate = validator.New()
|
validate = validator.New()
|
||||||
errs := validate.Struct(r)
|
errs := validate.Struct(r)
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *addSimulatorRequest) createSimulator() Simulator {
|
func (r *addICRequest) createIC() InfrastructureComponent {
|
||||||
var s Simulator
|
var s InfrastructureComponent
|
||||||
|
|
||||||
s.UUID = r.Simulator.UUID
|
s.UUID = r.InfrastructureComponent.UUID
|
||||||
s.Host = r.Simulator.Host
|
s.Host = r.InfrastructureComponent.Host
|
||||||
s.Modeltype = r.Simulator.Modeltype
|
s.Modeltype = r.InfrastructureComponent.Modeltype
|
||||||
s.Properties = r.Simulator.Properties
|
s.Properties = r.InfrastructureComponent.Properties
|
||||||
if r.Simulator.State != "" {
|
if r.InfrastructureComponent.State != "" {
|
||||||
s.State = r.Simulator.State
|
s.State = r.InfrastructureComponent.State
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *updateSimulatorRequest) updatedSimulator(oldSimulator Simulator) Simulator {
|
func (r *updateICRequest) updatedIC(oldIC InfrastructureComponent) InfrastructureComponent {
|
||||||
// Use the old Simulator as a basis for the updated Simulator `s`
|
// Use the old InfrastructureComponent as a basis for the updated InfrastructureComponent `s`
|
||||||
s := oldSimulator
|
s := oldIC
|
||||||
|
|
||||||
if r.Simulator.UUID != "" {
|
if r.InfrastructureComponent.UUID != "" {
|
||||||
s.UUID = r.Simulator.UUID
|
s.UUID = r.InfrastructureComponent.UUID
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.Simulator.Host != "" {
|
if r.InfrastructureComponent.Host != "" {
|
||||||
s.Host = r.Simulator.Host
|
s.Host = r.InfrastructureComponent.Host
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.Simulator.Modeltype != "" {
|
if r.InfrastructureComponent.Modeltype != "" {
|
||||||
s.Modeltype = r.Simulator.Modeltype
|
s.Modeltype = r.InfrastructureComponent.Modeltype
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.Simulator.State != "" {
|
if r.InfrastructureComponent.State != "" {
|
||||||
s.State = r.Simulator.State
|
s.State = r.InfrastructureComponent.State
|
||||||
}
|
}
|
||||||
|
|
||||||
// only update props if not empty
|
// only update props if not empty
|
||||||
var emptyJson postgres.Jsonb
|
var emptyJson postgres.Jsonb
|
||||||
// Serialize empty json and params
|
// Serialize empty json and params
|
||||||
emptyJson_ser, _ := json.Marshal(emptyJson)
|
emptyJson_ser, _ := json.Marshal(emptyJson)
|
||||||
startParams_ser, _ := json.Marshal(r.Simulator.Properties)
|
startParams_ser, _ := json.Marshal(r.InfrastructureComponent.Properties)
|
||||||
opts := jsondiff.DefaultConsoleOptions()
|
opts := jsondiff.DefaultConsoleOptions()
|
||||||
diff, _ := jsondiff.Compare(emptyJson_ser, startParams_ser, &opts)
|
diff, _ := jsondiff.Compare(emptyJson_ser, startParams_ser, &opts)
|
||||||
if diff.String() != "FullMatch" {
|
if diff.String() != "FullMatch" {
|
||||||
s.Properties = r.Simulator.Properties
|
s.Properties = r.InfrastructureComponent.Properties
|
||||||
}
|
}
|
||||||
|
|
||||||
return s
|
return s
|
|
@ -30,17 +30,17 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
SimulatorCounter = prometheus.NewCounter(
|
ICCounter = prometheus.NewCounter(
|
||||||
prometheus.CounterOpts{
|
prometheus.CounterOpts{
|
||||||
Name: "simulators",
|
Name: "infrastructure_components",
|
||||||
Help: "A counter for the total number of simulators",
|
Help: "A counter for the total number of infrastructure_components",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
SimulationModelCounter = prometheus.NewCounter(
|
ComponentConfigurationCounter = prometheus.NewCounter(
|
||||||
prometheus.CounterOpts{
|
prometheus.CounterOpts{
|
||||||
Name: "simulation_models",
|
Name: "component_configurations",
|
||||||
Help: "A counter for the total number of simulation models",
|
Help: "A counter for the total number of component configurations",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -102,8 +102,8 @@ func RegisterMetricsEndpoint(rg *gin.RouterGroup) {
|
||||||
|
|
||||||
// Register metrics
|
// Register metrics
|
||||||
prometheus.MustRegister(
|
prometheus.MustRegister(
|
||||||
SimulatorCounter,
|
ICCounter,
|
||||||
SimulationModelCounter,
|
ComponentConfigurationCounter,
|
||||||
FileCounter,
|
FileCounter,
|
||||||
ScenarioCounter,
|
ScenarioCounter,
|
||||||
UserCounter,
|
UserCounter,
|
||||||
|
@ -112,17 +112,17 @@ func RegisterMetricsEndpoint(rg *gin.RouterGroup) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitCounters(db *gorm.DB) {
|
func InitCounters(db *gorm.DB) {
|
||||||
var simulators, simulation_models, files, scenarios, users, dashboards float64
|
var infrastructure_components, component_configurations, files, scenarios, users, dashboards float64
|
||||||
|
|
||||||
db.Table("simulators").Count(&simulators)
|
db.Table("infrastructure_components").Count(&infrastructure_components)
|
||||||
db.Table("simulation_models").Count(&simulation_models)
|
db.Table("component_configurations").Count(&component_configurations)
|
||||||
db.Table("files").Count(&files)
|
db.Table("files").Count(&files)
|
||||||
db.Table("scenarios").Count(&scenarios)
|
db.Table("scenarios").Count(&scenarios)
|
||||||
db.Table("users").Count(&users)
|
db.Table("users").Count(&users)
|
||||||
db.Table("dashboards").Count(&dashboards)
|
db.Table("dashboards").Count(&dashboards)
|
||||||
|
|
||||||
SimulatorCounter.Add(simulators)
|
ICCounter.Add(infrastructure_components)
|
||||||
SimulationModelCounter.Add(simulation_models)
|
ComponentConfigurationCounter.Add(component_configurations)
|
||||||
FileCounter.Add(files)
|
FileCounter.Add(files)
|
||||||
ScenarioCounter.Add(scenarios)
|
ScenarioCounter.Add(scenarios)
|
||||||
UserCounter.Add(users)
|
UserCounter.Add(users)
|
||||||
|
|
|
@ -82,7 +82,7 @@ func getScenarios(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO return list of simulationModelIDs, dashboardIDs and userIDs per scenario
|
// TODO return list of configIDs, dashboardIDs and userIDs per scenario
|
||||||
c.JSON(http.StatusOK, gin.H{"scenarios": scenarios})
|
c.JSON(http.StatusOK, gin.H{"scenarios": scenarios})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ func getScenario(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO return list of simulationModelIDs, dashboardIDs and userIDs per scenario
|
// TODO return list of configIDs, dashboardIDs and userIDs per scenario
|
||||||
c.JSON(http.StatusOK, gin.H{"scenario": so.Scenario})
|
c.JSON(http.StatusOK, gin.H{"scenario": so.Scenario})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/simulationmodel"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/component-configuration"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RegisterSignalEndpoints(r *gin.RouterGroup) {
|
func RegisterSignalEndpoints(r *gin.RouterGroup) {
|
||||||
|
@ -45,8 +45,8 @@ func RegisterSignalEndpoints(r *gin.RouterGroup) {
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Tags signals
|
// @Tags signals
|
||||||
// @Param direction query string true "Direction of signal (in or out)"
|
// @Param direction query string true "Direction of signal (in or out)"
|
||||||
// @Param modelID query string true "Model ID of signals to be obtained"
|
// @Param configID query string true "Config ID of signals to be obtained"
|
||||||
// @Success 200 {object} docs.ResponseSignals "Signals which belong to simulation model"
|
// @Success 200 {object} docs.ResponseSignals "Signals which belong to component configuration"
|
||||||
// @Failure 404 {object} docs.ResponseError "Not found"
|
// @Failure 404 {object} docs.ResponseError "Not found"
|
||||||
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
||||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
||||||
|
@ -54,7 +54,7 @@ func RegisterSignalEndpoints(r *gin.RouterGroup) {
|
||||||
// @Router /signals [get]
|
// @Router /signals [get]
|
||||||
func getSignals(c *gin.Context) {
|
func getSignals(c *gin.Context) {
|
||||||
|
|
||||||
ok, m := simulationmodel.CheckPermissions(c, database.Read, "query", -1)
|
ok, m := component_configuration.CheckPermissions(c, database.Read, "query", -1)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ func getSignals(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddSignal godoc
|
// AddSignal godoc
|
||||||
// @Summary Add a signal to a signal mapping of a model
|
// @Summary Add a signal to a signal mapping of a component configuration
|
||||||
// @ID AddSignal
|
// @ID AddSignal
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce json
|
// @Produce json
|
||||||
|
@ -91,7 +91,7 @@ func getSignals(c *gin.Context) {
|
||||||
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
// @Failure 422 {object} docs.ResponseError "Unprocessable entity"
|
||||||
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
// @Failure 500 {object} docs.ResponseError "Internal server error"
|
||||||
// @Param Authorization header string true "Authorization token"
|
// @Param Authorization header string true "Authorization token"
|
||||||
// @Param inputSignal body signal.addSignalRequest true "A signal to be added to the model incl. direction and model ID to which signal shall be added"
|
// @Param inputSignal body signal.addSignalRequest true "A signal to be added to the component configuration incl. direction and config ID to which signal shall be added"
|
||||||
// @Router /signals [post]
|
// @Router /signals [post]
|
||||||
func addSignal(c *gin.Context) {
|
func addSignal(c *gin.Context) {
|
||||||
|
|
||||||
|
@ -110,13 +110,13 @@ func addSignal(c *gin.Context) {
|
||||||
// Create the new signal from the request
|
// Create the new signal from the request
|
||||||
newSignal := req.createSignal()
|
newSignal := req.createSignal()
|
||||||
|
|
||||||
ok, _ := simulationmodel.CheckPermissions(c, database.Update, "body", int(newSignal.SimulationModelID))
|
ok, _ := component_configuration.CheckPermissions(c, database.Update, "body", int(newSignal.ConfigID))
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add signal to model
|
// Add signal to component configuration
|
||||||
err := newSignal.addToSimulationModel()
|
err := newSignal.addToConfig()
|
||||||
if !helper.DBError(c, err) {
|
if !helper.DBError(c, err) {
|
||||||
c.JSON(http.StatusOK, gin.H{"signal": newSignal.Signal})
|
c.JSON(http.StatusOK, gin.H{"signal": newSignal.Signal})
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ package signal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/simulationmodel"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/component-configuration"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Signal struct {
|
type Signal struct {
|
||||||
|
@ -45,10 +45,10 @@ func (s *Signal) byID(id uint) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Signal) addToSimulationModel() error {
|
func (s *Signal) addToConfig() error {
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
var m simulationmodel.SimulationModel
|
var m component_configuration.ComponentConfiguration
|
||||||
err := m.ByID(s.SimulationModelID)
|
err := m.ByID(s.ConfigID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ func (s *Signal) addToSimulationModel() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// associate signal with simulation model in correct direction
|
// associate signal with component configuration in correct direction
|
||||||
if s.Direction == "in" {
|
if s.Direction == "in" {
|
||||||
err = db.Model(&m).Association("InputMapping").Append(s).Error
|
err = db.Model(&m).Association("InputMapping").Append(s).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -99,13 +99,13 @@ func (s *Signal) update(modifiedSignal Signal) error {
|
||||||
func (s *Signal) delete() error {
|
func (s *Signal) delete() error {
|
||||||
|
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
var m simulationmodel.SimulationModel
|
var m component_configuration.ComponentConfiguration
|
||||||
err := m.ByID(s.SimulationModelID)
|
err := m.ByID(s.ConfigID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove association between Signal and SimulationModel
|
// remove association between Signal and ComponentConfiguration
|
||||||
// Signal itself is not deleted from DB, it remains as "dangling"
|
// Signal itself is not deleted from DB, it remains as "dangling"
|
||||||
if s.Direction == "in" {
|
if s.Direction == "in" {
|
||||||
err = db.Model(&m).Association("InputMapping").Delete(s).Error
|
err = db.Model(&m).Association("InputMapping").Delete(s).Error
|
||||||
|
|
|
@ -27,7 +27,7 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/simulationmodel"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/component-configuration"
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkPermissions(c *gin.Context, operation database.CRUD) (bool, Signal) {
|
func checkPermissions(c *gin.Context, operation database.CRUD) (bool, Signal) {
|
||||||
|
@ -50,7 +50,7 @@ func checkPermissions(c *gin.Context, operation database.CRUD) (bool, Signal) {
|
||||||
return false, sig
|
return false, sig
|
||||||
}
|
}
|
||||||
|
|
||||||
ok, _ := simulationmodel.CheckPermissions(c, operation, "body", int(sig.SimulationModelID))
|
ok, _ := component_configuration.CheckPermissions(c, operation, "body", int(sig.ConfigID))
|
||||||
if !ok {
|
if !ok {
|
||||||
return false, sig
|
return false, sig
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,9 @@ import (
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
|
||||||
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/component-configuration"
|
||||||
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/infrastructure-component"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/simulationmodel"
|
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/simulator"
|
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/user"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/user"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
|
@ -46,17 +46,17 @@ type SignalRequest struct {
|
||||||
Unit string `json:"unit,omitempty"`
|
Unit string `json:"unit,omitempty"`
|
||||||
Index uint `json:"index,omitempty"`
|
Index uint `json:"index,omitempty"`
|
||||||
Direction string `json:"direction,omitempty"`
|
Direction string `json:"direction,omitempty"`
|
||||||
SimulationModelID uint `json:"simulationModelID,omitempty"`
|
ConfigID uint `json:"configID,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SimulationModelRequest struct {
|
type ConfigRequest struct {
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
ScenarioID uint `json:"scenarioID,omitempty"`
|
ScenarioID uint `json:"scenarioID,omitempty"`
|
||||||
SimulatorID uint `json:"simulatorID,omitempty"`
|
ICID uint `json:"icID,omitempty"`
|
||||||
StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
|
StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SimulatorRequest struct {
|
type ICRequest struct {
|
||||||
UUID string `json:"uuid,omitempty"`
|
UUID string `json:"uuid,omitempty"`
|
||||||
Host string `json:"host,omitempty"`
|
Host string `json:"host,omitempty"`
|
||||||
Modeltype string `json:"modelType,omitempty"`
|
Modeltype string `json:"modelType,omitempty"`
|
||||||
|
@ -70,25 +70,25 @@ type ScenarioRequest struct {
|
||||||
StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
|
StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func addScenarioAndSimulatorAndSimulationModel() (scenarioID uint, simulatorID uint, simulationModelID uint) {
|
func addScenarioAndICAndConfig() (scenarioID uint, ICID uint, configID uint) {
|
||||||
|
|
||||||
// authenticate as admin
|
// authenticate as admin
|
||||||
token, _ := helper.AuthenticateForTest(router,
|
token, _ := helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.AdminCredentials)
|
"/api/authenticate", "POST", helper.AdminCredentials)
|
||||||
|
|
||||||
// POST $newSimulatorA
|
// POST $newICA
|
||||||
newSimulatorA := SimulatorRequest{
|
newICA := ICRequest{
|
||||||
UUID: database.SimulatorA.UUID,
|
UUID: database.ICA.UUID,
|
||||||
Host: database.SimulatorA.Host,
|
Host: database.ICA.Host,
|
||||||
Modeltype: database.SimulatorA.Modeltype,
|
Modeltype: database.ICA.Modeltype,
|
||||||
State: database.SimulatorA.State,
|
State: database.ICA.State,
|
||||||
Properties: database.SimulatorA.Properties,
|
Properties: database.ICA.Properties,
|
||||||
}
|
}
|
||||||
_, resp, _ := helper.TestEndpoint(router, token,
|
_, resp, _ := helper.TestEndpoint(router, token,
|
||||||
"/api/simulators", "POST", helper.KeyModels{"simulator": newSimulatorA})
|
"/api/ic", "POST", helper.KeyModels{"ic": newICA})
|
||||||
|
|
||||||
// Read newSimulator's ID from the response
|
// Read newIC's ID from the response
|
||||||
newSimulatorID, _ := helper.GetResponseID(resp)
|
newICID, _ := helper.GetResponseID(resp)
|
||||||
|
|
||||||
// authenticate as normal user
|
// authenticate as normal user
|
||||||
token, _ = helper.AuthenticateForTest(router,
|
token, _ = helper.AuthenticateForTest(router,
|
||||||
|
@ -106,24 +106,24 @@ func addScenarioAndSimulatorAndSimulationModel() (scenarioID uint, simulatorID u
|
||||||
// Read newScenario's ID from the response
|
// Read newScenario's ID from the response
|
||||||
newScenarioID, _ := helper.GetResponseID(resp)
|
newScenarioID, _ := helper.GetResponseID(resp)
|
||||||
|
|
||||||
// test POST models/ $newSimulationModel
|
// test POST newConfig
|
||||||
newSimulationModel := SimulationModelRequest{
|
newConfig := ConfigRequest{
|
||||||
Name: database.SimulationModelA.Name,
|
Name: database.ConfigA.Name,
|
||||||
ScenarioID: uint(newScenarioID),
|
ScenarioID: uint(newScenarioID),
|
||||||
SimulatorID: uint(newSimulatorID),
|
ICID: uint(newICID),
|
||||||
StartParameters: database.SimulationModelA.StartParameters,
|
StartParameters: database.ConfigA.StartParameters,
|
||||||
}
|
}
|
||||||
_, resp, _ = helper.TestEndpoint(router, token,
|
_, resp, _ = helper.TestEndpoint(router, token,
|
||||||
"/api/models", "POST", helper.KeyModels{"simulationModel": newSimulationModel})
|
"/api/configs", "POST", helper.KeyModels{"config": newConfig})
|
||||||
|
|
||||||
// Read newSimulationModel's ID from the response
|
// Read newConfig's ID from the response
|
||||||
newSimulationModelID, _ := helper.GetResponseID(resp)
|
newConfigID, _ := helper.GetResponseID(resp)
|
||||||
|
|
||||||
// add the guest user to the new scenario
|
// add the guest user to the new scenario
|
||||||
_, resp, _ = helper.TestEndpoint(router, token,
|
_, resp, _ = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/scenarios/%v/user?username=User_C", newScenarioID), "PUT", nil)
|
fmt.Sprintf("/api/scenarios/%v/user?username=User_C", newScenarioID), "PUT", nil)
|
||||||
|
|
||||||
return uint(newScenarioID), uint(newSimulatorID), uint(newSimulationModelID)
|
return uint(newScenarioID), uint(newICID), uint(newConfigID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
|
@ -143,15 +143,15 @@ func TestMain(m *testing.M) {
|
||||||
|
|
||||||
user.RegisterAuthenticate(api.Group("/authenticate"))
|
user.RegisterAuthenticate(api.Group("/authenticate"))
|
||||||
api.Use(user.Authentication(true))
|
api.Use(user.Authentication(true))
|
||||||
// simulationmodel endpoints required here to first add a simulation to the DB
|
// component-configuration endpoints required here to first add a component config to the DB
|
||||||
// that can be associated with a new signal model
|
// that can be associated with a new signal
|
||||||
simulationmodel.RegisterSimulationModelEndpoints(api.Group("/models"))
|
component_configuration.RegisterComponentConfigurationEndpoints(api.Group("/configs"))
|
||||||
// scenario endpoints required here to first add a scenario to the DB
|
// scenario endpoints required here to first add a scenario to the DB
|
||||||
// that can be associated with a new simulation model
|
// that can be associated with a new component config
|
||||||
scenario.RegisterScenarioEndpoints(api.Group("/scenarios"))
|
scenario.RegisterScenarioEndpoints(api.Group("/scenarios"))
|
||||||
// simulator endpoints required here to first add a simulator to the DB
|
// IC endpoints required here to first add a IC to the DB
|
||||||
// that can be associated with a new simulation model
|
// that can be associated with a new component config
|
||||||
simulator.RegisterSimulatorEndpoints(api.Group("/simulators"))
|
infrastructure_component.RegisterICEndpoints(api.Group("/ic"))
|
||||||
RegisterSignalEndpoints(api.Group("/signals"))
|
RegisterSignalEndpoints(api.Group("/signals"))
|
||||||
|
|
||||||
os.Exit(m.Run())
|
os.Exit(m.Run())
|
||||||
|
@ -163,9 +163,9 @@ func TestAddSignal(t *testing.T) {
|
||||||
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
||||||
|
|
||||||
// prepare the content of the DB for testing
|
// prepare the content of the DB for testing
|
||||||
// by adding a scenario and a simulator to the DB
|
// by adding a scenario and a IC to the DB
|
||||||
// using the respective endpoints of the API
|
// using the respective endpoints of the API
|
||||||
_, _, simulationModelID := addScenarioAndSimulatorAndSimulationModel()
|
_, _, configID := addScenarioAndICAndConfig()
|
||||||
|
|
||||||
// authenticate as normal user
|
// authenticate as normal user
|
||||||
token, err := helper.AuthenticateForTest(router,
|
token, err := helper.AuthenticateForTest(router,
|
||||||
|
@ -177,7 +177,7 @@ func TestAddSignal(t *testing.T) {
|
||||||
Unit: database.InSignalA.Unit,
|
Unit: database.InSignalA.Unit,
|
||||||
Direction: database.InSignalA.Direction,
|
Direction: database.InSignalA.Direction,
|
||||||
Index: 1,
|
Index: 1,
|
||||||
SimulationModelID: simulationModelID,
|
ConfigID: configID,
|
||||||
}
|
}
|
||||||
|
|
||||||
// authenticate as normal userB who has no access to new scenario
|
// authenticate as normal userB who has no access to new scenario
|
||||||
|
@ -185,7 +185,7 @@ func TestAddSignal(t *testing.T) {
|
||||||
"/api/authenticate", "POST", helper.UserBCredentials)
|
"/api/authenticate", "POST", helper.UserBCredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// try to POST to simulation model without access
|
// try to POST to component config without access
|
||||||
// should result in unprocessable entity
|
// should result in unprocessable entity
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/signals", "POST", helper.KeyModels{"signal": newSignal})
|
"/api/signals", "POST", helper.KeyModels{"signal": newSignal})
|
||||||
|
@ -258,9 +258,9 @@ func TestUpdateSignal(t *testing.T) {
|
||||||
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
||||||
|
|
||||||
// prepare the content of the DB for testing
|
// prepare the content of the DB for testing
|
||||||
// by adding a scenario and a simulator to the DB
|
// by adding a scenario and a IC to the DB
|
||||||
// using the respective endpoints of the API
|
// using the respective endpoints of the API
|
||||||
_, _, simulationModelID := addScenarioAndSimulatorAndSimulationModel()
|
_, _, configID := addScenarioAndICAndConfig()
|
||||||
|
|
||||||
// authenticate as normal user
|
// authenticate as normal user
|
||||||
token, err := helper.AuthenticateForTest(router,
|
token, err := helper.AuthenticateForTest(router,
|
||||||
|
@ -273,7 +273,7 @@ func TestUpdateSignal(t *testing.T) {
|
||||||
Unit: database.InSignalA.Unit,
|
Unit: database.InSignalA.Unit,
|
||||||
Direction: database.InSignalA.Direction,
|
Direction: database.InSignalA.Direction,
|
||||||
Index: 1,
|
Index: 1,
|
||||||
SimulationModelID: simulationModelID,
|
ConfigID: configID,
|
||||||
}
|
}
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/signals", "POST", helper.KeyModels{"signal": newSignal})
|
"/api/signals", "POST", helper.KeyModels{"signal": newSignal})
|
||||||
|
@ -360,9 +360,9 @@ func TestDeleteSignal(t *testing.T) {
|
||||||
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
||||||
|
|
||||||
// prepare the content of the DB for testing
|
// prepare the content of the DB for testing
|
||||||
// by adding a scenario and a simulator to the DB
|
// by adding a scenario and a IC to the DB
|
||||||
// using the respective endpoints of the API
|
// using the respective endpoints of the API
|
||||||
_, _, simulationModelID := addScenarioAndSimulatorAndSimulationModel()
|
_, _, configID := addScenarioAndICAndConfig()
|
||||||
|
|
||||||
// authenticate as normal user
|
// authenticate as normal user
|
||||||
token, err := helper.AuthenticateForTest(router,
|
token, err := helper.AuthenticateForTest(router,
|
||||||
|
@ -375,7 +375,7 @@ func TestDeleteSignal(t *testing.T) {
|
||||||
Unit: database.InSignalA.Unit,
|
Unit: database.InSignalA.Unit,
|
||||||
Direction: database.InSignalA.Direction,
|
Direction: database.InSignalA.Direction,
|
||||||
Index: 1,
|
Index: 1,
|
||||||
SimulationModelID: simulationModelID,
|
ConfigID: configID,
|
||||||
}
|
}
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/signals", "POST", helper.KeyModels{"signal": newSignal})
|
"/api/signals", "POST", helper.KeyModels{"signal": newSignal})
|
||||||
|
@ -403,9 +403,9 @@ func TestDeleteSignal(t *testing.T) {
|
||||||
"/api/authenticate", "POST", helper.UserACredentials)
|
"/api/authenticate", "POST", helper.UserACredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Count the number of all the input signals returned for simulation model
|
// Count the number of all the input signals returned for component config
|
||||||
initialNumber, err := helper.LengthOfResponse(router, token,
|
initialNumber, err := helper.LengthOfResponse(router, token,
|
||||||
fmt.Sprintf("/api/signals?modelID=%v&direction=in", simulationModelID), "GET", nil)
|
fmt.Sprintf("/api/signals?configID=%v&direction=in", configID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// add an output signal to make sure that counting of input signals works
|
// add an output signal to make sure that counting of input signals works
|
||||||
|
@ -414,7 +414,7 @@ func TestDeleteSignal(t *testing.T) {
|
||||||
Unit: database.OutSignalA.Unit,
|
Unit: database.OutSignalA.Unit,
|
||||||
Direction: database.OutSignalA.Direction,
|
Direction: database.OutSignalA.Direction,
|
||||||
Index: 1,
|
Index: 1,
|
||||||
SimulationModelID: simulationModelID,
|
ConfigID: configID,
|
||||||
}
|
}
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
"/api/signals", "POST", helper.KeyModels{"signal": newSignalout})
|
"/api/signals", "POST", helper.KeyModels{"signal": newSignalout})
|
||||||
|
@ -435,9 +435,9 @@ func TestDeleteSignal(t *testing.T) {
|
||||||
err = helper.CompareResponse(resp, helper.KeyModels{"signal": newSignal})
|
err = helper.CompareResponse(resp, helper.KeyModels{"signal": newSignal})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Again count the number of all the input signals returned for simulation model
|
// Again count the number of all the input signals returned for component config
|
||||||
finalNumber, err := helper.LengthOfResponse(router, token,
|
finalNumber, err := helper.LengthOfResponse(router, token,
|
||||||
fmt.Sprintf("/api/signals?modelID=%v&direction=in", simulationModelID), "GET", nil)
|
fmt.Sprintf("/api/signals?configID=%v&direction=in", configID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, initialNumber-1, finalNumber)
|
assert.Equal(t, initialNumber-1, finalNumber)
|
||||||
|
@ -449,24 +449,24 @@ func TestDeleteSignal(t *testing.T) {
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetAllInputSignalsOfSimulationModel(t *testing.T) {
|
func TestGetAllInputSignalsOfConfig(t *testing.T) {
|
||||||
database.DropTables(db)
|
database.DropTables(db)
|
||||||
database.MigrateModels(db)
|
database.MigrateModels(db)
|
||||||
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
assert.NoError(t, database.DBAddAdminAndUserAndGuest(db))
|
||||||
|
|
||||||
// prepare the content of the DB for testing
|
// prepare the content of the DB for testing
|
||||||
// by adding a scenario and a simulator to the DB
|
// by adding a scenario and a IC to the DB
|
||||||
// using the respective endpoints of the API
|
// using the respective endpoints of the API
|
||||||
_, _, simulationModelID := addScenarioAndSimulatorAndSimulationModel()
|
_, _, configID := addScenarioAndICAndConfig()
|
||||||
|
|
||||||
// authenticate as normal user
|
// authenticate as normal user
|
||||||
token, err := helper.AuthenticateForTest(router,
|
token, err := helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.UserACredentials)
|
"/api/authenticate", "POST", helper.UserACredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Count the number of all the input signals returned for simulation model
|
// Count the number of all the input signals returned for component config
|
||||||
initialNumber, err := helper.LengthOfResponse(router, token,
|
initialNumber, err := helper.LengthOfResponse(router, token,
|
||||||
fmt.Sprintf("/api/signals?modelID=%v&direction=in", simulationModelID), "GET", nil)
|
fmt.Sprintf("/api/signals?configID=%v&direction=in", configID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// test POST signals/ $newSignal
|
// test POST signals/ $newSignal
|
||||||
|
@ -475,7 +475,7 @@ func TestGetAllInputSignalsOfSimulationModel(t *testing.T) {
|
||||||
Unit: database.InSignalA.Unit,
|
Unit: database.InSignalA.Unit,
|
||||||
Direction: database.InSignalA.Direction,
|
Direction: database.InSignalA.Direction,
|
||||||
Index: 1,
|
Index: 1,
|
||||||
SimulationModelID: simulationModelID,
|
ConfigID: configID,
|
||||||
}
|
}
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/signals", "POST", helper.KeyModels{"signal": newSignalA})
|
"/api/signals", "POST", helper.KeyModels{"signal": newSignalA})
|
||||||
|
@ -488,7 +488,7 @@ func TestGetAllInputSignalsOfSimulationModel(t *testing.T) {
|
||||||
Unit: database.InSignalB.Unit,
|
Unit: database.InSignalB.Unit,
|
||||||
Direction: database.InSignalB.Direction,
|
Direction: database.InSignalB.Direction,
|
||||||
Index: 2,
|
Index: 2,
|
||||||
SimulationModelID: simulationModelID,
|
ConfigID: configID,
|
||||||
}
|
}
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
"/api/signals", "POST", helper.KeyModels{"signal": newSignalB})
|
"/api/signals", "POST", helper.KeyModels{"signal": newSignalB})
|
||||||
|
@ -501,7 +501,7 @@ func TestGetAllInputSignalsOfSimulationModel(t *testing.T) {
|
||||||
Unit: database.OutSignalA.Unit,
|
Unit: database.OutSignalA.Unit,
|
||||||
Direction: database.OutSignalA.Direction,
|
Direction: database.OutSignalA.Direction,
|
||||||
Index: 1,
|
Index: 1,
|
||||||
SimulationModelID: simulationModelID,
|
ConfigID: configID,
|
||||||
}
|
}
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
"/api/signals", "POST", helper.KeyModels{"signal": newSignalAout})
|
"/api/signals", "POST", helper.KeyModels{"signal": newSignalAout})
|
||||||
|
@ -514,30 +514,30 @@ func TestGetAllInputSignalsOfSimulationModel(t *testing.T) {
|
||||||
Unit: database.OutSignalB.Unit,
|
Unit: database.OutSignalB.Unit,
|
||||||
Direction: database.OutSignalB.Direction,
|
Direction: database.OutSignalB.Direction,
|
||||||
Index: 1,
|
Index: 1,
|
||||||
SimulationModelID: simulationModelID,
|
ConfigID: configID,
|
||||||
}
|
}
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
"/api/signals", "POST", helper.KeyModels{"signal": newSignalBout})
|
"/api/signals", "POST", helper.KeyModels{"signal": newSignalBout})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// Again count the number of all the input signals returned for simulation model
|
// Again count the number of all the input signals returned for component config
|
||||||
finalNumber, err := helper.LengthOfResponse(router, token,
|
finalNumber, err := helper.LengthOfResponse(router, token,
|
||||||
fmt.Sprintf("/api/signals?modelID=%v&direction=in", simulationModelID), "GET", nil)
|
fmt.Sprintf("/api/signals?configID=%v&direction=in", configID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, initialNumber+2, finalNumber)
|
assert.Equal(t, initialNumber+2, finalNumber)
|
||||||
|
|
||||||
// Get the number of output signals
|
// Get the number of output signals
|
||||||
outputNumber, err := helper.LengthOfResponse(router, token,
|
outputNumber, err := helper.LengthOfResponse(router, token,
|
||||||
fmt.Sprintf("/api/signals?modelID=%v&direction=out", simulationModelID), "GET", nil)
|
fmt.Sprintf("/api/signals?configID=%v&direction=out", configID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, initialNumber+2, outputNumber)
|
assert.Equal(t, initialNumber+2, outputNumber)
|
||||||
|
|
||||||
// Try to get all signals for non-existing direction
|
// Try to get all signals for non-existing direction
|
||||||
// should result in bad request
|
// should result in bad request
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/signals?modelID=%v&direction=thisiswrong", simulationModelID), "GET", nil)
|
fmt.Sprintf("/api/signals?configID=%v&direction=thisiswrong", configID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 400, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 400, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
|
@ -549,7 +549,7 @@ func TestGetAllInputSignalsOfSimulationModel(t *testing.T) {
|
||||||
// try to get all input signals
|
// try to get all input signals
|
||||||
// should result in unprocessable entity
|
// should result in unprocessable entity
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
fmt.Sprintf("/api/signals?modelID=%v&direction=in", simulationModelID), "GET", nil)
|
fmt.Sprintf("/api/signals?configID=%v&direction=in", configID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ type validNewSignal struct {
|
||||||
Unit string `form:"unit" validate:"omitempty"`
|
Unit string `form:"unit" validate:"omitempty"`
|
||||||
Index uint `form:"index" validate:"required"`
|
Index uint `form:"index" validate:"required"`
|
||||||
Direction string `form:"direction" validate:"required,oneof=in out"`
|
Direction string `form:"direction" validate:"required,oneof=in out"`
|
||||||
SimulationModelID uint `form:"simulationModelID" validate:"required"`
|
ConfigID uint `form:"configID" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type validUpdatedSignal struct {
|
type validUpdatedSignal struct {
|
||||||
|
@ -68,7 +68,7 @@ func (r *addSignalRequest) createSignal() Signal {
|
||||||
s.Unit = r.Signal.Unit
|
s.Unit = r.Signal.Unit
|
||||||
s.Index = r.Signal.Index
|
s.Index = r.Signal.Index
|
||||||
s.Direction = r.Signal.Direction
|
s.Direction = r.Signal.Direction
|
||||||
s.SimulationModelID = r.Signal.SimulationModelID
|
s.ConfigID = r.Signal.ConfigID
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,108 +0,0 @@
|
||||||
/** Simulationmodel package, validators.
|
|
||||||
*
|
|
||||||
* @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 simulationmodel
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"github.com/jinzhu/gorm/dialects/postgres"
|
|
||||||
"github.com/nsf/jsondiff"
|
|
||||||
"gopkg.in/go-playground/validator.v9"
|
|
||||||
)
|
|
||||||
|
|
||||||
var validate *validator.Validate
|
|
||||||
|
|
||||||
type validNewSimulationModel struct {
|
|
||||||
Name string `form:"Name" validate:"required"`
|
|
||||||
ScenarioID uint `form:"ScenarioID" validate:"required"`
|
|
||||||
SimulatorID uint `form:"SimulatorID" validate:"required"`
|
|
||||||
StartParameters postgres.Jsonb `form:"StartParameters" validate:"required"`
|
|
||||||
SelectedModelFileID uint `form:"SelectedModelFilID" validate:"omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type validUpdatedSimulationModel struct {
|
|
||||||
Name string `form:"Name" validate:"omitempty"`
|
|
||||||
SimulatorID uint `form:"SimulatorID" validate:"omitempty"`
|
|
||||||
StartParameters postgres.Jsonb `form:"StartParameters" validate:"omitempty"`
|
|
||||||
SelectedModelFileID uint `form:"SelectedModelFileID" validate:"omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type addSimulationModelRequest struct {
|
|
||||||
SimulationModel validNewSimulationModel `json:"simulationModel"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type updateSimulationModelRequest struct {
|
|
||||||
SimulationModel validUpdatedSimulationModel `json:"simulationModel"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *addSimulationModelRequest) validate() error {
|
|
||||||
validate = validator.New()
|
|
||||||
errs := validate.Struct(r)
|
|
||||||
return errs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *validUpdatedSimulationModel) validate() error {
|
|
||||||
validate = validator.New()
|
|
||||||
errs := validate.Struct(r)
|
|
||||||
return errs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *addSimulationModelRequest) createSimulationModel() SimulationModel {
|
|
||||||
var s SimulationModel
|
|
||||||
|
|
||||||
s.Name = r.SimulationModel.Name
|
|
||||||
s.ScenarioID = r.SimulationModel.ScenarioID
|
|
||||||
s.SimulatorID = r.SimulationModel.SimulatorID
|
|
||||||
s.StartParameters = r.SimulationModel.StartParameters
|
|
||||||
s.SelectedModelFileID = r.SimulationModel.SelectedModelFileID
|
|
||||||
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *updateSimulationModelRequest) updatedSimulationModel(oldSimulationModel SimulationModel) SimulationModel {
|
|
||||||
// Use the old SimulationModel as a basis for the updated Simulation model
|
|
||||||
s := oldSimulationModel
|
|
||||||
|
|
||||||
if r.SimulationModel.Name != "" {
|
|
||||||
s.Name = r.SimulationModel.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.SimulationModel.SimulatorID != 0 {
|
|
||||||
s.SimulatorID = r.SimulationModel.SimulatorID
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.SimulationModel.SelectedModelFileID != 0 {
|
|
||||||
s.SelectedModelFileID = r.SimulationModel.SelectedModelFileID
|
|
||||||
}
|
|
||||||
|
|
||||||
// only update Params if not empty
|
|
||||||
var emptyJson postgres.Jsonb
|
|
||||||
// Serialize empty json and params
|
|
||||||
emptyJson_ser, _ := json.Marshal(emptyJson)
|
|
||||||
startParams_ser, _ := json.Marshal(r.SimulationModel.StartParameters)
|
|
||||||
opts := jsondiff.DefaultConsoleOptions()
|
|
||||||
diff, _ := jsondiff.Compare(emptyJson_ser, startParams_ser, &opts)
|
|
||||||
if diff.String() != "FullMatch" {
|
|
||||||
s.StartParameters = r.SimulationModel.StartParameters
|
|
||||||
}
|
|
||||||
|
|
||||||
return s
|
|
||||||
}
|
|
|
@ -289,7 +289,7 @@ func TestUpdateWidget(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 422, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
// authenticate as guest user who has access to simulation model
|
// authenticate as guest user who has access to scenario
|
||||||
token, err = helper.AuthenticateForTest(router,
|
token, err = helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.GuestCredentials)
|
"/api/authenticate", "POST", helper.GuestCredentials)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
14
start.go
14
start.go
|
@ -34,13 +34,13 @@ import (
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
||||||
apidocs "git.rwth-aachen.de/acs/public/villas/web-backend-go/doc/api" // doc/api folder is used by Swag CLI, you have to import it
|
apidocs "git.rwth-aachen.de/acs/public/villas/web-backend-go/doc/api" // doc/api folder is used by Swag CLI, you have to import it
|
||||||
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/component-configuration"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/dashboard"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/dashboard"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/file"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/file"
|
||||||
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/infrastructure-component"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/metrics"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/metrics"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/signal"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/signal"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/simulationmodel"
|
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/simulator"
|
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/user"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/user"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/widget"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/widget"
|
||||||
)
|
)
|
||||||
|
@ -114,13 +114,13 @@ func main() {
|
||||||
api.Use(user.Authentication(true))
|
api.Use(user.Authentication(true))
|
||||||
|
|
||||||
scenario.RegisterScenarioEndpoints(api.Group("/scenarios"))
|
scenario.RegisterScenarioEndpoints(api.Group("/scenarios"))
|
||||||
simulationmodel.RegisterSimulationModelEndpoints(api.Group("/models"))
|
component_configuration.RegisterComponentConfigurationEndpoints(api.Group("/configs"))
|
||||||
signal.RegisterSignalEndpoints(api.Group("/signals"))
|
signal.RegisterSignalEndpoints(api.Group("/signals"))
|
||||||
dashboard.RegisterDashboardEndpoints(api.Group("/dashboards"))
|
dashboard.RegisterDashboardEndpoints(api.Group("/dashboards"))
|
||||||
widget.RegisterWidgetEndpoints(api.Group("/widgets"))
|
widget.RegisterWidgetEndpoints(api.Group("/widgets"))
|
||||||
file.RegisterFileEndpoints(api.Group("/files"))
|
file.RegisterFileEndpoints(api.Group("/files"))
|
||||||
user.RegisterUserEndpoints(api.Group("/users"))
|
user.RegisterUserEndpoints(api.Group("/users"))
|
||||||
simulator.RegisterSimulatorEndpoints(api.Group("/simulators"))
|
infrastructure_component.RegisterICEndpoints(api.Group("/ic"))
|
||||||
|
|
||||||
r.GET("swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
r.GET("swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||||
|
|
||||||
|
@ -133,10 +133,10 @@ func main() {
|
||||||
log.Panic(err)
|
log.Panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// register simulator action endpoint only if AMQP client is used
|
// register IC action endpoint only if AMQP client is used
|
||||||
amqp.RegisterAMQPEndpoint(api.Group("/simulators"))
|
amqp.RegisterAMQPEndpoint(api.Group("/ic"))
|
||||||
|
|
||||||
// Periodically call the Ping function to check which simulators are still there
|
// Periodically call the Ping function to check which ICs are still there
|
||||||
ticker := time.NewTicker(10 * time.Second)
|
ticker := time.NewTicker(10 * time.Second)
|
||||||
go func() {
|
go func() {
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue