SEBA-841 importer to parse all status from redfish server for data collection purpose / remove demotest binary
SEBA-856 SendDeviceList- This API will add all devices in the list
SEBA-858 DeleteDeviceList- This API will remove all devices in the list
decouple add/remove event subscription routines and device data file update
remove 'protocol'
SEBA-874 get rid of the 'vendor' argument called by some API's
Change-Id: Icc044dd4661c3cc14f02ad1a5f52e18116da63aa
diff --git a/data_collector.go b/data_collector.go
index 77a67d9..c626427 100644
--- a/data_collector.go
+++ b/data_collector.go
@@ -18,48 +18,90 @@
"net/http"
"fmt"
"encoding/json"
- "regexp"
- "strings"
"io/ioutil"
)
-func (s *Server) get_status(ip string, service string) (rtn bool, data []string) {
- rtn = false
+/* parse_map() parses the json structure, amap, and returns all sub-folder paths found at the 2nd level of the multiplayer structure
+*/
+func parse_map(amap map[string]interface{}, level uint, archive map[string]bool) (paths []string) {
+ level = level + 1
+ for key, val := range amap {
+ switch val.(type) {
+ case map[string]interface{}:
+ p := parse_map(val.(map[string]interface{}), level, archive)
+ paths = append(paths, p...)
+ case []interface{}:
+ p := parse_array(val.([]interface{}), level, archive)
+ paths = append(paths, p...)
+ default:
+ if level == 2 && key == "@odata.id" {
+ /* sub-folder path of a resource can be found as the value of the key '@odata.id' showing up at the 2nd level of the data read from a resource. When a path is found, it's checked against the array 'archive' to avoid duplicates. */
+ if _, ok := archive[val.(string)]; !ok {
+ archive[val.(string)] = true
+ paths = append(paths, val.(string))
+ }
+ }
+ }
+ }
+ return paths
+}
- uri := s.devicemap[ip].Protocol + "://"+ip + REDFISH_ROOT + service
- fmt.Printf("%q", uri)
- resp, err := http.Get(uri)
+/* parse_array() parses any vlaue, if in the form of an array, of a key-value pair found in the json structure, and returns any paths found.
+*/
+func parse_array(anarray []interface{}, level uint, archive map[string]bool) (paths []string) {
+ for _, val := range anarray {
+ switch val.(type) {
+ case map[string]interface{}:
+ p := parse_map(val.(map[string]interface{}), level, archive)
+ paths = append(paths, p...)
+ }
+ }
+ return paths
+}
+
+/* read_resource() reads data from the specified Redfish resource, including its sub-folders, of the specified device ip and rerutnrs the data read.
+
+Based on careful examination of the data returned from several resources sampled, it was determined that sub-folder paths can be found as the value to the key '@odata.id' showing up at the 2nd level of the data read from a resource.
+*/
+func read_resource(ip string, resource string, archive map[string]bool) (data []string) {
+ resp, err := http.Get(ip + resource)
+ if resp != nil {
+ defer resp.Body.Close()
+ }
if err != nil {
fmt.Println(err)
return
}
- body := make(map[string]interface{})
- json.NewDecoder(resp.Body).Decode(&body)
- resp.Body.Close()
-
- if members, ok := body["Members"]; ok {
- re := regexp.MustCompile(`\[([^\[\]]*)\]`)
- memberstr := fmt.Sprintf("%v", members)
- matches := re.FindAllString(memberstr, -1)
- for _, match := range matches {
- m := strings.Trim(match, "[]")
- uri = s.devicemap[ip].Protocol +"://"+ip + strings.TrimPrefix(m, "@odata.id:")
- fmt.Println("Printing URI")
- fmt.Println(uri)
- resp, err = http.Get(uri)
- if err != nil {
- fmt.Println(err)
- } else {
- b, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- fmt.Println(err)
- } else {
- data = append(data, string(b))
- rtn = true
- }
- defer resp.Body.Close()
- }
- }
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ fmt.Println(err)
+ return
}
- return
+
+ data = append(data, string(body))
+
+ m := map[string]interface{}{}
+ err = json.Unmarshal([]byte(body), &m)
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+
+ resources := parse_map(m, 0, archive)
+
+ for _, resource := range resources {
+ d := read_resource(ip, resource, archive)
+ data = append(data, d...)
+ }
+ return data
+}
+
+/* sample JSON files can be found in the samples folder */
+func (s *Server) get_status(ip string, resource string) (data []string) {
+ archive := make(map[string]bool)
+ base_ip := RF_DEFAULT_PROTOCOL + ip
+ /* 'archive' maintains a list of all resources that will be/have been visited to avoid duplicates */
+ archive[resource] = true
+ data = read_resource(base_ip, resource, archive)
+ return data
}