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  }