service.go 14 KB

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