github.com/outbrain/consul@v1.4.5/api/event.go (about)

     1  package api
     2  
     3  import (
     4  	"bytes"
     5  	"strconv"
     6  )
     7  
     8  // Event can be used to query the Event endpoints
     9  type Event struct {
    10  	c *Client
    11  }
    12  
    13  // UserEvent represents an event that was fired by the user
    14  type 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
    26  func (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.
    33  func (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.
    67  func (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.
    92  func (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  }