utils.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package ucloud
  15. import (
  16. "reflect"
  17. "yunion.io/x/jsonutils"
  18. "yunion.io/x/log"
  19. )
  20. func unmarshalResult(resp jsonutils.JSONObject, respErr error, resultKey string, result interface{}) error {
  21. if respErr != nil {
  22. return respErr
  23. }
  24. if result == nil {
  25. return nil
  26. }
  27. if len(resultKey) > 0 {
  28. respErr = resp.Unmarshal(result, resultKey)
  29. } else {
  30. respErr = resp.Unmarshal(result)
  31. }
  32. if respErr != nil {
  33. log.Errorf("unmarshal json error %s", respErr)
  34. }
  35. return nil
  36. }
  37. func doListPart(client *SUcloudClient, action string, params SParams, resultKey string, result interface{}) (int, int, error) {
  38. params.SetAction(action)
  39. ret, err := jsonRequest(client, params)
  40. if err != nil {
  41. return 0, 0, err
  42. }
  43. total, _ := ret.Int("TotalCount")
  44. // if err != nil {
  45. // log.Debugf("%s TotalCount %s", action, err.Error())
  46. //}
  47. var lst []jsonutils.JSONObject
  48. lst, err = ret.GetArray(resultKey)
  49. if err != nil {
  50. return 0, 0, nil
  51. }
  52. resultValue := reflect.Indirect(reflect.ValueOf(result))
  53. elemType := resultValue.Type().Elem()
  54. for i := range lst {
  55. elemPtr := reflect.New(elemType)
  56. err = lst[i].Unmarshal(elemPtr.Interface())
  57. if err != nil {
  58. return 0, 0, err
  59. }
  60. resultValue.Set(reflect.Append(resultValue, elemPtr.Elem()))
  61. }
  62. return int(total), len(lst), nil
  63. }
  64. // 执行操作
  65. func DoAction(client *SUcloudClient, action string, params SParams, resultKey string, result interface{}) error {
  66. params.SetAction(action)
  67. resp, err := jsonRequest(client, params)
  68. return unmarshalResult(resp, err, resultKey, result)
  69. }
  70. // 遍历所有结果
  71. func DoListAll(client *SUcloudClient, action string, params SParams, resultKey string, result interface{}) error {
  72. pageLimit := 100
  73. offset := 0
  74. resultValue := reflect.Indirect(reflect.ValueOf(result))
  75. params.SetPagination(pageLimit, offset)
  76. for {
  77. total, part, err := doListPart(client, action, params, resultKey, result)
  78. if err != nil {
  79. return err
  80. }
  81. // total 大于零的情况下通过total字段判断列表是否遍历完成。total不存在或者为0的情况下,通过返回列表的长度判断是否遍历完成
  82. if (total > 0 && resultValue.Len() >= total) || (total == 0 && pageLimit > part) {
  83. break
  84. }
  85. params.SetPagination(pageLimit, offset+resultValue.Len())
  86. }
  87. return nil
  88. }