package api import ( "bytes" "strconv" ) // Event can be used to query the Event endpoints type Event struct { c *Client } // UserEvent represents an event that was fired by the user type UserEvent struct { ID string Name string Payload []byte NodeFilter string ServiceFilter string TagFilter string Version int LTime uint64 } // Event returns a handle to the event endpoints func (c *Client) Event() *Event { return &Event{c} } // Fire is used to fire a new user event. Only the Name, Payload and Filters // are respected. This returns the ID or an associated error. Cross DC requests // are supported. func (e *Event) Fire(params *UserEvent, q *WriteOptions) (string, *WriteMeta, error) { r := e.c.newRequest("PUT", "/v1/event/fire/"+params.Name) r.setWriteOptions(q) if params.NodeFilter != "" { r.params.Set("node", params.NodeFilter) } if params.ServiceFilter != "" { r.params.Set("service", params.ServiceFilter) } if params.TagFilter != "" { r.params.Set("tag", params.TagFilter) } if params.Payload != nil { r.body = bytes.NewReader(params.Payload) } r.header.Set("Content-Type", "application/octet-stream") rtt, resp, err := requireOK(e.c.doRequest(r)) if err != nil { return "", nil, err } defer resp.Body.Close() wm := &WriteMeta{RequestTime: rtt} var out UserEvent if err := decodeBody(resp, &out); err != nil { return "", nil, err } return out.ID, wm, nil } // List is used to get the most recent events an agent has received. // This list can be optionally filtered by the name. This endpoint supports // quasi-blocking queries. The index is not monotonic, nor does it provide provide // LastContact or KnownLeader. func (e *Event) List(name string, q *QueryOptions) ([]*UserEvent, *QueryMeta, error) { r := e.c.newRequest("GET", "/v1/event/list") r.setQueryOptions(q) if name != "" { r.params.Set("name", name) } rtt, resp, err := requireOK(e.c.doRequest(r)) if err != nil { return nil, nil, err } defer resp.Body.Close() qm := &QueryMeta{} parseQueryMeta(resp, qm) qm.RequestTime = rtt var entries []*UserEvent if err := decodeBody(resp, &entries); err != nil { return nil, nil, err } return entries, qm, nil } // IDToIndex is a bit of a hack. This simulates the index generation to // convert an event ID into a WaitIndex. func (e *Event) IDToIndex(uuid string) uint64 { lower := uuid[0:8] + uuid[9:13] + uuid[14:18] upper := uuid[19:23] + uuid[24:36] lowVal, err := strconv.ParseUint(lower, 16, 64) if err != nil { panic("Failed to convert " + lower) } highVal, err := strconv.ParseUint(upper, 16, 64) if err != nil { panic("Failed to convert " + upper) } return lowVal ^ highVal }