service.go raw
1 package service
2
3 import (
4 "bufio"
5 "bytes"
6 "crypto/md5"
7 "encoding/hex"
8 "encoding/json"
9 "errors"
10 "fmt"
11 "io"
12 "io/ioutil"
13 "math/rand"
14 "net/http"
15 "net/url"
16 "reflect"
17 "runtime"
18 "strconv"
19 "strings"
20 "sync/atomic"
21 "time"
22
23 "github.com/alibabacloud-go/tea/tea"
24 )
25
26 var defaultUserAgent = fmt.Sprintf("AlibabaCloud (%s; %s) Golang/%s Core/%s TeaDSL/1", runtime.GOOS, runtime.GOARCH, strings.Trim(runtime.Version(), "go"), "0.01")
27
28 type ExtendsParameters struct {
29 Headers map[string]*string `json:"headers,omitempty" xml:"headers,omitempty"`
30 Queries map[string]*string `json:"queries,omitempty" xml:"queries,omitempty"`
31 }
32
33 func (s ExtendsParameters) String() string {
34 return tea.Prettify(s)
35 }
36
37 func (s ExtendsParameters) GoString() string {
38 return s.String()
39 }
40
41 func (s *ExtendsParameters) SetHeaders(v map[string]*string) *ExtendsParameters {
42 s.Headers = v
43 return s
44 }
45
46 func (s *ExtendsParameters) SetQueries(v map[string]*string) *ExtendsParameters {
47 s.Queries = v
48 return s
49 }
50
51 type RuntimeOptions struct {
52 Autoretry *bool `json:"autoretry" xml:"autoretry"`
53 IgnoreSSL *bool `json:"ignoreSSL" xml:"ignoreSSL"`
54 Key *string `json:"key,omitempty" xml:"key,omitempty"`
55 Cert *string `json:"cert,omitempty" xml:"cert,omitempty"`
56 Ca *string `json:"ca,omitempty" xml:"ca,omitempty"`
57 MaxAttempts *int `json:"maxAttempts" xml:"maxAttempts"`
58 BackoffPolicy *string `json:"backoffPolicy" xml:"backoffPolicy"`
59 BackoffPeriod *int `json:"backoffPeriod" xml:"backoffPeriod"`
60 ReadTimeout *int `json:"readTimeout" xml:"readTimeout"`
61 ConnectTimeout *int `json:"connectTimeout" xml:"connectTimeout"`
62 LocalAddr *string `json:"localAddr" xml:"localAddr"`
63 HttpProxy *string `json:"httpProxy" xml:"httpProxy"`
64 HttpsProxy *string `json:"httpsProxy" xml:"httpsProxy"`
65 NoProxy *string `json:"noProxy" xml:"noProxy"`
66 MaxIdleConns *int `json:"maxIdleConns" xml:"maxIdleConns"`
67 Socks5Proxy *string `json:"socks5Proxy" xml:"socks5Proxy"`
68 Socks5NetWork *string `json:"socks5NetWork" xml:"socks5NetWork"`
69 KeepAlive *bool `json:"keepAlive" xml:"keepAlive"`
70 ExtendsParameters *ExtendsParameters `json:"extendsParameters,omitempty" xml:"extendsParameters,omitempty"`
71 }
72
73 var processStartTime int64 = time.Now().UnixNano() / 1e6
74 var seqId int64 = 0
75
76 type SSEEvent struct {
77 ID *string
78 Event *string
79 Data *string
80 Retry *int
81 }
82
83 func parseEvent(eventLines []string) (SSEEvent, error) {
84 var event SSEEvent
85
86 for _, line := range eventLines {
87 if strings.HasPrefix(line, "data:") {
88 event.Data = tea.String(tea.StringValue(event.Data) + strings.TrimPrefix(line, "data:") + "\n")
89 } else if strings.HasPrefix(line, "id:") {
90 id := strings.TrimPrefix(line, "id:")
91 event.ID = tea.String(strings.Trim(id, " "))
92 } else if strings.HasPrefix(line, "event:") {
93 eventName := strings.TrimPrefix(line, "event:")
94 event.Event = tea.String(strings.Trim(eventName, " "))
95 } else if strings.HasPrefix(line, "retry:") {
96 trimmedLine := strings.TrimPrefix(line, "retry:")
97 trimmedLine = strings.Trim(trimmedLine, " ")
98 retryValue, _err := strconv.Atoi(trimmedLine)
99 if _err != nil {
100 return event, fmt.Errorf("retry %v is not a int", trimmedLine)
101 }
102 event.Retry = tea.Int(retryValue)
103 }
104 }
105 data := strings.TrimRight(tea.StringValue(event.Data), "\n")
106 event.Data = tea.String(strings.Trim(data, " "))
107 return event, nil
108 }
109
110 func getGID() uint64 {
111 // https://blog.sgmansfield.com/2015/12/goroutine-ids/
112 b := make([]byte, 64)
113 b = b[:runtime.Stack(b, false)]
114 b = bytes.TrimPrefix(b, []byte("goroutine "))
115 b = b[:bytes.IndexByte(b, ' ')]
116 n, _ := strconv.ParseUint(string(b), 10, 64)
117 return n
118 }
119
120 func (s RuntimeOptions) String() string {
121 return tea.Prettify(s)
122 }
123
124 func (s RuntimeOptions) GoString() string {
125 return s.String()
126 }
127
128 func (s *RuntimeOptions) SetAutoretry(v bool) *RuntimeOptions {
129 s.Autoretry = &v
130 return s
131 }
132
133 func (s *RuntimeOptions) SetIgnoreSSL(v bool) *RuntimeOptions {
134 s.IgnoreSSL = &v
135 return s
136 }
137
138 func (s *RuntimeOptions) SetKey(v string) *RuntimeOptions {
139 s.Key = &v
140 return s
141 }
142
143 func (s *RuntimeOptions) SetCert(v string) *RuntimeOptions {
144 s.Cert = &v
145 return s
146 }
147
148 func (s *RuntimeOptions) SetCa(v string) *RuntimeOptions {
149 s.Ca = &v
150 return s
151 }
152
153 func (s *RuntimeOptions) SetMaxAttempts(v int) *RuntimeOptions {
154 s.MaxAttempts = &v
155 return s
156 }
157
158 func (s *RuntimeOptions) SetBackoffPolicy(v string) *RuntimeOptions {
159 s.BackoffPolicy = &v
160 return s
161 }
162
163 func (s *RuntimeOptions) SetBackoffPeriod(v int) *RuntimeOptions {
164 s.BackoffPeriod = &v
165 return s
166 }
167
168 func (s *RuntimeOptions) SetReadTimeout(v int) *RuntimeOptions {
169 s.ReadTimeout = &v
170 return s
171 }
172
173 func (s *RuntimeOptions) SetConnectTimeout(v int) *RuntimeOptions {
174 s.ConnectTimeout = &v
175 return s
176 }
177
178 func (s *RuntimeOptions) SetHttpProxy(v string) *RuntimeOptions {
179 s.HttpProxy = &v
180 return s
181 }
182
183 func (s *RuntimeOptions) SetHttpsProxy(v string) *RuntimeOptions {
184 s.HttpsProxy = &v
185 return s
186 }
187
188 func (s *RuntimeOptions) SetNoProxy(v string) *RuntimeOptions {
189 s.NoProxy = &v
190 return s
191 }
192
193 func (s *RuntimeOptions) SetMaxIdleConns(v int) *RuntimeOptions {
194 s.MaxIdleConns = &v
195 return s
196 }
197
198 func (s *RuntimeOptions) SetLocalAddr(v string) *RuntimeOptions {
199 s.LocalAddr = &v
200 return s
201 }
202
203 func (s *RuntimeOptions) SetSocks5Proxy(v string) *RuntimeOptions {
204 s.Socks5Proxy = &v
205 return s
206 }
207
208 func (s *RuntimeOptions) SetSocks5NetWork(v string) *RuntimeOptions {
209 s.Socks5NetWork = &v
210 return s
211 }
212
213 func (s *RuntimeOptions) SetKeepAlive(v bool) *RuntimeOptions {
214 s.KeepAlive = &v
215 return s
216 }
217
218 func (s *RuntimeOptions) SetExtendsParameters(v *ExtendsParameters) *RuntimeOptions {
219 s.ExtendsParameters = v
220 return s
221 }
222
223 func ReadAsString(body io.Reader) (*string, error) {
224 byt, err := ioutil.ReadAll(body)
225 if err != nil {
226 return tea.String(""), err
227 }
228 r, ok := body.(io.ReadCloser)
229 if ok {
230 r.Close()
231 }
232 return tea.String(string(byt)), nil
233 }
234
235 func StringifyMapValue(a map[string]interface{}) map[string]*string {
236 res := make(map[string]*string)
237 for key, value := range a {
238 if value != nil {
239 res[key] = ToJSONString(value)
240 }
241 }
242 return res
243 }
244
245 func AnyifyMapValue(a map[string]*string) map[string]interface{} {
246 res := make(map[string]interface{})
247 for key, value := range a {
248 res[key] = tea.StringValue(value)
249 }
250 return res
251 }
252
253 func ReadAsBytes(body io.Reader) ([]byte, error) {
254 byt, err := ioutil.ReadAll(body)
255 if err != nil {
256 return nil, err
257 }
258 r, ok := body.(io.ReadCloser)
259 if ok {
260 r.Close()
261 }
262 return byt, nil
263 }
264
265 func DefaultString(reaStr, defaultStr *string) *string {
266 if reaStr == nil {
267 return defaultStr
268 }
269 return reaStr
270 }
271
272 func ToJSONString(a interface{}) *string {
273 switch v := a.(type) {
274 case *string:
275 return v
276 case string:
277 return tea.String(v)
278 case []byte:
279 return tea.String(string(v))
280 case io.Reader:
281 byt, err := ioutil.ReadAll(v)
282 if err != nil {
283 return nil
284 }
285 return tea.String(string(byt))
286 }
287 byt := bytes.NewBuffer([]byte{})
288 jsonEncoder := json.NewEncoder(byt)
289 jsonEncoder.SetEscapeHTML(false)
290 if err := jsonEncoder.Encode(a); err != nil {
291 return nil
292 }
293 return tea.String(string(bytes.TrimSpace(byt.Bytes())))
294 }
295
296 func DefaultNumber(reaNum, defaultNum *int) *int {
297 if reaNum == nil {
298 return defaultNum
299 }
300 return reaNum
301 }
302
303 func ReadAsJSON(body io.Reader) (result interface{}, err error) {
304 byt, err := ioutil.ReadAll(body)
305 if err != nil {
306 return
307 }
308 if string(byt) == "" {
309 return
310 }
311 r, ok := body.(io.ReadCloser)
312 if ok {
313 r.Close()
314 }
315 d := json.NewDecoder(bytes.NewReader(byt))
316 d.UseNumber()
317 err = d.Decode(&result)
318 return
319 }
320
321 func GetNonce() *string {
322 routineId := getGID()
323 currentTime := time.Now().UnixNano() / 1e6
324 seq := atomic.AddInt64(&seqId, 1)
325 randNum := rand.Int63()
326 msg := fmt.Sprintf("%d-%d-%d-%d-%d", processStartTime, routineId, currentTime, seq, randNum)
327 h := md5.New()
328 h.Write([]byte(msg))
329 ret := hex.EncodeToString(h.Sum(nil))
330 return &ret
331 }
332
333 func Empty(val *string) *bool {
334 return tea.Bool(val == nil || tea.StringValue(val) == "")
335 }
336
337 func ValidateModel(a interface{}) error {
338 if a == nil {
339 return nil
340 }
341 err := tea.Validate(a)
342 return err
343 }
344
345 func EqualString(val1, val2 *string) *bool {
346 return tea.Bool(tea.StringValue(val1) == tea.StringValue(val2))
347 }
348
349 func EqualNumber(val1, val2 *int) *bool {
350 return tea.Bool(tea.IntValue(val1) == tea.IntValue(val2))
351 }
352
353 func IsUnset(val interface{}) *bool {
354 if val == nil {
355 return tea.Bool(true)
356 }
357
358 v := reflect.ValueOf(val)
359 if v.Kind() == reflect.Ptr || v.Kind() == reflect.Slice || v.Kind() == reflect.Map {
360 return tea.Bool(v.IsNil())
361 }
362
363 valType := reflect.TypeOf(val)
364 valZero := reflect.Zero(valType)
365 return tea.Bool(valZero == v)
366 }
367
368 func ToBytes(a *string) []byte {
369 return []byte(tea.StringValue(a))
370 }
371
372 func AssertAsMap(a interface{}) (_result map[string]interface{}, _err error) {
373 r := reflect.ValueOf(a)
374 if r.Kind().String() != "map" {
375 return nil, errors.New(fmt.Sprintf("%v is not a map[string]interface{}", a))
376 }
377
378 res := make(map[string]interface{})
379 tmp := r.MapKeys()
380 for _, key := range tmp {
381 res[key.String()] = r.MapIndex(key).Interface()
382 }
383
384 return res, nil
385 }
386
387 func AssertAsNumber(a interface{}) (_result *int, _err error) {
388 res := 0
389 switch a.(type) {
390 case int:
391 tmp := a.(int)
392 res = tmp
393 case *int:
394 tmp := a.(*int)
395 res = tea.IntValue(tmp)
396 default:
397 return nil, errors.New(fmt.Sprintf("%v is not a int", a))
398 }
399
400 return tea.Int(res), nil
401 }
402
403 /**
404 * Assert a value, if it is a integer, return it, otherwise throws
405 * @return the integer value
406 */
407 func AssertAsInteger(value interface{}) (_result *int, _err error) {
408 res := 0
409 switch value.(type) {
410 case int:
411 tmp := value.(int)
412 res = tmp
413 case *int:
414 tmp := value.(*int)
415 res = tea.IntValue(tmp)
416 default:
417 return nil, errors.New(fmt.Sprintf("%v is not a int", value))
418 }
419
420 return tea.Int(res), nil
421 }
422
423 func AssertAsBoolean(a interface{}) (_result *bool, _err error) {
424 res := false
425 switch a.(type) {
426 case bool:
427 tmp := a.(bool)
428 res = tmp
429 case *bool:
430 tmp := a.(*bool)
431 res = tea.BoolValue(tmp)
432 default:
433 return nil, errors.New(fmt.Sprintf("%v is not a bool", a))
434 }
435
436 return tea.Bool(res), nil
437 }
438
439 func AssertAsString(a interface{}) (_result *string, _err error) {
440 res := ""
441 switch a.(type) {
442 case string:
443 tmp := a.(string)
444 res = tmp
445 case *string:
446 tmp := a.(*string)
447 res = tea.StringValue(tmp)
448 default:
449 return nil, errors.New(fmt.Sprintf("%v is not a string", a))
450 }
451
452 return tea.String(res), nil
453 }
454
455 func AssertAsBytes(a interface{}) (_result []byte, _err error) {
456 res, ok := a.([]byte)
457 if !ok {
458 return nil, errors.New(fmt.Sprintf("%v is not a []byte", a))
459 }
460 return res, nil
461 }
462
463 func AssertAsReadable(a interface{}) (_result io.Reader, _err error) {
464 res, ok := a.(io.Reader)
465 if !ok {
466 return nil, errors.New(fmt.Sprintf("%v is not a reader", a))
467 }
468 return res, nil
469 }
470
471 func AssertAsArray(a interface{}) (_result []interface{}, _err error) {
472 r := reflect.ValueOf(a)
473 if r.Kind().String() != "array" && r.Kind().String() != "slice" {
474 return nil, errors.New(fmt.Sprintf("%v is not a []interface{}", a))
475 }
476 aLen := r.Len()
477 res := make([]interface{}, 0)
478 for i := 0; i < aLen; i++ {
479 res = append(res, r.Index(i).Interface())
480 }
481 return res, nil
482 }
483
484 func ParseJSON(a *string) interface{} {
485 mapTmp := make(map[string]interface{})
486 d := json.NewDecoder(bytes.NewReader([]byte(tea.StringValue(a))))
487 d.UseNumber()
488 err := d.Decode(&mapTmp)
489 if err == nil {
490 return mapTmp
491 }
492
493 sliceTmp := make([]interface{}, 0)
494 d = json.NewDecoder(bytes.NewReader([]byte(tea.StringValue(a))))
495 d.UseNumber()
496 err = d.Decode(&sliceTmp)
497 if err == nil {
498 return sliceTmp
499 }
500
501 if num, err := strconv.Atoi(tea.StringValue(a)); err == nil {
502 return num
503 }
504
505 if ok, err := strconv.ParseBool(tea.StringValue(a)); err == nil {
506 return ok
507 }
508
509 if floa64tVal, err := strconv.ParseFloat(tea.StringValue(a), 64); err == nil {
510 return floa64tVal
511 }
512 return nil
513 }
514
515 func ToString(a []byte) *string {
516 return tea.String(string(a))
517 }
518
519 func ToMap(in interface{}) map[string]interface{} {
520 if in == nil {
521 return nil
522 }
523 res := tea.ToMap(in)
524 return res
525 }
526
527 func ToFormString(a map[string]interface{}) *string {
528 if a == nil {
529 return tea.String("")
530 }
531 res := ""
532 urlEncoder := url.Values{}
533 for key, value := range a {
534 v := fmt.Sprintf("%v", value)
535 urlEncoder.Add(key, v)
536 }
537 res = urlEncoder.Encode()
538 return tea.String(res)
539 }
540
541 func GetDateUTCString() *string {
542 return tea.String(time.Now().UTC().Format(http.TimeFormat))
543 }
544
545 func GetUserAgent(userAgent *string) *string {
546 if userAgent != nil && tea.StringValue(userAgent) != "" {
547 return tea.String(defaultUserAgent + " " + tea.StringValue(userAgent))
548 }
549 return tea.String(defaultUserAgent)
550 }
551
552 func Is2xx(code *int) *bool {
553 tmp := tea.IntValue(code)
554 return tea.Bool(tmp >= 200 && tmp < 300)
555 }
556
557 func Is3xx(code *int) *bool {
558 tmp := tea.IntValue(code)
559 return tea.Bool(tmp >= 300 && tmp < 400)
560 }
561
562 func Is4xx(code *int) *bool {
563 tmp := tea.IntValue(code)
564 return tea.Bool(tmp >= 400 && tmp < 500)
565 }
566
567 func Is5xx(code *int) *bool {
568 tmp := tea.IntValue(code)
569 return tea.Bool(tmp >= 500 && tmp < 600)
570 }
571
572 func Sleep(millisecond *int) error {
573 ms := tea.IntValue(millisecond)
574 time.Sleep(time.Duration(ms) * time.Millisecond)
575 return nil
576 }
577
578 func ToArray(in interface{}) []map[string]interface{} {
579 if tea.BoolValue(IsUnset(in)) {
580 return nil
581 }
582
583 tmp := make([]map[string]interface{}, 0)
584 byt, _ := json.Marshal(in)
585 d := json.NewDecoder(bytes.NewReader(byt))
586 d.UseNumber()
587 err := d.Decode(&tmp)
588 if err != nil {
589 return nil
590 }
591 return tmp
592 }
593
594 func ReadAsSSE(body io.ReadCloser) (<-chan SSEEvent, <-chan error) {
595 eventChannel := make(chan SSEEvent)
596 errorChannel := make(chan error)
597
598 go func() {
599 defer body.Close()
600 defer close(eventChannel)
601
602 reader := bufio.NewReader(body)
603 var eventLines []string
604
605 for {
606 line, err := reader.ReadString('\n')
607 if err == io.EOF {
608 break
609 }
610 if err != nil {
611 errorChannel <- err
612 }
613
614 line = strings.TrimRight(line, "\n")
615 if line == "" {
616 if len(eventLines) > 0 {
617 event, err := parseEvent(eventLines)
618 if err != nil {
619 errorChannel <- err
620 }
621 eventChannel <- event
622 eventLines = []string{}
623 }
624 continue
625 }
626 eventLines = append(eventLines, line)
627 }
628 }()
629 return eventChannel, errorChannel
630 }
631