1package consulapi 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} 105