/
extensions_api_client.go
90 lines (75 loc) · 2.38 KB
/
extensions_api_client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package lambda
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
)
const (
headerExtensionName = "Lambda-Extension-Name"
headerExtensionIdentifier = "Lambda-Extension-Identifier"
extensionAPIVersion = "2020-01-01"
)
type extensionAPIEventType string
const (
extensionInvokeEvent extensionAPIEventType = "INVOKE" //nolint:deadcode,unused,varcheck
extensionShutdownEvent extensionAPIEventType = "SHUTDOWN" //nolint:deadcode,unused,varcheck
)
type extensionAPIClient struct {
baseURL string
httpClient *http.Client
}
func newExtensionAPIClient(address string) *extensionAPIClient {
client := &http.Client{
Timeout: 0, // connections to the extensions API are never expected to time out
}
endpoint := "http://" + address + "/" + extensionAPIVersion + "/extension/"
return &extensionAPIClient{
baseURL: endpoint,
httpClient: client,
}
}
func (c *extensionAPIClient) register(name string, events ...extensionAPIEventType) (string, error) {
url := c.baseURL + "register"
body, _ := json.Marshal(struct {
Events []extensionAPIEventType `json:"events"`
}{
Events: events,
})
req, _ := http.NewRequest(http.MethodPost, url, bytes.NewReader(body))
req.Header.Add(headerExtensionName, name)
res, err := c.httpClient.Do(req)
if err != nil {
return "", fmt.Errorf("failed to register extension: %v", err)
}
defer res.Body.Close()
_, _ = io.Copy(ioutil.Discard, res.Body)
if res.StatusCode != http.StatusOK {
return "", fmt.Errorf("failed to register extension, got response status: %d %s", res.StatusCode, http.StatusText(res.StatusCode))
}
return res.Header.Get(headerExtensionIdentifier), nil
}
type extensionEventResponse struct {
EventType extensionAPIEventType
// ... the rest not implemented
}
func (c *extensionAPIClient) next(id string) (response extensionEventResponse, err error) {
url := c.baseURL + "event/next"
req, _ := http.NewRequest(http.MethodGet, url, nil)
req.Header.Add(headerExtensionIdentifier, id)
res, err := c.httpClient.Do(req)
if err != nil {
err = fmt.Errorf("failed to get extension event: %v", err)
return
}
defer res.Body.Close()
_, _ = io.Copy(ioutil.Discard, res.Body)
if res.StatusCode != http.StatusOK {
err = fmt.Errorf("failed to register extension, got response status: %d %s", res.StatusCode, http.StatusText(res.StatusCode))
return
}
err = json.NewDecoder(res.Body).Decode(&response)
return
}