1package rabbithole
2
3import (
4	"encoding/json"
5	"net/http"
6)
7
8//
9// GET /api/exchanges
10//
11
12type IngressEgressStats struct {
13	PublishIn        int         `json:"publish_in"`
14	PublishInDetails RateDetails `json:"publish_in_details"`
15
16	PublishOut        int         `json:"publish_out"`
17	PublishOutDetails RateDetails `json:"publish_out_details"`
18}
19
20type ExchangeInfo struct {
21	Name       string                 `json:"name"`
22	Vhost      string                 `json:"vhost"`
23	Type       string                 `json:"type"`
24	Durable    bool                   `json:"durable"`
25	AutoDelete bool                   `json:"auto_delete"`
26	Internal   bool                   `json:"internal"`
27	Arguments  map[string]interface{} `json:"arguments"`
28
29	MessageStats IngressEgressStats `json:"message_stats"`
30}
31
32type ExchangeSettings struct {
33	Type       string                 `json:"type"`
34	Durable    bool                   `json:"durable"`
35	AutoDelete bool                   `json:"auto_delete,omitempty"`
36	Arguments  map[string]interface{} `json:"arguments,omitempty"`
37}
38
39func (c *Client) ListExchanges() (rec []ExchangeInfo, err error) {
40	req, err := newGETRequest(c, "exchanges")
41	if err != nil {
42		return []ExchangeInfo{}, err
43	}
44
45	if err = executeAndParseRequest(c, req, &rec); err != nil {
46		return []ExchangeInfo{}, err
47	}
48
49	return rec, nil
50}
51
52//
53// GET /api/exchanges/{vhost}
54//
55
56func (c *Client) ListExchangesIn(vhost string) (rec []ExchangeInfo, err error) {
57	req, err := newGETRequest(c, "exchanges/"+PathEscape(vhost))
58	if err != nil {
59		return []ExchangeInfo{}, err
60	}
61
62	if err = executeAndParseRequest(c, req, &rec); err != nil {
63		return []ExchangeInfo{}, err
64	}
65
66	return rec, nil
67}
68
69//
70// GET /api/exchanges/{vhost}/{name}
71//
72
73// Example response:
74//
75// {
76//   "incoming": [
77//     {
78//       "stats": {
79//         "publish": 2760,
80//         "publish_details": {
81//           "rate": 20
82//         }
83//       },
84//       "channel_details": {
85//         "name": "127.0.0.1:46928 -> 127.0.0.1:5672 (2)",
86//         "number": 2,
87//         "connection_name": "127.0.0.1:46928 -> 127.0.0.1:5672",
88//         "peer_port": 46928,
89//         "peer_host": "127.0.0.1"
90//       }
91//     }
92//   ],
93//   "outgoing": [
94//     {
95//       "stats": {
96//         "publish": 1280,
97//         "publish_details": {
98//           "rate": 20
99//         }
100//       },
101//       "queue": {
102//         "name": "amq.gen-7NhO_yRr4lDdp-8hdnvfuw",
103//         "vhost": "rabbit\/hole"
104//       }
105//     }
106//   ],
107//   "message_stats": {
108//     "publish_in": 2760,
109//     "publish_in_details": {
110//       "rate": 20
111//     },
112//     "publish_out": 1280,
113//     "publish_out_details": {
114//       "rate": 20
115//     }
116//   },
117//   "name": "amq.fanout",
118//   "vhost": "rabbit\/hole",
119//   "type": "fanout",
120//   "durable": true,
121//   "auto_delete": false,
122//   "internal": false,
123//   "arguments": {
124//   }
125// }
126
127type ExchangeIngressDetails struct {
128	Stats          MessageStats      `json:"stats"`
129	ChannelDetails PublishingChannel `json:"channel_details"`
130}
131
132type PublishingChannel struct {
133	Number         int    `json:"number"`
134	Name           string `json:"name"`
135	ConnectionName string `json:"connection_name"`
136	PeerPort       Port   `json:"peer_port"`
137	PeerHost       string `json:"peer_host"`
138}
139
140type NameAndVhost struct {
141	Name  string `json:"name"`
142	Vhost string `json:"vhost"`
143}
144
145type ExchangeEgressDetails struct {
146	Stats MessageStats `json:"stats"`
147	Queue NameAndVhost `json:"queue"`
148}
149
150type DetailedExchangeInfo struct {
151	Name       string                 `json:"name"`
152	Vhost      string                 `json:"vhost"`
153	Type       string                 `json:"type"`
154	Durable    bool                   `json:"durable"`
155	AutoDelete bool                   `json:"auto_delete"`
156	Internal   bool                   `json:"internal"`
157	Arguments  map[string]interface{} `json:"arguments"`
158
159	Incoming []ExchangeIngressDetails `json:"incoming"`
160	Outgoing []ExchangeEgressDetails  `json:"outgoing"`
161}
162
163func (c *Client) GetExchange(vhost, exchange string) (rec *DetailedExchangeInfo, err error) {
164	req, err := newGETRequest(c, "exchanges/"+PathEscape(vhost)+"/"+PathEscape(exchange))
165	if err != nil {
166		return nil, err
167	}
168
169	if err = executeAndParseRequest(c, req, &rec); err != nil {
170		return nil, err
171	}
172
173	return rec, nil
174}
175
176//
177// PUT /api/exchanges/{vhost}/{exchange}
178//
179
180func (c *Client) DeclareExchange(vhost, exchange string, info ExchangeSettings) (res *http.Response, err error) {
181	if info.Arguments == nil {
182		info.Arguments = make(map[string]interface{})
183	}
184	body, err := json.Marshal(info)
185	if err != nil {
186		return nil, err
187	}
188
189	req, err := newRequestWithBody(c, "PUT", "exchanges/"+PathEscape(vhost)+"/"+PathEscape(exchange), body)
190	if err != nil {
191		return nil, err
192	}
193
194	res, err = executeRequest(c, req)
195	if err != nil {
196		return nil, err
197	}
198
199	return res, nil
200}
201
202//
203// DELETE /api/exchanges/{vhost}/{name}
204//
205
206func (c *Client) DeleteExchange(vhost, exchange string) (res *http.Response, err error) {
207	req, err := newRequestWithBody(c, "DELETE", "exchanges/"+PathEscape(vhost)+"/"+PathEscape(exchange), nil)
208	if err != nil {
209		return nil, err
210	}
211
212	res, err = executeRequest(c, req)
213	if err != nil {
214		return nil, err
215	}
216
217	return res, nil
218}
219