From c33438b395051f9f89f586a6fd33f13b20e4b900 Mon Sep 17 00:00:00 2001 From: Sonja Happ Date: Thu, 18 Jul 2019 13:11:05 +0200 Subject: [PATCH] renaming visualization to dashboard --- .gitlab-ci.yml | 4 +- common/database.go | 24 +- common/database_test.go | 20 +- common/models.go | 24 +- common/responses.go | 12 +- common/roles.go | 8 +- common/serializers.go | 48 +- doc/api/api.yaml | 1397 ----------------- routes/dashboard/dashboardEndpoints.go | 183 +++ routes/dashboard/dashboardMethods.go | 75 + .../dashboardMiddleware.go} | 42 +- routes/dashboard/dashboard_test.go | 162 ++ .../visualization/visualizationEndpoints.go | 183 --- routes/visualization/visualizationMethods.go | 75 - routes/visualization/visualization_test.go | 162 -- routes/widget/widgetEndpoints.go | 20 +- routes/widget/widgetMethods.go | 22 +- routes/widget/widgetMiddleware.go | 4 +- routes/widget/widget_test.go | 28 +- start.go | 4 +- 20 files changed, 550 insertions(+), 1947 deletions(-) delete mode 100644 doc/api/api.yaml create mode 100644 routes/dashboard/dashboardEndpoints.go create mode 100644 routes/dashboard/dashboardMethods.go rename routes/{visualization/visualizationMiddleware.go => dashboard/dashboardMiddleware.go} (51%) create mode 100644 routes/dashboard/dashboard_test.go delete mode 100644 routes/visualization/visualizationEndpoints.go delete mode 100644 routes/visualization/visualizationMethods.go delete mode 100644 routes/visualization/visualization_test.go diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 948f3fb..fc4c800 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -105,10 +105,10 @@ test:signal: variables: TEST_FOLDER: routes/signal -test:visualization: +test:dashboard: extends: test:simulation variables: - TEST_FOLDER: routes/visualization + TEST_FOLDER: routes/dashboard test:widget: extends: test:simulation diff --git a/common/database.go b/common/database.go index 2154592..15fbbfd 100644 --- a/common/database.go +++ b/common/database.go @@ -62,7 +62,7 @@ func DropTables(db *gorm.DB) { db.DropTableIfExists(&File{}) db.DropTableIfExists(&Simulation{}) db.DropTableIfExists(&User{}) - db.DropTableIfExists(&Visualization{}) + db.DropTableIfExists(&Dashboard{}) db.DropTableIfExists(&Widget{}) } @@ -74,7 +74,7 @@ func MigrateModels(db *gorm.DB) { db.AutoMigrate(&File{}) db.AutoMigrate(&Simulation{}) db.AutoMigrate(&User{}) - db.AutoMigrate(&Visualization{}) + db.AutoMigrate(&Dashboard{}) db.AutoMigrate(&Widget{}) } @@ -154,10 +154,10 @@ func DummyPopulateDB(test_db *gorm.DB) { checkErr(test_db.Create(&usr_A).Error) checkErr(test_db.Create(&usr_B).Error) - vis_A := Visualization{Name: "Visualization_A"} - vis_B := Visualization{Name: "Visualization_B"} - checkErr(test_db.Create(&vis_A).Error) - checkErr(test_db.Create(&vis_B).Error) + dab_A := Dashboard{Name: "Dashboard_A"} + dab_B := Dashboard{Name: "Dashboard_B"} + checkErr(test_db.Create(&dab_A).Error) + checkErr(test_db.Create(&dab_B).Error) widg_A := Widget{Name: "Widget_A"} widg_B := Widget{Name: "Widget_B"} @@ -178,13 +178,13 @@ func DummyPopulateDB(test_db *gorm.DB) { checkErr(test_db.Model(&simn_A).Association("SimulationModels").Append(&mo_A).Error) checkErr(test_db.Model(&simn_A).Association("SimulationModels").Append(&mo_B).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) + // Simulation HM Dashboards + checkErr(test_db.Model(&simn_A).Association("Dashboards").Append(&dab_A).Error) + checkErr(test_db.Model(&simn_A).Association("Dashboards").Append(&dab_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) + // Dashboard HM Widget + checkErr(test_db.Model(&dab_A).Association("Widgets").Append(&widg_A).Error) + checkErr(test_db.Model(&dab_A).Association("Widgets").Append(&widg_B).Error) // SimulationModel HM Signals checkErr(test_db.Model(&mo_A).Association("InputMapping").Append(&inSig_A).Error) diff --git a/common/database_test.go b/common/database_test.go index 78ad426..7c538a5 100644 --- a/common/database_test.go +++ b/common/database_test.go @@ -34,7 +34,7 @@ func TestDummyDBAssociations(t *testing.T) { var simn Simulation var usr User var usrs []User - var vis Visualization + var dab Dashboard var widg Widget var sigs []Signal @@ -42,7 +42,7 @@ func TestDummyDBAssociations(t *testing.T) { var files []File var files_sm []File var simns []Simulation - var viss []Visualization + var dabs []Dashboard var widgs []Widget // User @@ -77,10 +77,10 @@ func TestDummyDBAssociations(t *testing.T) { "Expected to have %v simulation models. Has %v.", 2, len(mos)) } - a.NoError(db.Model(&simn).Related(&viss, "Visualizations").Error) - if len(viss) != 2 { + a.NoError(db.Model(&simn).Related(&dabs, "Dashboards").Error) + if len(dabs) != 2 { a.Fail("Simulation Associations", - "Expected to have %v Visualizations. Has %v.", 2, len(viss)) + "Expected to have %v Dashboards. Has %v.", 2, len(dabs)) } // Simulator @@ -115,14 +115,14 @@ func TestDummyDBAssociations(t *testing.T) { fmt.Println("SimulatorID: ", mo.SimulatorID) - // Visualization + // Dashboard - a.NoError(db.Find(&vis, 1).Error, fM("Visualization")) - a.EqualValues("Visualization_A", vis.Name) + a.NoError(db.Find(&dab, 1).Error, fM("Dashboard")) + a.EqualValues("Dashboard_A", dab.Name) - // Visualization Associations + // Dashboard Associations - a.NoError(db.Model(&vis).Related(&widgs, "Widgets").Error) + a.NoError(db.Model(&dab).Related(&widgs, "Widgets").Error) if len(widgs) != 2 { a.Fail("Widget Associations", "Expected to have %v Widget. Has %v.", 2, len(widgs)) diff --git a/common/models.go b/common/models.go index fb2a808..918bd41 100644 --- a/common/models.go +++ b/common/models.go @@ -30,8 +30,8 @@ type Simulation struct { Users []*User `gorm:"not null;many2many:user_simulations"` // SimulationModels that belong to the simulation SimulationModels []SimulationModel `gorm:"foreignkey:SimulationID"` - // Visualizations that belong to the simulation - Visualizations []Visualization `gorm:"foreignkey:SimulationID"` + // Dashboards that belong to the simulation + Dashboards []Dashboard `gorm:"foreignkey:SimulationID"` } // SimulationModel data model @@ -98,18 +98,18 @@ type Simulator struct { SimulationModels []SimulationModel `gorm:"foreignkey:SimulatorID"` } -// Visualization data model -type Visualization struct { - // ID of visualization +// Dashboard data model +type Dashboard struct { + // ID of dashboard ID uint `gorm:"primary_key;auto_increment"` - // Name of visualization + // Name of dashboard Name string `gorm:"not null"` - // Grid of visualization + // Grid of dashboard Grid int `gorm:"default:15"` - // ID of simulation to which visualization belongs + // ID of simulation to which dashboard belongs SimulationID uint - // Widgets that belong to visualization - Widgets []Widget `gorm:"foreignkey:VisualizationID"` + // Widgets that belong to dashboard + Widgets []Widget `gorm:"foreignkey:DashboardID"` } // Widget data model @@ -138,8 +138,8 @@ type Widget struct { IsLocked bool `gorm:"default:false"` // Custom properties of widget as JSON string CustomProperties string - // ID of visualization to which widget belongs - VisualizationID uint + // ID of dashboard to which widget belongs + DashboardID uint // Files that belong to widget (for example images) Files []File `gorm:"foreignkey:WidgetID"` } diff --git a/common/responses.go b/common/responses.go index a27c0a7..116d00b 100644 --- a/common/responses.go +++ b/common/responses.go @@ -36,7 +36,7 @@ type SimulatorResponse struct { RawProperties string `json:"RawProperties"` } -type VisualizationResponse struct { +type DashboardResponse struct { ID uint `json:"ID"` Name string `json:"Name"` Grid int `json:"Grid"` @@ -54,7 +54,7 @@ type WidgetResponse struct { X int `json:"X"` Y int `json:"Y"` Z int `json:"Z"` - VisualizationID uint `json:"VisualizationID"` + DashboardID uint `json:"DashboardID"` IsLocked bool `json:"IsLocked"` CustomProperties string `json:"CustomProperties"` } @@ -117,12 +117,12 @@ type ResponseMsgSignal struct { Signal SignalResponse `json:"signal"` } -type ResponseMsgVisualizations struct { - Visualizations []VisualizationResponse `json:"visualizations"` +type ResponseMsgDashboards struct { + Dashboards []DashboardResponse `json:"dashboards"` } -type ResponseMsgVisualization struct { - Visualization VisualizationResponse `json:"visualization"` +type ResponseMsgDashboard struct { + Dashboard DashboardResponse `json:"dashboard"` } type ResponseMsgWidgets struct { diff --git a/common/roles.go b/common/roles.go index f65e8c8..80669bc 100644 --- a/common/roles.go +++ b/common/roles.go @@ -18,7 +18,7 @@ const ModelUser = ModelName("user") const ModelSimulation = ModelName("simulation") const ModelSimulator = ModelName("simulator") const ModelSimulatorAction = ModelName("simulatoraction") -const ModelVisualization = ModelName("visualization") +const ModelDashboard = ModelName("dashboard") const ModelWidget = ModelName("widget") const ModelSimulationModel = ModelName("simulationmodel") const ModelSignal = ModelName("signal") @@ -56,7 +56,7 @@ var Roles = RoleActions{ ModelSimulator: crud, ModelSimulatorAction: crud, ModelWidget: crud, - ModelVisualization: crud, + ModelDashboard: crud, ModelSignal: crud, ModelFile: crud, }, @@ -67,14 +67,14 @@ var Roles = RoleActions{ ModelSimulator: _r__, ModelSimulatorAction: _ru_, ModelWidget: crud, - ModelVisualization: crud, + ModelDashboard: crud, ModelSignal: crud, ModelFile: crud, }, "Guest": { ModelSimulation: _r__, ModelSimulationModel: _r__, - ModelVisualization: _r__, + ModelDashboard: _r__, ModelWidget: _r__, ModelSimulator: _r__, ModelSimulatorAction: _r__, diff --git a/common/serializers.go b/common/serializers.go index 355c537..a06b3da 100644 --- a/common/serializers.go +++ b/common/serializers.go @@ -151,30 +151,30 @@ func (self *SimulatorSerializer) Response() SimulatorResponse { return response } -// Visualization/s Serializers +// Dashboard/s Serializers -type VisualizationsSerializer struct { - Ctx *gin.Context - Visualizations []Visualization +type DashboardsSerializer struct { + Ctx *gin.Context + Dashboards []Dashboard } -func (self *VisualizationsSerializer) Response() []VisualizationResponse { - response := []VisualizationResponse{} - for _, visualization := range self.Visualizations { - serializer := VisualizationSerializer{self.Ctx, visualization} +func (self *DashboardsSerializer) Response() []DashboardResponse { + response := []DashboardResponse{} + for _, dashboard := range self.Dashboards { + serializer := DashboardSerializer{self.Ctx, dashboard} response = append(response, serializer.Response()) } return response } -type VisualizationSerializer struct { +type DashboardSerializer struct { Ctx *gin.Context - Visualization + Dashboard } -func (self *VisualizationSerializer) Response() VisualizationResponse { +func (self *DashboardSerializer) Response() DashboardResponse { - response := VisualizationResponse{ + response := DashboardResponse{ Name: self.Name, Grid: self.Grid, SimulationID: self.SimulationID, @@ -207,18 +207,18 @@ type WidgetSerializer struct { func (self *WidgetSerializer) Response() WidgetResponse { response := WidgetResponse{ - ID: self.ID, - 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, + ID: self.ID, + 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, + DashboardID: self.DashboardID, + IsLocked: self.IsLocked, //CustomProperties } return response diff --git a/doc/api/api.yaml b/doc/api/api.yaml deleted file mode 100644 index 08a5e5e..0000000 --- a/doc/api/api.yaml +++ /dev/null @@ -1,1397 +0,0 @@ -openapi: 3.0.1 -info: - title: VILLASweb Backend API Documentation - description: API for VILLASweb Backend implementation in Go. Documentation in progress... please be patient. Removed endpoints are marked with "REMOVED". New endpoints are marked with "NEW". - version: 1.0.0 -servers: -- url: http://111.222.333.444:5555/api/v1 -tags: -- name: authentication - description: Manage user authentication -- name: counts - description: Get counters for database elements -- name: users - description: Manage Users -- name: files - description: Manage Files -- name: simulators - description: Manage Simulators -- name: projects - description: (REMOVED) Manage Projects -- name: simulations - description: Manage Simulations -- name: models - description: Manage Models -- name: visualizations - description: Manage Visualizations -- name: uploads - description: Manage Uploads (REMOVED, now in files) - -paths: - /authenticate: - post: - tags: - - authentication - summary: Authenticate a user - operationId: authenticateUser - requestBody: - description: "User object to authenticate" - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/User' - responses: - 200: - description: OK. - content: - application/json: - schema: - type: object - properties: - success: - type: boolean - message: - type: string - token: - type: object - properties: {} - 400: - description: Bad request. Unable to create user with existing username, username is already taken - 401: - description: Unauthorized access. Invalid or missing credentials. - 403: - description: Access forbidden. - 404: - description: Not found. - content: - application/json: - schema: - type: object - properties: - success: - type: boolean - example: false - message: - type: string - example: error message - 500: - description: Internal server error. Unable to compare passwords. - /counts: - get: - tags: - - counts - summary: Get counters for all elements in the database - operationId: getCounts - responses: - 200: - description: OK. - content: - application/json: - schema: - type: object - properties: - simulations: - type: integer - description: number of simulations - users: - type: integer - description: number of users - simulators: - type: integer - description: number of simulators - projects: - type: integer - description: number of projects - visualizations: - type: integer - description: number of visualizations - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. Unable to find at least one of the count targets. - 500: - description: Internal server error. - /simulations: - get: - tags: - - simulations - summary: Get all available simulations - description: Return a JSON representation of all simulations - operationId: getSimulations - responses: - 200: - description: OK. - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/Simulation' - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. No simulations found. - 500: - description: Internal server error. - post: - tags: - - simulations - summary: Add a new simulation to the database - operationId: addSimulation - requestBody: - description: "Simulation object to add to DB" - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/Simulation' - responses: - 200: - description: OK. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 500: - description: Internal server error. - /simulations/{SimulationID}: - put: - tags: - - simulations - summary: Update properties of simulation with ID SimulationID - operationId: updateSimulationProperties - parameters: - - in: path - name: SimulationID - description: ID of a simulation - required: true - schema: - type: integer - requestBody: - description: "Simulation object with new properties" - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/Simulation' - responses: - 200: - description: OK. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. Unable to find simulation or user. - 500: - description: Internal server error. Unable to save user. - get: - tags: - - simulations - summary: Get properties of simulation with ID SimulationID - operationId: getSimulationProperties - parameters: - - in: path - name: SimulationID - description: ID of a simulation - required: true - schema: - type: integer - responses: - 200: - description: OK. - content: - application/json: - schema: - $ref: '#/components/schemas/Simulation' - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. Unable to find simulation. - 500: - description: Internal server error. - delete: - tags: - - simulations - summary: Delete simulation with ID SimulationID - operationId: deleteSimulation - parameters: - - in: path - name: SimulationID - description: ID of a simulation - required: true - schema: - type: integer - responses: - 200: - description: OK. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. Unable to find simulation. - 500: - description: Internal server error. - /files: - get: - tags: - - files - summary: (REMOVED) Get files of user - operationId: (REMOVED) getFilesOfUser - responses: - 200: - description: OK. - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/File' - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. No files found. - 500: - description: Internal server error. Could not retrieve user's files. - post: - tags: - - files - summary: (REMOVED) Add a new file to the database - operationId: (REMOVED) addFile - requestBody: - description: "File object to be added" - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/File' - responses: - 200: - description: OK. - 400: - description: Bad request. File could not be uploaded because unable to process incoming form. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. User not found. - 500: - description: Internal server error. Unable to save reference file or user OR unable to create directory. - /files/{FileID}: - get: - tags: - - files - summary: (REMOVED) Get properties of file with ID FileID - operationId: (REMOVED) getFileProperties - parameters: - - in: path - name: FileID - description: ID of a file - required: true - schema: - type: integer - - in: header - name: X-Request-FileDesc - description: Set false if file itself, true if file description shall be returned - required: true - schema: - type: boolean - responses: - 200: - description: OK. - content: - application/json: - schema: - $ref: '#/components/schemas/File' - model/x-cim.zip: - schema: - type: string - format: byte - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. File not found. - 500: - description: Internal server error. - put: - tags: - - files - summary: (REMOVED) Update properties of file with ID FileID - operationId: (REMOVED) updateFileProperties - requestBody: - description: "File object to be updated" - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/File' - parameters: - - in: path - name: FileID - description: ID of a file - required: true - schema: - type: integer - responses: - 200: - description: OK. - 400: - description: Bad request. File could not be uploaded because unable to process incoming form. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. File not found. - 500: - description: Internal server error. Unable to save reference file or user OR unable to create directory. - delete: - tags: - - files - summary: (REMOVED) Delete file with ID FileID - operationId: (REMOVED) deleteFile - parameters: - - in: path - name: FileID - description: ID of a file - required: true - schema: - type: integer - responses: - 200: - description: OK. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. File not found. - 500: - description: Internal server error. Unable to remove file. - /projects: - get: - tags: - - projects - summary: (REMOVED) Get projects of user - operationId: (REMOVED) getProjects - responses: - 200: - description: OK. - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/Project' - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. No projects found. - 500: - description: Internal server error. - post: - tags: - - projects - summary: (REMOVED) Add a new project to the database - operationId: (REMOVED) addProject - requestBody: - description: "Project object to add to DB" - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/Project' - responses: - 200: - description: OK. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. Unknown user. - 500: - description: Internal server error. Unable to save user or project. - /projects/{ProjectID}: - put: - tags: - - projects - summary: (REMOVED) Update properties of project with ID ProjectID - operationId: (REMOVED) updateProjectProperties - parameters: - - in: path - name: ProjectID - description: ID of a project - required: true - schema: - type: integer - requestBody: - description: "Project object with new properties" - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/Project' - responses: - 200: - description: OK. - 400: - description: Bad request. Unable to process incoming form. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. Project not found. - 500: - description: Internal server error. Unable to save project or user. - get: - tags: - - projects - summary: (REMOVED) Get properties of project with ID ProjectID - operationId: (REMOVED) getProjectProperties - parameters: - - in: path - name: ProjectID - description: ID of a project - required: true - schema: - type: integer - responses: - 200: - description: OK. - content: - application/json: - schema: - $ref: '#/components/schemas/Project' - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. Project not found. - 500: - description: Internal server error. - delete: - tags: - - projects - summary: (REMOVED) Delete project with ID ProjectID - operationId: (REMOVED) deleteProject - parameters: - - in: path - name: ProjectID - description: ID of a project - required: true - schema: - type: integer - responses: - 200: - description: OK. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. Project not found. - 500: - description: Internal server error. Unable to remove project. - /models: - get: - tags: - - models - summary: (REMOVED) Get simulation models of user - operationId: (REMOVED) getModels - responses: - 200: - description: OK. - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/Model' - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. No simulation models found. - 500: - description: Internal server error. - post: - tags: - - models - summary: (REMOVED) Add a new Model to the database - operationId: (REMOVED) addModel - requestBody: - description: "Model object to add to DB" - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/Model' - responses: - 200: - description: OK. - 400: - description: Bad request. Unable to process incoming form. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 500: - description: Internal server error. Unable to save simulation or simulation model. - /models/{ModelID}: - put: - tags: - - models - summary: (REMOVED) Update properties of Model with ID ModelID - operationId: (REMOVED) updateModelProperties - parameters: - - in: path - name: ModelID - description: ID of a Model - required: true - schema: - type: integer - requestBody: - description: "Model object with new properties" - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/Model' - responses: - 200: - description: OK. - 400: - description: Bad request. Unable to process incoming form. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. Simulation model not found. - 500: - description: Internal server error. Unable to save simulation model. - get: - tags: - - models - summary: (REMOVED) Get properties of Model with ID ModelID - operationId: (REMOVED) getModelProperties - parameters: - - in: path - name: ModelID - description: ID of a Model - required: true - schema: - type: integer - responses: - 200: - description: OK. - content: - application/json: - schema: - $ref: '#/components/schemas/Model' - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. Simulation model not found. - 500: - description: Internal server error. - delete: - tags: - - models - summary: (REMOVED) Delete Model with ID ModelID - operationId: (REMOVED) deleteModel - parameters: - - in: path - name: ModelID - description: ID of a Model - required: true - schema: - type: integer - responses: - 200: - description: OK. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. Simulation or simulation model not found. - 500: - description: Internal server error. Unable to save changed simulation or to remove simulation model. - simulations/{SimulationID}/models/{ModelID}/file: - get: - tags: - - simulations - summary: (NEW) Get file from Model with ID ModelID - operationId: getFileFromModel - parameters: - - in: path - name: ModelID - description: ID of a Model - required: true - schema: - type: integer - requestBody: - description: "Info about file to download" - required: true - content: - application/json: - schema: - required: - - NumberOfFiles - - MIMEType - type: object - properties: - NumberOfFiles: - type: integer - MIMEType: - type: string - examples: - cim: - summary: "An example for CIM file" - value: - NumberOfFiles: 1 - MIMEType: "model/x-cim.zip" - responses: - 200: - description: OK. - content: - model/x-cim.zip: - schema: - type: string - format: byte - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. Simulation model not found. - 500: - description: Internal server error. - put: - tags: - - simulations - summary: (NEW) Update (Overwrite) file of Model with ID ModelID, File object has to be in database - operationId: updateFileForModel - parameters: - - in: path - name: ModelID - description: ID of a Model - required: true - schema: - type: integer - requestBody: - description: "File to be updated for simulation model" - required: true - content: - model/x-cim.zip: - schema: - type: string - format: byte - responses: - 200: - description: OK. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. Simulation model not found. - 500: - description: Internal server error. Unable to save simulation model. - /simulators: - get: - tags: - - simulators - summary: Get simulators - operationId: getSimulators - responses: - 200: - description: OK. - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/Simulator' - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. No simulators found. - 500: - description: Internal server error. - post: - tags: - - simulators - summary: Add a new Simulator to the database - operationId: addSimulator - requestBody: - description: "Simulator object to add to DB" - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/Simulator' - responses: - 200: - description: OK. - 400: - description: Bad request. Unable to process incoming form. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 500: - description: Internal server error. Unable to save simulator. - /simulators/{SimulatorID}: - put: - tags: - - simulators - summary: Update properties of Simulator with ID SimulatorID - operationId: updateSimulatorProperties - parameters: - - in: path - name: SimulatorID - description: ID of a Simulator - required: true - schema: - type: integer - requestBody: - description: "Simulator object with new properties" - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/Simulator' - responses: - 200: - description: OK. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. Simulator not found. - 500: - description: Internal server error. Unable to save simulator. - get: - tags: - - simulators - summary: Get properties of Simulator with ID SimulatorID - operationId: getSimulatorProperties - parameters: - - in: path - name: SimulatorID - description: ID of a Simulator - required: true - schema: - type: integer - responses: - 200: - description: OK. - content: - application/json: - schema: - $ref: '#/components/schemas/Simulator' - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. Simulator not found. - 500: - description: Internal server error. - delete: - tags: - - simulators - summary: Delete Simulator with ID SimulatorID - operationId: deleteSimulator - parameters: - - in: path - name: SimulatorID - description: ID of a Simulator - required: true - schema: - type: integer - responses: - 200: - description: OK. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. Simulator not found. - 500: - description: Internal server error. Unable to remove simulator. - post: - tags: - - simulators - summary: Send actions to Simulator with ID SimulatorID - operationId: sendActionsToSimulator - parameters: - - in: path - name: SimulatorID - description: ID of a Simulator - required: true - schema: - type: integer - requestBody: - description: "Array containing simulator actions" - required: true - content: - application/json: - schema: - type: array - items: - type: string - responses: - 200: - description: OK. - 400: - description: Bad request. Unable to process incoming form. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. Simulator not found. - 500: - description: Internal server error. Unable to send actions to simulator. - /users: - get: - tags: - - users - summary: Get users - operationId: getUsers - responses: - 200: - description: OK. - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/User' - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. No users found. - 500: - description: Internal server error. - post: - tags: - - users - summary: Add a new User to the database - operationId: addUser - requestBody: - description: "User object to add to DB" - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/User' - responses: - 200: - description: OK. - 400: - description: Bad request. Unable to process incoming form. Username is already taken - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 500: - description: Internal server error. Unable to save user. - /users/{UserID}: - put: - tags: - - users - summary: Update properties of User with ID UserID - operationId: updateUserProperties - parameters: - - in: path - name: UserID - description: ID of a User - required: true - schema: - type: integer - requestBody: - description: "User object with new properties" - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/User' - responses: - 200: - description: OK. - 400: - description: Bad request. Username is already taken. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. User not found. - 500: - description: Internal server error. - get: - tags: - - users - summary: Get properties of User with ID UserID - operationId: getUserProperties - parameters: - - in: path - name: UserID - description: ID of a User - required: true - schema: - type: integer - responses: - 200: - description: OK. - content: - application/json: - schema: - $ref: '#/components/schemas/User' - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. User not found. - 500: - description: Internal server error. - delete: - tags: - - users - summary: Delete User with ID UserID - operationId: deleteUser - parameters: - - in: path - name: UserID - description: ID of a User - required: true - schema: - type: integer - responses: - 200: - description: OK. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. User not found. - 500: - description: Internal server error. Unable to remove user. - /users/me: - get: - tags: - - users - summary: Get properties of user that issues the request (REMOVED) - operationId: getUserPropertiesCurrent - responses: - 200: - description: OK. - content: - application/json: - schema: - $ref: '#/components/schemas/User' - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. User not found. - 500: - description: Internal server error. - /visualizations: - get: - tags: - - visualizations - summary: (REMOVED) Get all available visualizations - description: (REMOVED) Return a JSON representation of all visualizations - operationId: (REMOVED) getVisualizations - responses: - 200: - description: OK. - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/Visualization' - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. No visualizations found. - 500: - description: Internal server error. - post: - tags: - - visualizations - summary: (REMOVED) Add a new visualization to the database - operationId: (REMOVED) addVisualization - requestBody: - description: "Visualization object to add to DB" - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/Visualization' - responses: - 200: - description: OK. - 400: - description: Bad request. Unable to process incoming form. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. Project of visualization not found. - 500: - description: Internal server error. Unable to save project or visualization. - /visualization/{VisualizationID}: - put: - tags: - - visualizations - summary: (REMOVED) Update properties of Visualization with ID VisualizationID - operationId: (REMOVED) updateVisualizationrProperties - parameters: - - in: path - name: VisualizationID - description: ID of a Visualization - required: true - schema: - type: integer - requestBody: - description: "Visualization object with new properties" - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/Visualization' - responses: - 200: - description: OK. - 400: - description: Bad request. Unable to process incoming form. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. Visualization not found. - 500: - description: Internal server error. Unable to save Visualization. - get: - tags: - - visualizations - summary: (REMOVED) Get properties of Visualization with ID VisualizationID - operationId: (REMOVED) getVisualizationProperties - parameters: - - in: path - name: VisualizationID - description: ID of a Visualization - required: true - schema: - type: integer - responses: - 200: - description: OK. - content: - application/json: - schema: - $ref: '#/components/schemas/Visualization' - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. Visualization not found. - 500: - description: Internal server error. - delete: - tags: - - visualizations - summary: (REMOVED) Delete Visualization with ID VisualizationID - operationId: (REMOVED) deleteVisualization - parameters: - - in: path - name: VisualizationID - description: ID of a Visualization - required: true - schema: - type: integer - responses: - 200: - description: OK. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. Visualization or project of visualization not found. - 500: - description: Internal server error. Unable to remove visualization or to save changed project. - /uploads: - post: - tags: - - uploads - summary: (REMOVED) Upload a new file to the database - operationId: (REMOVED) uploadFile - requestBody: - description: "File object to upload TODO CHANGE TO FORM" - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/File' - responses: - 200: - description: OK. - 400: - description: Bad request. Unable to process incoming form. - 401: - description: Unauthorized access. - 403: - description: Access forbidden. - 404: - description: Not found. User or reference file not found. - 500: - description: Internal server error. Unable to save user or reference file OR unable to create directory. - - -components: - schemas: - Project: - required: - - Name - - SimulationID - - UserID - type: object - properties: - Name: - type: string - UserID: - type: integer - SimulationID: - type: integer - Visualization: - required: - - Name - - Grid - - ProjectID - - UserID - type: object - properties: - Name: - type: string - Grid: - type: integer - UserID: - type: integer - ProjectID: - type: integer - User: - required: - - Username - - Password - - Role - - Mail - type: object - properties: - Username: - type: string - Password: - type: string - Role: - type: string - Mail: - type: string - Simulation: - required: - - ID - - Name - - UserID - type: object - properties: - ID: - type: integer - Name: - type: string - Running: - type: boolean - UserID: - type: integer - StartParameters: - type: object - properties: {} - File: - required: - - Name - - Path - - Type - - Size - - Date - - UserID - type: object - properties: - Name: - type: string - Path: - type: string - Type: - type: string - Size: - type: integer - ImageHeight: - type: integer - ImageWidth: - type: integer - UserID: - type: integer - ModelID: - type: integer - Date: - type: string - Simulator: - required: - - UUID - - Host - - ModelType - type: object - properties: - UUID: - type: string - Host: - type: string - ModelType: - type: string - UpTime: - type: integer - State: - type: string - StateUpdateAt: - type: string - Properties: - type: object - properties: {} - RawProperties: - type: object - properties: {} - Model: - required: - - Name - - OutputLength - - InputLength - - BelongsToSimulationID - - BelongsToSimulatorID - type: object - properties: - Name: - type: string - OutputLength: - type: integer - InputLength: - type: integer - SimulationID: - type: integer - SimulatorID: - type: integer - StartParameters: - type: object - properties: {} - OutputMapping: - type: array - items: - $ref: '#/components/schemas/Signal' - InputMapping: - type: array - items: - $ref: '#/components/schemas/Signal' - Signal: - required: - - Name - - Unit - - ModelID - type: object - properties: - Name: - type: string - Unit: - type: string - ModelID: - type: integer - Widget: - required: - - Name - - Type - - Width - - Height - - MinWidth - - MinHeight - - X - - Y - - Z - - IsLocked - - VisualizationID - type: object - properties: - Name: - type: string - Type: - type: string - Width: - type: integer - Height: - type: integer - MinWidth: - type: integer - MinHeight: - type: integer - X: - type: integer - Y: - type: integer - Z: - type: integer - IsLocked: - type: boolean - VisualizationID: - type: integer - CustomProperties: - type: object - properties: {} - - - diff --git a/routes/dashboard/dashboardEndpoints.go b/routes/dashboard/dashboardEndpoints.go new file mode 100644 index 0000000..7afbae1 --- /dev/null +++ b/routes/dashboard/dashboardEndpoints.go @@ -0,0 +1,183 @@ +package dashboard + +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" +) + +func RegisterDashboardEndpoints(r *gin.RouterGroup) { + + r.GET("", getDashboards) + r.POST("", addDashboard) + r.PUT("/:dashboardID", updateDashboard) + r.GET("/:dashboardID", getDashboard) + r.DELETE("/:dashboardID", deleteDashboard) +} + +// getDashboards godoc +// @Summary Get all dashboards of simulation +// @ID getDashboards +// @Produce json +// @Tags dashboards +// @Success 200 {array} common.DashboardResponse "Array of dashboards 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 /dashboards [get] +func getDashboards(c *gin.Context) { + + ok, sim := simulation.CheckPermissions(c, common.Read, "query", -1) + if !ok { + return + } + + db := common.GetDB() + var dab []common.Dashboard + err := db.Order("ID asc").Model(sim).Related(&dab, "Dashboards").Error + if common.ProvideErrorResponse(c, err) { + return + } + + serializer := common.DashboardsSerializer{c, dab} + c.JSON(http.StatusOK, gin.H{ + "dashboards": serializer.Response(), + }) +} + +// addDashboard godoc +// @Summary Add a dashboard to a simulation +// @ID addDashboard +// @Accept json +// @Produce json +// @Tags dashboards +// @Param inputDab body common.DashboardResponse true "Dashboard 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 /dashboards [post] +func addDashboard(c *gin.Context) { + + var newDab Dashboard + err := c.BindJSON(&newDab) + if err != nil { + errormsg := "Bad request. Error binding form data to JSON: " + err.Error() + c.JSON(http.StatusBadRequest, gin.H{ + "error": errormsg, + }) + return + } + + ok, _ := simulation.CheckPermissions(c, common.Create, "body", int(newDab.SimulationID)) + if !ok { + return + } + + // add dashboard to DB and add association to simulation + err = newDab.addToSimulation() + if common.ProvideErrorResponse(c, err) == false { + c.JSON(http.StatusOK, gin.H{ + "message": "OK.", + }) + } + +} + +// updateDashboard godoc +// @Summary Update a dashboard +// @ID updateDashboard +// @Tags dashboards +// @Accept json +// @Produce json +// @Param inputDab body common.DashboardResponse true "Dashboard to be updated" +// @Success 200 "OK." +// @Failure 401 "Unauthorized Access" +// @Failure 403 "Access forbidden." +// @Failure 404 "Not found" +// @Failure 500 "Internal server error" +// @Param dashboardID path int true "Dashboard ID" +// @Router /dashboards/{dashboardID} [put] +func updateDashboard(c *gin.Context) { + + ok, d := CheckPermissions(c, common.Update, "path", -1) + if !ok { + return + } + + var modifiedDab Dashboard + err := c.BindJSON(&modifiedDab) + if err != nil { + errormsg := "Bad request. Error binding form data to JSON: " + err.Error() + c.JSON(http.StatusBadRequest, gin.H{ + "error": errormsg, + }) + return + } + + err = d.update(modifiedDab) + if common.ProvideErrorResponse(c, err) == false { + c.JSON(http.StatusOK, gin.H{ + "message": "OK.", + }) + } +} + +// getDashboard godoc +// @Summary Get a dashboard +// @ID getDashboard +// @Tags dashboards +// @Produce json +// @Success 200 {object} common.DashboardResponse "Requested dashboard." +// @Failure 401 "Unauthorized Access" +// @Failure 403 "Access forbidden." +// @Failure 404 "Not found" +// @Failure 500 "Internal server error" +// @Param dashboardID path int true "Dashboard ID" +// @Router /dashboards/{dashboardID} [get] +func getDashboard(c *gin.Context) { + + ok, dab := CheckPermissions(c, common.Read, "path", -1) + if !ok { + return + } + + serializer := common.DashboardSerializer{c, dab.Dashboard} + c.JSON(http.StatusOK, gin.H{ + "dashboard": serializer.Response(), + }) +} + +// deleteDashboard godoc +// @Summary Delete a dashboard +// @ID deleteDashboard +// @Tags dashboards +// @Produce json +// @Success 200 "OK." +// @Failure 401 "Unauthorized Access" +// @Failure 403 "Access forbidden." +// @Failure 404 "Not found" +// @Failure 500 "Internal server error" +// @Param dashboardID path int true "Dashboard ID" +// @Router /dashboards/{dashboardID} [delete] +func deleteDashboard(c *gin.Context) { + ok, dab := CheckPermissions(c, common.Delete, "path", -1) + if !ok { + return + } + + err := dab.delete() + if common.ProvideErrorResponse(c, err) { + return + } + + c.JSON(http.StatusOK, gin.H{ + "message": "OK.", + }) +} diff --git a/routes/dashboard/dashboardMethods.go b/routes/dashboard/dashboardMethods.go new file mode 100644 index 0000000..1c0ef90 --- /dev/null +++ b/routes/dashboard/dashboardMethods.go @@ -0,0 +1,75 @@ +package dashboard + +import ( + "fmt" + + "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common" + "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulation" +) + +type Dashboard struct { + common.Dashboard +} + +func (v *Dashboard) save() error { + db := common.GetDB() + err := db.Create(v).Error + return err +} + +func (d *Dashboard) ByID(id uint) error { + db := common.GetDB() + err := db.Find(d, id).Error + if err != nil { + return fmt.Errorf("Dashboard with id=%v does not exist", id) + } + return nil +} + +func (d *Dashboard) addToSimulation() error { + db := common.GetDB() + var sim simulation.Simulation + err := sim.ByID(d.SimulationID) + if err != nil { + return err + } + + // save dashboard to DB + err = d.save() + if err != nil { + return err + } + + // associate dashboard with simulation + err = db.Model(&sim).Association("Dashboards").Append(d).Error + + return err +} + +func (d *Dashboard) update(modifiedDab Dashboard) error { + + db := common.GetDB() + + err := db.Model(d).Updates(map[string]interface{}{ + "Name": modifiedDab.Name, + "Grid": modifiedDab.Grid, + }).Error + + return err +} + +func (d *Dashboard) delete() error { + + db := common.GetDB() + var sim simulation.Simulation + err := sim.ByID(d.SimulationID) + if err != nil { + return err + } + + // remove association between Dashboard and Simulation + // Dashboard itself is not deleted from DB, it remains as "dangling" + err = db.Model(&sim).Association("Dashboards").Delete(d).Error + + return err +} diff --git a/routes/visualization/visualizationMiddleware.go b/routes/dashboard/dashboardMiddleware.go similarity index 51% rename from routes/visualization/visualizationMiddleware.go rename to routes/dashboard/dashboardMiddleware.go index 08319e7..be14a73 100644 --- a/routes/visualization/visualizationMiddleware.go +++ b/routes/dashboard/dashboardMiddleware.go @@ -1,4 +1,4 @@ -package visualization +package dashboard import ( "fmt" @@ -11,48 +11,48 @@ import ( "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulation" ) -func CheckPermissions(c *gin.Context, operation common.CRUD, visIDSource string, visIDBody int) (bool, Visualization) { +func CheckPermissions(c *gin.Context, operation common.CRUD, dabIDSource string, dabIDBody int) (bool, Dashboard) { - var vis Visualization + var dab Dashboard - err := common.ValidateRole(c, common.ModelVisualization, operation) + err := common.ValidateRole(c, common.ModelDashboard, operation) if err != nil { c.JSON(http.StatusUnprocessableEntity, "Access denied (role validation failed).") - return false, vis + return false, dab } - var visID int - if visIDSource == "path" { - visID, err = strconv.Atoi(c.Param("visualizationID")) + var dabID int + if dabIDSource == "path" { + dabID, err = strconv.Atoi(c.Param("dashboardID")) if err != nil { - errormsg := fmt.Sprintf("Bad request. No or incorrect format of simulationID path parameter") + errormsg := fmt.Sprintf("Bad request. No or incorrect format of dashboardID path parameter") c.JSON(http.StatusBadRequest, gin.H{ "error": errormsg, }) - return false, vis + return false, dab } - } else if visIDSource == "query" { - visID, err = strconv.Atoi(c.Request.URL.Query().Get("visualizationID")) + } else if dabIDSource == "query" { + dabID, err = strconv.Atoi(c.Request.URL.Query().Get("dashboardID")) if err != nil { - errormsg := fmt.Sprintf("Bad request. No or incorrect format of visualizationID query parameter") + errormsg := fmt.Sprintf("Bad request. No or incorrect format of dashboardID query parameter") c.JSON(http.StatusBadRequest, gin.H{ "error": errormsg, }) - return false, vis + return false, dab } - } else if visIDSource == "body" { - visID = visIDBody + } else if dabIDSource == "body" { + dabID = dabIDBody } - err = vis.ByID(uint(visID)) + err = dab.ByID(uint(dabID)) if common.ProvideErrorResponse(c, err) { - return false, vis + return false, dab } - ok, _ := simulation.CheckPermissions(c, operation, "body", int(vis.SimulationID)) + ok, _ := simulation.CheckPermissions(c, operation, "body", int(dab.SimulationID)) if !ok { - return false, vis + return false, dab } - return true, vis + return true, dab } diff --git a/routes/dashboard/dashboard_test.go b/routes/dashboard/dashboard_test.go new file mode 100644 index 0000000..19193fb --- /dev/null +++ b/routes/dashboard/dashboard_test.go @@ -0,0 +1,162 @@ +package dashboard + +import ( + "encoding/json" + "testing" + + "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/user" +) + +var token string + +type credentials struct { + Username string `json:"username"` + Password string `json:"password"` +} + +var cred = credentials{ + Username: "User_A", + Password: "abc123", +} + +var msgOK = common.ResponseMsg{ + Message: "OK.", +} + +var dabA = common.DashboardResponse{ + ID: 1, + Name: "Dashboard_A", + Grid: 15, + SimulationID: 1, +} + +var dabB = common.DashboardResponse{ + ID: 2, + Name: "Dashboard_B", + Grid: 15, + SimulationID: 1, +} + +var dabC = common.Dashboard{ + ID: 3, + Name: "Dashboard_C", + Grid: 99, + SimulationID: 1, +} + +var dabCupdated = common.Dashboard{ + ID: dabC.ID, + Name: "Dashboard_CUpdated", + SimulationID: dabC.SimulationID, + Grid: dabC.Grid, +} + +var dabC_response = common.DashboardResponse{ + ID: dabC.ID, + Name: dabC.Name, + Grid: dabC.Grid, + SimulationID: dabC.SimulationID, +} + +var dabC_responseUpdated = common.DashboardResponse{ + ID: dabCupdated.ID, + Name: dabCupdated.Name, + Grid: dabCupdated.Grid, + SimulationID: dabCupdated.SimulationID, +} + +var myDashboards = []common.DashboardResponse{ + dabA, + dabB, +} + +var msgDashboards = common.ResponseMsgDashboards{ + Dashboards: myDashboards, +} + +var msgDab = common.ResponseMsgDashboard{ + Dashboard: dabC_response, +} + +var msgDabupdated = common.ResponseMsgDashboard{ + Dashboard: dabC_responseUpdated, +} + +// Test /dashboards endpoints +func TestEndpoints(t *testing.T) { + + db := common.DummyInitDB() + defer db.Close() + common.DummyPopulateDB(db) + + router := gin.Default() + api := router.Group("/api") + + // All endpoints require authentication except when someone wants to + // login (POST /authenticate) + user.VisitorAuthenticate(api.Group("/authenticate")) + + api.Use(user.Authentication(true)) + + RegisterDashboardEndpoints(api.Group("/dashboards")) + + credjson, err := json.Marshal(cred) + if err != nil { + panic(err) + } + + msgOKjson, err := json.Marshal(msgOK) + if err != nil { + panic(err) + } + + msgDashboardsjson, err := json.Marshal(msgDashboards) + if err != nil { + panic(err) + } + + msgDabjson, err := json.Marshal(msgDab) + if err != nil { + panic(err) + } + + msgDabupdatedjson, err := json.Marshal(msgDabupdated) + if err != nil { + panic(err) + } + + dabCjson, err := json.Marshal(dabC) + if err != nil { + panic(err) + } + + dabCupdatedjson, err := json.Marshal(dabCupdated) + if err != nil { + panic(err) + } + + token = common.AuthenticateForTest(t, router, "/api/authenticate", "POST", credjson, 200) + + // test GET models + common.TestEndpoint(t, router, token, "/api/dashboards?simulationID=1", "GET", nil, 200, string(msgDashboardsjson)) + + // test POST models + common.TestEndpoint(t, router, token, "/api/dashboards", "POST", dabCjson, 200, string(msgOKjson)) + + // test GET models/:ModelID to check if previous POST worked correctly + common.TestEndpoint(t, router, token, "/api/dashboards/3", "GET", nil, 200, string(msgDabjson)) + + // test PUT models/:ModelID + common.TestEndpoint(t, router, token, "/api/dashboards/3", "PUT", dabCupdatedjson, 200, string(msgOKjson)) + common.TestEndpoint(t, router, token, "/api/dashboards/3", "GET", nil, 200, string(msgDabupdatedjson)) + + // test DELETE models/:ModelID + common.TestEndpoint(t, router, token, "/api/dashboards/3", "DELETE", nil, 200, string(msgOKjson)) + common.TestEndpoint(t, router, token, "/api/dashboards?simulationID=1", "GET", nil, 200, string(msgDashboardsjson)) + + // TODO add testing for other return codes + +} diff --git a/routes/visualization/visualizationEndpoints.go b/routes/visualization/visualizationEndpoints.go deleted file mode 100644 index 8180677..0000000 --- a/routes/visualization/visualizationEndpoints.go +++ /dev/null @@ -1,183 +0,0 @@ -package visualization - -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" -) - -func RegisterVisualizationEndpoints(r *gin.RouterGroup) { - - r.GET("", getVisualizations) - r.POST("", addVisualization) - r.PUT("/:visualizationID", updateVisualization) - r.GET("/:visualizationID", getVisualization) - r.DELETE("/:visualizationID", deleteVisualization) -} - -// 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) { - - ok, sim := simulation.CheckPermissions(c, common.Read, "query", -1) - if !ok { - return - } - - db := common.GetDB() - var vis []common.Visualization - err := db.Order("ID asc").Model(sim).Related(&vis, "Visualizations").Error - if common.ProvideErrorResponse(c, err) { - return - } - - serializer := common.VisualizationsSerializer{c, vis} - c.JSON(http.StatusOK, gin.H{ - "visualizations": serializer.Response(), - }) -} - -// 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) { - - var newVis Visualization - err := c.BindJSON(&newVis) - if err != nil { - errormsg := "Bad request. Error binding form data to JSON: " + err.Error() - c.JSON(http.StatusBadRequest, gin.H{ - "error": errormsg, - }) - return - } - - ok, _ := simulation.CheckPermissions(c, common.Create, "body", int(newVis.SimulationID)) - if !ok { - return - } - - // add visualization to DB and add association to simulation - err = newVis.addToSimulation() - if common.ProvideErrorResponse(c, err) == false { - c.JSON(http.StatusOK, gin.H{ - "message": "OK.", - }) - } - -} - -// 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) { - - ok, v := CheckPermissions(c, common.Update, "path", -1) - if !ok { - return - } - - var modifiedVis Visualization - err := c.BindJSON(&modifiedVis) - if err != nil { - errormsg := "Bad request. Error binding form data to JSON: " + err.Error() - c.JSON(http.StatusBadRequest, gin.H{ - "error": errormsg, - }) - return - } - - err = v.update(modifiedVis) - 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) { - - ok, vis := CheckPermissions(c, common.Read, "path", -1) - if !ok { - return - } - - serializer := common.VisualizationSerializer{c, vis.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) { - ok, vis := CheckPermissions(c, common.Delete, "path", -1) - if !ok { - return - } - - err := vis.delete() - if common.ProvideErrorResponse(c, err) { - return - } - - c.JSON(http.StatusOK, gin.H{ - "message": "OK.", - }) -} diff --git a/routes/visualization/visualizationMethods.go b/routes/visualization/visualizationMethods.go deleted file mode 100644 index 7f5b85c..0000000 --- a/routes/visualization/visualizationMethods.go +++ /dev/null @@ -1,75 +0,0 @@ -package visualization - -import ( - "fmt" - - "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common" - "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/simulation" -) - -type Visualization struct { - common.Visualization -} - -func (v *Visualization) save() error { - db := common.GetDB() - err := db.Create(v).Error - return err -} - -func (v *Visualization) ByID(id uint) error { - db := common.GetDB() - err := db.Find(v, id).Error - if err != nil { - return fmt.Errorf("Visualization with id=%v does not exist", id) - } - return nil -} - -func (v *Visualization) addToSimulation() error { - db := common.GetDB() - var sim simulation.Simulation - err := sim.ByID(v.SimulationID) - if err != nil { - return err - } - - // save visualization to DB - err = v.save() - if err != nil { - return err - } - - // associate visualization with simulation - err = db.Model(&sim).Association("Visualizations").Append(v).Error - - return err -} - -func (v *Visualization) update(modifiedVis Visualization) error { - - db := common.GetDB() - - err := db.Model(v).Updates(map[string]interface{}{ - "Name": modifiedVis.Name, - "Grid": modifiedVis.Grid, - }).Error - - return err -} - -func (v *Visualization) delete() error { - - db := common.GetDB() - var sim simulation.Simulation - err := sim.ByID(v.SimulationID) - if err != nil { - return err - } - - // remove association between Visualization and Simulation - // Visualization itself is not deleted from DB, it remains as "dangling" - err = db.Model(&sim).Association("Visualizations").Delete(v).Error - - return err -} diff --git a/routes/visualization/visualization_test.go b/routes/visualization/visualization_test.go deleted file mode 100644 index 68b5bbe..0000000 --- a/routes/visualization/visualization_test.go +++ /dev/null @@ -1,162 +0,0 @@ -package visualization - -import ( - "encoding/json" - "testing" - - "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/user" -) - -var token string - -type credentials struct { - Username string `json:"username"` - Password string `json:"password"` -} - -var cred = credentials{ - Username: "User_A", - Password: "abc123", -} - -var msgOK = common.ResponseMsg{ - Message: "OK.", -} - -var visA = common.VisualizationResponse{ - ID: 1, - Name: "Visualization_A", - Grid: 15, - SimulationID: 1, -} - -var visB = common.VisualizationResponse{ - ID: 2, - Name: "Visualization_B", - Grid: 15, - SimulationID: 1, -} - -var visC = common.Visualization{ - ID: 3, - Name: "Visualization_C", - Grid: 99, - SimulationID: 1, -} - -var visCupdated = common.Visualization{ - ID: visC.ID, - Name: "Visualization_CUpdated", - SimulationID: visC.SimulationID, - Grid: visC.Grid, -} - -var visC_response = common.VisualizationResponse{ - ID: visC.ID, - Name: visC.Name, - Grid: visC.Grid, - SimulationID: visC.SimulationID, -} - -var visC_responseUpdated = common.VisualizationResponse{ - ID: visCupdated.ID, - Name: visCupdated.Name, - Grid: visCupdated.Grid, - SimulationID: visCupdated.SimulationID, -} - -var myVisualizations = []common.VisualizationResponse{ - visA, - visB, -} - -var msgVisualizations = common.ResponseMsgVisualizations{ - Visualizations: myVisualizations, -} - -var msgVis = common.ResponseMsgVisualization{ - Visualization: visC_response, -} - -var msgVisupdated = common.ResponseMsgVisualization{ - Visualization: visC_responseUpdated, -} - -// Test /models endpoints -func TestVisualizationEndpoints(t *testing.T) { - - db := common.DummyInitDB() - defer db.Close() - common.DummyPopulateDB(db) - - router := gin.Default() - api := router.Group("/api") - - // All endpoints require authentication except when someone wants to - // login (POST /authenticate) - user.VisitorAuthenticate(api.Group("/authenticate")) - - api.Use(user.Authentication(true)) - - RegisterVisualizationEndpoints(api.Group("/visualizations")) - - credjson, err := json.Marshal(cred) - if err != nil { - panic(err) - } - - msgOKjson, err := json.Marshal(msgOK) - if err != nil { - panic(err) - } - - msgVisualizationsjson, err := json.Marshal(msgVisualizations) - if err != nil { - panic(err) - } - - msgVisjson, err := json.Marshal(msgVis) - if err != nil { - panic(err) - } - - msgVisupdatedjson, err := json.Marshal(msgVisupdated) - if err != nil { - panic(err) - } - - visCjson, err := json.Marshal(visC) - if err != nil { - panic(err) - } - - visCupdatedjson, err := json.Marshal(visCupdated) - if err != nil { - panic(err) - } - - token = common.AuthenticateForTest(t, router, "/api/authenticate", "POST", credjson, 200) - - // test GET models - common.TestEndpoint(t, router, token, "/api/visualizations?simulationID=1", "GET", nil, 200, string(msgVisualizationsjson)) - - // test POST models - common.TestEndpoint(t, router, token, "/api/visualizations", "POST", visCjson, 200, string(msgOKjson)) - - // test GET models/:ModelID to check if previous POST worked correctly - common.TestEndpoint(t, router, token, "/api/visualizations/3", "GET", nil, 200, string(msgVisjson)) - - // test PUT models/:ModelID - common.TestEndpoint(t, router, token, "/api/visualizations/3", "PUT", visCupdatedjson, 200, string(msgOKjson)) - common.TestEndpoint(t, router, token, "/api/visualizations/3", "GET", nil, 200, string(msgVisupdatedjson)) - - // test DELETE models/:ModelID - common.TestEndpoint(t, router, token, "/api/visualizations/3", "DELETE", nil, 200, string(msgOKjson)) - common.TestEndpoint(t, router, token, "/api/visualizations?simulationID=1", "GET", nil, 200, string(msgVisualizationsjson)) - - // TODO add testing for other return codes - -} diff --git a/routes/widget/widgetEndpoints.go b/routes/widget/widgetEndpoints.go index 3b16839..f18b3d8 100644 --- a/routes/widget/widgetEndpoints.go +++ b/routes/widget/widgetEndpoints.go @@ -6,7 +6,7 @@ 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/visualization" + "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/dashboard" ) func RegisterWidgetEndpoints(r *gin.RouterGroup) { @@ -18,27 +18,27 @@ func RegisterWidgetEndpoints(r *gin.RouterGroup) { } // getWidgets godoc -// @Summary Get all widgets of visualization +// @Summary Get all widgets of dashboard // @ID getWidgets // @Produce json // @Tags widgets -// @Success 200 {array} common.WidgetResponse "Array of widgets to which belong to visualization" +// @Success 200 {array} common.WidgetResponse "Array of widgets to which belong to dashboard" // @Failure 401 "Unauthorized Access" // @Failure 403 "Access forbidden." // @Failure 404 "Not found" // @Failure 500 "Internal server error" -// @Param visualizationID query int true "Visualization ID" +// @Param dashboardID query int true "Dashboard ID" // @Router /widgets [get] func getWidgets(c *gin.Context) { - ok, vis := visualization.CheckPermissions(c, common.Read, "query", -1) + ok, dab := dashboard.CheckPermissions(c, common.Read, "query", -1) if !ok { return } db := common.GetDB() var widgets []common.Widget - err := db.Order("ID asc").Model(vis).Related(&widgets, "Widgets").Error + err := db.Order("ID asc").Model(dab).Related(&widgets, "Widgets").Error if common.ProvideErrorResponse(c, err) { return } @@ -50,12 +50,12 @@ func getWidgets(c *gin.Context) { } // addWidget godoc -// @Summary Add a widget to a visualization +// @Summary Add a widget to a dashboard // @ID addWidget // @Accept json // @Produce json // @Tags widgets -// @Param inputWidget body common.WidgetResponse true "Widget to be added incl. ID of visualization" +// @Param inputWidget body common.WidgetResponse true "Widget to be added incl. ID of dashboard" // @Success 200 "OK." // @Failure 401 "Unauthorized Access" // @Failure 403 "Access forbidden." @@ -74,12 +74,12 @@ func addWidget(c *gin.Context) { return } - ok, _ := visualization.CheckPermissions(c, common.Create, "body", int(newWidget.VisualizationID)) + ok, _ := dashboard.CheckPermissions(c, common.Create, "body", int(newWidget.DashboardID)) if !ok { return } - err = newWidget.addToVisualization() + err = newWidget.addToDashboard() if common.ProvideErrorResponse(c, err) == false { c.JSON(http.StatusOK, gin.H{ diff --git a/routes/widget/widgetMethods.go b/routes/widget/widgetMethods.go index f476e0b..aeb3e90 100644 --- a/routes/widget/widgetMethods.go +++ b/routes/widget/widgetMethods.go @@ -4,7 +4,7 @@ import ( "fmt" "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common" - "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/visualization" + "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/dashboard" ) type Widget struct { @@ -26,22 +26,22 @@ func (w *Widget) ByID(id uint) error { return nil } -func (w *Widget) addToVisualization() error { +func (w *Widget) addToDashboard() error { db := common.GetDB() - var vis visualization.Visualization - err := vis.ByID(uint(w.VisualizationID)) + var dab dashboard.Dashboard + err := dab.ByID(uint(w.DashboardID)) if err != nil { return err } - // save visualization to DB + // save widget to DB err = w.save() if err != nil { return err } - // associate visualization with simulation - err = db.Model(&vis).Association("Widgets").Append(w).Error + // associate dashboard with simulation + err = db.Model(&dab).Association("Widgets").Append(w).Error return err } @@ -69,15 +69,15 @@ func (w *Widget) update(modifiedWidget Widget) error { func (w *Widget) delete() error { db := common.GetDB() - var vis visualization.Visualization - err := vis.ByID(w.VisualizationID) + var dab dashboard.Dashboard + err := dab.ByID(w.DashboardID) if err != nil { return err } - // remove association between Visualization and Widget + // remove association between Dashboard and Widget // Widget itself is not deleted from DB, it remains as "dangling" - err = db.Model(&vis).Association("Widgets").Delete(w).Error + err = db.Model(&dab).Association("Widgets").Delete(w).Error // TODO: What about files that belong to a widget? Keep them or remove them here? diff --git a/routes/widget/widgetMiddleware.go b/routes/widget/widgetMiddleware.go index 1bf85f5..c6d3f06 100644 --- a/routes/widget/widgetMiddleware.go +++ b/routes/widget/widgetMiddleware.go @@ -8,7 +8,7 @@ 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/visualization" + "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/dashboard" ) func CheckPermissions(c *gin.Context, operation common.CRUD, widgetIDBody int) (bool, Widget) { @@ -40,7 +40,7 @@ func CheckPermissions(c *gin.Context, operation common.CRUD, widgetIDBody int) ( return false, w } - ok, _ := visualization.CheckPermissions(c, operation, "body", int(w.VisualizationID)) + ok, _ := dashboard.CheckPermissions(c, operation, "body", int(w.DashboardID)) if !ok { return false, w } diff --git a/routes/widget/widget_test.go b/routes/widget/widget_test.go index 1fb01ae..0994a3f 100644 --- a/routes/widget/widget_test.go +++ b/routes/widget/widget_test.go @@ -39,7 +39,7 @@ var wdgA = common.WidgetResponse{ Z: 0, IsLocked: false, CustomProperties: "", - VisualizationID: 1, + DashboardID: 1, } var wdgB = common.WidgetResponse{ @@ -55,7 +55,7 @@ var wdgB = common.WidgetResponse{ Z: 0, IsLocked: false, CustomProperties: "", - VisualizationID: 1, + DashboardID: 1, } var wdgC = common.Widget{ @@ -71,7 +71,7 @@ var wdgC = common.Widget{ Z: 13, IsLocked: false, CustomProperties: "", - VisualizationID: 1, + DashboardID: 1, } var wdgCupdated = common.Widget{ @@ -87,7 +87,7 @@ var wdgCupdated = common.Widget{ Z: wdgC.Z, IsLocked: wdgC.IsLocked, CustomProperties: wdgC.CustomProperties, - VisualizationID: wdgC.VisualizationID, + DashboardID: wdgC.DashboardID, } var wdgC_response = common.WidgetResponse{ @@ -103,7 +103,7 @@ var wdgC_response = common.WidgetResponse{ Z: wdgC.Z, IsLocked: wdgC.IsLocked, CustomProperties: wdgC.CustomProperties, - VisualizationID: wdgC.VisualizationID, + DashboardID: wdgC.DashboardID, } var wdgC_responseUpdated = common.WidgetResponse{ @@ -119,7 +119,7 @@ var wdgC_responseUpdated = common.WidgetResponse{ Z: wdgC.Z, IsLocked: wdgC.IsLocked, CustomProperties: wdgC.CustomProperties, - VisualizationID: wdgC.VisualizationID, + DashboardID: wdgC.DashboardID, } var myWidgets = []common.WidgetResponse{ @@ -139,7 +139,7 @@ var msgWdgupdated = common.ResponseMsgWidget{ Widget: wdgC_responseUpdated, } -// Test /models endpoints +// Test /widgets endpoints func TestWidgetEndpoints(t *testing.T) { db := common.DummyInitDB() @@ -194,22 +194,22 @@ func TestWidgetEndpoints(t *testing.T) { token = common.AuthenticateForTest(t, router, "/api/authenticate", "POST", credjson, 200) - // test GET models - common.TestEndpoint(t, router, token, "/api/widgets?visualizationID=1", "GET", nil, 200, string(msgWidgetsjson)) + // test GET widgets + common.TestEndpoint(t, router, token, "/api/widgets?dashboardID=1", "GET", nil, 200, string(msgWidgetsjson)) - // test POST models + // test POST widgets common.TestEndpoint(t, router, token, "/api/widgets", "POST", wdgCjson, 200, string(msgOKjson)) - // test GET models/:ModelID to check if previous POST worked correctly + // test GET widgets/:widgetID to check if previous POST worked correctly common.TestEndpoint(t, router, token, "/api/widgets/3", "GET", nil, 200, string(msgWdgjson)) - // test PUT models/:ModelID + // test PUT widgets/:widgetID common.TestEndpoint(t, router, token, "/api/widgets/3", "PUT", wdgCupdatedjson, 200, string(msgOKjson)) common.TestEndpoint(t, router, token, "/api/widgets/3", "GET", nil, 200, string(msgWdgupdatedjson)) - // test DELETE models/:ModelID + // test DELETE widgets/:widgetID common.TestEndpoint(t, router, token, "/api/widgets/3", "DELETE", nil, 200, string(msgOKjson)) - common.TestEndpoint(t, router, token, "/api/widgets?visualizationID=1", "GET", nil, 200, string(msgWidgetsjson)) + common.TestEndpoint(t, router, token, "/api/widgets?dashboardID=1", "GET", nil, 200, string(msgWidgetsjson)) // TODO add testing for other return codes diff --git a/start.go b/start.go index c0532f4..3880486 100644 --- a/start.go +++ b/start.go @@ -12,11 +12,11 @@ import ( "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common" _ "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/doc/api" // doc/api folder is used by Swag CLI, you have to import it + "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/dashboard" "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" "git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/routes/widget" ) @@ -57,7 +57,7 @@ func main() { simulation.RegisterSimulationEndpoints(api.Group("/simulations")) simulationmodel.RegisterSimulationModelEndpoints(api.Group("/models")) signal.RegisterSignalEndpoints(api.Group("/signals")) - visualization.RegisterVisualizationEndpoints(api.Group("/visualizations")) + dashboard.RegisterDashboardEndpoints(api.Group("/dashboards")) widget.RegisterWidgetEndpoints(api.Group("/widgets")) file.RegisterFileEndpoints(api.Group("/files")) user.RegisterUserEndpoints(api.Group("/users"))