blob: 4572526bb791206f3561324dbfa16ab21ab434cd [file] [log] [blame]
mce7028402019-07-18 04:10:01 +00001// Copyright 2018 Open Networking Foundation
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package main
16
17import (
mce7028402019-07-18 04:10:01 +000018 "encoding/json"
Dinesh Belwalkara6ba07d2020-01-10 23:22:34 +000019 logrus "github.com/sirupsen/logrus"
mce7028402019-07-18 04:10:01 +000020 "io/ioutil"
Dinesh Belwalkar72ecafb2019-12-12 00:08:56 +000021 "net/http"
mce7028402019-07-18 04:10:01 +000022)
23
mc20a4b5f2019-10-16 20:28:24 +000024/* parse_map() parses the json structure, amap, and returns all sub-folder paths found at the 2nd level of the multiplayer structure
Dinesh Belwalkar72ecafb2019-12-12 00:08:56 +000025 */
mc20a4b5f2019-10-16 20:28:24 +000026func parse_map(amap map[string]interface{}, level uint, archive map[string]bool) (paths []string) {
27 level = level + 1
28 for key, val := range amap {
29 switch val.(type) {
30 case map[string]interface{}:
31 p := parse_map(val.(map[string]interface{}), level, archive)
32 paths = append(paths, p...)
33 case []interface{}:
34 p := parse_array(val.([]interface{}), level, archive)
35 paths = append(paths, p...)
36 default:
37 if level == 2 && key == "@odata.id" {
Dinesh Belwalkar72ecafb2019-12-12 00:08:56 +000038 /* 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. */
mc20a4b5f2019-10-16 20:28:24 +000039 if _, ok := archive[val.(string)]; !ok {
40 archive[val.(string)] = true
41 paths = append(paths, val.(string))
42 }
43 }
44 }
45 }
46 return paths
47}
mce7028402019-07-18 04:10:01 +000048
mc20a4b5f2019-10-16 20:28:24 +000049/* 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.
Dinesh Belwalkar72ecafb2019-12-12 00:08:56 +000050 */
mc20a4b5f2019-10-16 20:28:24 +000051func parse_array(anarray []interface{}, level uint, archive map[string]bool) (paths []string) {
52 for _, val := range anarray {
53 switch val.(type) {
54 case map[string]interface{}:
55 p := parse_map(val.(map[string]interface{}), level, archive)
56 paths = append(paths, p...)
57 }
58 }
59 return paths
60}
61
62/* read_resource() reads data from the specified Redfish resource, including its sub-folders, of the specified device ip and rerutnrs the data read.
63
64Based 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.
65*/
66func read_resource(ip string, resource string, archive map[string]bool) (data []string) {
67 resp, err := http.Get(ip + resource)
68 if resp != nil {
69 defer resp.Body.Close()
70 }
mce7028402019-07-18 04:10:01 +000071 if err != nil {
Dinesh Belwalkara6ba07d2020-01-10 23:22:34 +000072 logrus.Errorf("Error http get %s", err)
mce7028402019-07-18 04:10:01 +000073 return
74 }
mc20a4b5f2019-10-16 20:28:24 +000075 body, err := ioutil.ReadAll(resp.Body)
76 if err != nil {
Dinesh Belwalkara6ba07d2020-01-10 23:22:34 +000077 logrus.Errorf("Error Read %s", err)
mc20a4b5f2019-10-16 20:28:24 +000078 return
mce7028402019-07-18 04:10:01 +000079 }
mc20a4b5f2019-10-16 20:28:24 +000080
81 data = append(data, string(body))
82
83 m := map[string]interface{}{}
84 err = json.Unmarshal([]byte(body), &m)
85 if err != nil {
Dinesh Belwalkara6ba07d2020-01-10 23:22:34 +000086 logrus.Errorf("Error Unmarshal %s", err)
mc20a4b5f2019-10-16 20:28:24 +000087 return
88 }
89
90 resources := parse_map(m, 0, archive)
91
92 for _, resource := range resources {
93 d := read_resource(ip, resource, archive)
94 data = append(data, d...)
95 }
96 return data
97}
98
99/* sample JSON files can be found in the samples folder */
100func (s *Server) get_status(ip string, resource string) (data []string) {
101 archive := make(map[string]bool)
102 base_ip := RF_DEFAULT_PROTOCOL + ip
103 /* 'archive' maintains a list of all resources that will be/have been visited to avoid duplicates */
104 archive[resource] = true
105 data = read_resource(base_ip, resource, archive)
106 return data
mce7028402019-07-18 04:10:01 +0000107}