2015-11-19 05:45:05 +00:00
|
|
|
package rabbithole
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
)
|
|
|
|
|
2019-11-06 13:15:06 +00:00
|
|
|
// BackingQueueStatus exposes backing queue (queue storage engine) metrics.
|
|
|
|
// They can change in a future version of RabbitMQ.
|
2015-11-19 05:45:05 +00:00
|
|
|
type BackingQueueStatus struct {
|
2016-06-08 14:33:08 +00:00
|
|
|
Q1 int `json:"q1"`
|
|
|
|
Q2 int `json:"q2"`
|
|
|
|
Q3 int `json:"q3"`
|
|
|
|
Q4 int `json:"q4"`
|
2015-11-19 05:45:05 +00:00
|
|
|
// Total queue length
|
2016-06-08 14:33:08 +00:00
|
|
|
Length int64 `json:"len"`
|
2015-11-19 05:45:05 +00:00
|
|
|
// Number of pending acks from consumers
|
2016-06-08 14:33:08 +00:00
|
|
|
PendingAcks int64 `json:"pending_acks"`
|
2015-11-19 05:45:05 +00:00
|
|
|
// Number of messages held in RAM
|
2016-06-08 14:33:08 +00:00
|
|
|
RAMMessageCount int64 `json:"ram_msg_count"`
|
2015-11-19 05:45:05 +00:00
|
|
|
// Number of outstanding acks held in RAM
|
2016-06-08 14:33:08 +00:00
|
|
|
RAMAckCount int64 `json:"ram_ack_count"`
|
2015-11-19 05:45:05 +00:00
|
|
|
// Number of persistent messages in the store
|
2016-06-08 14:33:08 +00:00
|
|
|
PersistentCount int64 `json:"persistent_count"`
|
2015-11-19 05:45:05 +00:00
|
|
|
// Average ingress (inbound) rate, not including messages
|
|
|
|
// that straight through to auto-acking consumers.
|
2016-06-08 14:33:08 +00:00
|
|
|
AverageIngressRate float64 `json:"avg_ingress_rate"`
|
2015-11-19 05:45:05 +00:00
|
|
|
// Average egress (outbound) rate, not including messages
|
|
|
|
// that straight through to auto-acking consumers.
|
2016-06-08 14:33:08 +00:00
|
|
|
AverageEgressRate float64 `json:"avg_egress_rate"`
|
2015-11-19 05:45:05 +00:00
|
|
|
// rate at which unacknowledged message records enter RAM,
|
|
|
|
// e.g. because messages are delivered requiring acknowledgement
|
|
|
|
AverageAckIngressRate float32 `json:"avg_ack_ingress_rate"`
|
|
|
|
// rate at which unacknowledged message records leave RAM,
|
|
|
|
// e.g. because acks arrive or unacked messages are paged out
|
2016-06-08 14:33:08 +00:00
|
|
|
AverageAckEgressRate float32 `json:"avg_ack_egress_rate"`
|
2015-11-19 05:45:05 +00:00
|
|
|
}
|
|
|
|
|
2019-11-06 13:15:06 +00:00
|
|
|
// OwnerPidDetails describes an exclusive queue owner (connection).
|
2015-11-19 05:45:05 +00:00
|
|
|
type OwnerPidDetails struct {
|
|
|
|
Name string `json:"name"`
|
|
|
|
PeerPort Port `json:"peer_port"`
|
|
|
|
PeerHost string `json:"peer_host"`
|
|
|
|
}
|
|
|
|
|
2019-11-06 13:15:06 +00:00
|
|
|
// QueueInfo represents a queue, its properties and key metrics.
|
2015-11-19 05:45:05 +00:00
|
|
|
type QueueInfo struct {
|
|
|
|
// Queue name
|
2016-06-08 14:33:08 +00:00
|
|
|
Name string `json:"name"`
|
2015-11-19 05:45:05 +00:00
|
|
|
// Virtual host this queue belongs to
|
2016-06-08 14:33:08 +00:00
|
|
|
Vhost string `json:"vhost"`
|
2015-11-19 05:45:05 +00:00
|
|
|
// Is this queue durable?
|
2016-06-08 14:33:08 +00:00
|
|
|
Durable bool `json:"durable"`
|
2015-11-19 05:45:05 +00:00
|
|
|
// Is this queue auto-delted?
|
2016-06-08 14:33:08 +00:00
|
|
|
AutoDelete bool `json:"auto_delete"`
|
2015-11-19 05:45:05 +00:00
|
|
|
// Extra queue arguments
|
2016-06-08 14:33:08 +00:00
|
|
|
Arguments map[string]interface{} `json:"arguments"`
|
2015-11-19 05:45:05 +00:00
|
|
|
|
|
|
|
// RabbitMQ node that hosts master for this queue
|
2016-06-08 14:33:08 +00:00
|
|
|
Node string `json:"node"`
|
2015-11-19 05:45:05 +00:00
|
|
|
// Queue status
|
2019-11-06 13:15:06 +00:00
|
|
|
Status string `json:"state"`
|
2015-11-19 05:45:05 +00:00
|
|
|
|
|
|
|
// Total amount of RAM used by this queue
|
2016-06-08 14:33:08 +00:00
|
|
|
Memory int64 `json:"memory"`
|
2015-11-19 05:45:05 +00:00
|
|
|
// How many consumers this queue has
|
2016-06-08 14:33:08 +00:00
|
|
|
Consumers int `json:"consumers"`
|
2016-06-30 18:19:03 +00:00
|
|
|
// Utilisation of all the consumers
|
|
|
|
ConsumerUtilisation float64 `json:"consumer_utilisation"`
|
2015-11-19 05:45:05 +00:00
|
|
|
// If there is an exclusive consumer, its consumer tag
|
|
|
|
ExclusiveConsumerTag string `json:"exclusive_consumer_tag"`
|
|
|
|
|
|
|
|
// Policy applied to this queue, if any
|
|
|
|
Policy string `json:"policy"`
|
|
|
|
|
2016-06-08 14:33:08 +00:00
|
|
|
// Total bytes of messages in this queues
|
|
|
|
MessagesBytes int64 `json:"message_bytes"`
|
|
|
|
MessagesBytesPersistent int64 `json:"message_bytes_persistent"`
|
|
|
|
MessagesBytesRAM int64 `json:"message_bytes_ram"`
|
|
|
|
|
2015-11-19 05:45:05 +00:00
|
|
|
// Total number of messages in this queue
|
2016-06-08 14:33:08 +00:00
|
|
|
Messages int `json:"messages"`
|
|
|
|
MessagesDetails RateDetails `json:"messages_details"`
|
|
|
|
MessagesPersistent int `json:"messages_persistent"`
|
|
|
|
MessagesRAM int `json:"messages_ram"`
|
2015-11-19 05:45:05 +00:00
|
|
|
|
|
|
|
// Number of messages ready to be delivered
|
|
|
|
MessagesReady int `json:"messages_ready"`
|
|
|
|
MessagesReadyDetails RateDetails `json:"messages_ready_details"`
|
|
|
|
|
|
|
|
// Number of messages delivered and pending acknowledgements from consumers
|
|
|
|
MessagesUnacknowledged int `json:"messages_unacknowledged"`
|
|
|
|
MessagesUnacknowledgedDetails RateDetails `json:"messages_unacknowledged_details"`
|
|
|
|
|
|
|
|
MessageStats MessageStats `json:"message_stats"`
|
|
|
|
|
|
|
|
OwnerPidDetails OwnerPidDetails `json:"owner_pid_details"`
|
|
|
|
|
|
|
|
BackingQueueStatus BackingQueueStatus `json:"backing_queue_status"`
|
2019-04-12 15:51:37 +00:00
|
|
|
|
|
|
|
ActiveConsumers int64 `json:"active_consumers"`
|
|
|
|
}
|
|
|
|
|
2019-11-06 13:15:06 +00:00
|
|
|
// PagedQueueInfo is additional context returned for paginated requests.
|
2019-04-12 15:51:37 +00:00
|
|
|
type PagedQueueInfo struct {
|
|
|
|
Page int `json:"page"`
|
|
|
|
PageCount int `json:"page_count"`
|
|
|
|
PageSize int `json:"page_size"`
|
|
|
|
FilteredCount int `json:"filtered_count"`
|
|
|
|
ItemCount int `json:"item_count"`
|
|
|
|
TotalCount int `json:"total_count"`
|
|
|
|
Items []QueueInfo `json:"items"`
|
2015-11-19 05:45:05 +00:00
|
|
|
}
|
|
|
|
|
2019-11-06 13:15:06 +00:00
|
|
|
// DetailedQueueInfo is an alias for QueueInfo
|
2015-11-19 05:45:05 +00:00
|
|
|
type DetailedQueueInfo QueueInfo
|
|
|
|
|
|
|
|
//
|
|
|
|
// GET /api/queues
|
|
|
|
//
|
|
|
|
|
|
|
|
// [
|
|
|
|
// {
|
|
|
|
// "owner_pid_details": {
|
|
|
|
// "name": "127.0.0.1:46928 -> 127.0.0.1:5672",
|
|
|
|
// "peer_port": 46928,
|
|
|
|
// "peer_host": "127.0.0.1"
|
|
|
|
// },
|
|
|
|
// "message_stats": {
|
|
|
|
// "publish": 19830,
|
|
|
|
// "publish_details": {
|
|
|
|
// "rate": 5
|
|
|
|
// }
|
|
|
|
// },
|
|
|
|
// "messages": 15,
|
|
|
|
// "messages_details": {
|
|
|
|
// "rate": 0
|
|
|
|
// },
|
|
|
|
// "messages_ready": 15,
|
|
|
|
// "messages_ready_details": {
|
|
|
|
// "rate": 0
|
|
|
|
// },
|
|
|
|
// "messages_unacknowledged": 0,
|
|
|
|
// "messages_unacknowledged_details": {
|
|
|
|
// "rate": 0
|
|
|
|
// },
|
|
|
|
// "policy": "",
|
|
|
|
// "exclusive_consumer_tag": "",
|
|
|
|
// "consumers": 0,
|
|
|
|
// "memory": 143112,
|
|
|
|
// "backing_queue_status": {
|
|
|
|
// "q1": 0,
|
|
|
|
// "q2": 0,
|
|
|
|
// "delta": [
|
|
|
|
// "delta",
|
|
|
|
// "undefined",
|
|
|
|
// 0,
|
|
|
|
// "undefined"
|
|
|
|
// ],
|
|
|
|
// "q3": 0,
|
|
|
|
// "q4": 15,
|
|
|
|
// "len": 15,
|
|
|
|
// "pending_acks": 0,
|
|
|
|
// "target_ram_count": "infinity",
|
|
|
|
// "ram_msg_count": 15,
|
|
|
|
// "ram_ack_count": 0,
|
|
|
|
// "next_seq_id": 19830,
|
|
|
|
// "persistent_count": 0,
|
|
|
|
// "avg_ingress_rate": 4.9920127795527,
|
|
|
|
// "avg_egress_rate": 4.9920127795527,
|
|
|
|
// "avg_ack_ingress_rate": 0,
|
|
|
|
// "avg_ack_egress_rate": 0
|
|
|
|
// },
|
|
|
|
// "status": "running",
|
|
|
|
// "name": "amq.gen-QLEaT5Rn_ogbN3O8ZOQt3Q",
|
|
|
|
// "vhost": "rabbit\/hole",
|
|
|
|
// "durable": false,
|
|
|
|
// "auto_delete": false,
|
|
|
|
// "arguments": {
|
|
|
|
// "x-message-ttl": 5000
|
|
|
|
// },
|
|
|
|
// "node": "rabbit@marzo"
|
|
|
|
// }
|
|
|
|
// ]
|
|
|
|
|
2019-11-06 13:15:06 +00:00
|
|
|
// ListQueues lists all queues in the cluster. This only includes queues in the
|
|
|
|
// virtual hosts accessible to the user.
|
2015-11-19 05:45:05 +00:00
|
|
|
func (c *Client) ListQueues() (rec []QueueInfo, err error) {
|
|
|
|
req, err := newGETRequest(c, "queues")
|
|
|
|
if err != nil {
|
|
|
|
return []QueueInfo{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = executeAndParseRequest(c, req, &rec); err != nil {
|
|
|
|
return []QueueInfo{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return rec, nil
|
|
|
|
}
|
|
|
|
|
2019-11-06 13:15:06 +00:00
|
|
|
// ListQueuesWithParameters lists queues with a list of query string values.
|
2017-01-04 21:47:38 +00:00
|
|
|
func (c *Client) ListQueuesWithParameters(params url.Values) (rec []QueueInfo, err error) {
|
|
|
|
req, err := newGETRequestWithParameters(c, "queues", params)
|
|
|
|
if err != nil {
|
|
|
|
return []QueueInfo{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = executeAndParseRequest(c, req, &rec); err != nil {
|
|
|
|
return []QueueInfo{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return rec, nil
|
|
|
|
}
|
|
|
|
|
2019-11-06 13:15:06 +00:00
|
|
|
// PagedListQueuesWithParameters lists queues with pagination.
|
2019-04-12 15:51:37 +00:00
|
|
|
func (c *Client) PagedListQueuesWithParameters(params url.Values) (rec PagedQueueInfo, err error) {
|
|
|
|
req, err := newGETRequestWithParameters(c, "queues", params)
|
|
|
|
if err != nil {
|
|
|
|
return PagedQueueInfo{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = executeAndParseRequest(c, req, &rec); err != nil {
|
|
|
|
return PagedQueueInfo{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return rec, nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2015-11-19 05:45:05 +00:00
|
|
|
//
|
|
|
|
// GET /api/queues/{vhost}
|
|
|
|
//
|
|
|
|
|
2019-11-06 13:15:06 +00:00
|
|
|
// ListQueuesIn lists all queues in a virtual host.
|
2015-11-19 05:45:05 +00:00
|
|
|
func (c *Client) ListQueuesIn(vhost string) (rec []QueueInfo, err error) {
|
2019-11-06 13:15:06 +00:00
|
|
|
req, err := newGETRequest(c, "queues/"+url.PathEscape(vhost))
|
2015-11-19 05:45:05 +00:00
|
|
|
if err != nil {
|
|
|
|
return []QueueInfo{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = executeAndParseRequest(c, req, &rec); err != nil {
|
|
|
|
return []QueueInfo{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return rec, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// GET /api/queues/{vhost}/{name}
|
|
|
|
//
|
|
|
|
|
2019-11-06 13:15:06 +00:00
|
|
|
// GetQueue returns information about a queue.
|
2015-11-19 05:45:05 +00:00
|
|
|
func (c *Client) GetQueue(vhost, queue string) (rec *DetailedQueueInfo, err error) {
|
2019-11-06 13:15:06 +00:00
|
|
|
req, err := newGETRequest(c, "queues/"+url.PathEscape(vhost)+"/"+url.PathEscape(queue))
|
2017-01-04 21:47:38 +00:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = executeAndParseRequest(c, req, &rec); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return rec, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// GET /api/queues/{vhost}/{name}?{query}
|
|
|
|
|
2019-11-06 13:15:06 +00:00
|
|
|
// GetQueueWithParameters returns information about a queue. Compared to the regular GetQueue function,
|
|
|
|
// this one accepts additional query string values.
|
2017-01-04 21:47:38 +00:00
|
|
|
func (c *Client) GetQueueWithParameters(vhost, queue string, qs url.Values) (rec *DetailedQueueInfo, err error) {
|
2019-11-06 13:15:06 +00:00
|
|
|
req, err := newGETRequestWithParameters(c, "queues/"+url.PathEscape(vhost)+"/"+url.PathEscape(queue), qs)
|
2015-11-19 05:45:05 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = executeAndParseRequest(c, req, &rec); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return rec, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// PUT /api/exchanges/{vhost}/{exchange}
|
|
|
|
//
|
|
|
|
|
2019-11-06 13:15:06 +00:00
|
|
|
// QueueSettings represents queue properties. Use it to declare a queue.
|
2015-11-19 05:45:05 +00:00
|
|
|
type QueueSettings struct {
|
2018-10-03 16:55:26 +00:00
|
|
|
Type string `json:"type"`
|
2015-11-19 05:45:05 +00:00
|
|
|
Durable bool `json:"durable"`
|
2018-10-03 16:55:26 +00:00
|
|
|
AutoDelete bool `json:"auto_delete,omitempty"`
|
|
|
|
Arguments map[string]interface{} `json:"arguments,omitempty"`
|
2015-11-19 05:45:05 +00:00
|
|
|
}
|
|
|
|
|
2019-11-06 13:15:06 +00:00
|
|
|
// DeclareQueue declares a queue.
|
2015-11-19 05:45:05 +00:00
|
|
|
func (c *Client) DeclareQueue(vhost, queue string, info QueueSettings) (res *http.Response, err error) {
|
|
|
|
if info.Arguments == nil {
|
|
|
|
info.Arguments = make(map[string]interface{})
|
|
|
|
}
|
|
|
|
body, err := json.Marshal(info)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2019-11-06 13:15:06 +00:00
|
|
|
req, err := newRequestWithBody(c, "PUT", "queues/"+url.PathEscape(vhost)+"/"+url.PathEscape(queue), body)
|
2015-11-19 05:45:05 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2019-11-06 13:15:06 +00:00
|
|
|
if res, err = executeRequest(c, req); err != nil {
|
2015-11-19 05:45:05 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return res, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// DELETE /api/queues/{vhost}/{name}
|
|
|
|
//
|
|
|
|
|
2019-11-06 13:15:06 +00:00
|
|
|
// DeleteQueue deletes a queue.
|
2015-11-19 05:45:05 +00:00
|
|
|
func (c *Client) DeleteQueue(vhost, queue string) (res *http.Response, err error) {
|
2019-11-06 13:15:06 +00:00
|
|
|
req, err := newRequestWithBody(c, "DELETE", "queues/"+url.PathEscape(vhost)+"/"+url.PathEscape(queue), nil)
|
2015-11-19 05:45:05 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2019-11-06 13:15:06 +00:00
|
|
|
if res, err = executeRequest(c, req); err != nil {
|
2015-11-19 05:45:05 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return res, nil
|
|
|
|
}
|
2016-07-23 00:11:47 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// DELETE /api/queues/{vhost}/{name}/contents
|
|
|
|
//
|
|
|
|
|
2019-11-06 13:15:06 +00:00
|
|
|
// PurgeQueue purges a queue (deletes all messages ready for delivery in it).
|
2016-07-23 00:11:47 +00:00
|
|
|
func (c *Client) PurgeQueue(vhost, queue string) (res *http.Response, err error) {
|
2019-11-06 13:15:06 +00:00
|
|
|
req, err := newRequestWithBody(c, "DELETE", "queues/"+url.PathEscape(vhost)+"/"+url.PathEscape(queue)+"/contents", nil)
|
2016-07-23 00:11:47 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2019-11-06 13:15:06 +00:00
|
|
|
if res, err = executeRequest(c, req); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return res, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// queueAction represents an action that can be performed on a queue (sync/cancel_sync)
|
|
|
|
type queueAction struct {
|
|
|
|
Action string `json:"action"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// SyncQueue synchronises queue contents with the mirrors remaining in the cluster.
|
|
|
|
func (c *Client) SyncQueue(vhost, queue string) (res *http.Response, err error) {
|
|
|
|
return c.sendQueueAction(vhost, queue, queueAction{"sync"})
|
|
|
|
}
|
|
|
|
|
|
|
|
// CancelSyncQueue cancels queue synchronisation process.
|
|
|
|
func (c *Client) CancelSyncQueue(vhost, queue string) (res *http.Response, err error) {
|
|
|
|
return c.sendQueueAction(vhost, queue, queueAction{"cancel_sync"})
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// POST /api/queues/{vhost}/{name}/actions
|
|
|
|
//
|
|
|
|
func (c *Client) sendQueueAction(vhost string, queue string, action queueAction) (res *http.Response, err error) {
|
|
|
|
body, err := json.Marshal(action)
|
2016-07-23 00:11:47 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2019-11-06 13:15:06 +00:00
|
|
|
req, err := newRequestWithBody(c, "POST", "queues/"+url.PathEscape(vhost)+"/"+url.PathEscape(queue)+"/actions", body)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if res, err = executeRequest(c, req); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2016-07-23 00:11:47 +00:00
|
|
|
return res, nil
|
|
|
|
}
|