From 4bd2e156ec4753f4001e078d521b570313196ee9 Mon Sep 17 00:00:00 2001 From: Valentin Beauchamp Date: Wed, 9 Aug 2023 18:03:10 +0200 Subject: [PATCH] feat(cli): binding info from object and devices --- ARANGO_API/handlers/devices.go | 8 +-- ARANGO_API/services/router.go | 8 +-- ARANGO_API/swagger.json | 6 +- BFF/controllers/devices.go | 89 ++++++++++++++++++++++++++++ BFF/handlers/devices.go | 67 +++++++++++++++++++-- BFF/services/router.go | 10 ++-- BFF/swagger.json | 85 +++++++++++++++++++++++++- CLI/controllers/commandController.go | 65 +++++++++++++------- 8 files changed, 294 insertions(+), 44 deletions(-) create mode 100644 BFF/controllers/devices.go diff --git a/ARANGO_API/handlers/devices.go b/ARANGO_API/handlers/devices.go index fc6e95d8a..59b9f37f8 100644 --- a/ARANGO_API/handlers/devices.go +++ b/ARANGO_API/handlers/devices.go @@ -8,7 +8,7 @@ import ( "github.com/gin-gonic/gin" ) -// swagger:operation GET /Devices Devices Devices +// swagger:operation GET /devices Devices Devices // Get Devices list // // --- @@ -61,7 +61,7 @@ func GetDevices(c *gin.Context) { c.IndentedJSON(http.StatusOK, devices) } -// swagger:operation GET /Devices/ConnecteTo/{device} Devices GetDevicesConnectedTo +// swagger:operation GET /devices/ConnecteTo/{device} Devices GetDevicesConnectedTo // Get Devices connected to a device // // --- @@ -120,7 +120,7 @@ func GetDevicesConnectedTo(c *gin.Context) { c.IndentedJSON(http.StatusOK, devices) } -// swagger:operation POST /Devices Devices CreateDevices +// swagger:operation POST /devices Devices CreateDevices // Create new Devices // // --- @@ -168,7 +168,7 @@ func PostDevices(c *gin.Context) { c.IndentedJSON(http.StatusCreated, result) } -// swagger:operation DELETE /Devices/{device} Devices DeleteDevices +// swagger:operation DELETE /devices/{device} Devices DeleteDevices // Delete Devices by key // // --- diff --git a/ARANGO_API/services/router.go b/ARANGO_API/services/router.go index 5294349a4..9b2ebcccc 100644 --- a/ARANGO_API/services/router.go +++ b/ARANGO_API/services/router.go @@ -41,10 +41,10 @@ func InitRouter(db driver.Database, addr string) *gin.Engine { router.Use(DBMiddleware(db, addr)) proteted := router.Group("/api") //proteted.Use(JwtAuthMiddleware()) - proteted.GET("/Devices", handlers.GetDevices) - proteted.POST("/Devices", handlers.PostDevices) - proteted.DELETE("/Devices/:key", handlers.DeleteDevice) - proteted.GET("/Devices/ConnecteTo/:key", handlers.GetDevicesConnectedTo) + proteted.GET("/:devices", handlers.GetDevices) + proteted.POST("/:devices", handlers.PostDevices) + proteted.DELETE(":devices/:key", handlers.DeleteDevice) + proteted.GET(":devices/ConnecteTo/:key", handlers.GetDevicesConnectedTo) proteted.GET("/Connections", handlers.GetConnection) proteted.POST("/Connections", handlers.PostConnection) diff --git a/ARANGO_API/swagger.json b/ARANGO_API/swagger.json index 816cf9753..a28b4a59d 100644 --- a/ARANGO_API/swagger.json +++ b/ARANGO_API/swagger.json @@ -149,7 +149,7 @@ } } }, - "/Devices": { + "/devices": { "get": { "security": [ { @@ -247,7 +247,7 @@ } } }, - "/Devices/ConnecteTo/{device}": { + "/devices/ConnecteTo/{device}": { "get": { "security": [ { @@ -312,7 +312,7 @@ } } }, - "/Devices/{device}": { + "/devices/{device}": { "delete": { "security": [ { diff --git a/BFF/controllers/devices.go b/BFF/controllers/devices.go new file mode 100644 index 000000000..e0802d21c --- /dev/null +++ b/BFF/controllers/devices.go @@ -0,0 +1,89 @@ +package controllers + +import ( + + "net/http" + "ogree-bff/utils/token" + + "github.com/gin-gonic/gin" +) + + + +func DeviceBindingObject(c *gin.Context,database string) { + + objAttr:= c.Param("objAttr") + + obj := c.Param("obj") + + //MONGO Check + mongoURL, ok := c.Value("mongo").(string) + if !ok { + c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Failed to get api connection"}) + return + } + key := token.ExtractToken(c) + mongoResp,err := Send("GET",mongoURL+"/api/objects/"+obj,"",key,nil) + if err != nil { + if mongoResp != nil { + result := GetJSONBody(mongoResp) + c.IndentedJSON(mongoResp.StatusCode,result.Message) + return + } + c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": err.Error()}) + return + } + mongoBody:=GetJSONBody(mongoResp) + if mongoBody.StatusCode != http.StatusOK { + c.IndentedJSON(mongoBody.StatusCode,mongoBody.Message) + return + } + mongoDataResult := mongoBody.Message.(map[string]interface{}) + mongoResult := mongoDataResult["data"].(map[string]interface{}) + if mongoResult["category"] != "device"{ + c.IndentedJSON(http.StatusBadRequest, gin.H{"message":obj +" is not a device"}) + return + } + mongoAttr := mongoResult["attributes"].(map[string]interface{}) + if mongoAttr[objAttr] == nil && mongoResult[objAttr] == nil { + c.IndentedJSON(http.StatusBadRequest, gin.H{"message":obj +" has not attributes :" + objAttr}) + return + } + var attributeNeed string + if mongoResult[objAttr] != nil { + attributeNeed = mongoResult[objAttr].(string) + }else{ + attributeNeed = mongoAttr[objAttr].(string) + } + + //ARANGO + deviceAttr:= c.Param("deviceAttr") + deviceURL, ok := c.Value(database).(string) + if !ok { + c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Failed to get api connection"}) + return + } + query := GetQueryString(c) + if query == "" { + query +="?"+deviceAttr+"="+attributeNeed + }else{ + query +="&"+deviceAttr+"="+attributeNeed + } + + deviceResp,err := Send("GET",deviceURL+"/api/devices",query,key,nil) + if err != nil { + if deviceResp != nil { + result := GetJSONBody(deviceResp) + c.IndentedJSON(deviceResp.StatusCode,result.Message) + return + } + c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": err.Error()}) + return + } + result := GetJSONBody(deviceResp) + c.IndentedJSON(deviceResp.StatusCode, result.Message) + return + + + +} \ No newline at end of file diff --git a/BFF/handlers/devices.go b/BFF/handlers/devices.go index 1503c62c8..77c454273 100644 --- a/BFF/handlers/devices.go +++ b/BFF/handlers/devices.go @@ -6,7 +6,7 @@ import ( "github.com/gin-gonic/gin" ) -// swagger:operation GET /Devices Devices Devices +// swagger:operation GET /devices Devices Devices // Get Devices list // // --- @@ -49,7 +49,7 @@ func GetDevices(c *gin.Context) { controllers.Get(c,"arango") } -// swagger:operation GET /Devices/ConnecteTo/{device} Devices GetDevicesConnectedTo +// swagger:operation GET /devices/ConnecteTo/{device} Devices GetDevicesConnectedTo // Get Devices connected to a device // // --- @@ -95,7 +95,7 @@ func GetDevices(c *gin.Context) { func GetDevicesConnectedTo(c *gin.Context) { controllers.Get(c,"arango") } -// swagger:operation POST /Devices Devices CreateDevices +// swagger:operation POST /devices Devices CreateDevices // Create new Devices // // --- @@ -123,7 +123,7 @@ func CreateDevices(c *gin.Context) { controllers.Post(c,"arango") } -// swagger:operation DELETE /Devices/{device} Devices DeleteDevices +// swagger:operation DELETE /devices/{device} Devices DeleteDevices // Delete Devices by key // // --- @@ -240,4 +240,63 @@ func CreateConnections(c *gin.Context){ // "$ref": "#/definitions/ErrorResponse" func DeleteConnections(c *gin.Context){ controllers.Delete(c,"arango") +} + + + +// swagger:operation GET /devices/{obj}/objAttr/{objAttr}/deviceAttr/{deviceAttr} Devices GetDeviceBindingObject +// Get Devices list +// +// --- +// parameters: +// - name: obj +// in: path +// description: object for binding +// required: true +// type: string +// - name: objAttr +// in: path +// description: object attribute for binding +// required: true +// type: string +// - name: deviceAttr +// in: path +// description: devices attribute for binding +// required: true +// type: string +// - name: _key +// in: query +// description: Key of device +// required: false +// type: string +// - name: _name +// in: query +// description: Name of device +// required: false +// type: string +// - name: group_name +// in: query +// description: Group_name of device +// required: false +// type: string +// - name: serial +// in: query +// description: Serial number of device +// required: false +// type: string +// security: +// - Bearer: [] +// responses: +// '200': +// description: successful +// schema: +// items: +// "$ref": "#/definitions/SuccessResponse" +// '500': +// description: Error +// schema: +// items: +// "$ref": "#/definitions/ErrorResponse" +func GetDeviceBindingObject(c*gin.Context){ + controllers.DeviceBindingObject(c,"arango") } \ No newline at end of file diff --git a/BFF/services/router.go b/BFF/services/router.go index f8d01a3ad..370c0f320 100644 --- a/BFF/services/router.go +++ b/BFF/services/router.go @@ -39,14 +39,16 @@ func APIMiddleware(apiList []models.API) gin.HandlerFunc { } func initDevices(protected, unprotected *gin.RouterGroup){ - protected.GET("/Devices",handlers.GetDevices) - protected.GET("/Devices/ConnecteTo/:key",handlers.GetDevicesConnectedTo) - protected.POST("/Devices",handlers.CreateDevices) - protected.DELETE("/Devices/:id",handlers.DeleteDevice) + protected.GET("/devices",handlers.GetDevices) + protected.GET("/devices/ConnecteTo/:key",handlers.GetDevicesConnectedTo) + protected.POST("/devices",handlers.CreateDevices) + protected.DELETE("/devices/:id",handlers.DeleteDevice) protected.GET("/Connections",handlers.GetConnections) protected.POST("/Connections",handlers.CreateConnections) protected.DELETE("/Connections/:id",handlers.DeleteConnections) + + protected.GET("/devices/:obj/objAttr/:objAttr/deviceAttr/:deviceAttr",handlers.GetDeviceBindingObject) } func initAuth(protected, unprotected *gin.RouterGroup){ diff --git a/BFF/swagger.json b/BFF/swagger.json index 9fd40d01f..4a0527563 100644 --- a/BFF/swagger.json +++ b/BFF/swagger.json @@ -149,7 +149,7 @@ } } }, - "/Devices": { + "/devices": { "get": { "security": [ { @@ -247,7 +247,7 @@ } } }, - "/Devices/ConnecteTo/{device}": { + "/devices/ConnecteTo/{device}": { "get": { "security": [ { @@ -312,7 +312,7 @@ } } }, - "/Devices/{device}": { + "/devices/{device}": { "delete": { "security": [ { @@ -353,6 +353,85 @@ } } }, + "/devices/{obj}/objAttr/{objAttr}/deviceAttr/{deviceAttr}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "Get Devices list", + "tags": [ + "Devices" + ], + "operationId": "GetDeviceBindingObject", + "parameters": [ + { + "type": "string", + "description": "object for binding", + "name": "obj", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "object attribute for binding", + "name": "objAttr", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "devices attribute for binding", + "name": "deviceAttr", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Key of device", + "name": "_key", + "in": "query" + }, + { + "type": "string", + "description": "Name of device", + "name": "_name", + "in": "query" + }, + { + "type": "string", + "description": "Group_name of device", + "name": "group_name", + "in": "query" + }, + { + "type": "string", + "description": "Serial number of device", + "name": "serial", + "in": "query" + } + ], + "responses": { + "200": { + "description": "successful", + "schema": { + "items": { + "$ref": "#/definitions/SuccessResponse" + } + } + }, + "500": { + "description": "Error", + "schema": { + "items": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + } + }, "/domains/bulk": { "post": { "security": [ diff --git a/CLI/controllers/commandController.go b/CLI/controllers/commandController.go index 293d46cbe..b5cdae588 100755 --- a/CLI/controllers/commandController.go +++ b/CLI/controllers/commandController.go @@ -70,14 +70,6 @@ func ObjectUrl(path string, depth int) (string, error) { return fmt.Sprintf(url + "/" + suffix), nil } -func GetObjectDevice(path string) (string,error) { - object := strings.Split(path,"/") - if(len(object) != 7) { - return "", fmt.Errorf(object[len(object)-1] +" is not a device"); - } - return object[6], nil -} - func IsTemplate(path string) bool { if strings.HasPrefix(path, "/Logical/ObjectTemplates/") { return true @@ -149,20 +141,48 @@ func PollObject(path string) (map[string]any, error) { func GetObject(path string) (map[string]any, error) { return GetObjectWithChildren(path, 0) } - +func ObjectAttributes(path string)(string, error){ + attr := strings.Split(path, "%"); + if(len(attr) !=2 ){ + return "name",nil + } + return attr[1],nil +} +func DevicesAttrs(devices string)(string, error){ + attr := strings.Split(strings.Split(devices,".")[0],"%"); + if(len(attr) !=2 ){ + return "group_name",nil + } + return attr[1],nil +} +func removeFirstOccurrence(input string, pattern string) string { + inputs := strings.Split(input,pattern) + if len(inputs) <3 { + return input + } + return strings.Join(inputs[2:],".") +} func GetDevicesInfo(path string,filters string) (map[string]any, error) { - device,err := GetObjectDevice(path) + + objAttr ,err:= ObjectAttributes(path) + if err != nil { + return nil, err + } + devicesAttr ,err:= DevicesAttrs(filters) if err != nil { return nil, err } - url,err := DevicesUrl(device,filters) + path = removeFirstOccurrence(path,"/") + + url,err := DevicesUrl(strings.Split(path,"%")[0],objAttr,devicesAttr,filters) if err != nil { return nil, err } resp, err := RequestAPI("GET", url, nil, http.StatusOK) if err != nil { if resp != nil && resp.status == http.StatusNotFound { - return nil, fmt.Errorf("Devices not found") + device := strings.Split(strings.Split(filters, ".")[0],"%")[0] + return nil, fmt.Errorf(device+" not found") } return nil, err } @@ -172,21 +192,22 @@ func GetDevicesInfo(path string,filters string) (map[string]any, error) { } return obj, nil } -func DevicesUrl(path,filters string) (string, error){ - query := GenerateQuery(filters) - device := strings.Split(filters, ".")[0] - if device == "devices" { - return "/api/Devices?group_name="+path+query,nil - } - return "", fmt.Errorf("invalid object path") +func DevicesUrl(path,objAttr,devAttr,filters string) (string, error){ + query := GenerateDeviceQuery(filters) + device := strings.Split(strings.Split(filters, ".")[0],"%")[0] + return "/api/"+device+"/"+path+"/objAttr/"+objAttr+"/deviceAttr/"+devAttr+query,nil } -func GenerateQuery(filters string) (string) { +func GenerateDeviceQuery(filters string) (string) { queries:= strings.Split(filters,".") result:="" for _,query := range queries { if strings.Contains(query,"="){ - result+="&"+query + if result == "" { + result+= "?"+query + }else{ + result+="&"+query + } } } return result @@ -677,7 +698,7 @@ func Help(entry string) { case "ls", "pwd", "print", "cd", "tree", "get", "clear", "lsog", "grep", "for", "while", "if", "env", "cmds", "var", "unset", "selection", "camera", "ui", "hc", "drawable", - "link", "unlink", "draw", "getu", "getslot","undraw", + "link", "unlink", "draw", "getu", "getslot", "undraw", "lsenterprise": path = "./other/man/" + entry + ".md"