# parse ```go= package main import ( "encoding/json" "flag" "fmt" "io" "io/ioutil" "net/http" "net/url" "strings" "time" ) var ( port = flag.String("port", "8080", "port") whatsup = flag.String("api", "http://whatsup-test.dev001.wise-paas.com", "api URL") emptyData = Data{ DeviceName: "-", PollTimeUtc: "1970-01-01T00:00:00Z", ID: "-", } emptySeries = Series{ PollTimeUtc: "1970-01-01T00:00:00Z", } ) func main() { flag.Parse() fmt.Println(*port) fmt.Println(*whatsup) http.HandleFunc("/", handler) http.HandleFunc("/api/v1/devices/", deviceHandler) http.ListenAndServe(":"+*port, nil) } func handler(w http.ResponseWriter, r *http.Request) { fmt.Println(time.Now(), r.URL.Path) token := r.Header.Get("Authorization") bytesBody, statusCode, err := call(r.Method, r.URL.Path, r.URL.RawQuery, token, r.Body) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(statusCode) w.Write(bytesBody) return } func deviceHandler(w http.ResponseWriter, r *http.Request) { fmt.Println(time.Now(), r.URL.Path) token := r.Header.Get("Authorization") w.Header().Set("Content-Type", "application/json") bytesBody, statusCode, err := call(r.Method, r.URL.Path, r.URL.RawQuery, token, r.Body) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } if statusCode > 299 { w.WriteHeader(statusCode) w.Write(bytesBody) return } switch { case strings.HasSuffix(r.URL.Path, "/cpu-utilization"): result, err := cpuJson(bytesBody) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } w.WriteHeader(statusCode) w.Write(result) return case strings.HasSuffix(r.URL.Path, "/memory-utilization"): result, err := memoryJson(bytesBody) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } w.WriteHeader(statusCode) w.Write(result) return case strings.HasSuffix(r.URL.Path, "/disk-utilization"): result, err := diskJson(bytesBody) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } w.WriteHeader(statusCode) w.Write(result) return default: w.WriteHeader(statusCode) w.Write(bytesBody) return } } func call(method, path, rawQuery, token string, reqBody io.ReadCloser) ([]byte, int, error) { split := strings.Split(*whatsup, "://") if len(split) != 2 { return nil, http.StatusInternalServerError, fmt.Errorf("invalid url") } url := url.URL{ Scheme: split[0], Host: split[1], Path: path, RawQuery: rawQuery, } client := &http.Client{ Timeout: 30 * time.Second, Transport: &http.Transport{DisableKeepAlives: true, DisableCompression: true,}, } req, err := http.NewRequest(method, url.String(), reqBody) if err != nil { return nil, http.StatusInternalServerError, err } setHeader(req, token) res, err := client.Do(req) if err != nil { return nil, http.StatusInternalServerError, err } if res == nil { return nil, http.StatusInternalServerError, fmt.Errorf("no response.") } defer res.Body.Close() var body []byte body, err = ioutil.ReadAll(res.Body) if err != nil { return nil, http.StatusInternalServerError, err } return body, res.StatusCode, nil } func setHeader(req *http.Request, token string) { req.Header.Set("Authorization", token) req.Header.Set("Content-Type", "application/json") } func cpuJson(bytesBody []byte) ([]byte, error) { var cpuStruct CpuUtilization if err := json.Unmarshal(bytesBody, &cpuStruct); err != nil { return nil, err } if cpuStruct.Data == nil || len(cpuStruct.Data) == 0 { cpuStruct.Data = []CpuData{{ Series: []CpuSeries{{ CpuID: "-", ID: "-", Series: emptySeries, }}, CpuID: "-", Cpu: "-", Data: emptyData, }} result, err := json.Marshal(cpuStruct) if err != nil { return nil, err } return result, nil } for i := 0; i < len(cpuStruct.Data); i++ { if cpuStruct.Data[i].Series == nil || len(cpuStruct.Data[i].Series) == 0 { cpuStruct.Data[i].Series = []CpuSeries{{ CpuID: "-", ID: "-", Series: emptySeries, }} continue } for j := 0; j < len(cpuStruct.Data[i].Series); j++ { cpuStruct.Data[i].Series[j].CpuID = cpuStruct.Data[i].CpuID cpuStruct.Data[i].Series[j].ID = cpuStruct.Data[i].ID } } result, err := json.Marshal(cpuStruct) if err != nil { return nil, err } return result, nil } func memoryJson(bytesBody []byte) ([]byte, error) { var memStruct MemoryUtilization if err := json.Unmarshal(bytesBody, &memStruct); err != nil { return nil, err } if memStruct.Data == nil || len(memStruct.Data) == 0 { memStruct.Data = []MemoryData{{ Series: []MemorySeries{{ MemoryID: "-", ID: "-", Series: emptySeries, }}, MemoryID: "-", Memory: "-", Data: emptyData, }} result, err := json.Marshal(memStruct) if err != nil { return nil, err } return result, nil } for i := 0; i < len(memStruct.Data); i++ { if memStruct.Data[i].Series == nil || len(memStruct.Data[i].Series) == 0 { memStruct.Data[i].Series = []MemorySeries{{ MemoryID: "-", ID: "-", Series: emptySeries, }, } continue } for j := 0; j < len(memStruct.Data[i].Series); j++ { memStruct.Data[i].Series[j].MemoryID = memStruct.Data[i].MemoryID memStruct.Data[i].Series[j].ID = memStruct.Data[i].ID } } result, err := json.Marshal(memStruct) if err != nil { return nil, err } return result, nil } func diskJson(bytesBody []byte) ([]byte, error) { var diskStruct DiskUtilization if err := json.Unmarshal(bytesBody, &diskStruct); err != nil { return nil, err } if diskStruct.Data == nil || len(diskStruct.Data) == 0 { diskStruct.Data = []DiskData{{ Series: []DiskSeries{{ DiskID: "-", ID: "-", Series: emptySeries, }}, DiskID: "-", Disk: "-", Data: emptyData, }} result, err := json.Marshal(diskStruct) if err != nil { return nil, err } return result, nil } for i := 0; i < len(diskStruct.Data); i++ { if diskStruct.Data[i].Series == nil || len(diskStruct.Data[i].Series) == 0 { diskStruct.Data[i].Series = []DiskSeries{{ DiskID: "-", ID: "-", Series: emptySeries, }, } continue } for j := 0; j < len(diskStruct.Data[i].Series); j++ { diskStruct.Data[i].Series[j].DiskID = diskStruct.Data[i].DiskID diskStruct.Data[i].Series[j].ID = diskStruct.Data[i].ID } } result, err := json.Marshal(diskStruct) if err != nil { return nil, err } return result, nil } type CpuUtilization struct { Paging Paging `json:"paging"` Data []CpuData `json:"data"` } type MemoryUtilization struct { Paging Paging `json:"paging"` Data []MemoryData `json:"data"` } type DiskUtilization struct { Paging Paging `json:"paging"` Data []DiskData `json:"data"` } type Paging struct { PageID string `json:"pageId"` Size int `json:"size"` } type CpuData struct { Cpu string `json:"cpu"` CpuID string `json:"cpuId"` Series []CpuSeries `json:"series"` Data } type MemoryData struct { Memory string `json:"memory"` MemoryID string `json:"memoryId"` Series []MemorySeries `json:"series"` Data } type DiskData struct { Disk string `json:"disk"` DiskID string `json:"diskId"` Series []DiskSeries `json:"series"` Data } type Data struct { DeviceName string `json:"deviceName"` PollTimeUtc string `json:"pollTimeUtc"` TimeFromLastPollSeconds int `json:"timeFromLastPollSeconds"` Size float64 `json:"size"` MinUsed float64 `json:"minUsed"` MaxUsed float64 `json:"maxUsed"` AvgUsed float64 `json:"avgUsed"` MinPercent float64 `json:"minPercent"` MaxPercent float64 `json:"maxPercent"` AvgPercent float64 `json:"avgPercent"` ID string `json:"id"` } type CpuSeries struct { CpuID string `json:"cpuId"` ID string `json:"id"` Series } type MemorySeries struct { MemoryID string `json:"memoryId"` ID string `json:"id"` Series } type DiskSeries struct { DiskID string `json:"diskId"` ID string `json:"id"` Series } type Series struct { PollTimeUtc string `json:"pollTimeUtc"` AvgPercent float64 `json:"avgPercent"` MinPercent float64 `json:"minPercent"` MaxPercent float64 `json:"maxPercent"` } ```