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