# 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"`
}
```