github.com/kyma-project/kyma-environment-broker@v0.0.1/common/events/client.go (about) 1 package events 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "net/http" 9 "strings" 10 "time" 11 ) 12 13 type EventLevel string 14 15 const ( 16 InfoEventLevel EventLevel = "info" 17 ErrorEventLevel EventLevel = "error" 18 ) 19 20 type EventDTO struct { 21 ID string 22 Level EventLevel 23 InstanceID *string 24 OperationID *string 25 Message string 26 CreatedAt time.Time 27 } 28 29 type EventFilter struct { 30 InstanceIDs []string 31 OperationIDs []string 32 } 33 34 // Client is the interface to interact with the KEB /events API as an HTTP client using OIDC ID token in JWT format. 35 type Client interface { 36 ListEvents(instanceIDs []string) ([]EventDTO, error) 37 } 38 39 type client struct { 40 url string 41 httpClient *http.Client 42 } 43 44 // NewClient constructs and returns new Client for KEB /events API 45 // It takes the following arguments: 46 // - url : base url of all KEB APIs, e.g. https://kyma-env-broker.kyma.local 47 // - httpClient : underlying HTTP client used for API call to KEB 48 func NewClient(url string, httpClient *http.Client) Client { 49 return &client{ 50 url: url, 51 httpClient: httpClient, 52 } 53 } 54 55 // ListEvents 56 func (c *client) ListEvents(instanceIDs []string) ([]EventDTO, error) { 57 var events []EventDTO 58 req, err := http.NewRequest("GET", fmt.Sprintf("%s/events", c.url), nil) 59 if err != nil { 60 return events, fmt.Errorf("while creating request: %v", err) 61 } 62 q := req.URL.Query() 63 q.Add("instance_ids", strings.Join(instanceIDs, ",")) 64 req.URL.RawQuery = q.Encode() 65 resp, err := c.httpClient.Do(req) 66 if err != nil { 67 return events, fmt.Errorf("while calling %s: %v", req.URL.String(), err) 68 } 69 70 // Drain response body and close, return error to context if there isn't any. 71 defer func() { 72 derr := drainResponseBody(resp.Body) 73 if err == nil { 74 err = derr 75 } 76 cerr := resp.Body.Close() 77 if err == nil { 78 err = cerr 79 } 80 }() 81 82 if resp.StatusCode != http.StatusOK { 83 return events, fmt.Errorf("calling %s returned %d (%s) status", req.URL.String(), resp.StatusCode, resp.Status) 84 } 85 86 decoder := json.NewDecoder(resp.Body) 87 err = decoder.Decode(&events) 88 if err != nil { 89 return events, fmt.Errorf("while decoding response body: %v", err) 90 } 91 return events, nil 92 } 93 94 func drainResponseBody(body io.Reader) error { 95 if body == nil { 96 return nil 97 } 98 _, err := io.Copy(ioutil.Discard, io.LimitReader(body, 4096)) 99 return err 100 }