mirror of
https://git.rwth-aachen.de/acs/public/villas/web-backend-go/
synced 2025-03-30 00:00:12 +01:00
Merge branch 'master' into authentication
# Conflicts: # go.mod # go.sum # routes/user/userEndpoints.go # routes/user/userSerializer.go # start.go
This commit is contained in:
commit
f6ea39af12
43 changed files with 3261 additions and 1154 deletions
|
@ -51,13 +51,15 @@ build:backend:
|
|||
image: villaswebbackendgo:ubuntu
|
||||
script:
|
||||
- go mod tidy
|
||||
- go get -u github.com/swaggo/swag/cmd/swag
|
||||
- ~/go/bin/swag init -p pascalcase -g "start.go" -o "./doc/autoapi/"
|
||||
- go build
|
||||
|
||||
|
||||
# Stage: test
|
||||
##############################################################################
|
||||
|
||||
test:backend:
|
||||
test:backend:database:
|
||||
stage: test
|
||||
tags:
|
||||
- docker
|
||||
|
@ -65,11 +67,28 @@ test:backend:
|
|||
script:
|
||||
- /etc/init.d/postgresql start
|
||||
- go mod tidy
|
||||
- go get -u github.com/swaggo/swag/cmd/swag
|
||||
- ~/go/bin/swag init -p pascalcase -g "start.go" -o "./doc/autoapi/"
|
||||
- cd common
|
||||
- go test -v -args -dbhost=/var/run/postgresql
|
||||
dependencies:
|
||||
- build:backend
|
||||
|
||||
test:backend:endpoints:
|
||||
stage: test
|
||||
tags:
|
||||
- docker
|
||||
image: villaswebbackendgo:ubuntu
|
||||
script:
|
||||
- /etc/init.d/postgresql start
|
||||
- go mod tidy
|
||||
- go get -u github.com/swaggo/swag/cmd/swag
|
||||
- ~/go/bin/swag init -p pascalcase -g "start.go" -o "./doc/autoapi/"
|
||||
- cd routes/simulation
|
||||
- go test -v -args -dbhost=/var/run/postgresql
|
||||
dependencies:
|
||||
- build:backend
|
||||
|
||||
# Stage: deploy
|
||||
##############################################################################
|
||||
|
||||
|
|
|
@ -54,10 +54,9 @@ func VerifyConnection(db *gorm.DB) error {
|
|||
// to the Dummy*() where it is called
|
||||
func DropTables(db *gorm.DB) {
|
||||
db.DropTableIfExists(&Simulator{})
|
||||
db.DropTableIfExists(&Signal{})
|
||||
db.DropTableIfExists(&SimulationModel{})
|
||||
//db.DropTableIfExists(&Signal{})
|
||||
db.DropTableIfExists(&Model{})
|
||||
db.DropTableIfExists(&File{})
|
||||
db.DropTableIfExists(&Project{})
|
||||
db.DropTableIfExists(&Simulation{})
|
||||
db.DropTableIfExists(&User{})
|
||||
db.DropTableIfExists(&Visualization{})
|
||||
|
@ -67,10 +66,9 @@ func DropTables(db *gorm.DB) {
|
|||
// AutoMigrate the models
|
||||
func MigrateModels(db *gorm.DB) {
|
||||
db.AutoMigrate(&Simulator{})
|
||||
db.AutoMigrate(&Signal{})
|
||||
db.AutoMigrate(&SimulationModel{})
|
||||
//db.AutoMigrate(&Signal{})
|
||||
db.AutoMigrate(&Model{})
|
||||
db.AutoMigrate(&File{})
|
||||
db.AutoMigrate(&Project{})
|
||||
db.AutoMigrate(&Simulation{})
|
||||
db.AutoMigrate(&User{})
|
||||
db.AutoMigrate(&Visualization{})
|
||||
|
@ -103,30 +101,25 @@ func DummyPopulateDB(test_db *gorm.DB) {
|
|||
checkErr(test_db.Create(&simr_A).Error)
|
||||
checkErr(test_db.Create(&simr_B).Error)
|
||||
|
||||
outSig_A := Signal{Name: "outSignal_A"}
|
||||
outSig_B := Signal{Name: "outSignal_B"}
|
||||
inSig_A := Signal{Name: "inSignal_A"}
|
||||
inSig_B := Signal{Name: "inSignal_B"}
|
||||
checkErr(test_db.Create(&outSig_A).Error)
|
||||
checkErr(test_db.Create(&outSig_B).Error)
|
||||
checkErr(test_db.Create(&inSig_A).Error)
|
||||
checkErr(test_db.Create(&inSig_B).Error)
|
||||
//outSig_A := Signal{Name: "outSignal_A", Direction: "out"}
|
||||
//outSig_B := Signal{Name: "outSignal_B", Direction: "out"}
|
||||
//inSig_A := Signal{Name: "inSignal_A", Direction: "in"}
|
||||
//inSig_B := Signal{Name: "inSignal_B", Direction: "in"}
|
||||
//checkErr(test_db.Create(&outSig_A).Error)
|
||||
//checkErr(test_db.Create(&outSig_B).Error)
|
||||
//checkErr(test_db.Create(&inSig_A).Error)
|
||||
//checkErr(test_db.Create(&inSig_B).Error)
|
||||
|
||||
smo_A := SimulationModel{Name: "SimModel_A"}
|
||||
smo_B := SimulationModel{Name: "SimModel_B"}
|
||||
checkErr(test_db.Create(&smo_A).Error)
|
||||
checkErr(test_db.Create(&smo_B).Error)
|
||||
mo_A := Model{Name: "Model_A"}
|
||||
mo_B := Model{Name: "Model_B"}
|
||||
checkErr(test_db.Create(&mo_A).Error)
|
||||
checkErr(test_db.Create(&mo_B).Error)
|
||||
|
||||
file_A := File{Name: "File_A"}
|
||||
file_B := File{Name: "File_B"}
|
||||
checkErr(test_db.Create(&file_A).Error)
|
||||
checkErr(test_db.Create(&file_B).Error)
|
||||
|
||||
proj_A := Project{Name: "Project_A"}
|
||||
proj_B := Project{Name: "Project_B"}
|
||||
checkErr(test_db.Create(&proj_A).Error)
|
||||
checkErr(test_db.Create(&proj_B).Error)
|
||||
|
||||
simn_A := Simulation{Name: "Simulation_A"}
|
||||
simn_B := Simulation{Name: "Simulation_B"}
|
||||
checkErr(test_db.Create(&simn_A).Error)
|
||||
|
@ -162,49 +155,40 @@ func DummyPopulateDB(test_db *gorm.DB) {
|
|||
// For `belongs to` use the model with id=1
|
||||
// For `has many` use the models with id=1 and id=2
|
||||
|
||||
// Project HM Visualization, Visualization BT Project
|
||||
checkErr(test_db.Model(&vis_A).Association("Project").Append(&proj_A).Error)
|
||||
checkErr(test_db.Model(&vis_B).Association("Project").Append(&proj_A).Error)
|
||||
// User HM Simulations, Simulation HM Users (Many-to-Many)
|
||||
checkErr(test_db.Model(&simn_A).Association("Users").Append(&usr_A).Error)
|
||||
checkErr(test_db.Model(&simn_A).Association("Users").Append(&usr_B).Error)
|
||||
checkErr(test_db.Model(&simn_B).Association("Users").Append(&usr_A).Error)
|
||||
checkErr(test_db.Model(&simn_B).Association("Users").Append(&usr_B).Error)
|
||||
|
||||
// User HM Project, Project BT User
|
||||
checkErr(test_db.Model(&proj_A).Association("User").Append(&usr_A).Error)
|
||||
checkErr(test_db.Model(&proj_B).Association("User").Append(&usr_A).Error)
|
||||
// Simulation HM Model
|
||||
checkErr(test_db.Model(&simn_A).Association("Models").Append(&mo_A).Error)
|
||||
checkErr(test_db.Model(&simn_A).Association("Models").Append(&mo_B).Error)
|
||||
|
||||
// Simulation HM Project, Project BT Simulation
|
||||
checkErr(test_db.Model(&proj_A).Association("Simulation").Append(&simn_A).Error)
|
||||
checkErr(test_db.Model(&proj_B).Association("Simulation").Append(&simn_A).Error)
|
||||
|
||||
// User HM Files
|
||||
checkErr(test_db.Model(&usr_A).Association("Files").Append(&file_A).Error)
|
||||
checkErr(test_db.Model(&usr_A).Association("Files").Append(&file_B).Error)
|
||||
|
||||
// Simulation HM SimModel, SimModel BT Simulation
|
||||
checkErr(test_db.Model(&smo_A).Association("BelongsToSimulation").Append(&simn_A).Error)
|
||||
checkErr(test_db.Model(&smo_B).Association("BelongsToSimulation").Append(&simn_A).Error)
|
||||
|
||||
// User HM Simulation, Simulation BT User
|
||||
checkErr(test_db.Model(&simn_A).Association("User").Append(&usr_A).Error)
|
||||
checkErr(test_db.Model(&simn_B).Association("User").Append(&usr_A).Error)
|
||||
// Simulation HM Visualizations
|
||||
checkErr(test_db.Model(&simn_A).Association("Visualizations").Append(&vis_A).Error)
|
||||
checkErr(test_db.Model(&simn_A).Association("Visualizations").Append(&vis_B).Error)
|
||||
|
||||
// Visualization HM Widget
|
||||
checkErr(test_db.Model(&vis_A).Association("Widgets").Append(&widg_A).Error)
|
||||
checkErr(test_db.Model(&vis_A).Association("Widgets").Append(&widg_B).Error)
|
||||
|
||||
// SimModel HM Signal
|
||||
checkErr(test_db.Model(&smo_A).Association("InputMapping").Append(&inSig_A).Error)
|
||||
checkErr(test_db.Model(&smo_A).Association("InputMapping").Append(&inSig_B).Error)
|
||||
checkErr(test_db.Model(&smo_A).Association("OutputMapping").Append(&outSig_A).Error)
|
||||
checkErr(test_db.Model(&smo_A).Association("OutputMapping").Append(&outSig_B).Error)
|
||||
// Model HM Signal
|
||||
//checkErr(test_db.Model(&mo_A).Association("InputMapping").Append(&inSig_A).Error)
|
||||
//checkErr(test_db.Model(&mo_A).Association("InputMapping").Append(&inSig_B).Error)
|
||||
//checkErr(test_db.Model(&mo_A).Association("OutputMapping").Append(&outSig_A).Error)
|
||||
//checkErr(test_db.Model(&mo_A).Association("OutputMapping").Append(&outSig_B).Error)
|
||||
|
||||
//SimulationModel HM Files
|
||||
checkErr(test_db.Model(&smo_A).Association("Files").Append(&file_A).Error)
|
||||
checkErr(test_db.Model(&smo_A).Association("Files").Append(&file_B).Error)
|
||||
// Model HM Files
|
||||
checkErr(test_db.Model(&mo_A).Association("Files").Append(&file_A).Error)
|
||||
checkErr(test_db.Model(&mo_A).Association("Files").Append(&file_B).Error)
|
||||
|
||||
// Visualization BT User
|
||||
checkErr(test_db.Model(&vis_A).Association("User").Append(&usr_A).Error)
|
||||
// Simulator BT Model
|
||||
checkErr(test_db.Model(&mo_A).Association("Simulator").Append(&simr_A).Error)
|
||||
|
||||
// Simulator BT SimModel
|
||||
checkErr(test_db.Model(&smo_A).Association("BelongsToSimulator").Append(&simr_A).Error)
|
||||
// Widget HM Files
|
||||
checkErr(test_db.Model(&widg_A).Association("Files").Append(&file_A).Error)
|
||||
checkErr(test_db.Model(&widg_A).Association("Files").Append(&file_B).Error)
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,9 @@ package common
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// Verify that you can connect to the database
|
||||
|
@ -28,45 +29,33 @@ func TestDummyDBAssociations(t *testing.T) {
|
|||
|
||||
// Variables for tests
|
||||
var simr Simulator
|
||||
var smo SimulationModel
|
||||
var mo Model
|
||||
var file File
|
||||
var proj Project
|
||||
var simn Simulation
|
||||
var usr User
|
||||
var usrs []User
|
||||
var vis Visualization
|
||||
var widg Widget
|
||||
|
||||
var sigs []Signal
|
||||
var smos []SimulationModel
|
||||
//var sigs []Signal
|
||||
var mos []Model
|
||||
var files []File
|
||||
var files_sm []File
|
||||
var projs []Project
|
||||
var simns []Simulation
|
||||
var viss []Visualization
|
||||
var widgs []Widget
|
||||
|
||||
// Simulation Model
|
||||
// User
|
||||
|
||||
a.NoError(db.Find(&smo, 1).Error, fM("SimulationModel"))
|
||||
a.EqualValues("SimModel_A", smo.Name)
|
||||
a.NoError(db.Find(&usr, 1).Error, fM("User"))
|
||||
a.EqualValues("User_A", usr.Username)
|
||||
|
||||
// Simulation Model Associations
|
||||
// User Associations
|
||||
|
||||
a.NoError(db.Model(&smo).Association("BelongsToSimulation").Find(&simn).Error)
|
||||
a.EqualValues("Simulation_A", simn.Name, "Expected Simulation_A")
|
||||
|
||||
a.NoError(db.Model(&smo).Association("BelongsToSimulator").Find(&simr).Error)
|
||||
a.EqualValues("Host_A", simr.Host, "Expected Host_A")
|
||||
|
||||
a.NoError(db.Model(&smo).Related(&sigs, "OutputMapping").Error)
|
||||
if len(sigs) != 4 {
|
||||
a.Fail("Simulation Model Associations",
|
||||
"Expected to have %v Output AND Input Signals. Has %v.", 4, len(sigs))
|
||||
}
|
||||
|
||||
a.NoError(db.Model(&smo).Related(&files_sm, "Files").Error)
|
||||
if len(files_sm) != 2 {
|
||||
a.Fail("Simulation Model Associations",
|
||||
"Expected to have %v Files. Has %v.", 2, len(files_sm))
|
||||
a.NoError(db.Model(&usr).Related(&simns, "Simulations").Error)
|
||||
if len(simns) != 2 {
|
||||
a.Fail("User Associations",
|
||||
"Expected to have %v Simulations. Has %v.", 2, len(simns))
|
||||
}
|
||||
|
||||
// Simulation
|
||||
|
@ -76,64 +65,47 @@ func TestDummyDBAssociations(t *testing.T) {
|
|||
|
||||
// Simulation Associations
|
||||
|
||||
a.NoError(db.Model(&simn).Association("User").Find(&usr).Error)
|
||||
a.EqualValues("User_A", usr.Username)
|
||||
|
||||
a.NoError(db.Model(&simn).Related(&smos, "Models").Error)
|
||||
if len(smos) != 2 {
|
||||
a.Fail("Simulation Associations",
|
||||
"Expected to have %v Simulation Models. Has %v.", 2, len(smos))
|
||||
a.NoError(db.Model(&simn).Association("Users").Find(&usrs).Error)
|
||||
if len(usrs) != 2 {
|
||||
a.Fail("Simulations Associations",
|
||||
"Expected to have %v Users. Has %v.", 2, len(usrs))
|
||||
}
|
||||
|
||||
a.NoError(db.Model(&simn).Related(&projs, "Projects").Error)
|
||||
if len(projs) != 2 {
|
||||
a.NoError(db.Model(&simn).Related(&mos, "Models").Error)
|
||||
if len(mos) != 2 {
|
||||
a.Fail("Simulation Associations",
|
||||
"Expected to have %v Projects. Has %v.", 2, len(projs))
|
||||
"Expected to have %v Models. Has %v.", 2, len(mos))
|
||||
}
|
||||
|
||||
// Project
|
||||
|
||||
a.NoError(db.Find(&proj, 1).Error, fM("Project"))
|
||||
a.EqualValues("Project_A", proj.Name)
|
||||
|
||||
// Project Associations
|
||||
|
||||
a.NoError(db.Model(&proj).Association("Simulation").Find(&simn).Error)
|
||||
a.EqualValues("Simulation_A", simn.Name)
|
||||
|
||||
a.NoError(db.Model(&proj).Association("User").Find(&usr).Error)
|
||||
a.EqualValues("User_A", usr.Username)
|
||||
|
||||
a.NoError(db.Model(&proj).Related(&viss, "Visualizations").Error)
|
||||
a.NoError(db.Model(&simn).Related(&viss, "Visualizations").Error)
|
||||
if len(viss) != 2 {
|
||||
a.Fail("Project Associations",
|
||||
a.Fail("Simulation Associations",
|
||||
"Expected to have %v Visualizations. Has %v.", 2, len(viss))
|
||||
}
|
||||
|
||||
// User
|
||||
|
||||
a.NoError(db.Find(&usr, 1).Error, fM("User"))
|
||||
a.EqualValues("User_A", usr.Username)
|
||||
// Model
|
||||
|
||||
// User Associations
|
||||
a.NoError(db.Find(&mo, 1).Error, fM("Model"))
|
||||
a.EqualValues("Model_A", mo.Name)
|
||||
|
||||
a.NoError(db.Model(&usr).Related(&projs, "Projects").Error)
|
||||
if len(projs) != 2 {
|
||||
a.Fail("User Associations",
|
||||
"Expected to have %v Projects. Has %v.", 2, len(projs))
|
||||
// Model Associations
|
||||
|
||||
a.NoError(db.Model(&mo).Association("Simulator").Find(&simr).Error)
|
||||
a.EqualValues("Host_A", simr.Host, "Expected Host_A")
|
||||
|
||||
//a.NoError(db.Model(&mo).Where("Direction = ?", "out").Related(&sigs, "OutputMapping").Error)
|
||||
//if len(sigs) != 2 {
|
||||
// a.Fail("Model Associations",
|
||||
// "Expected to have %v Output AND Input Signals. Has %v.", 2, len(sigs))
|
||||
//}
|
||||
|
||||
a.NoError(db.Model(&mo).Related(&files_sm, "Files").Error)
|
||||
if len(files_sm) != 2 {
|
||||
a.Fail("Model Associations",
|
||||
"Expected to have %v Files. Has %v.", 2, len(files_sm))
|
||||
}
|
||||
|
||||
a.NoError(db.Model(&usr).Related(&simns, "Simulations").Error)
|
||||
if len(simns) != 2 {
|
||||
a.Fail("User Associations",
|
||||
"Expected to have %v Simulations. Has %v.", 2, len(simns))
|
||||
}
|
||||
|
||||
a.NoError(db.Model(&usr).Related(&files, "Files").Error)
|
||||
if len(files) != 2 {
|
||||
a.Fail("User Associations",
|
||||
"Expected to have %v Files. Has %v.", 2, len(files))
|
||||
}
|
||||
|
||||
// Visualization
|
||||
|
||||
|
@ -142,26 +114,29 @@ func TestDummyDBAssociations(t *testing.T) {
|
|||
|
||||
// Visualization Associations
|
||||
|
||||
a.NoError(db.Model(&vis).Association("Project").Find(&proj).Error)
|
||||
a.EqualValues("Project_A", proj.Name)
|
||||
|
||||
a.NoError(db.Model(&vis).Association("User").Find(&usr).Error)
|
||||
a.EqualValues("User_A", usr.Username)
|
||||
|
||||
a.NoError(db.Model(&vis).Related(&widgs, "Widgets").Error)
|
||||
if len(widgs) != 2 {
|
||||
a.Fail("Widget Associations",
|
||||
"Expected to have %v Widget. Has %v.", 2, len(widgs))
|
||||
}
|
||||
|
||||
|
||||
// Widget
|
||||
a.NoError(db.Find(&widg, 1).Error, fM("Widget"))
|
||||
a.EqualValues("Widget_A", widg.Name)
|
||||
|
||||
|
||||
// Widget Association
|
||||
a.NoError(db.Model(&widg).Related(&files, "Files").Error)
|
||||
if len(files) != 2 {
|
||||
a.Fail("Widget Associations",
|
||||
"Expected to have %v Files. Has %v.", 2, len(files))
|
||||
}
|
||||
|
||||
// File
|
||||
|
||||
a.NoError(db.Find(&file, 1).Error, fM("File"))
|
||||
a.EqualValues("File_A", file.Name)
|
||||
|
||||
// File Associations
|
||||
|
||||
//a.NoError(db.Model(&file).Association("User").Find(&usr).Error)
|
||||
//a.EqualValues("User_A", usr.Username)
|
||||
|
||||
}
|
||||
|
|
|
@ -1,142 +0,0 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
//"github.com/jinzhu/gorm"
|
||||
"github.com/jinzhu/gorm/dialects/postgres"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Simulator struct {
|
||||
//gorm.Model
|
||||
ID uint `gorm:"primary_key;auto_increment"`
|
||||
UUID string `gorm:"unique;not null"`
|
||||
Host string `gorm:"default:''"`
|
||||
Modeltype string `gorm:"default:''"`
|
||||
Uptime int `gorm:"default:0"`
|
||||
State string `gorm:"default:''"`
|
||||
StateUpdateAt time.Time
|
||||
Properties postgres.Jsonb // TODO: default value?
|
||||
RawProperties postgres.Jsonb // TODO: default value?
|
||||
}
|
||||
|
||||
type File struct {
|
||||
//gorm.Model
|
||||
ID uint `gorm:"primary_key;auto_increment"`
|
||||
Name string `gorm:"not null"`
|
||||
Path string `gorm:"not null"`
|
||||
Type string `gorm:"not null"`
|
||||
Size uint `gorm:"not null"`
|
||||
ImageHeight uint // only required in case file is an image
|
||||
ImageWidth uint // only required in case file is an image
|
||||
Date time.Time
|
||||
|
||||
//remove belongs to User relation
|
||||
//User User `gorm:"not null;association_autoupdate:false"`
|
||||
UserID uint `gorm:"not null"`
|
||||
SimulationModelID uint `gorm:""`
|
||||
}
|
||||
|
||||
type Project struct {
|
||||
//gorm.Model
|
||||
ID uint `gorm:"primary_key;auto_increment"`
|
||||
Name string `gorm:"not null"`
|
||||
|
||||
User User `gorm:"not null;association_autoupdate:false"`
|
||||
UserID uint `gorm:"not null"`
|
||||
|
||||
Simulation Simulation `gorm:"not null;association_autoupdate:false"`
|
||||
SimulationID uint `gorm:"not null"`
|
||||
|
||||
Visualizations []Visualization `gorm:"association_autoupdate:false"`
|
||||
}
|
||||
|
||||
type Simulation struct {
|
||||
//gorm.Model
|
||||
ID uint `gorm:"primary_key;auto_increment"`
|
||||
Name string `gorm:"not null"`
|
||||
Running bool `gorm:"default:false"`
|
||||
StartParameters postgres.Jsonb // TODO default value
|
||||
|
||||
User User `gorm:"not null;association_autoupdate:false"`
|
||||
UserID uint `gorm:"not null"`
|
||||
|
||||
Models []SimulationModel `gorm:"foreignkey:BelongsToSimulationID;association_autoupdate:false"`
|
||||
Projects []Project `gorm:"association_autoupdate:false"`
|
||||
}
|
||||
|
||||
type SimulationModel struct {
|
||||
//gorm.Model
|
||||
ID uint `gorm:"primary_key;auto_increment"`
|
||||
Name string `gorm:"not null"`
|
||||
OutputLength int `gorm:"default:1"`
|
||||
InputLength int `gorm:"default:1"`
|
||||
StartParameters postgres.Jsonb // TODO: default value?
|
||||
|
||||
BelongsToSimulation Simulation `gorm:"not null;association_autoupdate:false"`
|
||||
BelongsToSimulationID uint `gorm:"not null"`
|
||||
|
||||
BelongsToSimulator Simulator `gorm:"not null;association_autoupdate:false"`
|
||||
BelongsToSimulatorID uint `gorm:"not null"`
|
||||
// NOTE: order of signals is important
|
||||
OutputMapping []Signal `gorm:""`
|
||||
InputMapping []Signal `gorm:""`
|
||||
|
||||
//new in villasweb 2.0 (for CIM file of simulation model and other model file formats)
|
||||
Files []File `gorm:""`
|
||||
|
||||
|
||||
}
|
||||
|
||||
type User struct {
|
||||
//gorm.Model
|
||||
ID uint `gorm:"primary_key;auto_increment"`
|
||||
Username string `gorm:"unique;not null"`
|
||||
Password string `gorm:"not null"`
|
||||
Mail string `gorm:"default:''"`
|
||||
Role string `gorm:"default:'user'"`
|
||||
|
||||
Projects []Project `gorm:"association_autoupdate:false"`
|
||||
Simulations []Simulation `gorm:"association_autoupdate:false"`
|
||||
Files []File `gorm:""`
|
||||
}
|
||||
|
||||
type Visualization struct {
|
||||
//gorm.Model
|
||||
ID uint `gorm:"primary_key;auto_increment"`
|
||||
Name string `gorm:"not null"`
|
||||
Grid int `gorm:"default:15"`
|
||||
|
||||
Project Project `gorm:"not null;association_autoupdate:false"`
|
||||
ProjectID uint `gorm:"not null"`
|
||||
|
||||
User User `gorm:"not null;association_autoupdate:false"`
|
||||
UserID uint `gorm:"not null"`
|
||||
|
||||
Widgets []Widget `gorm:""`
|
||||
}
|
||||
|
||||
type Signal struct {
|
||||
//gorm.Model
|
||||
ID uint `gorm:"primary_key;auto_increment"`
|
||||
Name string `gorm:"not null"`
|
||||
Unit string `gorm:"not null"`
|
||||
SimulationModelID uint
|
||||
//IsRecorded bool `gorm:"default:false"`
|
||||
}
|
||||
|
||||
type Widget struct {
|
||||
//gorm.Model
|
||||
ID uint `gorm:"primary_key;auto_increment"`
|
||||
Name string `gorm:"not null"`
|
||||
Type string `gorm:"not null"`
|
||||
Width uint `gorm:"not null"`
|
||||
Height uint `gorm:"not null"`
|
||||
MinWidth uint `gorm:"not null"`
|
||||
MinHeight uint `gorm:"not null"`
|
||||
X int `gorm:"not null"`
|
||||
Y int `gorm:"not null"`
|
||||
Z int `gorm:"not null"`
|
||||
IsLocked bool `gorm:"default:false"`
|
||||
CustomProperties postgres.Jsonb // TODO: default value?
|
||||
VisualizationID uint
|
||||
}
|
172
common/models.go
Normal file
172
common/models.go
Normal file
|
@ -0,0 +1,172 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// User data model
|
||||
type User struct {
|
||||
// ID of user
|
||||
ID uint `gorm:"primary_key;auto_increment"`
|
||||
// Username of user
|
||||
Username string `gorm:"unique;not null"`
|
||||
// Password of user
|
||||
Password string `gorm:"not null"`
|
||||
// Mail of user
|
||||
Mail string `gorm:"default:''"`
|
||||
// Role of user
|
||||
Role string `gorm:"default:'user'"`
|
||||
// Simulations to which user has access
|
||||
Simulations []Simulation `gorm:"many2many:user_simulations"`
|
||||
}
|
||||
|
||||
|
||||
// Simulation data model
|
||||
type Simulation struct {
|
||||
// ID of simulation
|
||||
ID uint `gorm:"primary_key;auto_increment"`
|
||||
// Name of simulation
|
||||
Name string `gorm:"not null"`
|
||||
// Running state of simulation
|
||||
Running bool `gorm:"default:false"`
|
||||
// Start parameters of simulation as JSON string
|
||||
StartParameters string
|
||||
// Users that have access to the simulation
|
||||
Users []User `gorm:"not null;many2many:user_simulations"`
|
||||
// Models that belong to the simulation
|
||||
Models []Model `gorm:"foreignkey:SimulationID"`
|
||||
// Visualizations that belong to the simulation
|
||||
Visualizations []Visualization `gorm:"foreignkey:SimulationID"`
|
||||
}
|
||||
|
||||
// Model data model
|
||||
type Model struct {
|
||||
// ID of model
|
||||
ID uint `gorm:"primary_key;auto_increment"`
|
||||
// Name of model
|
||||
Name string `gorm:"not null"`
|
||||
// Number of output signals
|
||||
OutputLength int `gorm:"default:1"`
|
||||
// Number of input signals
|
||||
InputLength int `gorm:"default:1"`
|
||||
// Start parameters of model as JSON string
|
||||
StartParameters string
|
||||
// ID of simulation to which model belongs
|
||||
SimulationID uint
|
||||
// Simulator associated with model
|
||||
Simulator Simulator
|
||||
// ID of simulator associated with model
|
||||
SimulatorID uint
|
||||
// Mapping of output signals of the model, order of signals is important
|
||||
OutputMapping []Signal
|
||||
// Mapping of input signals of the model, order of signals is important
|
||||
InputMapping []Signal
|
||||
// Files of model (can be CIM and other model file formats)
|
||||
Files []File `gorm:"foreignkey:ModelID"`
|
||||
}
|
||||
|
||||
type Signal struct {
|
||||
// Name of Signal
|
||||
Name string
|
||||
// Unit of Signal
|
||||
Unit string
|
||||
// Index of the Signal in the mapping
|
||||
Index uint
|
||||
// Direction of the signal (in or out)
|
||||
Direction string
|
||||
}
|
||||
|
||||
|
||||
// Simulator data model
|
||||
type Simulator struct {
|
||||
// ID of the simulator
|
||||
ID uint `gorm:"primary_key;auto_increment"`
|
||||
// UUID of the simulator
|
||||
UUID string `gorm:"unique;not null"`
|
||||
// Host if the simulator
|
||||
Host string `gorm:"default:''"`
|
||||
// Model type supported by the simulator
|
||||
Modeltype string `gorm:"default:''"`
|
||||
// Uptime of the simulator
|
||||
Uptime int `gorm:"default:0"`
|
||||
// State of the simulator
|
||||
State string `gorm:"default:''"`
|
||||
// Time of last state update
|
||||
StateUpdateAt time.Time
|
||||
// Properties of simulator as JSON string
|
||||
Properties string
|
||||
// Raw properties of simulator as JSON string
|
||||
RawProperties string
|
||||
}
|
||||
|
||||
// Visualization data model
|
||||
type Visualization struct {
|
||||
// ID of visualization
|
||||
ID uint `gorm:"primary_key;auto_increment"`
|
||||
// Name of visualization
|
||||
Name string `gorm:"not null"`
|
||||
// Grid of visualization
|
||||
Grid int `gorm:"default:15"`
|
||||
// ID of simulation to which visualization belongs
|
||||
SimulationID uint `gorm:"not null"`
|
||||
// Widgets that belong to visualization
|
||||
Widgets []Widget `gorm:"foreignkey:VisualizationID"`
|
||||
}
|
||||
|
||||
|
||||
// Widget data model
|
||||
type Widget struct {
|
||||
// ID of widget
|
||||
ID uint `gorm:"primary_key;auto_increment"`
|
||||
// Name of widget
|
||||
Name string `gorm:"not null"`
|
||||
// Type of widget
|
||||
Type string `gorm:"not null"`
|
||||
// Width of widget
|
||||
Width uint `gorm:"not null"`
|
||||
// Height of widget
|
||||
Height uint `gorm:"not null"`
|
||||
// Minimal width of widget
|
||||
MinWidth uint `gorm:"not null"`
|
||||
// Minimal height of widget
|
||||
MinHeight uint `gorm:"not null"`
|
||||
// X position of widget
|
||||
X int `gorm:"not null"`
|
||||
// Y position of widget
|
||||
Y int `gorm:"not null"`
|
||||
// Z position of widget
|
||||
Z int `gorm:"not null"`
|
||||
// Locked state of widget
|
||||
IsLocked bool `gorm:"default:false"`
|
||||
// Custom properties of widget as JSON string
|
||||
CustomProperties string
|
||||
// ID of visualization to which widget belongs
|
||||
VisualizationID uint `gorm:"not null"`
|
||||
// Files that belong to widget (for example images)
|
||||
Files []File `gorm:"foreignkey:WidgetID"`
|
||||
}
|
||||
|
||||
|
||||
// File data model
|
||||
type File struct {
|
||||
// ID of file
|
||||
ID uint `gorm:"primary_key;auto_increment"`
|
||||
// Name of file
|
||||
Name string `gorm:"not null"`
|
||||
// Path at which file is saved at server side
|
||||
Path string `gorm:"not null"`
|
||||
// Type of file (MIME type)
|
||||
Type string `gorm:"not null"`
|
||||
// Size of file (in byte)
|
||||
Size uint `gorm:"not null"`
|
||||
// Height of image (only needed in case of image)
|
||||
ImageHeight uint
|
||||
// Width of image (only needed in case of image)
|
||||
ImageWidth uint
|
||||
// Last modification time of file
|
||||
Date time.Time
|
||||
// ID of model to which file belongs
|
||||
ModelID uint `gorm:""`
|
||||
// ID of widget to which file belongs
|
||||
WidgetID uint `gorm:""`
|
||||
}
|
95
common/responses.go
Normal file
95
common/responses.go
Normal file
|
@ -0,0 +1,95 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type UserResponse struct {
|
||||
Username string `json:"Username"`
|
||||
Role string `json:"Role"`
|
||||
Mail string `json:"Mail"`
|
||||
}
|
||||
|
||||
type SimulationResponse struct {
|
||||
Name string `json:"Name"`
|
||||
ID uint `json:"SimulationID"`
|
||||
Running bool `json:"Running"`
|
||||
StartParams string `json:"Starting Parameters"`
|
||||
}
|
||||
|
||||
type ModelResponse struct {
|
||||
Name string `json:"Name"`
|
||||
OutputLength int `json:"OutputLength"`
|
||||
InputLength int `json:"InputLength"`
|
||||
SimulationID uint `json:"SimulationID"`
|
||||
SimulatorID uint `json:"SimulatorID"`
|
||||
StartParams string `json:"StartParams"`
|
||||
InputMapping []Signal `json:"InputMapping"`
|
||||
OutputMapping []Signal `json:"OutputMapping"`
|
||||
}
|
||||
|
||||
type SimulatorResponse struct {
|
||||
UUID string `json:"UUID"`
|
||||
Host string `json:"Host"`
|
||||
ModelType string `json:"ModelType"`
|
||||
Uptime int `json:"Uptime"`
|
||||
State string `json:"State"`
|
||||
StateUpdateAt time.Time `json:"StateUpdateAt"`
|
||||
Properties string `json:"Properties"`
|
||||
RawProperties string `json:"RawProperties"`
|
||||
}
|
||||
|
||||
type VisualizationResponse struct {
|
||||
Name string `json:"Name"`
|
||||
Grid int `json:"Grid"`
|
||||
SimulationID uint `json:"SimulationID"`
|
||||
}
|
||||
|
||||
type WidgetResponse struct {
|
||||
Name string `json:"Name"`
|
||||
Type string `json:"Type"`
|
||||
Width uint `json:"Width"`
|
||||
Height uint `json:"Height"`
|
||||
MinWidth uint `json:"MinWidth"`
|
||||
MinHeight uint `json:"MinHeight"`
|
||||
X int `json:"X"`
|
||||
Y int `json:"Y"`
|
||||
Z int `json:"Z"`
|
||||
VisualizationID uint `json:"VisualizationID"`
|
||||
IsLocked bool `json:"IsLocked"`
|
||||
CustomProperties string `json:"CustomProperties"`
|
||||
}
|
||||
|
||||
type FileResponse struct {
|
||||
Name string `json:"Name"`
|
||||
ID uint `json:"FileID"`
|
||||
Path string `json:"Path"`
|
||||
Type string `json:"Type"`
|
||||
Size uint `json:"Size"`
|
||||
H uint `json:"ImageHeight"`
|
||||
W uint `json:"ImageWidth"`
|
||||
Date time.Time `json:"Date"`
|
||||
}
|
||||
|
||||
// Response messages
|
||||
|
||||
type ResponseMsg struct{
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type ResponseMsgUsers struct {
|
||||
Users []UserResponse `json:"users"`
|
||||
}
|
||||
|
||||
type ResponseMsgUser struct {
|
||||
User UserResponse `json:"user"`
|
||||
}
|
||||
|
||||
type ResponseMsgSimulations struct {
|
||||
Simulations []SimulationResponse `json:"simulations"`
|
||||
}
|
||||
|
||||
type ResponseMsgSimulation struct {
|
||||
Simulation SimulationResponse `json:"simulation"`
|
||||
}
|
||||
|
262
common/serializers.go
Normal file
262
common/serializers.go
Normal file
|
@ -0,0 +1,262 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// User/s Serializers
|
||||
|
||||
type UsersSerializer struct {
|
||||
Ctx *gin.Context
|
||||
Users []User
|
||||
}
|
||||
|
||||
func (self *UsersSerializer) Response(assoc bool) []UserResponse {
|
||||
response := []UserResponse{}
|
||||
for _, user := range self.Users {
|
||||
serializer := UserSerializer{self.Ctx, user}
|
||||
response = append(response, serializer.Response(assoc))
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
type UserSerializer struct {
|
||||
Ctx *gin.Context
|
||||
User
|
||||
}
|
||||
|
||||
|
||||
func (self *UserSerializer) Response(assoc bool) UserResponse {
|
||||
|
||||
response := UserResponse{
|
||||
Username: self.Username,
|
||||
Role: self.Role,
|
||||
Mail: self.Mail,
|
||||
}
|
||||
|
||||
// Associated models MUST NOT called with assoc=true otherwise we
|
||||
// will have an infinite loop due to the circular dependencies
|
||||
if assoc {
|
||||
|
||||
// TODO: maybe all those should be made in one transaction
|
||||
|
||||
//simulations, _, _ := simulation.FindUserSimulations(&self.User)
|
||||
//simulationsSerializer :=
|
||||
// SimulationsSerializer{self.Ctx, simulations}
|
||||
|
||||
// Add the associated models to the response
|
||||
//response.Simulations = simulationsSerializer.Response()
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
// Simulation/s Serializers
|
||||
|
||||
type SimulationsSerializer struct {
|
||||
Ctx *gin.Context
|
||||
Simulations []Simulation
|
||||
}
|
||||
|
||||
func (self *SimulationsSerializer) Response() []SimulationResponse {
|
||||
response := []SimulationResponse{}
|
||||
for _, simulation := range self.Simulations {
|
||||
serializer := SimulationSerializer{self.Ctx, simulation}
|
||||
response = append(response, serializer.Response())
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
type SimulationSerializer struct {
|
||||
Ctx *gin.Context
|
||||
Simulation
|
||||
}
|
||||
|
||||
|
||||
func (self *SimulationSerializer) Response() SimulationResponse {
|
||||
response := SimulationResponse{
|
||||
Name: self.Name,
|
||||
ID: self.ID,
|
||||
Running: self.Running,
|
||||
StartParams: self.StartParameters,
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
|
||||
// Model/s Serializers
|
||||
|
||||
type ModelsSerializer struct {
|
||||
Ctx *gin.Context
|
||||
Models []Model
|
||||
}
|
||||
|
||||
func (self *ModelsSerializer) Response() []ModelResponse {
|
||||
response := []ModelResponse{}
|
||||
for _, model := range self.Models {
|
||||
serializer := ModelSerializer{self.Ctx, model}
|
||||
response = append(response, serializer.Response())
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
type ModelSerializer struct {
|
||||
Ctx *gin.Context
|
||||
Model
|
||||
}
|
||||
|
||||
func (self *ModelSerializer) Response() ModelResponse {
|
||||
response := ModelResponse{
|
||||
Name: self.Name,
|
||||
OutputLength: self.OutputLength,
|
||||
InputLength: self.InputLength,
|
||||
SimulationID: self.SimulationID,
|
||||
SimulatorID: self.SimulatorID,
|
||||
StartParams: self.StartParameters,
|
||||
//InputMapping
|
||||
//OutputMapping
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
// Simulator/s Serializers
|
||||
|
||||
type SimulatorsSerializer struct {
|
||||
Ctx *gin.Context
|
||||
Simulators []Simulator
|
||||
}
|
||||
|
||||
func (self *SimulatorsSerializer) Response() []SimulatorResponse {
|
||||
response := []SimulatorResponse{}
|
||||
for _, simulator := range self.Simulators {
|
||||
serializer := SimulatorSerializer{self.Ctx, simulator}
|
||||
response = append(response, serializer.Response())
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
type SimulatorSerializer struct {
|
||||
Ctx *gin.Context
|
||||
Simulator
|
||||
}
|
||||
|
||||
func (self *SimulatorSerializer) Response() SimulatorResponse {
|
||||
|
||||
response := SimulatorResponse{
|
||||
UUID: self.UUID,
|
||||
Host: self.Host,
|
||||
ModelType: self.Modeltype,
|
||||
Uptime: self.Uptime,
|
||||
State: self.State,
|
||||
StateUpdateAt: self.StateUpdateAt,
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
// Visualization/s Serializers
|
||||
|
||||
type VisualizationsSerializer struct {
|
||||
Ctx *gin.Context
|
||||
Visualizations []Visualization
|
||||
}
|
||||
|
||||
func (self *VisualizationsSerializer) Response() []VisualizationResponse {
|
||||
response := []VisualizationResponse{}
|
||||
for _, visualization := range self.Visualizations {
|
||||
serializer := VisualizationSerializer{self.Ctx, visualization}
|
||||
response = append(response, serializer.Response())
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
type VisualizationSerializer struct {
|
||||
Ctx *gin.Context
|
||||
Visualization
|
||||
}
|
||||
|
||||
|
||||
func (self *VisualizationSerializer) Response() VisualizationResponse {
|
||||
|
||||
response := VisualizationResponse{
|
||||
Name: self.Name,
|
||||
Grid: self.Grid,
|
||||
SimulationID: self.SimulationID,
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
// Widget/s Serializers
|
||||
|
||||
type WidgetsSerializer struct {
|
||||
Ctx *gin.Context
|
||||
Widgets []Widget
|
||||
}
|
||||
|
||||
func (self *WidgetsSerializer) Response() []WidgetResponse {
|
||||
response := []WidgetResponse{}
|
||||
for _, widget := range self.Widgets {
|
||||
serializer := WidgetSerializer{self.Ctx, widget}
|
||||
response = append(response, serializer.Response())
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
type WidgetSerializer struct {
|
||||
Ctx *gin.Context
|
||||
Widget
|
||||
}
|
||||
|
||||
func (self *WidgetSerializer) Response() WidgetResponse {
|
||||
|
||||
response := WidgetResponse{
|
||||
Name: self.Name,
|
||||
Type: self.Type,
|
||||
Width: self.Width,
|
||||
Height: self.Height,
|
||||
MinWidth: self.MinWidth,
|
||||
MinHeight: self.MinHeight,
|
||||
X: self.X,
|
||||
Y: self.Y,
|
||||
Z: self.Z,
|
||||
VisualizationID: self.VisualizationID,
|
||||
IsLocked: self.IsLocked,
|
||||
//CustomProperties
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
// File/s Serializers
|
||||
|
||||
type FilesSerializerNoAssoc struct {
|
||||
Ctx *gin.Context
|
||||
Files []File
|
||||
}
|
||||
|
||||
func (self *FilesSerializerNoAssoc) Response() []FileResponse {
|
||||
response := []FileResponse{}
|
||||
for _, files := range self.Files {
|
||||
serializer := FileSerializerNoAssoc{self.Ctx, files}
|
||||
response = append(response, serializer.Response())
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
type FileSerializerNoAssoc struct {
|
||||
Ctx *gin.Context
|
||||
File
|
||||
}
|
||||
|
||||
|
||||
func (self *FileSerializerNoAssoc) Response() FileResponse {
|
||||
response := FileResponse{
|
||||
Name: self.Name,
|
||||
ID: self.ID,
|
||||
Path: self.Path,
|
||||
Type: self.Type,
|
||||
Size: self.Size,
|
||||
H: self.ImageHeight,
|
||||
W: self.ImageWidth,
|
||||
// Date
|
||||
}
|
||||
return response
|
||||
}
|
93
common/utilities.go
Normal file
93
common/utilities.go
Normal file
|
@ -0,0 +1,93 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
func ProvideErrorResponse(c *gin.Context, err error) bool {
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
errormsg := "Record not Found in DB: " + err.Error()
|
||||
c.JSON(http.StatusNotFound, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
} else {
|
||||
errormsg := "Error on DB Query or transaction: " + err.Error()
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
}
|
||||
return true // Error
|
||||
}
|
||||
return false // No error
|
||||
}
|
||||
|
||||
|
||||
func GetSimulationID(c *gin.Context) (int, error) {
|
||||
|
||||
simID, err := strconv.Atoi(c.Param("simulationID"))
|
||||
|
||||
if err != nil {
|
||||
errormsg := fmt.Sprintf("Bad request. No or incorrect format of simulation ID")
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
return -1, err
|
||||
} else {
|
||||
return simID, err
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func GetModelID(c *gin.Context) (int, error) {
|
||||
|
||||
modelID, err := strconv.Atoi(c.Param("modelID"))
|
||||
|
||||
if err != nil {
|
||||
errormsg := fmt.Sprintf("Bad request. No or incorrect format of model ID")
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
return -1, err
|
||||
} else {
|
||||
return modelID, err
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func GetVisualizationID(c *gin.Context) (int, error) {
|
||||
|
||||
simID, err := strconv.Atoi(c.Param("visualizationID"))
|
||||
|
||||
if err != nil {
|
||||
errormsg := fmt.Sprintf("Bad request. No or incorrect format of visualization ID")
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
return -1, err
|
||||
} else {
|
||||
return simID, err
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func GetWidgetID(c *gin.Context) (int, error) {
|
||||
|
||||
widgetID, err := strconv.Atoi(c.Param("widgetID"))
|
||||
|
||||
if err != nil {
|
||||
errormsg := fmt.Sprintf("Bad request. No or incorrect format of widget ID")
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
return -1, err
|
||||
} else {
|
||||
return widgetID, err
|
||||
|
||||
}
|
||||
}
|
158
doc/api/api.yaml
158
doc/api/api.yaml
|
@ -17,11 +17,11 @@ tags:
|
|||
- name: simulators
|
||||
description: Manage Simulators
|
||||
- name: projects
|
||||
description: Manage Projects
|
||||
description: (REMOVED) Manage Projects
|
||||
- name: simulations
|
||||
description: Manage Simulations
|
||||
- name: simulationmodels
|
||||
description: Manage SimulationModels
|
||||
- name: models
|
||||
description: Manage Models
|
||||
- name: visualizations
|
||||
description: Manage Visualizations
|
||||
- name: uploads
|
||||
|
@ -244,8 +244,8 @@ paths:
|
|||
get:
|
||||
tags:
|
||||
- files
|
||||
summary: Get files of user
|
||||
operationId: getFilesOfUser
|
||||
summary: (REMOVED) Get files of user
|
||||
operationId: (REMOVED) getFilesOfUser
|
||||
responses:
|
||||
200:
|
||||
description: OK.
|
||||
|
@ -266,8 +266,8 @@ paths:
|
|||
post:
|
||||
tags:
|
||||
- files
|
||||
summary: Add a new file to the database (NEW, was /uploads before))
|
||||
operationId: addFile
|
||||
summary: (REMOVED) Add a new file to the database
|
||||
operationId: (REMOVED) addFile
|
||||
requestBody:
|
||||
description: "File object to be added"
|
||||
required: true
|
||||
|
@ -292,8 +292,8 @@ paths:
|
|||
get:
|
||||
tags:
|
||||
- files
|
||||
summary: Get properties of file with ID FileID
|
||||
operationId: getFileProperties
|
||||
summary: (REMOVED) Get properties of file with ID FileID
|
||||
operationId: (REMOVED) getFileProperties
|
||||
parameters:
|
||||
- in: path
|
||||
name: FileID
|
||||
|
@ -329,8 +329,8 @@ paths:
|
|||
put:
|
||||
tags:
|
||||
- files
|
||||
summary: Update properties of file with ID FileID (NEW)
|
||||
operationId: updateFileProperties
|
||||
summary: (REMOVED) Update properties of file with ID FileID
|
||||
operationId: (REMOVED) updateFileProperties
|
||||
requestBody:
|
||||
description: "File object to be updated"
|
||||
required: true
|
||||
|
@ -361,8 +361,8 @@ paths:
|
|||
delete:
|
||||
tags:
|
||||
- files
|
||||
summary: Delete file with ID FileID
|
||||
operationId: deleteFile
|
||||
summary: (REMOVED) Delete file with ID FileID
|
||||
operationId: (REMOVED) deleteFile
|
||||
parameters:
|
||||
- in: path
|
||||
name: FileID
|
||||
|
@ -385,8 +385,8 @@ paths:
|
|||
get:
|
||||
tags:
|
||||
- projects
|
||||
summary: Get projects of user
|
||||
operationId: getProjects
|
||||
summary: (REMOVED) Get projects of user
|
||||
operationId: (REMOVED) getProjects
|
||||
responses:
|
||||
200:
|
||||
description: OK.
|
||||
|
@ -407,8 +407,8 @@ paths:
|
|||
post:
|
||||
tags:
|
||||
- projects
|
||||
summary: Add a new project to the database
|
||||
operationId: addProject
|
||||
summary: (REMOVED) Add a new project to the database
|
||||
operationId: (REMOVED) addProject
|
||||
requestBody:
|
||||
description: "Project object to add to DB"
|
||||
required: true
|
||||
|
@ -431,8 +431,8 @@ paths:
|
|||
put:
|
||||
tags:
|
||||
- projects
|
||||
summary: Update properties of project with ID ProjectID
|
||||
operationId: updateProjectProperties
|
||||
summary: (REMOVED) Update properties of project with ID ProjectID
|
||||
operationId: (REMOVED) updateProjectProperties
|
||||
parameters:
|
||||
- in: path
|
||||
name: ProjectID
|
||||
|
@ -463,8 +463,8 @@ paths:
|
|||
get:
|
||||
tags:
|
||||
- projects
|
||||
summary: Get properties of project with ID ProjectID
|
||||
operationId: getProjectProperties
|
||||
summary: (REMOVED) Get properties of project with ID ProjectID
|
||||
operationId: (REMOVED) getProjectProperties
|
||||
parameters:
|
||||
- in: path
|
||||
name: ProjectID
|
||||
|
@ -490,8 +490,8 @@ paths:
|
|||
delete:
|
||||
tags:
|
||||
- projects
|
||||
summary: Delete project with ID ProjectID
|
||||
operationId: deleteProject
|
||||
summary: (REMOVED) Delete project with ID ProjectID
|
||||
operationId: (REMOVED) deleteProject
|
||||
parameters:
|
||||
- in: path
|
||||
name: ProjectID
|
||||
|
@ -513,9 +513,9 @@ paths:
|
|||
/models:
|
||||
get:
|
||||
tags:
|
||||
- simulationmodels
|
||||
summary: Get simulation models of user
|
||||
operationId: getSimulationModels
|
||||
- models
|
||||
summary: (REMOVED) Get simulation models of user
|
||||
operationId: (REMOVED) getModels
|
||||
responses:
|
||||
200:
|
||||
description: OK.
|
||||
|
@ -524,7 +524,7 @@ paths:
|
|||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/SimulationModel'
|
||||
$ref: '#/components/schemas/Model'
|
||||
401:
|
||||
description: Unauthorized access.
|
||||
403:
|
||||
|
@ -535,16 +535,16 @@ paths:
|
|||
description: Internal server error.
|
||||
post:
|
||||
tags:
|
||||
- simulationmodels
|
||||
summary: Add a new SimulationModel to the database
|
||||
operationId: addSimulationModel
|
||||
- models
|
||||
summary: (REMOVED) Add a new Model to the database
|
||||
operationId: (REMOVED) addModel
|
||||
requestBody:
|
||||
description: "SimulationModel object to add to DB"
|
||||
description: "Model object to add to DB"
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SimulationModel'
|
||||
$ref: '#/components/schemas/Model'
|
||||
responses:
|
||||
200:
|
||||
description: OK.
|
||||
|
@ -556,26 +556,26 @@ paths:
|
|||
description: Access forbidden.
|
||||
500:
|
||||
description: Internal server error. Unable to save simulation or simulation model.
|
||||
/models/{SimulationModelID}:
|
||||
/models/{ModelID}:
|
||||
put:
|
||||
tags:
|
||||
- simulationmodels
|
||||
summary: Update properties of SimulationModel with ID SimulationModelID
|
||||
operationId: updateSimulationModelProperties
|
||||
- models
|
||||
summary: (REMOVED) Update properties of Model with ID ModelID
|
||||
operationId: (REMOVED) updateModelProperties
|
||||
parameters:
|
||||
- in: path
|
||||
name: SimulationModelID
|
||||
description: ID of a SimulationModel
|
||||
name: ModelID
|
||||
description: ID of a Model
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
requestBody:
|
||||
description: "SimulationModel object with new properties"
|
||||
description: "Model object with new properties"
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SimulationModel'
|
||||
$ref: '#/components/schemas/Model'
|
||||
responses:
|
||||
200:
|
||||
description: OK.
|
||||
|
@ -591,13 +591,13 @@ paths:
|
|||
description: Internal server error. Unable to save simulation model.
|
||||
get:
|
||||
tags:
|
||||
- simulationmodels
|
||||
summary: Get properties of SimulationModel with ID SimulationModelID
|
||||
operationId: getSimulationModelProperties
|
||||
- models
|
||||
summary: (REMOVED) Get properties of Model with ID ModelID
|
||||
operationId: (REMOVED) getModelProperties
|
||||
parameters:
|
||||
- in: path
|
||||
name: SimulationModelID
|
||||
description: ID of a SimulationModel
|
||||
name: ModelID
|
||||
description: ID of a Model
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
|
@ -607,7 +607,7 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SimulationModel'
|
||||
$ref: '#/components/schemas/Model'
|
||||
401:
|
||||
description: Unauthorized access.
|
||||
403:
|
||||
|
@ -618,13 +618,13 @@ paths:
|
|||
description: Internal server error.
|
||||
delete:
|
||||
tags:
|
||||
- simulationmodels
|
||||
summary: Delete SimulationModel with ID SimulationModelID
|
||||
operationId: deleteSimulationModel
|
||||
- models
|
||||
summary: (REMOVED) Delete Model with ID ModelID
|
||||
operationId: (REMOVED) deleteModel
|
||||
parameters:
|
||||
- in: path
|
||||
name: SimulationModelID
|
||||
description: ID of a SimulationModel
|
||||
name: ModelID
|
||||
description: ID of a Model
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
|
@ -639,16 +639,16 @@ paths:
|
|||
description: Not found. Simulation or simulation model not found.
|
||||
500:
|
||||
description: Internal server error. Unable to save changed simulation or to remove simulation model.
|
||||
/models/{SimulationModelID}/file:
|
||||
simulations/{SimulationID}/models/{ModelID}/file:
|
||||
get:
|
||||
tags:
|
||||
- simulationmodels
|
||||
summary: Get file from SimulationModel with ID SimulationModelID (NEW)
|
||||
operationId: getFileFromSimulationModel
|
||||
- simulations
|
||||
summary: (NEW) Get file from Model with ID ModelID
|
||||
operationId: getFileFromModel
|
||||
parameters:
|
||||
- in: path
|
||||
name: SimulationModelID
|
||||
description: ID of a SimulationModel
|
||||
name: ModelID
|
||||
description: ID of a Model
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
|
@ -691,13 +691,13 @@ paths:
|
|||
description: Internal server error.
|
||||
put:
|
||||
tags:
|
||||
- simulationmodels
|
||||
summary: Update (Overwrite) file of SimulationModel with ID SimulationModelID, File object has to be in database (NEW)
|
||||
operationId: updateFileForSimulationModel
|
||||
- simulations
|
||||
summary: (NEW) Update (Overwrite) file of Model with ID ModelID, File object has to be in database
|
||||
operationId: updateFileForModel
|
||||
parameters:
|
||||
- in: path
|
||||
name: SimulationModelID
|
||||
description: ID of a SimulationModel
|
||||
name: ModelID
|
||||
description: ID of a Model
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
|
@ -1035,9 +1035,9 @@ paths:
|
|||
get:
|
||||
tags:
|
||||
- visualizations
|
||||
summary: Get all available visualizations
|
||||
description: Return a JSON representation of all visualizations
|
||||
operationId: getVisualizations
|
||||
summary: (REMOVED) Get all available visualizations
|
||||
description: (REMOVED) Return a JSON representation of all visualizations
|
||||
operationId: (REMOVED) getVisualizations
|
||||
responses:
|
||||
200:
|
||||
description: OK.
|
||||
|
@ -1058,8 +1058,8 @@ paths:
|
|||
post:
|
||||
tags:
|
||||
- visualizations
|
||||
summary: Add a new visualization to the database
|
||||
operationId: addVisualization
|
||||
summary: (REMOVED) Add a new visualization to the database
|
||||
operationId: (REMOVED) addVisualization
|
||||
requestBody:
|
||||
description: "Visualization object to add to DB"
|
||||
required: true
|
||||
|
@ -1084,8 +1084,8 @@ paths:
|
|||
put:
|
||||
tags:
|
||||
- visualizations
|
||||
summary: Update properties of Visualization with ID VisualizationID
|
||||
operationId: updateVisualizationrProperties
|
||||
summary: (REMOVED) Update properties of Visualization with ID VisualizationID
|
||||
operationId: (REMOVED) updateVisualizationrProperties
|
||||
parameters:
|
||||
- in: path
|
||||
name: VisualizationID
|
||||
|
@ -1116,8 +1116,8 @@ paths:
|
|||
get:
|
||||
tags:
|
||||
- visualizations
|
||||
summary: Get properties of Visualization with ID VisualizationID
|
||||
operationId: getVisualizationProperties
|
||||
summary: (REMOVED) Get properties of Visualization with ID VisualizationID
|
||||
operationId: (REMOVED) getVisualizationProperties
|
||||
parameters:
|
||||
- in: path
|
||||
name: VisualizationID
|
||||
|
@ -1143,8 +1143,8 @@ paths:
|
|||
delete:
|
||||
tags:
|
||||
- visualizations
|
||||
summary: Delete Visualization with ID VisualizationID
|
||||
operationId: deleteVisualization
|
||||
summary: (REMOVED) Delete Visualization with ID VisualizationID
|
||||
operationId: (REMOVED) deleteVisualization
|
||||
parameters:
|
||||
- in: path
|
||||
name: VisualizationID
|
||||
|
@ -1167,8 +1167,8 @@ paths:
|
|||
post:
|
||||
tags:
|
||||
- uploads
|
||||
summary: Upload a new file to the database (REMOVED)
|
||||
operationId: uploadFile
|
||||
summary: (REMOVED) Upload a new file to the database
|
||||
operationId: (REMOVED) uploadFile
|
||||
requestBody:
|
||||
description: "File object to upload TODO CHANGE TO FORM"
|
||||
required: true
|
||||
|
@ -1280,7 +1280,7 @@ components:
|
|||
type: integer
|
||||
UserID:
|
||||
type: integer
|
||||
SimulationModelID:
|
||||
ModelID:
|
||||
type: integer
|
||||
Date:
|
||||
type: string
|
||||
|
@ -1309,7 +1309,7 @@ components:
|
|||
RawProperties:
|
||||
type: object
|
||||
properties: {}
|
||||
SimulationModel:
|
||||
Model:
|
||||
required:
|
||||
- Name
|
||||
- OutputLength
|
||||
|
@ -1343,14 +1343,14 @@ components:
|
|||
required:
|
||||
- Name
|
||||
- Unit
|
||||
- SimulationModelID
|
||||
- ModelID
|
||||
type: object
|
||||
properties:
|
||||
Name:
|
||||
type: string
|
||||
Unit:
|
||||
type: string
|
||||
SimulationModelID:
|
||||
ModelID:
|
||||
type: integer
|
||||
Widget:
|
||||
required:
|
||||
|
|
9
doc/autoapi/generateapidoc.sh
Executable file
9
doc/autoapi/generateapidoc.sh
Executable file
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
cd ../../
|
||||
go mod tidy
|
||||
swag init -p pascalcase -g "start.go" -o "./doc/autoapi/"
|
||||
cd -
|
||||
|
||||
redoc-cli bundle --cdn --title "VILLASweb Backend API" --output index.html swagger.yaml
|
28
go.mod
28
go.mod
|
@ -1,26 +1,14 @@
|
|||
module git.rwth-aachen.de/acs/public/villas/villasweb-backend-go
|
||||
|
||||
require (
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20190401154936-ce35bd87d4b3 // indirect
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 // indirect
|
||||
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 // indirect
|
||||
github.com/gin-gonic/gin v1.3.0
|
||||
github.com/go-sql-driver/mysql v1.4.1 // indirect
|
||||
github.com/gofrs/uuid v3.2.0+incompatible // indirect
|
||||
github.com/jinzhu/gorm v1.9.2
|
||||
github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a // indirect
|
||||
github.com/jinzhu/now v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.6 // indirect
|
||||
github.com/kr/pretty v0.1.0 // indirect
|
||||
github.com/lib/pq v1.0.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.7 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.10.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||
github.com/stretchr/testify v1.2.2
|
||||
github.com/ugorji/go v1.1.4 // indirect
|
||||
github.com/gin-gonic/gin v1.4.0
|
||||
github.com/jinzhu/gorm v1.9.8
|
||||
github.com/stretchr/testify v1.3.0
|
||||
github.com/swaggo/gin-swagger v1.1.0
|
||||
github.com/swaggo/swag v1.5.0
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
|
||||
gopkg.in/go-playground/validator.v8 v8.18.2 // indirect
|
||||
)
|
||||
|
||||
replace github.com/ugorji/go v1.1.4 => github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43
|
||||
|
|
138
go.sum
138
go.sum
|
@ -1,25 +1,26 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.37.2 h1:4y4L7BdHenTfZL0HervofNTHh9Ad6mNX72cQvl+5eH0=
|
||||
cloud.google.com/go v0.37.2/go.mod h1:H8IAquKe2L30IxoupDgqTaQvKSwF/c8prYHynGIWQbA=
|
||||
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||
git.apache.org/thrift.git v0.12.0/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||
cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU=
|
||||
cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20190401154936-ce35bd87d4b3 h1:3mNLx0iFqaq/Ssxqkjte26072KMu96uz1VBlbiZhQU4=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20190401154936-ce35bd87d4b3/go.mod h1:EcO5fNtMZHCMjAvj8LE6T+5bphSdR6LQ75n+m1TtsFI=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20190423183735-731ef375ac02 h1:PS3xfVPa8N84AzoWZHFCbA0+ikz4f4skktfjQoNMsgk=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20190423183735-731ef375ac02/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
|
@ -27,49 +28,51 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1
|
|||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
||||
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 h1:t8FVkw33L+wilf2QiWkw0UV77qRpcH/JHPKGpKa2E8g=
|
||||
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
||||
github.com/gin-gonic/gin v1.3.0 h1:kCmZyPklC0gVdL728E6Aj20uYBJV93nj/TkwBTKhFbs=
|
||||
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
|
||||
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/gin-gonic/gin v1.4.0 h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ=
|
||||
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonpointer v0.18.0 h1:KVRzjXpMzgdM4GEMDmDTnGcY5yBwGWreJwmmk4k35yU=
|
||||
github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/jsonreference v0.18.0 h1:oP2OUNdG1l2r5kYhrfVMXO54gWmzcfAwP/GFuHpNTkE=
|
||||
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/spec v0.18.0 h1:aIjeyG5mo5/FrvDkpKKEGZPmF9MPHahS72mzfVqeQXQ=
|
||||
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/swag v0.18.0 h1:1DU8Km1MRGv9Pj7BNLmkA+umwTStwDHttXvx3NhJA70=
|
||||
github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
|
||||
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.6.2/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
|
||||
github.com/jinzhu/gorm v1.9.2 h1:lCvgEaqe/HVE+tjAR2mt4HbbHAZsQOv3XAZiEZV37iw=
|
||||
github.com/jinzhu/gorm v1.9.2/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo=
|
||||
github.com/jinzhu/gorm v1.9.8 h1:n5uvxqLepIP2R1XF7pudpt9Rv8I3m7G9trGxJVjLZ5k=
|
||||
github.com/jinzhu/gorm v1.9.8/go.mod h1:bdqTT3q6dhSph2K3pWxrHP6nqxuAp2yQ3KFtc3U3F84=
|
||||
github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a h1:eeaG9XMUvRBYXJi4pg1ZKM7nxc5AfXfojeLLW7O5J3k=
|
||||
github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.0.0 h1:6WV8LvwPpDhKjo5U9O6b4+xdG/jTXNPwlDme/MTo8Ns=
|
||||
|
@ -84,11 +87,14 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB
|
|||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.0 h1:/5u4a+KGJptBRqGzPvYQL9p0d/tPR4S31+Tnzj9lEO4=
|
||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe h1:W/GaMY0y69G4cFlmsC6B9sbuo2fP8OFP1ABjt4kPz+w=
|
||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
|
||||
|
@ -102,104 +108,97 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
|
|||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||
github.com/openzipkin/zipkin-go v0.1.3/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/swaggo/gin-swagger v1.1.0 h1:ZI6/82S07DkkrMfGKbJhKj1R+QNTICkeAJP06pU36pU=
|
||||
github.com/swaggo/gin-swagger v1.1.0/go.mod h1:FQlm07YuT1glfN3hQiO11UQ2m39vOCZ/aa3WWr5E+XU=
|
||||
github.com/swaggo/swag v1.4.0/go.mod h1:hog2WgeMOrQ/LvQ+o1YGTeT+vWVrbi0SiIslBtxKTyM=
|
||||
github.com/swaggo/swag v1.5.0 h1:haK8VG3hj+v/c8hQ4f3U+oYpkdI/26m9LAUTXHOv+2U=
|
||||
github.com/swaggo/swag v1.5.0/go.mod h1:+xZrnu5Ut3GcUkKAJm9spnOooIS1WB1cUOkLNPrvrE0=
|
||||
github.com/ugorji/go v1.1.2/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
|
||||
github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
||||
go.opencensus.io v0.19.1/go.mod h1:gug0GbSHa8Pafr0d2urOSgoXHZ6x/RUlaiT0d9pqb4A=
|
||||
go.opencensus.io v0.19.2/go.mod h1:NO/8qkisMZLZ1FCsKNqtJPwc8/TaclWyY0B6wcYNg9M=
|
||||
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
||||
golang.org/x/build v0.0.0-20190314133821-5284462c4bec/go.mod h1:atTaCNAy0f16Ah5aV1gMSwgiKVHwu/JncqDpuRr7lS4=
|
||||
github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43 h1:BasDe+IErOQKrMVXab7UayvSlIpiyGwRvuX3EKYY7UA=
|
||||
github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43/go.mod h1:iT03XoTwV7xq/+UGwKO3UbC1nNNlopQiY61beSdrtOA=
|
||||
github.com/ugorji/go/codec v0.0.0-20190320090025-2dc34c0b8780 h1:vG/gY/PxA3v3l04qxe3tDjXyu3bozii8ulSlIPOYKhI=
|
||||
github.com/ugorji/go/codec v0.0.0-20190320090025-2dc34c0b8780/go.mod h1:iT03XoTwV7xq/+UGwKO3UbC1nNNlopQiY61beSdrtOA=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190322120337-addf6b3196f6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181218192612-074acd46bca6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc h1:4gbWbmmPFp4ySWICouJl6emP0MyS31yy9SrTlAGFT+g=
|
||||
golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181219222714-6e267b5cc78e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190110015856-aa033095749b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.0.0-20181220000619-583d854617af/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.2.0/go.mod h1:IfRCZScioGtypHNTlz3gFk67J8uePVW7uDTBzXuIkhU=
|
||||
google.golang.org/api v0.3.0/go.mod h1:IuvZyQh8jgscv8qWfQ4ABd8m7hEudgBFM/EdhA3BnXw=
|
||||
golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89 h1:iWXXYN3edZ3Nd/7I6Rt1sXrWVmhF9bgVtlEJ7BbH124=
|
||||
golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20181219182458-5a97ab628bfb/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
||||
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
|
@ -211,13 +210,10 @@ gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXa
|
|||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||
gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ=
|
||||
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20180920025451-e3ad64cb4ed3/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
|
|
@ -1,46 +1,405 @@
|
|||
package file
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
)
|
||||
|
||||
func FilesRegister(r *gin.RouterGroup) {
|
||||
r.GET("/", filesReadEp)
|
||||
r.POST("/", fileRegistrationEp) // NEW in API
|
||||
r.PUT("/:FileID", fileUpdateEp) // NEW in API
|
||||
r.GET("/:FileID", fileReadEp)
|
||||
r.DELETE("/:FileID", fileDeleteEp)
|
||||
func RegisterFileEndpoints(r *gin.RouterGroup){
|
||||
r.GET("/", GetFiles)
|
||||
r.POST ("/", AddFile)
|
||||
r.GET("/:fileID", GetFile)
|
||||
r.PUT("/:fileID", UpdateFile)
|
||||
r.DELETE("/:fileID", DeleteFile)
|
||||
//r.GET("/:simulationID/visualizations/:visualizationID/widgets/:widgetID/files", GetFilesOfWidget)
|
||||
//r.POST ("/:simulationID/visualizations/:visualizationID/widgets/:widgetID/file", AddFileToWidget)
|
||||
//r.GET("/:simulationID/visualizations/:visualizationID/widgets/:widgetID/file", GetFileOfWidget)
|
||||
//r.PUT("/:simulationID/visualizations/:visualizationID/widgets/:widgetID/file", UpdateFileOfWidget)
|
||||
//r.DELETE("/:simulationID/visualizations/:visualizationID/widgets/:widgetID/file", DeleteFileOfWidget)
|
||||
}
|
||||
|
||||
func filesReadEp(c *gin.Context) {
|
||||
allFiles, _, _ := FindAllFiles()
|
||||
serializer := FilesSerializerNoAssoc{c, allFiles}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"files": serializer.Response(),
|
||||
})
|
||||
|
||||
|
||||
// GetFiles godoc
|
||||
// @Summary Get all files of a specific model or widget
|
||||
// @ID GetFiles
|
||||
// @Tags files
|
||||
// @Produce json
|
||||
// @Success 200 {array} common.FileResponse "File parameters requested by user"
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param originType query string true "Set to model for files of model, set to widget for files of widget"
|
||||
// @Param originID query int true "ID of either model or widget of which files are requested"
|
||||
// @Router /files [get]
|
||||
func GetFiles(c *gin.Context) {
|
||||
|
||||
// TODO if originType == "model" --> GetFilesOfModel, if originType == "vis" --> GetFilesOfWidget
|
||||
|
||||
}
|
||||
|
||||
func fileRegistrationEp(c *gin.Context) {
|
||||
// AddFile godoc
|
||||
// @Summary Add a file to a specific model or widget
|
||||
// @ID AddFile
|
||||
// @Tags files
|
||||
// @Produce json
|
||||
// @Accept text/plain
|
||||
// @Accept png
|
||||
// @Accept jpeg
|
||||
// @Accept gif
|
||||
// @Accept model/x-cim
|
||||
// @Accept model/x-cim.zip
|
||||
// @Success 200 "OK"
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param inputFile formData file true "File to be uploaded"
|
||||
// @Param originType query string true "Set to model for files of model, set to widget for files of widget"
|
||||
// @Param originID query int true "ID of either model or widget of which files are requested"
|
||||
// @Router /files [post]
|
||||
func AddFile(c *gin.Context){
|
||||
// TODO if originType == "model" --> AddFileToModel, if originType == "vis" --> AddFileToWidget
|
||||
}
|
||||
|
||||
// GetFile godoc
|
||||
// @Summary Download a file
|
||||
// @ID GetFile
|
||||
// @Tags files
|
||||
// @Produce text/plain
|
||||
// @Produce png
|
||||
// @Produce jpeg
|
||||
// @Produce gif
|
||||
// @Produce model/x-cim
|
||||
// @Produce model/x-cim.zip
|
||||
// @Success 200 "OK"
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param fileID path int true "ID of the file to download"
|
||||
// @Router /files/{fileID} [get]
|
||||
func GetFile(c *gin.Context){
|
||||
// TODO
|
||||
}
|
||||
|
||||
// UpdateFile godoc
|
||||
// @Summary Update a file
|
||||
// @ID UpdateFile
|
||||
// @Tags files
|
||||
// @Produce json
|
||||
// @Accept text/plain
|
||||
// @Accept png
|
||||
// @Accept jpeg
|
||||
// @Accept gif
|
||||
// @Accept model/x-cim
|
||||
// @Accept model/x-cim.zip
|
||||
// @Success 200 "OK"
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param fileID path int true "ID of the file to update"
|
||||
// @Router /files/{fileID} [put]
|
||||
func UpdateFile(c *gin.Context){
|
||||
|
||||
//TODO parse this info based on fileID parameter
|
||||
simulationID := 1
|
||||
modelID := 1
|
||||
widgetID := 1
|
||||
|
||||
|
||||
// Extract file from PUT request form
|
||||
err := c.Request.ParseForm()
|
||||
if err != nil {
|
||||
errormsg := fmt.Sprintf("Bad request. Get form error: %s", err.Error())
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
file_header, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
errormsg := fmt.Sprintf("Bad request. Get form error: %s", err.Error())
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
filename := filepath.Base(file_header.Filename)
|
||||
filetype := file_header.Header.Get("Content-Type") // TODO make sure this is properly set in file header
|
||||
size := file_header.Size
|
||||
foldername := getFolderName(simulationID, modelID, widgetID)
|
||||
|
||||
err = modifyFileOnDisc(file_header, filename, foldername, uint(size), false)
|
||||
if err != nil {
|
||||
errormsg := fmt.Sprintf("Internal Server Error. Error saving file: %s", err.Error())
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
saveFileInDB(c, filename, foldername, filetype, uint(size), widgetID, modelID, false)
|
||||
}
|
||||
|
||||
|
||||
// DeleteFile godoc
|
||||
// @Summary Delete a file
|
||||
// @ID DeleteFile
|
||||
// @Tags files
|
||||
// @Produce json
|
||||
// @Success 200 "OK"
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param fileID path int true "ID of the file to update"
|
||||
// @Router /files/{fileID} [delete]
|
||||
func DeleteFile(c *gin.Context){
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
func GetFilesOfModel(c *gin.Context) {
|
||||
|
||||
simulationID, modelID, err := getRequestParams(c)
|
||||
if err != nil{
|
||||
return
|
||||
}
|
||||
|
||||
// Find files' properties in DB and return in HTTP response, no change to DB
|
||||
allFiles, _, err := FindFiles(c, -1, modelID, simulationID)
|
||||
|
||||
if common.ProvideErrorResponse(c, err) == false {
|
||||
serializer := common.FilesSerializerNoAssoc{c, allFiles}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"files": serializer.Response(),
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
func AddFileToModel(c *gin.Context) {
|
||||
|
||||
simulationID, modelID, err := getRequestParams(c)
|
||||
if err != nil{
|
||||
return
|
||||
}
|
||||
|
||||
// Save file locally and register file in DB, HTTP response is set by this method
|
||||
RegisterFile(c,-1, modelID, simulationID)
|
||||
|
||||
}
|
||||
|
||||
func CloneFileOfModel(c *gin.Context) {
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func fileUpdateEp(c *gin.Context) {
|
||||
|
||||
func GetFileOfModel(c *gin.Context) {
|
||||
|
||||
simulationID, modelID, err := getRequestParams(c)
|
||||
if err != nil{
|
||||
return
|
||||
}
|
||||
|
||||
// Read file from disk and return in HTTP response, no change to DB
|
||||
ReadFile(c, -1, modelID, simulationID)
|
||||
}
|
||||
|
||||
|
||||
func UpdateFileOfModel(c *gin.Context) {
|
||||
|
||||
//simulationID, modelID, err := getRequestParams(c)
|
||||
//if err != nil{
|
||||
// return
|
||||
//}
|
||||
|
||||
// Update file locally and update file entry in DB, HTTP response is set by this method
|
||||
//UpdateFile(c,-1, modelID, simulationID)
|
||||
}
|
||||
|
||||
func DeleteFileOfModel(c *gin.Context) {
|
||||
|
||||
//simulationID, modelID, err := getRequestParams(c)
|
||||
//if err != nil{
|
||||
// return
|
||||
//}
|
||||
|
||||
// Delete file from disk and remove entry from DB, HTTP response is set by this method
|
||||
//DeleteFile(c, -1, modelID, simulationID)
|
||||
|
||||
|
||||
}
|
||||
|
||||
func GetFilesOfWidget(c *gin.Context) {
|
||||
|
||||
simulationID, widgetID, err := getRequestParams(c)
|
||||
if err != nil{
|
||||
return
|
||||
}
|
||||
|
||||
// Find files' properties in DB and return in HTTP response, no change to DB
|
||||
allFiles, _, err := FindFiles(c, widgetID, -1, simulationID)
|
||||
|
||||
if common.ProvideErrorResponse(c, err) == false {
|
||||
serializer := common.FilesSerializerNoAssoc{c, allFiles}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"files": serializer.Response(),
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
func AddFileToWidget(c *gin.Context) {
|
||||
|
||||
simulationID, widgetID, err := getRequestParams(c)
|
||||
if err != nil{
|
||||
return
|
||||
}
|
||||
|
||||
// Save file locally and register file in DB, HTTP response is set by this method
|
||||
RegisterFile(c,widgetID, -1, simulationID)
|
||||
|
||||
}
|
||||
|
||||
func CloneFileOfWidget(c *gin.Context) {
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func fileReadEp(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
|
||||
func GetFileOfWidget(c *gin.Context) {
|
||||
|
||||
simulationID, widgetID, err := getRequestParams(c)
|
||||
if err != nil{
|
||||
return
|
||||
}
|
||||
|
||||
// Read file from disk and return in HTTP response, no change to DB
|
||||
ReadFile(c, widgetID, -1, simulationID)
|
||||
}
|
||||
|
||||
func fileDeleteEp(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
|
||||
func UpdateFileOfWidget(c *gin.Context) {
|
||||
|
||||
//simulationID, widgetID, err := getRequestParams(c)
|
||||
//if err != nil{
|
||||
// return
|
||||
//}
|
||||
//
|
||||
//// Update file locally and update file entry in DB, HTTP response is set by this method
|
||||
//UpdateFile(c,widgetID, -1, simulationID)
|
||||
}
|
||||
|
||||
|
||||
func DeleteFileOfWidget(c *gin.Context) {
|
||||
|
||||
//simulationID, widgetID, err := getRequestParams(c)
|
||||
//if err != nil{
|
||||
// return
|
||||
//}
|
||||
//
|
||||
//// Delete file from disk and remove entry from DB, HTTP response is set by this method
|
||||
//DeleteFile(c, widgetID, -1, simulationID)
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// local functions
|
||||
|
||||
//func filesReadEp(c *gin.Context) {
|
||||
// // Database query
|
||||
// allFiles, _, err := FindAllFiles()
|
||||
//
|
||||
// if common.ProvideErrorResponse(c, err) == false {
|
||||
// serializer := FilesSerializerNoAssoc{c, allFiles}
|
||||
// c.JSON(http.StatusOK, gin.H{
|
||||
// "files": serializer.Response(),
|
||||
// })
|
||||
// }
|
||||
//
|
||||
//}
|
||||
//
|
||||
//
|
||||
//
|
||||
//func fileUpdateEp(c *gin.Context) {
|
||||
// c.JSON(http.StatusOK, gin.H{
|
||||
// "message": "NOT implemented",
|
||||
// })
|
||||
//}
|
||||
//
|
||||
//func fileReadEp(c *gin.Context) {
|
||||
// var err error
|
||||
// var file common.File
|
||||
// fileID := c.Param("FileID")
|
||||
// desc := c.GetHeader("X-Request-FileDesc")
|
||||
// desc_b, _ := strconv.ParseBool(desc)
|
||||
//
|
||||
// userID := 1 // TODO obtain ID of user making the request
|
||||
//
|
||||
// //check if description of file or file itself shall be returned
|
||||
// if desc_b {
|
||||
// file, err = FindFile(userID, fileID)
|
||||
// if common.ProvideErrorResponse(c, err) == false {
|
||||
// serializer := FileSerializerNoAssoc{c, file}
|
||||
// c.JSON(http.StatusOK, gin.H{
|
||||
// "file": serializer.Response(),
|
||||
// })
|
||||
// }
|
||||
//
|
||||
//
|
||||
// } else {
|
||||
// //TODO: return file itself
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//func fileDeleteEp(c *gin.Context) {
|
||||
// c.JSON(http.StatusOK, gin.H{
|
||||
// "message": "NOT implemented",
|
||||
// })
|
||||
//}
|
||||
|
||||
|
||||
func getRequestParams(c *gin.Context) (int, int, error){
|
||||
simulationID, err := strconv.Atoi(c.Param("SimulationID"))
|
||||
|
||||
if err != nil {
|
||||
errormsg := fmt.Sprintf("Bad request. No or incorrect format of simulation ID")
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
return -1, -1, err
|
||||
}
|
||||
|
||||
var subID int
|
||||
subID, err = common.GetModelID(c)
|
||||
if err != nil{
|
||||
subID, err = common.GetWidgetID(c)
|
||||
if err != nil {
|
||||
return -1, -1, err
|
||||
}
|
||||
}
|
||||
|
||||
return simulationID, subID, err
|
||||
}
|
|
@ -1,19 +1,352 @@
|
|||
package file
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
_ "github.com/gin-gonic/gin"
|
||||
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/model"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulation"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/widget"
|
||||
)
|
||||
|
||||
func FindAllFiles() ([]common.File, int, error) {
|
||||
//func FindAllFiles() ([]common.File, int, error) {
|
||||
// db := common.GetDB()
|
||||
// var files []common.File
|
||||
// err := db.Find(&files).Error
|
||||
// if err != nil {
|
||||
// // print error message to screen
|
||||
// fmt.Println(fmt.Errorf("DB Error in FindAllFiles(): %q", err).Error())
|
||||
// }
|
||||
// return files, len(files), err
|
||||
//}
|
||||
//
|
||||
//func FindUserFiles(user *common.User) ([]common.File, int, error) {
|
||||
// db := common.GetDB()
|
||||
// var files []common.File
|
||||
// err := db.Model(user).Related(&files, "Files").Error
|
||||
// return files, len(files), err
|
||||
//}
|
||||
//
|
||||
//func FindFile(userID int, fileID string) ( common.File, error) {
|
||||
// var file common.File
|
||||
// db := common.GetDB()
|
||||
// fileID_i, _ := strconv.Atoi(fileID)
|
||||
//
|
||||
// err := db.First(&file, fileID_i).Error
|
||||
//
|
||||
// return file, err
|
||||
//
|
||||
//}
|
||||
|
||||
func FindFiles(c *gin.Context, widgetID int, modelID int, simulationID int) ([]common.File, int, error){
|
||||
db := common.GetDB()
|
||||
var files []common.File
|
||||
err := db.Find(&files).Error
|
||||
var err error
|
||||
|
||||
if widgetID != -1 {
|
||||
var w common.Widget
|
||||
err = db.First(&w, widgetID).Error
|
||||
if err != nil {
|
||||
return files, 0, err
|
||||
}
|
||||
err = db.Model(&w).Related(&files, "Files").Error
|
||||
if err != nil {
|
||||
return files, 0, err
|
||||
}
|
||||
|
||||
} else if modelID != -1 {
|
||||
var m common.Model
|
||||
err = db.First(&m, modelID).Error
|
||||
if err != nil {
|
||||
return files, 0, err
|
||||
}
|
||||
err = db.Model(&m).Related(&files, "Files").Error
|
||||
if err != nil {
|
||||
return files, 0, err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return files, len(files), err
|
||||
}
|
||||
|
||||
func FindUserFiles(user *common.User) ([]common.File, int, error) {
|
||||
func FindFileByPath(path string) (common.File, error) {
|
||||
var file common.File
|
||||
db := common.GetDB()
|
||||
var files []common.File
|
||||
err := db.Model(user).Related(&files, "Files").Error
|
||||
return files, len(files), err
|
||||
err := db.Where("Path = ?", path).Find(file).Error
|
||||
|
||||
return file, err
|
||||
}
|
||||
|
||||
func RegisterFile(c *gin.Context, widgetID int, modelID int, simulationID int){
|
||||
|
||||
// Extract file from PUT request form
|
||||
file_header, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
errormsg := fmt.Sprintf("Bad request. Get form error: %s", err.Error())
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
// Obtain properties of file
|
||||
filetype := file_header.Header.Get("Content-Type") // TODO make sure this is properly set in file header
|
||||
filename := filepath.Base(file_header.Filename)
|
||||
foldername := getFolderName(simulationID, modelID, widgetID)
|
||||
size := file_header.Size
|
||||
|
||||
// Check if simulation and widget or model exist in DB
|
||||
_, err = simulation.FindSimulation(simulationID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
if modelID != -1 {
|
||||
_, err = model.FindModel(modelID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
} else if widgetID != -1 {
|
||||
_, err = widget.FindWidget(widgetID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Save file to local disc (NOT DB!)
|
||||
err = modifyFileOnDisc(file_header, filename, foldername, uint(size), true)
|
||||
if err != nil {
|
||||
errormsg := fmt.Sprintf("Internal Server Error. Error saving file: %s", err.Error())
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Add File object with parameters to DB
|
||||
saveFileInDB(c, filename, foldername, filetype, uint(size), widgetID, modelID, true)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
func ReadFile(c *gin.Context, widgetID int, modelID int, simulationID int){
|
||||
|
||||
//contentType := c.GetHeader("Content-Type")
|
||||
|
||||
//TODO currently returns first file it finds in DB
|
||||
|
||||
db := common.GetDB()
|
||||
var fileInDB common.File
|
||||
if widgetID != -1 {
|
||||
// get associated Widget
|
||||
var wdgt common.Widget
|
||||
err := db.First(&wdgt, modelID).Error
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
err = db.Model(&wdgt).Related(&fileInDB).Error
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
} else if modelID != -1 {
|
||||
|
||||
// get associated Simulation Model
|
||||
var model common.Model
|
||||
err := db.First(&model, modelID).Error
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
err = db.Model(&model).Related(&fileInDB).Error
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
//Seems this headers needed for some browsers (for example without this headers Chrome will download files as txt)
|
||||
c.Header("Content-Description", "File Transfer")
|
||||
c.Header("Content-Transfer-Encoding", "binary")
|
||||
c.Header("Content-Disposition", "attachment; filename="+fileInDB.Name )
|
||||
//c.Header("Content-Type", contentType)
|
||||
c.File(fileInDB.Path)
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "OK.",
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
func saveFileInDB(c *gin.Context, filename string, foldername string, filetype string, size uint, widgetID int, modelID int, createObj bool) {
|
||||
|
||||
filesavepath := filepath.Join(foldername, filename)
|
||||
|
||||
// get last modify time of target file
|
||||
fileinfo, err := os.Stat(filesavepath)
|
||||
if err != nil {
|
||||
errormsg := fmt.Sprintf("Internal Server Error. Error stat on file: %s", err.Error())
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
return
|
||||
}
|
||||
modTime := fileinfo.ModTime()
|
||||
|
||||
// Create file object for Database
|
||||
var fileObj common.File
|
||||
fileObj.Size = uint(size)
|
||||
fileObj.Type = filetype
|
||||
fileObj.Path = filesavepath
|
||||
fileObj.Date = modTime
|
||||
fileObj.Name = filename
|
||||
fileObj.ImageHeight = 0
|
||||
fileObj.ImageWidth = 0
|
||||
|
||||
// Check if file shall be associated with Widget or Simulation Model
|
||||
db := common.GetDB()
|
||||
if widgetID != -1 {
|
||||
|
||||
if createObj {
|
||||
// associate to Widget
|
||||
var wdgt common.Widget
|
||||
err := db.First(&wdgt, widgetID).Error
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
err = db.Model(&wdgt).Association("Files").Append(&fileObj).Error
|
||||
} else {
|
||||
// update file obj in DB
|
||||
fileInDB, err := FindFileByPath(filesavepath)
|
||||
if common.ProvideErrorResponse(c, err){
|
||||
return
|
||||
}
|
||||
|
||||
err = db.Model(&fileInDB).Where("Path = ?", filesavepath).Updates(map[string]interface{}{"Size": fileObj.Size, "Date": fileObj.Date, "ImageHeight": fileObj.ImageHeight, "ImageWidth": fileObj.ImageWidth}).Error
|
||||
|
||||
}
|
||||
|
||||
if common.ProvideErrorResponse(c, err) == false {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "OK.",
|
||||
"fileID": fileObj.ID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
if modelID != -1 {
|
||||
|
||||
if createObj {
|
||||
// associate to Simulation Model
|
||||
db := common.GetDB()
|
||||
var model common.Model
|
||||
err := db.First(&model, modelID).Error
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
err = db.Model(&model).Association("Files").Append(&fileObj).Error
|
||||
} else {
|
||||
// update file obj in DB
|
||||
fileInDB, err := FindFileByPath(filesavepath)
|
||||
if common.ProvideErrorResponse(c, err){
|
||||
return
|
||||
}
|
||||
|
||||
err = db.Model(&fileInDB).Where("Path = ?", filesavepath).Updates(map[string]interface{}{"Size": fileObj.Size, "Date": fileObj.Date, "ImageHeight": fileObj.ImageHeight, "ImageWidth": fileObj.ImageWidth}).Error
|
||||
}
|
||||
|
||||
if common.ProvideErrorResponse(c, err) == false {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "OK.",
|
||||
"fileID": fileObj.ID,
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func modifyFileOnDisc(file_header *multipart.FileHeader, filename string, foldername string, size uint, createFile bool) error {
|
||||
|
||||
filesavepath := filepath.Join(foldername, filename)
|
||||
var err error
|
||||
|
||||
if createFile {
|
||||
// Ensure folder with name foldername exists
|
||||
err = os.MkdirAll(foldername, os.ModePerm)
|
||||
} else {
|
||||
// test if file exists
|
||||
_, err = os.Stat(filesavepath)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var open_options int
|
||||
if createFile {
|
||||
// create file it not exists, file MUST not exist
|
||||
open_options = os.O_RDWR|os.O_CREATE|os.O_EXCL
|
||||
} else {
|
||||
open_options = os.O_RDWR
|
||||
}
|
||||
|
||||
fileTarget , err := os.OpenFile(filesavepath, open_options, 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fileTarget.Close()
|
||||
|
||||
// Save file to target path
|
||||
uploadedFile, err := file_header.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer uploadedFile.Close()
|
||||
|
||||
var uploadContent = make([]byte, size)
|
||||
for {
|
||||
|
||||
n, err := uploadedFile.Read(uploadContent)
|
||||
if err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
if n == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
_, err = fileTarget.Write(uploadContent[:n])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
func getFolderName(simulationID int, modelID int, widgetID int) string {
|
||||
base_foldername := "files/"
|
||||
elementname := ""
|
||||
elementid := 0
|
||||
if modelID == -1{
|
||||
elementname = "/widget_"
|
||||
elementid = widgetID
|
||||
} else {
|
||||
elementname = "/model_"
|
||||
elementid = modelID
|
||||
}
|
||||
|
||||
|
||||
foldername := base_foldername + "simulation_"+ strconv.Itoa(simulationID) + elementname + strconv.Itoa(elementid) + "/"
|
||||
return foldername
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
package file
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
)
|
||||
|
||||
// File/s Serializers
|
||||
|
||||
type FilesSerializerNoAssoc struct {
|
||||
Ctx *gin.Context
|
||||
Files []common.File
|
||||
}
|
||||
|
||||
func (self *FilesSerializerNoAssoc) Response() []FileResponseNoAssoc {
|
||||
response := []FileResponseNoAssoc{}
|
||||
for _, files := range self.Files {
|
||||
serializer := FileSerializerNoAssoc{self.Ctx, files}
|
||||
response = append(response, serializer.Response())
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
type FileSerializerNoAssoc struct {
|
||||
Ctx *gin.Context
|
||||
common.File
|
||||
}
|
||||
|
||||
type FileResponseNoAssoc struct {
|
||||
Name string `json:"Name"`
|
||||
ID uint `json:"FileID"`
|
||||
Path string `json:"Path"`
|
||||
Type string `json:"Type"`
|
||||
Size uint `json:"Size"`
|
||||
H uint `json:"ImageHeight"`
|
||||
W uint `json:"ImageWidth"`
|
||||
// Date
|
||||
}
|
||||
|
||||
func (self *FileSerializerNoAssoc) Response() FileResponseNoAssoc {
|
||||
response := FileResponseNoAssoc{
|
||||
Name: self.Name,
|
||||
ID: self.ID,
|
||||
Path: self.Path,
|
||||
Type: self.Type,
|
||||
Size: self.Size,
|
||||
H: self.ImageHeight,
|
||||
W: self.ImageWidth,
|
||||
// Date
|
||||
}
|
||||
return response
|
||||
}
|
355
routes/model/modelEndpoints.go
Normal file
355
routes/model/modelEndpoints.go
Normal file
|
@ -0,0 +1,355 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulator"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func RegisterModelEndpoints(r *gin.RouterGroup){
|
||||
r.GET("/", GetModels)
|
||||
r.POST("/", AddModel)
|
||||
//r.POST("/:modelID", CloneModel)
|
||||
r.PUT("/:modelID", UpdateModel)
|
||||
r.GET("/:modelID", GetModel)
|
||||
r.DELETE("/:modelID", DeleteModel)
|
||||
//r.PUT("/:modelID/simulator", UpdateSimulator)
|
||||
//r.GET("/:modelID/simulator", GetSimulator)
|
||||
//r.POST("/:modelID/signals/:direction", UpdateSignals)
|
||||
//r.GET("/:modelID/signals/:direction", GetSignals)
|
||||
}
|
||||
|
||||
// GetModels godoc
|
||||
// @Summary Get all models of simulation
|
||||
// @ID GetModels
|
||||
// @Produce json
|
||||
// @Tags models
|
||||
// @Success 200 {array} common.ModelResponse "Array of models to which belong to simulation"
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param simulationID query int true "Simulation ID"
|
||||
// @Router /models [get]
|
||||
func GetModels(c *gin.Context) {
|
||||
|
||||
simID, err := common.GetSimulationID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
allModels, _, err := FindAllModels(simID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
serializer := common.ModelsSerializer{c, allModels}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"models": serializer.Response(),
|
||||
})
|
||||
}
|
||||
|
||||
// AddModel godoc
|
||||
// @Summary Add a model to a simulation
|
||||
// @ID AddModel
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Tags models
|
||||
// @Param inputModel body common.ModelResponse true "Model to be added incl. IDs of simulation and simulator"
|
||||
// @Success 200 "OK."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Router /models [post]
|
||||
func AddModel(c *gin.Context) {
|
||||
|
||||
simID, err := common.GetSimulationID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var m Model
|
||||
err = c.BindJSON(&m)
|
||||
if err != nil {
|
||||
errormsg := "Bad request. Error binding form data to JSON: " + err.Error()
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
err = m.addToSimulation(simID)
|
||||
if common.ProvideErrorResponse(c, err) == false {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "OK.",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func CloneModel(c *gin.Context) {
|
||||
|
||||
// modelID, err := routes.GetModelID(c)
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// targetSimID, err := strconv.Atoi(c.PostForm("TargetSim"))
|
||||
// if err != nil {
|
||||
// errormsg := fmt.Sprintf("Bad request. No or incorrect format of target sim ID")
|
||||
// c.JSON(http.StatusBadRequest, gin.H{
|
||||
// "error": errormsg,
|
||||
// })
|
||||
// return
|
||||
// }
|
||||
|
||||
// TODO TO BE IMPLEMENTED
|
||||
// Check if target sim exists
|
||||
// Check if model exists
|
||||
|
||||
// Get all Signals of Model
|
||||
// Get Simulator of Model
|
||||
// Get Files of model
|
||||
|
||||
// Add new model object to DB and associate with target sim
|
||||
// Add new signal objects to DB and associate with new model object (careful with directions)
|
||||
// Associate Simulator with new Model object
|
||||
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "Not implemented.",
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
// UpdateModel godoc
|
||||
// @Summary Update a model
|
||||
// @ID UpdateModel
|
||||
// @Tags models
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param inputModel body common.ModelResponse true "Model to be updated"
|
||||
// @Success 200 "OK."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param modelID path int true "Model ID"
|
||||
// @Router /models/{modelID} [put]
|
||||
func UpdateModel(c *gin.Context) {
|
||||
|
||||
modelID, err := common.GetModelID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var m Model
|
||||
err = c.BindJSON(&m)
|
||||
if err != nil {
|
||||
errormsg := "Bad request. Error binding form data to JSON: " + err.Error()
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
err = m.UpdateModel(modelID)
|
||||
if common.ProvideErrorResponse(c, err) == false {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "OK.",
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// GetModel godoc
|
||||
// @Summary Get a model
|
||||
// @ID GetModel
|
||||
// @Tags models
|
||||
// @Produce json
|
||||
// @Success 200 {object} common.ModelResponse "Requested model."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param modelID path int true "Model ID"
|
||||
// @Router /models/{modelID} [get]
|
||||
func GetModel(c *gin.Context) {
|
||||
|
||||
modelID, err := common.GetModelID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
m, err := FindModel(modelID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
serializer := common.ModelSerializer{c, m}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"model": serializer.Response(),
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteModel godoc
|
||||
// @Summary Delete a model
|
||||
// @ID DeleteModel
|
||||
// @Tags models
|
||||
// @Produce json
|
||||
// @Success 200 "OK."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param modelID path int true "Model ID"
|
||||
// @Router /models/{modelID} [delete]
|
||||
func DeleteModel(c *gin.Context) {
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "Not implemented.",
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
func GetSimulator(c *gin.Context) {
|
||||
|
||||
modelID, err := common.GetModelID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
m, err := FindModel(modelID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
smtr, err := simulator.FindSimulator(int(m.SimulatorID))
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
serializer := common.SimulatorSerializer{c, smtr}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"simulator": serializer.Response(),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
func UpdateSimulator(c *gin.Context) {
|
||||
|
||||
// simulator ID as parameter of Query, e.g. simulations/:SimulationID/models/:ModelID/simulator?simulatorID=42
|
||||
simulatorID, err := strconv.Atoi(c.Query("simulatorID"))
|
||||
if err != nil {
|
||||
errormsg := fmt.Sprintf("Bad request. No or incorrect simulator ID")
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
modelID, err := common.GetModelID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
smtr, err := simulator.FindSimulator(simulatorID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
_m, err := FindModel(modelID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
var m = Model{_m}
|
||||
err = m.UpdateSimulator(&smtr)
|
||||
if common.ProvideErrorResponse(c, err) == false {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "OK",
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
func UpdateSignals(c *gin.Context) {
|
||||
|
||||
modelID, err := common.GetModelID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_m, err := FindModel(modelID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
direction := c.Param("direction")
|
||||
if !(direction == "out") && !(direction == "in") {
|
||||
errormsg := "Bad request. Direction has to be in or out"
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
var sigs []common.Signal
|
||||
err = c.BindJSON(&sigs)
|
||||
if err != nil {
|
||||
errormsg := "Bad request. Error binding form data to JSON: " + err.Error()
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Add signals to model and remove all existing Signals of the requested direction (if any)
|
||||
var m = Model{_m}
|
||||
err = m.UpdateSignals(sigs, direction)
|
||||
if common.ProvideErrorResponse(c, err) == false {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "OK.",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func GetSignals(c *gin.Context) {
|
||||
|
||||
modelID, err := common.GetModelID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
m, err := FindModel(modelID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
direction := c.Param("direction")
|
||||
if !(direction == "out") && !(direction == "in") {
|
||||
errormsg := "Bad request. Direction has to be in or out"
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
var signals []common.Signal
|
||||
if direction == "in" {
|
||||
signals = m.InputMapping
|
||||
} else {
|
||||
signals = m.OutputMapping
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"signals": signals,
|
||||
})
|
||||
}
|
79
routes/model/modelQueries.go
Normal file
79
routes/model/modelQueries.go
Normal file
|
@ -0,0 +1,79 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulation"
|
||||
)
|
||||
|
||||
type Model struct{
|
||||
common.Model
|
||||
}
|
||||
|
||||
func FindAllModels(simID int) ([]common.Model, int, error) {
|
||||
db := common.GetDB()
|
||||
var models []common.Model
|
||||
sim, err := simulation.FindSimulation(simID)
|
||||
if err != nil {
|
||||
return models, 0, err
|
||||
}
|
||||
|
||||
err = db.Order("ID asc").Model(sim).Related(&models, "Models").Error
|
||||
|
||||
return models, len(models), err
|
||||
}
|
||||
|
||||
func FindModel(modelID int) (common.Model, error){
|
||||
db := common.GetDB()
|
||||
var m common.Model
|
||||
err := db.First(&m, modelID).Error
|
||||
return m, err
|
||||
}
|
||||
|
||||
func (m *Model) addToSimulation(simID int) error {
|
||||
db := common.GetDB()
|
||||
sim, err := simulation.FindSimulation(simID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = db.Create(m).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = db.Model(&sim).Association("Models").Append(m).Error
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *Model) UpdateModel(modelID int) error {
|
||||
db := common.GetDB()
|
||||
model_to_update, err := FindModel(modelID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// only Name and Start Params can be updated directly by the user
|
||||
err = db.Model(&model_to_update).Updates(map[string]interface{}{"Name": m.Name, "StartParameters": m.StartParameters}).Error
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
func (m *Model) UpdateSimulator(simulator *common.Simulator) error {
|
||||
db := common.GetDB()
|
||||
err := db.Model(m).Association("Simulator").Replace(simulator).Error
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *Model) UpdateSignals(signals []common.Signal, direction string) error {
|
||||
|
||||
db := common.GetDB()
|
||||
var err error
|
||||
|
||||
if direction == "in" {
|
||||
err = db.Model(m).Select("InputMapping").Update("InputMapping", signals).Error
|
||||
} else {
|
||||
err = db.Model(m).Select("OutputMapping").Update("OutputMapping", signals).Error
|
||||
}
|
||||
|
||||
return err
|
||||
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
package project
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func ProjectsRegister(r *gin.RouterGroup) {
|
||||
r.GET("/", projectsReadEp)
|
||||
r.POST("/", projectRegistrationEp)
|
||||
r.PUT("/:ProjectID", projectUpdateEp)
|
||||
r.GET("/:ProjectID", projectReadEp)
|
||||
r.DELETE("/:ProjectID", projectDeleteEp)
|
||||
}
|
||||
|
||||
func projectsReadEp(c *gin.Context) {
|
||||
allProjects, _, _ := FindAllProjects()
|
||||
serializer := ProjectsSerializerNoAssoc{c, allProjects}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"projects": serializer.Response(),
|
||||
})
|
||||
}
|
||||
|
||||
func projectRegistrationEp(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
||||
func projectUpdateEp(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
||||
func projectReadEp(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
||||
func projectDeleteEp(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package project
|
||||
|
||||
import (
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
)
|
||||
|
||||
func FindAllProjects() ([]common.Project, int, error) {
|
||||
db := common.GetDB()
|
||||
var projects []common.Project
|
||||
err := db.Find(&projects).Error
|
||||
return projects, len(projects), err
|
||||
}
|
||||
|
||||
func FindUserProjects(user *common.User) ([]common.Project, int, error) {
|
||||
db := common.GetDB()
|
||||
var projects []common.Project
|
||||
err := db.Model(user).Related(&projects, "Projects").Error
|
||||
return projects, len(projects), err
|
||||
}
|
||||
|
||||
func FindVisualizationProject(visualization *common.Visualization) (common.Project, int, error) {
|
||||
db := common.GetDB()
|
||||
var project common.Project
|
||||
err := db.Model(visualization).Related(&project, "Projects").Error
|
||||
return project, 1, err
|
||||
}
|
||||
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
package project
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
)
|
||||
|
||||
type ProjectsSerializerNoAssoc struct {
|
||||
Ctx *gin.Context
|
||||
Projects []common.Project
|
||||
}
|
||||
|
||||
func (self *ProjectsSerializerNoAssoc) Response() []ProjectResponseNoAssoc {
|
||||
response := []ProjectResponseNoAssoc{}
|
||||
for _, project := range self.Projects {
|
||||
serializer := ProjectSerializerNoAssoc{self.Ctx, project}
|
||||
response = append(response, serializer.Response())
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
type ProjectSerializerNoAssoc struct {
|
||||
Ctx *gin.Context
|
||||
common.Project
|
||||
}
|
||||
|
||||
type ProjectResponseNoAssoc struct {
|
||||
Name string `json:"Name"`
|
||||
ID uint `json:"ProjectID"`
|
||||
}
|
||||
|
||||
func (self *ProjectSerializerNoAssoc) Response() ProjectResponseNoAssoc {
|
||||
response := ProjectResponseNoAssoc{
|
||||
Name: self.Name,
|
||||
ID: self.ID,
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
package signal
|
||||
|
||||
|
||||
//TODO extend API with signal endpoints
|
|
@ -1,3 +0,0 @@
|
|||
package signal
|
||||
|
||||
//TODO extend API with signal endpoints
|
|
@ -1,3 +0,0 @@
|
|||
package signal
|
||||
|
||||
//TODO extend API with signal endpoints
|
|
@ -1,47 +1,258 @@
|
|||
package simulation
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/user"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
)
|
||||
|
||||
func SimulationsRegister(r *gin.RouterGroup) {
|
||||
r.GET("/", simulationsReadEp)
|
||||
r.POST("/", simulationRegistrationEp)
|
||||
r.PUT("/:SimulationID", simulationUpdateEp)
|
||||
r.GET("/:SimulationID", simulationReadEp)
|
||||
r.DELETE("/:SimulationID", simulationDeleteEp)
|
||||
func RegisterSimulationEndpoints(r *gin.RouterGroup){
|
||||
r.GET("/", GetSimulations)
|
||||
r.POST("/", AddSimulation)
|
||||
//r.POST("/:simulationID", CloneSimulation)
|
||||
r.PUT("/:simulationID", UpdateSimulation)
|
||||
r.GET("/:simulationID", GetSimulation)
|
||||
r.DELETE("/:simulationID", DeleteSimulation)
|
||||
|
||||
r.GET("/:simulationID/users", GetUsersOfSimulation)
|
||||
r.PUT("/:simulationID/user", AddUserToSimulation)
|
||||
r.DELETE("/:simulationID/user", DeleteUserFromSimulation)
|
||||
}
|
||||
|
||||
func simulationsReadEp(c *gin.Context) {
|
||||
// GetSimulations godoc
|
||||
// @Summary Get all simulations
|
||||
// @ID GetSimulations
|
||||
// @Produce json
|
||||
// @Tags simulations
|
||||
// @Success 200 {array} common.SimulationResponse "Array of simulations to which user has access"
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Router /simulations [get]
|
||||
func GetSimulations(c *gin.Context) {
|
||||
|
||||
//TODO Identify user who is issuing the request and return only those simulations that are known to the user
|
||||
|
||||
allSimulations, _, _ := FindAllSimulations()
|
||||
serializer := SimulationsSerializerNoAssoc{c, allSimulations}
|
||||
serializer := common.SimulationsSerializer{c, allSimulations}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"simulations": serializer.Response(),
|
||||
})
|
||||
}
|
||||
|
||||
func simulationRegistrationEp(c *gin.Context) {
|
||||
// AddSimulation godoc
|
||||
// @Summary Add a simulation
|
||||
// @ID AddSimulation
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Tags simulations
|
||||
// @Param inputModel body common.ModelResponse true "Simulation to be added"
|
||||
// @Success 200 "OK."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Router /simulations [post]
|
||||
func AddSimulation(c *gin.Context) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
func CloneSimulation(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
||||
func simulationUpdateEp(c *gin.Context) {
|
||||
// UpdateSimulation godoc
|
||||
// @Summary Update a simulation
|
||||
// @ID UpdateSimulation
|
||||
// @Tags simulations
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param inputSimulation body common.SimulationResponse true "Simulation to be updated"
|
||||
// @Success 200 "OK."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param simulationID path int true "Simulation ID"
|
||||
// @Router /simulations/{simulationID} [put]
|
||||
func UpdateSimulation(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
||||
func simulationReadEp(c *gin.Context) {
|
||||
// GetSimulation godoc
|
||||
// @Summary Get simulation
|
||||
// @ID GetSimulation
|
||||
// @Produce json
|
||||
// @Tags simulations
|
||||
// @Success 200 {object} common.SimulationResponse "Simulation requested by user"
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param simulationID path int true "Simulation ID"
|
||||
// @Router /simulations/{simulationID} [get]
|
||||
func GetSimulation(c *gin.Context) {
|
||||
|
||||
simID, err := common.GetSimulationID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sim, err := FindSimulation(simID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
serializer := common.SimulationSerializer{c, sim}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"simulation": serializer.Response(),
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteSimulation godoc
|
||||
// @Summary Delete a simulation
|
||||
// @ID DeleteSimulation
|
||||
// @Tags simulations
|
||||
// @Produce json
|
||||
// @Success 200 "OK."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param simulationID path int true "Simulation ID"
|
||||
// @Router /simulations/{simulationID} [delete]
|
||||
func DeleteSimulation(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
||||
func simulationDeleteEp(c *gin.Context) {
|
||||
|
||||
// GetUsersOfSimulation godoc
|
||||
// @Summary Get users of simulation
|
||||
// @ID GetUsersOfSimulation
|
||||
// @Produce json
|
||||
// @Tags simulations
|
||||
// @Success 200 {array} common.UserResponse "Array of users that have access to the simulation"
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param simulationID path int true "Simulation ID"
|
||||
// @Router /simulations/{simulationID}/users/ [get]
|
||||
func GetUsersOfSimulation(c *gin.Context) {
|
||||
|
||||
simID, err := common.GetSimulationID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sim, err := FindSimulation(simID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
// Find all users of simulation
|
||||
allUsers, _, err := user.FindAllUsersSim(&sim)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
serializer := common.UsersSerializer{c, allUsers}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
"users": serializer.Response(false),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// AddUserToSimulation godoc
|
||||
// @Summary Add a user to a a simulation
|
||||
// @ID AddUserToSimulation
|
||||
// @Tags simulations
|
||||
// @Produce json
|
||||
// @Success 200 "OK."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param simulationID path int true "Simulation ID"
|
||||
// @Param username query string true "User name"
|
||||
// @Router /simulations/{simulationID}/user [put]
|
||||
func AddUserToSimulation(c *gin.Context) {
|
||||
simID, err := common.GetSimulationID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sim, err := FindSimulation(simID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
querydata := c.Request.URL.Query()
|
||||
|
||||
username := querydata.Get("username")
|
||||
|
||||
u, err := user.FindUserByName(username)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
err = user.AddUserToSim(&sim, &u)
|
||||
if common.ProvideErrorResponse(c, err){
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "OK.",
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteUserFromSimulation godoc
|
||||
// @Summary Delete a user from a simulation
|
||||
// @ID DeleteUserFromSimulation
|
||||
// @Tags simulations
|
||||
// @Produce json
|
||||
// @Success 200 "OK."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param simulationID path int true "Simulation ID"
|
||||
// @Param username query string true "User name"
|
||||
// @Router /simulations/{simulationID}/user [delete]
|
||||
func DeleteUserFromSimulation(c *gin.Context) {
|
||||
simID, err := common.GetSimulationID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sim, err := FindSimulation(simID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
querydata := c.Request.URL.Query()
|
||||
|
||||
username := querydata.Get("username")
|
||||
|
||||
err = user.RemoveUserFromSim(&sim, username)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "OK.",
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -4,16 +4,27 @@ import (
|
|||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
)
|
||||
|
||||
type Simulation struct{
|
||||
common.Simulation
|
||||
}
|
||||
|
||||
func FindAllSimulations() ([]common.Simulation, int, error) {
|
||||
db := common.GetDB()
|
||||
var simulations []common.Simulation
|
||||
err := db.Find(&simulations).Error
|
||||
err := db.Order("ID asc").Find(&simulations).Error
|
||||
return simulations, len(simulations), err
|
||||
}
|
||||
|
||||
func FindUserSimulations(user *common.User) ([]common.Simulation, int, error) {
|
||||
db := common.GetDB()
|
||||
var simulations []common.Simulation
|
||||
err := db.Model(user).Related(&simulations, "Simulations").Error
|
||||
err := db.Order("ID asc").Model(user).Related(&simulations, "Simulations").Error
|
||||
return simulations, len(simulations), err
|
||||
}
|
||||
|
||||
func FindSimulation(simID int) (common.Simulation, error) {
|
||||
db := common.GetDB()
|
||||
var sim common.Simulation
|
||||
err := db.First(&sim, simID).Error
|
||||
return sim, err
|
||||
}
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
package simulation
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
)
|
||||
|
||||
type SimulationsSerializerNoAssoc struct {
|
||||
Ctx *gin.Context
|
||||
Simulations []common.Simulation
|
||||
}
|
||||
|
||||
func (self *SimulationsSerializerNoAssoc) Response() []SimulationResponseNoAssoc {
|
||||
response := []SimulationResponseNoAssoc{}
|
||||
for _, simulation := range self.Simulations {
|
||||
serializer := SimulationSerializerNoAssoc{self.Ctx, simulation}
|
||||
response = append(response, serializer.Response())
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
type SimulationSerializerNoAssoc struct {
|
||||
Ctx *gin.Context
|
||||
common.Simulation
|
||||
}
|
||||
|
||||
type SimulationResponseNoAssoc struct {
|
||||
Name string `json:"Name"`
|
||||
ID uint `json:"SimulationID"`
|
||||
Running bool `json:"Running"`
|
||||
//StartParams postgres.Jsonb `json:"Starting Parameters"`
|
||||
}
|
||||
|
||||
func (self *SimulationSerializerNoAssoc) Response() SimulationResponseNoAssoc {
|
||||
response := SimulationResponseNoAssoc{
|
||||
Name: self.Name,
|
||||
ID: self.ID,
|
||||
Running: self.Running,
|
||||
//StartParams: self.StartParameters,
|
||||
}
|
||||
return response
|
||||
}
|
127
routes/simulation/simulation_test.go
Normal file
127
routes/simulation/simulation_test.go
Normal file
|
@ -0,0 +1,127 @@
|
|||
package simulation
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
)
|
||||
|
||||
|
||||
var msgOK = common.ResponseMsg{
|
||||
Message: "OK.",
|
||||
}
|
||||
|
||||
|
||||
var user_A = common.UserResponse{
|
||||
Username: "User_A",
|
||||
Role: "user",
|
||||
Mail: "",
|
||||
}
|
||||
|
||||
var user_B = common.UserResponse{
|
||||
Username: "User_B",
|
||||
Role: "user",
|
||||
Mail: "",
|
||||
}
|
||||
|
||||
var myUsers = []common.UserResponse{
|
||||
user_A,
|
||||
user_B,
|
||||
}
|
||||
|
||||
var msgUsers = common.ResponseMsgUsers{
|
||||
Users: myUsers,
|
||||
}
|
||||
|
||||
|
||||
var simulationA = common.SimulationResponse{
|
||||
Name: "Simulation_A",
|
||||
ID: 1,
|
||||
Running: false,
|
||||
}
|
||||
|
||||
var simulationB = common.SimulationResponse{
|
||||
Name: "Simulation_B",
|
||||
ID: 2,
|
||||
Running: false,
|
||||
}
|
||||
|
||||
var mySimulations = []common.SimulationResponse{
|
||||
simulationA,
|
||||
simulationB,
|
||||
}
|
||||
|
||||
var msgSimulations = common.ResponseMsgSimulations{
|
||||
Simulations: mySimulations,
|
||||
}
|
||||
|
||||
var msgSimulation = common.ResponseMsgSimulation{
|
||||
Simulation: simulationA,
|
||||
}
|
||||
|
||||
// Test /simulation endpoints
|
||||
func TestSimulationEndpoints(t *testing.T) {
|
||||
|
||||
db := common.DummyInitDB()
|
||||
defer db.Close()
|
||||
common.DummyPopulateDB(db)
|
||||
|
||||
|
||||
router := gin.Default()
|
||||
api := router.Group("/api")
|
||||
RegisterSimulationEndpoints(api.Group("/simulations"))
|
||||
|
||||
msgOKjson, err := json.Marshal(msgOK)
|
||||
if err !=nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
msgUsersjson, err := json.Marshal(msgUsers)
|
||||
if err !=nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
msgSimulationsjson, err := json.Marshal(msgSimulations)
|
||||
if err !=nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
msgSimulationjson, err := json.Marshal(msgSimulation)
|
||||
if err !=nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// test GET simulations/
|
||||
testEndpoint(t, router, "/api/simulations/", "GET", "", 200, string(msgSimulationsjson))
|
||||
|
||||
// test GET simulations/:SimulationID
|
||||
testEndpoint(t, router, "/api/simulations/1", "GET", "", 200, string(msgSimulationjson))
|
||||
|
||||
// test GET simulations/:SimulationID/users
|
||||
testEndpoint(t, router, "/api/simulations/1/users", "GET", "", 200, string(msgUsersjson))
|
||||
|
||||
// test DELETE simulations/:SimulationID/user
|
||||
testEndpoint(t, router, "/api/simulations/1/user?username=User_A", "DELETE", "", 200, string(msgOKjson))
|
||||
|
||||
// test PUT simulations/:SimulationID/user
|
||||
testEndpoint(t, router, "/api/simulations/1/user?username=User_A", "PUT", "", 200, string(msgOKjson))
|
||||
|
||||
// TODO add more tests
|
||||
}
|
||||
|
||||
|
||||
func testEndpoint(t *testing.T, router *gin.Engine, url string, method string, body string, expected_code int, expected_response string ) {
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(method, url, nil)
|
||||
router.ServeHTTP(w, req)
|
||||
assert.Equal(t, expected_code, w.Code)
|
||||
fmt.Println(w.Body.String())
|
||||
assert.Equal(t, expected_response, w.Body.String())
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
package simulationmodel
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func SimulationModelsRegister(r *gin.RouterGroup) {
|
||||
r.GET("/", simulationmodelsReadEp)
|
||||
r.POST("/", simulationmodelRegistrationEp)
|
||||
r.PUT("/:SimulationModelID", simulationmodelUpdateEp)
|
||||
r.GET("/:SimulationModelID", simulationmodelReadEp)
|
||||
r.DELETE("/:SimulationModelID", simulationmodelDeleteEp)
|
||||
r.GET("/:SimulationModelID/file", simulationmodelReadFileEp) // NEW in API
|
||||
r.PUT("/:SimulationModelID/file", simulationmodelUpdateFileEp) // NEW in API
|
||||
}
|
||||
|
||||
func simulationmodelsReadEp(c *gin.Context) {
|
||||
allSimulationModels, _, _ := FindAllSimulationModels()
|
||||
serializer := SimulationModelsSerializerNoAssoc{c, allSimulationModels}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"simulationmodels": serializer.Response(),
|
||||
})
|
||||
}
|
||||
|
||||
func simulationmodelRegistrationEp(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
||||
func simulationmodelUpdateEp(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
||||
func simulationmodelReadEp(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
||||
func simulationmodelDeleteEp(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
||||
func simulationmodelReadFileEp(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
||||
func simulationmodelUpdateFileEp(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
package simulationmodel
|
||||
|
||||
import (
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
)
|
||||
|
||||
func FindAllSimulationModels() ([]common.SimulationModel, int, error) {
|
||||
db := common.GetDB()
|
||||
var simulationmodels []common.SimulationModel
|
||||
err := db.Find(&simulationmodels).Error
|
||||
return simulationmodels, len(simulationmodels), err
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
package simulationmodel
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
)
|
||||
|
||||
type SimulationModelsSerializerNoAssoc struct {
|
||||
Ctx *gin.Context
|
||||
SimulationModels []common.SimulationModel
|
||||
}
|
||||
|
||||
func (self *SimulationModelsSerializerNoAssoc) Response() []SimulationModelResponseNoAssoc {
|
||||
response := []SimulationModelResponseNoAssoc{}
|
||||
for _, simulationmodel := range self.SimulationModels {
|
||||
serializer := SimulationModelSerializerNoAssoc{self.Ctx, simulationmodel}
|
||||
response = append(response, serializer.Response())
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
type SimulationModelSerializerNoAssoc struct {
|
||||
Ctx *gin.Context
|
||||
common.SimulationModel
|
||||
}
|
||||
|
||||
type SimulationModelResponseNoAssoc struct {
|
||||
Name string `json:"Name"`
|
||||
OutputLength int `json:"OutputLength"`
|
||||
InputLength int `json:"InputLength"`
|
||||
BelongsToSimulationID uint `json:"BelongsToSimulationID"`
|
||||
BelongsToSimulatorID uint `json:"BelongsToSimulatiorID"`
|
||||
//StartParams postgres.Jsonb `json:"Starting Parameters"`
|
||||
//Output Mapping
|
||||
//Input Mapping
|
||||
}
|
||||
|
||||
func (self *SimulationModelSerializerNoAssoc) Response() SimulationModelResponseNoAssoc {
|
||||
response := SimulationModelResponseNoAssoc{
|
||||
Name: self.Name,
|
||||
OutputLength: self.OutputLength,
|
||||
InputLength: self.InputLength,
|
||||
BelongsToSimulationID: self.BelongsToSimulationID,
|
||||
BelongsToSimulatorID: self.BelongsToSimulatorID,
|
||||
//StartParams: self.StartParameters,
|
||||
//InputMapping
|
||||
//OutputMapping
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
|
@ -1,53 +1,134 @@
|
|||
package simulator
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
)
|
||||
|
||||
func SimulatorsRegister(r *gin.RouterGroup) {
|
||||
r.GET("/", simulatorsReadEp)
|
||||
r.POST("/", simulatorRegistrationEp)
|
||||
r.PUT("/:SimulatorID", simulatorUpdateEp)
|
||||
r.GET("/:SimulatorID", simulatorReadEp)
|
||||
r.DELETE("/:SimulatorID", simulatorDeleteEp)
|
||||
r.POST("/:SimulatorID", simulatorSendActionEp)
|
||||
func RegisterSimulatorEndpoints(r *gin.RouterGroup){
|
||||
r.GET("/", GetSimulators)
|
||||
r.POST("/", AddSimulator)
|
||||
r.PUT("/:simulatorID", UpdateSimulator)
|
||||
r.GET("/:simulatorID", GetSimulator)
|
||||
r.DELETE("/:simulatorID", DeleteSimulator)
|
||||
r.POST("/:simulatorID/action", SendActionToSimulator)
|
||||
}
|
||||
|
||||
func simulatorsReadEp(c *gin.Context) {
|
||||
// GetSimulators godoc
|
||||
// @Summary Get all simulators
|
||||
// @ID GetSimulators
|
||||
// @Tags simulators
|
||||
// @Produce json
|
||||
// @Success 200 {array} common.SimulatorResponse "Simulator parameters requested by user"
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Router /simulators [get]
|
||||
func GetSimulators(c *gin.Context) {
|
||||
allSimulators, _, _ := FindAllSimulators()
|
||||
serializer := SimulatorsSerializer{c, allSimulators}
|
||||
serializer := common.SimulatorsSerializer{c, allSimulators}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"simulators": serializer.Response(),
|
||||
})
|
||||
}
|
||||
|
||||
func simulatorRegistrationEp(c *gin.Context) {
|
||||
// AddSimulator godoc
|
||||
// @Summary Add a simulator
|
||||
// @ID AddSimulator
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Tags simulators
|
||||
// @Param inputSimulator body common.SimulatorResponse true "Simulator to be added"
|
||||
// @Success 200 "OK."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Router /simulators [post]
|
||||
func AddSimulator(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
||||
func simulatorUpdateEp(c *gin.Context) {
|
||||
|
||||
// UpdateSimulator godoc
|
||||
// @Summary Update a simulator
|
||||
// @ID UpdateSimulator
|
||||
// @Tags simulators
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param inputSimulator body common.SimulatorResponse true "Simulator to be updated"
|
||||
// @Success 200 "OK."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param simulatorID path int true "Simulator ID"
|
||||
// @Router /simulators/{simulatorID} [put]
|
||||
func UpdateSimulator(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
||||
func simulatorReadEp(c *gin.Context) {
|
||||
// GetSimulator godoc
|
||||
// @Summary Get simulator
|
||||
// @ID GetSimulator
|
||||
// @Produce json
|
||||
// @Tags simulators
|
||||
// @Success 200 {object} common.SimulatorResponse "Simulator requested by user"
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param simulatorID path int true "Simulator ID"
|
||||
// @Router /simulators/{simulatorID} [get]
|
||||
func GetSimulator(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
||||
func simulatorDeleteEp(c *gin.Context) {
|
||||
// DeleteSimulator godoc
|
||||
// @Summary Delete a simulator
|
||||
// @ID DeleteSimulator
|
||||
// @Tags simulators
|
||||
// @Produce json
|
||||
// @Success 200 "OK."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param simulatorID path int true "Simulator ID"
|
||||
// @Router /simulators/{simulatorID} [delete]
|
||||
func DeleteSimulator(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
||||
func simulatorSendActionEp(c *gin.Context) {
|
||||
// SendActionToSimulator godoc
|
||||
// @Summary Send an action to simulator
|
||||
// @ID SendActionToSimulator
|
||||
// @Tags simulators
|
||||
// @Produce json
|
||||
// @Param inputAction query string true "Action for simulator"
|
||||
// @Success 200 "OK."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param simulatorID path int true "Simulator ID"
|
||||
// @Router /simulators/{simulatorID}/action [post]
|
||||
func SendActionToSimulator(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -7,7 +7,14 @@ import (
|
|||
func FindAllSimulators() ([]common.Simulator, int, error) {
|
||||
db := common.GetDB()
|
||||
var simulators []common.Simulator
|
||||
err := db.Find(&simulators).Error
|
||||
err := db.Order("ID asc").Find(&simulators).Error
|
||||
return simulators, len(simulators), err
|
||||
}
|
||||
|
||||
func FindSimulator(simulatorID int) (common.Simulator, error) {
|
||||
db := common.GetDB()
|
||||
var simulator common.Simulator
|
||||
err := db.First(&simulator, simulatorID).Error
|
||||
return simulator, err
|
||||
}
|
||||
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
package simulator
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
)
|
||||
|
||||
type SimulatorsSerializer struct {
|
||||
Ctx *gin.Context
|
||||
Simulators []common.Simulator
|
||||
}
|
||||
|
||||
func (self *SimulatorsSerializer) Response() []SimulatorResponse {
|
||||
response := []SimulatorResponse{}
|
||||
for _, simulator := range self.Simulators {
|
||||
serializer := SimulatorSerializer{self.Ctx, simulator}
|
||||
response = append(response, serializer.Response())
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
type SimulatorSerializer struct {
|
||||
Ctx *gin.Context
|
||||
common.Simulator
|
||||
}
|
||||
|
||||
type SimulatorResponse struct {
|
||||
UUID string `json:"UUID"`
|
||||
Host string `json:"Host"`
|
||||
ModelType string `json:"ModelType"`
|
||||
Uptime int `json:"Uptime"`
|
||||
State string `json:"State"`
|
||||
StateUpdateAt time.Time `json:"StateUpdateAt"`
|
||||
// Properties
|
||||
// Raw Properties
|
||||
}
|
||||
|
||||
func (self *SimulatorSerializer) Response() SimulatorResponse {
|
||||
|
||||
response := SimulatorResponse{
|
||||
UUID: self.UUID,
|
||||
Host: self.Host,
|
||||
ModelType: self.Modeltype,
|
||||
Uptime: self.Uptime,
|
||||
State: self.State,
|
||||
StateUpdateAt: self.StateUpdateAt,
|
||||
}
|
||||
return response
|
||||
}
|
|
@ -8,6 +8,8 @@ import (
|
|||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
)
|
||||
|
||||
// TODO: the signing secret must be environmental variable
|
||||
|
@ -20,19 +22,37 @@ type tokenClaims struct {
|
|||
jwt.StandardClaims
|
||||
}
|
||||
|
||||
type AuthResponse struct{
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message"`
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
// `/authenticate` endpoint does not require Authentication
|
||||
func VisitorAuthenticate(r *gin.RouterGroup) {
|
||||
r.POST("", authenticationEp)
|
||||
}
|
||||
|
||||
func UsersRegister(r *gin.RouterGroup) {
|
||||
r.POST("", userRegistrationEp)
|
||||
r.PUT("/:UserID", userUpdateEp)
|
||||
r.GET("", usersReadEp)
|
||||
r.GET("/:UserID", userReadEp)
|
||||
r.DELETE("/:UserID", userDeleteEp)
|
||||
func RegisterUserEndpoints(r *gin.RouterGroup) {
|
||||
r.POST("", addUser)
|
||||
r.PUT("/:UserID", updateUser)
|
||||
r.GET("", getUsers)
|
||||
r.GET("/:UserID", getUser)
|
||||
r.DELETE("/:UserID", deleteUser)
|
||||
}
|
||||
|
||||
// authenticationEp godoc
|
||||
// @Summary Authentication for user
|
||||
// @ID authenticationEp
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Tags users
|
||||
// @Param inputUser body user.Credentials true "Credentials of user"
|
||||
// @Success 200 {object} user.AuthResponse "JSON web token and message"
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 422 "Unprocessable entity."
|
||||
// @Router /authenticate [post]
|
||||
func authenticationEp(c *gin.Context) {
|
||||
|
||||
// Bind the response (context) with the Credentials struct
|
||||
|
@ -101,7 +121,18 @@ func authenticationEp(c *gin.Context) {
|
|||
})
|
||||
}
|
||||
|
||||
func usersReadEp(c *gin.Context) {
|
||||
// GetUsers godoc
|
||||
// @Summary Get all users
|
||||
// @ID GetUsers
|
||||
// @Produce json
|
||||
// @Tags users
|
||||
// @Success 200 {array} common.UserResponse "Array of users"
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Router /users [get]
|
||||
func getUsers(c *gin.Context) {
|
||||
//// dummy TODO: check in the middleware if the user is authorized
|
||||
//authorized := false
|
||||
//// TODO: move this redirect in the authentication middleware
|
||||
|
@ -110,13 +141,26 @@ func usersReadEp(c *gin.Context) {
|
|||
//return
|
||||
//}
|
||||
allUsers, _, _ := FindAllUsers()
|
||||
serializer := UsersSerializer{c, allUsers}
|
||||
serializer := common.UsersSerializer{c, allUsers}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"users": serializer.Response(true),
|
||||
})
|
||||
}
|
||||
|
||||
func userRegistrationEp(c *gin.Context) {
|
||||
// AddUser godoc
|
||||
// @Summary Add a user
|
||||
// @ID AddUser
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Tags users
|
||||
// @Param inputUser body common.UserResponse true "User to be added"
|
||||
// @Success 200 "OK."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Router /users [post]
|
||||
func addUser(c *gin.Context) {
|
||||
|
||||
// Bind the response (context) with the User struct
|
||||
var newUser User
|
||||
|
@ -163,13 +207,39 @@ func userRegistrationEp(c *gin.Context) {
|
|||
})
|
||||
}
|
||||
|
||||
func userUpdateEp(c *gin.Context) {
|
||||
// UpdateUser godoc
|
||||
// @Summary Update a user
|
||||
// @ID UpdateUser
|
||||
// @Tags users
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param inputUser body common.UserResponse true "User to be updated"
|
||||
// @Success 200 "OK."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param userID path int true "User ID"
|
||||
// @Router /users/{userID} [put]
|
||||
func updateUser(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
||||
func userReadEp(c *gin.Context) {
|
||||
// GetUser godoc
|
||||
// @Summary Get user
|
||||
// @ID GetUser
|
||||
// @Produce json
|
||||
// @Tags users
|
||||
// @Success 200 {object} common.UserResponse "User requested by user"
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param userID path int true "User ID"
|
||||
// @Router /users/{userID} [get]
|
||||
func getUser(c *gin.Context) {
|
||||
|
||||
var user User
|
||||
id, _ := strconv.ParseInt(c.Param("UserID"), 10, 64)
|
||||
|
@ -180,13 +250,25 @@ func userReadEp(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
serializer := UserSerializer{c, user.User}
|
||||
serializer := common.UserSerializer{c, user.User}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"user": serializer.Response(false),
|
||||
})
|
||||
}
|
||||
|
||||
func userDeleteEp(c *gin.Context) {
|
||||
// DeleteUser godoc
|
||||
// @Summary Delete a user
|
||||
// @ID DeleteUser
|
||||
// @Tags users
|
||||
// @Produce json
|
||||
// @Success 200 "OK."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param userID path int true "User ID"
|
||||
// @Router /users/{userID} [delete]
|
||||
func deleteUser(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
|
|
|
@ -7,6 +7,46 @@ import (
|
|||
func FindAllUsers() ([]common.User, int, error) {
|
||||
db := common.GetDB()
|
||||
var users []common.User
|
||||
err := db.Find(&users).Error
|
||||
err := db.Order("ID asc").Find(&users).Error
|
||||
return users, len(users), err
|
||||
}
|
||||
|
||||
func FindAllUsersSim(sim *common.Simulation) ([]common.User, int, error) {
|
||||
db := common.GetDB()
|
||||
var users []common.User
|
||||
err := db.Order("ID asc").Model(sim).Related(&users, "Users").Error
|
||||
return users, len(users), err
|
||||
}
|
||||
|
||||
func FindUserByName(username string) (common.User, error){
|
||||
db := common.GetDB()
|
||||
var user common.User
|
||||
err := db.Where("Username = ?", username).Find(&user).Error
|
||||
return user, err
|
||||
}
|
||||
|
||||
func AddUserToSim(sim *common.Simulation, user *common.User) error {
|
||||
db := common.GetDB()
|
||||
err := db.Model(sim).Association("Users").Append(user).Error
|
||||
return err
|
||||
}
|
||||
|
||||
func RemoveUserFromSim(sim *common.Simulation, username string) error {
|
||||
db := common.GetDB()
|
||||
|
||||
user, err := FindUserByName(username)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove user from simulation
|
||||
err = db.Model(sim).Association("Users").Delete(&user).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove simulation from user
|
||||
err = db.Model(&user).Association("Simulations").Delete(sim).Error
|
||||
|
||||
return err
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
package user
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/file"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/project"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulation"
|
||||
)
|
||||
|
||||
type UsersSerializer struct {
|
||||
Ctx *gin.Context
|
||||
Users []common.User
|
||||
}
|
||||
|
||||
func (self *UsersSerializer) Response(assoc bool) []UserResponse {
|
||||
response := []UserResponse{}
|
||||
for _, user := range self.Users {
|
||||
serializer := UserSerializer{self.Ctx, user}
|
||||
response = append(response, serializer.Response(assoc))
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
type UserSerializer struct {
|
||||
Ctx *gin.Context
|
||||
common.User
|
||||
}
|
||||
|
||||
type UserResponse struct {
|
||||
Username string `json:"Username"`
|
||||
Password string `json:"Password"` // XXX: this is the hashed pw
|
||||
Role string `json:"Role"`
|
||||
Mail string `json:"Mail"`
|
||||
Projects []project.ProjectResponseNoAssoc
|
||||
Simulations []simulation.SimulationResponseNoAssoc
|
||||
Files []file.FileResponseNoAssoc
|
||||
}
|
||||
|
||||
func (self *UserSerializer) Response(assoc bool) UserResponse {
|
||||
|
||||
response := UserResponse{
|
||||
Username: self.Username,
|
||||
Password: self.Password,
|
||||
Role: self.Role,
|
||||
Mail: self.Mail,
|
||||
}
|
||||
|
||||
// Associated models MUST NOT called with assoc=true otherwise we
|
||||
// will have an infinite loop due to the circular dependencies
|
||||
if assoc {
|
||||
|
||||
// TODO: maybe all those should be made in one transaction
|
||||
projects, _, _ := project.FindUserProjects(&self.User)
|
||||
projectsSerializer :=
|
||||
project.ProjectsSerializerNoAssoc{self.Ctx, projects}
|
||||
|
||||
simulations, _, _ := simulation.FindUserSimulations(&self.User)
|
||||
simulationsSerializer :=
|
||||
simulation.SimulationsSerializerNoAssoc{self.Ctx, simulations}
|
||||
|
||||
files, _, _ := file.FindUserFiles(&self.User)
|
||||
filesSerializer := file.FilesSerializerNoAssoc{self.Ctx, files}
|
||||
|
||||
// Add the associated models to the response
|
||||
response.Projects = projectsSerializer.Response()
|
||||
response.Simulations = simulationsSerializer.Response()
|
||||
response.Files = filesSerializer.Response()
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
|
@ -1,46 +1,211 @@
|
|||
package visualization
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulation"
|
||||
)
|
||||
|
||||
func VisualizationsRegister(r *gin.RouterGroup) {
|
||||
r.GET("/", visualizationsReadEp)
|
||||
r.POST("/", visualizationRegistrationEp)
|
||||
r.PUT("/:VisualizationID", visualizationUpdateEp)
|
||||
r.GET("/:VisualizationID", visualizationReadEp)
|
||||
r.DELETE("/:VisualizationID", visualizationDeleteEp)
|
||||
func RegisterVisualizationEndpoints(r *gin.RouterGroup){
|
||||
|
||||
r.GET("/", GetVisualizations)
|
||||
r.POST("/", AddVisualization)
|
||||
//r.POST("/:visualizationID", CloneVisualization)
|
||||
r.PUT("/:visualizationID", UpdateVisualization)
|
||||
r.GET("/:visualizationID", GetVisualization)
|
||||
r.DELETE("/:visualizationID", DeleteVisualization)
|
||||
|
||||
}
|
||||
|
||||
func visualizationsReadEp(c *gin.Context) {
|
||||
allVisualizations, _, _ := FindAllVisualizations()
|
||||
serializer := VisualizationsSerializer{c, allVisualizations}
|
||||
// GetVisualizations godoc
|
||||
// @Summary Get all visualizations of simulation
|
||||
// @ID GetVisualizations
|
||||
// @Produce json
|
||||
// @Tags visualizations
|
||||
// @Success 200 {array} common.VisualizationResponse "Array of visualizations to which belong to simulation"
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param simulationID query int true "Simulation ID"
|
||||
// @Router /visualizations [get]
|
||||
func GetVisualizations(c *gin.Context) {
|
||||
|
||||
simID, err := common.GetSimulationID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sim, err := simulation.FindSimulation(simID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
allVisualizations, _, _ := FindAllVisualizationsOfSim(&sim)
|
||||
serializer := common.VisualizationsSerializer{c, allVisualizations}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"visualizations": serializer.Response(),
|
||||
})
|
||||
}
|
||||
|
||||
func visualizationRegistrationEp(c *gin.Context) {
|
||||
// AddVisualization godoc
|
||||
// @Summary Add a visualization to a simulation
|
||||
// @ID AddVisualization
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Tags visualizations
|
||||
// @Param inputVis body common.VisualizationResponse true "Visualization to be added incl. ID of simulation"
|
||||
// @Success 200 "OK."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Router /visualizations [post]
|
||||
func AddVisualization(c *gin.Context) {
|
||||
|
||||
simID, err := common.GetSimulationID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sim, err := simulation.FindSimulation(simID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
var vis common.Visualization
|
||||
err = c.BindJSON(&vis)
|
||||
if err != nil {
|
||||
errormsg := "Bad request. Error binding form data to JSON: " + err.Error()
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// add visualization to DB and add association to simulation
|
||||
err = AddVisualizationToSim(&sim, &vis)
|
||||
if common.ProvideErrorResponse(c, err) == false {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "OK",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func CloneVisualization(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
||||
func visualizationUpdateEp(c *gin.Context) {
|
||||
// UpdateVisualization godoc
|
||||
// @Summary Update a visualization
|
||||
// @ID UpdateVisualization
|
||||
// @Tags visualizations
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param inputVis body common.VisualizationResponse true "Visualization to be updated"
|
||||
// @Success 200 "OK."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param visualizationID path int true "Visualization ID"
|
||||
// @Router /visualizations/{visualizationID} [put]
|
||||
func UpdateVisualization(c *gin.Context) {
|
||||
|
||||
simID, err := common.GetSimulationID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sim, err := simulation.FindSimulation(simID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
visID, err := common.GetVisualizationID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var vis common.Visualization
|
||||
err = c.BindJSON(&vis)
|
||||
if err != nil {
|
||||
errormsg := "Bad request. Error binding form data to JSON: " + err.Error()
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
err = UpdateVisualizationOfSim(&sim, vis, visID)
|
||||
if common.ProvideErrorResponse(c, err) == false {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "OK",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// GetVisualization godoc
|
||||
// @Summary Get a visualization
|
||||
// @ID GetVisualization
|
||||
// @Tags visualizations
|
||||
// @Produce json
|
||||
// @Success 200 {object} common.VisualizationResponse "Requested visualization."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param visualizationID path int true "Visualization ID"
|
||||
// @Router /visualizations/{visualizationID} [get]
|
||||
func GetVisualization(c *gin.Context) {
|
||||
|
||||
simID, err := common.GetSimulationID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sim, err := simulation.FindSimulation(simID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
visID, err := common.GetVisualizationID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
visualization, err := FindVisualizationOfSim(&sim, visID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
serializer := common.VisualizationSerializer{c, visualization}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"visualization": serializer.Response(),
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteVisualization godoc
|
||||
// @Summary Delete a visualization
|
||||
// @ID DeleteVisualization
|
||||
// @Tags visualizations
|
||||
// @Produce json
|
||||
// @Success 200 "OK."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param visualizationID path int true "Visualization ID"
|
||||
// @Router /visualizations/{visualizationID} [delete]
|
||||
func DeleteVisualization(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
||||
func visualizationReadEp(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
||||
func visualizationDeleteEp(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
|
|
@ -4,9 +4,46 @@ import (
|
|||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
)
|
||||
|
||||
func FindAllVisualizations() ([]common.Visualization, int, error) {
|
||||
func FindAllVisualizationsOfSim(sim *common.Simulation) ([]common.Visualization, int, error) {
|
||||
db := common.GetDB()
|
||||
var visualization []common.Visualization
|
||||
err := db.Find(&visualization).Error
|
||||
return visualization, len(visualization), err
|
||||
var visualizations []common.Visualization
|
||||
err := db.Order("ID asc").Model(sim).Related(&visualizations, "Visualizations").Error
|
||||
return visualizations, len(visualizations), err
|
||||
}
|
||||
|
||||
func FindVisualizationOfSim(sim *common.Simulation, visID int) (common.Visualization, error) {
|
||||
db := common.GetDB()
|
||||
var vis common.Visualization
|
||||
err := db.Model(sim).Where("ID = ?", visID).Related(&vis, "Visualizations").Error
|
||||
return vis, err
|
||||
}
|
||||
|
||||
func AddVisualizationToSim(sim * common.Simulation, vis * common.Visualization) error {
|
||||
db := common.GetDB()
|
||||
|
||||
// Add visualization to DB
|
||||
err := db.Create(vis).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Add association with simulation
|
||||
err = db.Model(sim).Association("Visualizations").Append(vis).Error
|
||||
return err
|
||||
|
||||
}
|
||||
|
||||
func UpdateVisualizationOfSim(sim * common.Simulation, vis common.Visualization, visID int) error {
|
||||
db := common.GetDB()
|
||||
|
||||
// Get visualization of simulation that matches with ID (= visualization to be updated)
|
||||
var vis_old common.Visualization
|
||||
err := db.Model(sim).Where("ID = ?", visID).Related(&vis_old, "Visualizations").Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Update visualization in DB (only name and grid can be updated)
|
||||
err = db.Model(&vis_old).Updates(map[string]interface{}{"Name": vis.Name, "Grid": vis.Grid}).Error
|
||||
return err
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
package visualization
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/project"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/widget"
|
||||
)
|
||||
|
||||
type VisualizationsSerializer struct {
|
||||
Ctx *gin.Context
|
||||
Visualizations []common.Visualization
|
||||
}
|
||||
|
||||
func (self *VisualizationsSerializer) Response() []VisualizationResponse {
|
||||
response := []VisualizationResponse{}
|
||||
for _, visualization := range self.Visualizations {
|
||||
serializer := VisualizationSerializer{self.Ctx, visualization}
|
||||
response = append(response, serializer.Response())
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
type VisualizationSerializer struct {
|
||||
Ctx *gin.Context
|
||||
common.Visualization
|
||||
}
|
||||
|
||||
type VisualizationResponse struct {
|
||||
Name string `json:"Name"`
|
||||
UserID uint `json:"UserID"`
|
||||
Grid int `json:"Grid"`
|
||||
ProjectID uint `json:"ProjectID"`
|
||||
Project project.ProjectResponseNoAssoc
|
||||
Widgets []widget.WidgetResponse
|
||||
}
|
||||
|
||||
func (self *VisualizationSerializer) Response() VisualizationResponse {
|
||||
|
||||
// TODO: maybe all those should be made in one transaction
|
||||
p, _, _ := project.FindVisualizationProject(&self.Visualization)
|
||||
projectSerializer := project.ProjectSerializerNoAssoc{self.Ctx, p}
|
||||
|
||||
w, _, _:= widget.FindVisualizationWidgets(&self.Visualization)
|
||||
widgetsSerializer := widget.WidgetsSerializer{self.Ctx, w}
|
||||
|
||||
|
||||
response := VisualizationResponse{
|
||||
Name: self.Name,
|
||||
UserID: self.UserID,
|
||||
Grid: self.Grid,
|
||||
ProjectID: self.ProjectID,
|
||||
Project: projectSerializer.Response(),
|
||||
Widgets: widgetsSerializer.Response(),
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
|
@ -1,3 +1,287 @@
|
|||
package widget
|
||||
|
||||
// TODO add new API endpoints for widgets
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulation"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/visualization"
|
||||
)
|
||||
|
||||
func RegisterWidgetEndpoints(r *gin.RouterGroup){
|
||||
r.GET("/", GetWidgets)
|
||||
r.POST("/", AddWidget)
|
||||
//r.POST("/:widgetID", CloneWidget)
|
||||
r.PUT("/:widgetID", UpdateWidget)
|
||||
r.GET("/:widgetID", GetWidget)
|
||||
r.DELETE("/:widgetID", DeleteWidget)
|
||||
}
|
||||
|
||||
// GetWidgets godoc
|
||||
// @Summary Get all widgets of visualization
|
||||
// @ID GetWidgets
|
||||
// @Produce json
|
||||
// @Tags widgets
|
||||
// @Success 200 {array} common.WidgetResponse "Array of widgets to which belong to visualization"
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param visualizationID query int true "Visualization ID"
|
||||
// @Router /widgets [get]
|
||||
func GetWidgets(c *gin.Context) {
|
||||
|
||||
simID, err := common.GetSimulationID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sim, err := simulation.FindSimulation(simID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
visID, err := common.GetVisualizationID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
vis, err := visualization.FindVisualizationOfSim(&sim, visID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
widgets,_, err := FindWidgetsOfVisualization(&vis)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
serializer := common.WidgetsSerializer{c, widgets}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"widgets": serializer.Response(),
|
||||
})
|
||||
}
|
||||
|
||||
// AddWidget godoc
|
||||
// @Summary Add a widget to a visualization
|
||||
// @ID AddWidget
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Tags widgets
|
||||
// @Param inputWidget body common.WidgetResponse true "Widget to be added incl. ID of visualization"
|
||||
// @Success 200 "OK."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Router /widgets [post]
|
||||
func AddWidget(c *gin.Context) {
|
||||
|
||||
simID, err := common.GetSimulationID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sim, err := simulation.FindSimulation(simID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
visID, err := common.GetVisualizationID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
vis, err := visualization.FindVisualizationOfSim(&sim, visID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
var widget_input common.Widget
|
||||
err = c.BindJSON(&widget_input)
|
||||
if err != nil {
|
||||
errormsg := "Bad request. Error binding form data to JSON: " + err.Error()
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
err = AddWidgetToVisualization(&vis, &widget_input)
|
||||
if common.ProvideErrorResponse(c, err) == false {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "OK.",
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
func CloneWidget(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateWidget godoc
|
||||
// @Summary Update a widget
|
||||
// @ID UpdateWidget
|
||||
// @Tags widgets
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param inputWidget body common.WidgetResponse true "Widget to be updated"
|
||||
// @Success 200 "OK."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param widgetID path int true "Widget ID"
|
||||
// @Router /widgets/{widgetID} [put]
|
||||
func UpdateWidget(c *gin.Context) {
|
||||
simID, err := common.GetSimulationID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sim, err := simulation.FindSimulation(simID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
visID, err := common.GetVisualizationID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
vis, err := visualization.FindVisualizationOfSim(&sim, visID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
widgetID, err := common.GetWidgetID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var widget_input common.Widget
|
||||
err = c.BindJSON(&widget_input)
|
||||
if err != nil {
|
||||
errormsg := "Bad request. Error binding form data to JSON: " + err.Error()
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": errormsg,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
err = UpdateWidgetOfVisualization(&vis, widget_input, widgetID)
|
||||
if common.ProvideErrorResponse(c, err) == false {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "OK",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// GetWidget godoc
|
||||
// @Summary Get a widget
|
||||
// @ID GetWidget
|
||||
// @Tags widgets
|
||||
// @Produce json
|
||||
// @Success 200 {object} common.WidgetResponse "Requested widget."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param widgetID path int true "Widget ID"
|
||||
// @Router /widgets/{widgetID} [get]
|
||||
func GetWidget(c *gin.Context) {
|
||||
|
||||
simID, err := common.GetSimulationID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sim, err := simulation.FindSimulation(simID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
visID, err := common.GetVisualizationID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
vis, err := visualization.FindVisualizationOfSim(&sim, visID)
|
||||
if common.ProvideErrorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
widgetID, err := common.GetWidgetID(c)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
widget, err := FindWidgetOfVisualization(&vis, widgetID)
|
||||
serializer := common.WidgetSerializer{c, widget}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"widget": serializer.Response(),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// DeleteWidget godoc
|
||||
// @Summary Delete a widget
|
||||
// @ID DeleteWidget
|
||||
// @Tags widgets
|
||||
// @Produce json
|
||||
// @Success 200 "OK."
|
||||
// @Failure 401 "Unauthorized Access"
|
||||
// @Failure 403 "Access forbidden."
|
||||
// @Failure 404 "Not found"
|
||||
// @Failure 500 "Internal server error"
|
||||
// @Param widgetID path int true "Widget ID"
|
||||
// @Router /widgets/{widgetID} [delete]
|
||||
func DeleteWidget(c *gin.Context) {
|
||||
|
||||
// simID, err := GetSimulationID(c)
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// sim, err := queries.FindSimulation(simID)
|
||||
// if common.ProvideErrorResponse(c, err) {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// visID, err := GetVisualizationID(c)
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// visualization, err := queries.FindVisualizationOfSim(&sim, visID)
|
||||
// if common.ProvideErrorResponse(c, err) {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// widgetID, err := GetWidgetID(c)
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// widget, err := queries.FindWidgetOfVisualization(&visualization, widgetID)
|
||||
// if common.ProvideErrorResponse(c, err) {
|
||||
// return
|
||||
// }
|
||||
|
||||
// TODO delete files of widget in DB and on disk
|
||||
|
||||
|
||||
// TODO Delete widget itself + association with visualization
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "NOT implemented",
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -7,8 +7,61 @@ import (
|
|||
func FindVisualizationWidgets(visualization *common.Visualization) ([]common.Widget, int, error) {
|
||||
db := common.GetDB()
|
||||
var widgets []common.Widget
|
||||
err := db.Model(visualization).Related(&widgets, "Widgets").Error
|
||||
err := db.Order("ID asc").Model(visualization).Related(&widgets, "Widgets").Error
|
||||
return widgets, len(widgets), err
|
||||
}
|
||||
|
||||
|
||||
func FindWidget(widgetID int) (common.Widget, error){
|
||||
db := common.GetDB()
|
||||
var w common.Widget
|
||||
err := db.First(&w, widgetID).Error
|
||||
return w, err
|
||||
}
|
||||
|
||||
|
||||
func FindWidgetsOfVisualization(vis * common.Visualization) ([]common.Widget, int, error) {
|
||||
db := common.GetDB()
|
||||
var widgets []common.Widget
|
||||
err := db.Order("ID asc").Model(vis).Related(&vis, "Widgets").Error
|
||||
return widgets, len(widgets), err
|
||||
}
|
||||
|
||||
func FindWidgetOfVisualization(visualization *common.Visualization, widgetID int) (common.Widget, error){
|
||||
db := common.GetDB()
|
||||
var widget common.Widget
|
||||
err := db.Model(visualization).Where("ID = ?", widgetID).Related(&widget, "Widgets").Error
|
||||
return widget, err
|
||||
}
|
||||
|
||||
|
||||
func AddWidgetToVisualization(vis *common.Visualization, widget_input * common.Widget) error {
|
||||
|
||||
db := common.GetDB()
|
||||
|
||||
// Add widget to DB
|
||||
err := db.Create(widget_input).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Add association with visualization
|
||||
err = db.Model(vis).Association("Widgets").Append(widget_input).Error
|
||||
return err
|
||||
}
|
||||
|
||||
func UpdateWidgetOfVisualization(vis * common.Visualization, widget_input common.Widget, widgetID int) error {
|
||||
db := common.GetDB()
|
||||
|
||||
// Get widget of visualization that matches with ID (= widget to be updated)
|
||||
var widget_old common.Widget
|
||||
err := db.Model(vis).Where("ID = ?", widgetID).Related(&widget_old, "Widgets").Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Update widget in DB
|
||||
err = db.Model(&widget_old).Updates(map[string]interface{}{"Name": widget_input.Name, "Type": widget_input.Type, "MinHeight": widget_input.MinHeight, "MinWidth": widget_input.MinWidth, "Height": widget_input.Height, "Width": widget_input.Width, "X": widget_input.X, "Y": widget_input.Y, "Z": widget_input.Z, "CustomProperties": widget_input.CustomProperties}).Error
|
||||
return err
|
||||
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
package widget
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
)
|
||||
|
||||
type WidgetsSerializer struct {
|
||||
Ctx *gin.Context
|
||||
Widgets []common.Widget
|
||||
}
|
||||
|
||||
func (self *WidgetsSerializer) Response() []WidgetResponse {
|
||||
response := []WidgetResponse{}
|
||||
for _, widget := range self.Widgets {
|
||||
serializer := WidgetSerializer{self.Ctx, widget}
|
||||
response = append(response, serializer.Response())
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
type WidgetSerializer struct {
|
||||
Ctx *gin.Context
|
||||
common.Widget
|
||||
}
|
||||
|
||||
type WidgetResponse struct {
|
||||
Name string `json:"Name"`
|
||||
Type string `json:"Type"`
|
||||
Width uint `json:"Width"`
|
||||
Height uint `json:"Height"`
|
||||
MinWidth uint `json:"MinWidth"`
|
||||
MinHeight uint `json:"MinHeight"`
|
||||
X int `json:"X"`
|
||||
Y int `json:"Y"`
|
||||
Z int `json:"Z"`
|
||||
VisualizationID uint `json:"VisualizationID"`
|
||||
IsLocked bool `json:"IsLocked"`
|
||||
//CustomProperties
|
||||
}
|
||||
|
||||
func (self *WidgetSerializer) Response() WidgetResponse {
|
||||
|
||||
response := WidgetResponse{
|
||||
Name: self.Name,
|
||||
Type: self.Type,
|
||||
Width: self.Width,
|
||||
Height: self.Height,
|
||||
MinWidth: self.MinWidth,
|
||||
MinHeight: self.MinHeight,
|
||||
X: self.X,
|
||||
Y: self.Y,
|
||||
Z: self.Z,
|
||||
VisualizationID: self.VisualizationID,
|
||||
IsLocked: self.IsLocked,
|
||||
//CustomProperties
|
||||
}
|
||||
return response
|
||||
}
|
45
start.go
45
start.go
|
@ -1,18 +1,37 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/file"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/project"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/swaggo/gin-swagger"
|
||||
"github.com/swaggo/gin-swagger/swaggerFiles"
|
||||
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
|
||||
_ "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/doc/autoapi" // apidocs folder is generated by Swag CLI, you have to import it
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/model"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulation"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulationmodel"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulator"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/user"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/visualization"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/widget"
|
||||
)
|
||||
|
||||
// @title VILLASweb Backend API
|
||||
// @version 2.0
|
||||
// @description This is the API of the VILLASweb Backend
|
||||
// @description WORK IN PROGRESS! PLEASE BE PATIENT!
|
||||
|
||||
// @description This documentation is auto-generated based on the API documentation in the code.
|
||||
// @description The tool https://github.com/swaggo/swag is used to auto-generate API docs for gin.
|
||||
|
||||
// @contact.name Sonja Happ
|
||||
// @contact.email sonja.happ@eonerc.rwth-aachen.de
|
||||
|
||||
// @license.name GNU GPL 3.0
|
||||
// @license.url http://www.gnu.de/documents/gpl-3.0.en.html
|
||||
|
||||
// @host localhost:4000
|
||||
// @BasePath /api/v1
|
||||
func main() {
|
||||
// Testing
|
||||
db := common.DummyInitDB()
|
||||
|
@ -31,13 +50,15 @@ func main() {
|
|||
|
||||
api.Use(user.Authentication(true))
|
||||
|
||||
user.UsersRegister(api.Group("/users"))
|
||||
file.FilesRegister(api.Group("/files"))
|
||||
project.ProjectsRegister(api.Group("/projects"))
|
||||
simulation.SimulationsRegister(api.Group("/simulations"))
|
||||
simulationmodel.SimulationModelsRegister(api.Group("/models"))
|
||||
simulator.SimulatorsRegister(api.Group("/simulators"))
|
||||
visualization.VisualizationsRegister(api.Group("/visualizations"))
|
||||
simulation.RegisterSimulationEndpoints(api.Group("/simulations"))
|
||||
model.RegisterModelEndpoints(api.Group("/models"))
|
||||
visualization.RegisterVisualizationEndpoints(api.Group("/visualizations"))
|
||||
widget.RegisterWidgetEndpoints(api.Group("/widgets"))
|
||||
file.RegisterFileEndpoints(api.Group("/files"))
|
||||
user.RegisterUserEndpoints(api.Group("/users"))
|
||||
simulator.RegisterSimulatorEndpoints(api.Group("/simulators"))
|
||||
|
||||
r.GET("swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||
|
||||
// server at port 4000 to match frontend's redirect path
|
||||
r.Run(":4000")
|
||||
|
|
Loading…
Add table
Reference in a new issue