blob: 85b5b069b038c7b2463712884c88c35a810af856 [file] [log] [blame]
divyadesai81bb7ba2020-03-11 11:45:23 +00001package api
2
3import (
4 "bytes"
5 "strconv"
6)
7
8// Event can be used to query the Event endpoints
9type Event struct {
10 c *Client
11}
12
13// UserEvent represents an event that was fired by the user
14type UserEvent struct {
15 ID string
16 Name string
17 Payload []byte
18 NodeFilter string
19 ServiceFilter string
20 TagFilter string
21 Version int
22 LTime uint64
23}
24
25// Event returns a handle to the event endpoints
26func (c *Client) Event() *Event {
27 return &Event{c}
28}
29
30// Fire is used to fire a new user event. Only the Name, Payload and Filters
31// are respected. This returns the ID or an associated error. Cross DC requests
32// are supported.
33func (e *Event) Fire(params *UserEvent, q *WriteOptions) (string, *WriteMeta, error) {
34 r := e.c.newRequest("PUT", "/v1/event/fire/"+params.Name)
35 r.setWriteOptions(q)
36 if params.NodeFilter != "" {
37 r.params.Set("node", params.NodeFilter)
38 }
39 if params.ServiceFilter != "" {
40 r.params.Set("service", params.ServiceFilter)
41 }
42 if params.TagFilter != "" {
43 r.params.Set("tag", params.TagFilter)
44 }
45 if params.Payload != nil {
46 r.body = bytes.NewReader(params.Payload)
47 }
48
49 rtt, resp, err := requireOK(e.c.doRequest(r))
50 if err != nil {
51 return "", nil, err
52 }
53 defer resp.Body.Close()
54
55 wm := &WriteMeta{RequestTime: rtt}
56 var out UserEvent
57 if err := decodeBody(resp, &out); err != nil {
58 return "", nil, err
59 }
60 return out.ID, wm, nil
61}
62
63// List is used to get the most recent events an agent has received.
64// This list can be optionally filtered by the name. This endpoint supports
65// quasi-blocking queries. The index is not monotonic, nor does it provide provide
66// LastContact or KnownLeader.
67func (e *Event) List(name string, q *QueryOptions) ([]*UserEvent, *QueryMeta, error) {
68 r := e.c.newRequest("GET", "/v1/event/list")
69 r.setQueryOptions(q)
70 if name != "" {
71 r.params.Set("name", name)
72 }
73 rtt, resp, err := requireOK(e.c.doRequest(r))
74 if err != nil {
75 return nil, nil, err
76 }
77 defer resp.Body.Close()
78
79 qm := &QueryMeta{}
80 parseQueryMeta(resp, qm)
81 qm.RequestTime = rtt
82
83 var entries []*UserEvent
84 if err := decodeBody(resp, &entries); err != nil {
85 return nil, nil, err
86 }
87 return entries, qm, nil
88}
89
90// IDToIndex is a bit of a hack. This simulates the index generation to
91// convert an event ID into a WaitIndex.
92func (e *Event) IDToIndex(uuid string) uint64 {
93 lower := uuid[0:8] + uuid[9:13] + uuid[14:18]
94 upper := uuid[19:23] + uuid[24:36]
95 lowVal, err := strconv.ParseUint(lower, 16, 64)
96 if err != nil {
97 panic("Failed to convert " + lower)
98 }
99 highVal, err := strconv.ParseUint(upper, 16, 64)
100 if err != nil {
101 panic("Failed to convert " + upper)
102 }
103 return lowVal ^ highVal
104}