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
 }