github.com/netdata/go.d.plugin@v0.58.1/modules/activemq/apiclient.go (about) 1 // SPDX-License-Identifier: GPL-3.0-or-later 2 3 package activemq 4 5 import ( 6 "encoding/xml" 7 "fmt" 8 "github.com/netdata/go.d.plugin/pkg/web" 9 "io" 10 "net/http" 11 "net/url" 12 "path" 13 ) 14 15 type topics struct { 16 XMLName xml.Name `xml:"topics"` 17 Items []topic `xml:"topic"` 18 } 19 20 type topic struct { 21 XMLName xml.Name `xml:"topic"` 22 Name string `xml:"name,attr"` 23 Stats stats `xml:"stats"` 24 } 25 26 type queues struct { 27 XMLName xml.Name `xml:"queues"` 28 Items []queue `xml:"queue"` 29 } 30 31 type queue struct { 32 XMLName xml.Name `xml:"queue"` 33 Name string `xml:"name,attr"` 34 Stats stats `xml:"stats"` 35 } 36 37 type stats struct { 38 XMLName xml.Name `xml:"stats"` 39 Size int64 `xml:"size,attr"` 40 ConsumerCount int64 `xml:"consumerCount,attr"` 41 EnqueueCount int64 `xml:"enqueueCount,attr"` 42 DequeueCount int64 `xml:"dequeueCount,attr"` 43 } 44 45 const pathStats = "/%s/xml/%s.jsp" 46 47 func newAPIClient(client *http.Client, request web.Request, webadmin string) *apiClient { 48 return &apiClient{ 49 httpClient: client, 50 request: request, 51 webadmin: webadmin, 52 } 53 } 54 55 type apiClient struct { 56 httpClient *http.Client 57 request web.Request 58 webadmin string 59 } 60 61 func (a *apiClient) getQueues() (*queues, error) { 62 req, err := a.createRequest(fmt.Sprintf(pathStats, a.webadmin, keyQueues)) 63 if err != nil { 64 return nil, fmt.Errorf("error on creating request '%s' : %v", a.request.URL, err) 65 } 66 67 resp, err := a.doRequestOK(req) 68 69 defer closeBody(resp) 70 71 if err != nil { 72 return nil, err 73 } 74 75 var queues queues 76 77 if err := xml.NewDecoder(resp.Body).Decode(&queues); err != nil { 78 return nil, fmt.Errorf("error on decoding resp from %s : %s", req.URL, err) 79 } 80 81 return &queues, nil 82 } 83 84 func (a *apiClient) getTopics() (*topics, error) { 85 req, err := a.createRequest(fmt.Sprintf(pathStats, a.webadmin, keyTopics)) 86 if err != nil { 87 return nil, fmt.Errorf("error on creating request '%s' : %v", a.request.URL, err) 88 } 89 90 resp, err := a.doRequestOK(req) 91 92 defer closeBody(resp) 93 94 if err != nil { 95 return nil, err 96 } 97 98 var topics topics 99 100 if err := xml.NewDecoder(resp.Body).Decode(&topics); err != nil { 101 return nil, fmt.Errorf("error on decoding resp from %s : %s", req.URL, err) 102 } 103 104 return &topics, nil 105 } 106 107 func (a apiClient) doRequestOK(req *http.Request) (*http.Response, error) { 108 resp, err := a.httpClient.Do(req) 109 if err != nil { 110 return resp, fmt.Errorf("error on request to %s : %v", req.URL, err) 111 } 112 113 if resp.StatusCode != http.StatusOK { 114 return resp, fmt.Errorf("%s returned HTTP status %d", req.URL, resp.StatusCode) 115 } 116 117 return resp, err 118 } 119 120 func (a apiClient) createRequest(urlPath string) (*http.Request, error) { 121 req := a.request.Copy() 122 u, err := url.Parse(req.URL) 123 if err != nil { 124 return nil, err 125 } 126 u.Path = path.Join(u.Path, urlPath) 127 req.URL = u.String() 128 return web.NewHTTPRequest(req) 129 } 130 131 func closeBody(resp *http.Response) { 132 if resp != nil && resp.Body != nil { 133 _, _ = io.Copy(io.Discard, resp.Body) 134 _ = resp.Body.Close() 135 } 136 }