/
zz_generated_cosmosdb.go
133 lines (110 loc) · 3.12 KB
/
zz_generated_cosmosdb.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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Code generated by github.com/jim-minter/go-cosmosdb, DO NOT EDIT.
package cosmosdb
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"fmt"
"io/ioutil"
"net/http"
"net/textproto"
"net/url"
"strings"
"time"
"github.com/ugorji/go/codec"
)
// Options represents API options
type Options struct {
NoETag bool
PreTriggers []string
PostTriggers []string
}
// Error represents an error
type Error struct {
StatusCode int
Code string `json:"code"`
Message string `json:"message"`
}
func (e *Error) Error() string {
return fmt.Sprintf("%d %s: %s", e.StatusCode, e.Code, e.Message)
}
// IsErrorStatusCode returns true if err is of type Error and its StatusCode
// matches statusCode
func IsErrorStatusCode(err error, statusCode int) bool {
if err, ok := err.(*Error); ok {
return err.StatusCode == statusCode
}
return false
}
// ErrETagRequired is the error returned if the ETag field is not populate on a
// PUT or DELETE operation
var ErrETagRequired = fmt.Errorf("ETag is required")
// RetryOnPreconditionFailed retries a function if it fails due to
// PreconditionFailed
func RetryOnPreconditionFailed(f func() error) (err error) {
for i := 0; i < 5; i++ {
err = f()
if !IsErrorStatusCode(err, http.StatusPreconditionFailed) {
return
}
time.Sleep(time.Duration(100*i) * time.Millisecond)
}
return
}
func (c *databaseClient) authorizeRequest(req *http.Request, resourceType, resourceLink string) {
date := time.Now().UTC().Format("Mon, 02 Jan 2006 15:04:05 GMT")
h := hmac.New(sha256.New, c.masterKey)
fmt.Fprintf(h, "%s\n%s\n%s\n%s\n\n", strings.ToLower(req.Method), resourceType, resourceLink, strings.ToLower(date))
req.Header.Set("Authorization", url.QueryEscape(fmt.Sprintf("type=master&ver=1.0&sig=%s", base64.StdEncoding.EncodeToString(h.Sum(nil)))))
req.Header.Set("x-ms-date", date)
}
func (c *databaseClient) do(method, path, resourceType, resourceLink string, expectedStatusCode int, in, out interface{}, headers http.Header) error {
req, err := http.NewRequest(method, "https://"+c.databaseAccount+".documents.azure.com/"+path, nil)
if err != nil {
return err
}
if in != nil {
buf := &bytes.Buffer{}
err := codec.NewEncoder(buf, c.jsonHandle).Encode(in)
if err != nil {
return err
}
req.Body = ioutil.NopCloser(buf)
req.Header.Set("Content-Type", "application/json")
}
for k, v := range headers {
req.Header[textproto.CanonicalMIMEHeaderKey(k)] = v
}
req.Header.Set("x-ms-version", "2018-12-31")
c.authorizeRequest(req, resourceType, resourceLink)
resp, err := c.hc.Do(req)
if err != nil {
return err
}
defer func() {
resp.Body.Read(nil)
resp.Body.Close()
}()
if headers != nil {
for k := range headers {
delete(headers, k)
}
for k, v := range resp.Header {
headers[k] = v
}
}
d := codec.NewDecoder(resp.Body, c.jsonHandle)
if resp.StatusCode != expectedStatusCode {
var err *Error
if resp.Header.Get("Content-Type") == "application/json" {
d.Decode(&err)
}
err.StatusCode = resp.StatusCode
return err
}
if out != nil && resp.Header.Get("Content-Type") == "application/json" {
return d.Decode(&out)
}
return nil
}