tasks.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Copyright (c) 2016 VMware, Inc. All Rights Reserved.
  2. //
  3. // This product is licensed to you under the Apache License, Version 2.0 (the "License").
  4. // You may not use this product except in compliance with the License.
  5. //
  6. // This product may include a number of subcomponents with separate copyright notices and
  7. // license terms. Your use of these subcomponents is subject to the terms and conditions
  8. // of the subcomponent's license, as noted in the LICENSE file.
  9. package photon
  10. import (
  11. "encoding/json"
  12. "time"
  13. )
  14. // Contains functionality for tasks API.
  15. type TasksAPI struct {
  16. client *Client
  17. }
  18. var taskUrl string = rootUrl + "/tasks"
  19. // Gets a task by ID.
  20. func (api *TasksAPI) Get(id string) (task *Task, err error) {
  21. res, err := api.client.restClient.Get(api.client.Endpoint+taskUrl+"/"+id, api.client.options.TokenOptions)
  22. if err != nil {
  23. return
  24. }
  25. defer res.Body.Close()
  26. result, err := getTask(getError(res))
  27. return result, err
  28. }
  29. // Gets all tasks, using options to filter the results.
  30. // If options is nil, no filtering will occur.
  31. func (api *TasksAPI) GetAll(options *TaskGetOptions) (result *TaskList, err error) {
  32. uri := api.client.Endpoint + taskUrl
  33. if options != nil {
  34. uri += getQueryString(options)
  35. }
  36. res, err := api.client.restClient.GetList(api.client.Endpoint, uri, api.client.options.TokenOptions)
  37. if err != nil {
  38. return
  39. }
  40. result = &TaskList{}
  41. err = json.Unmarshal(res, result)
  42. return
  43. }
  44. // Waits for a task to complete by polling the tasks API until a task returns with
  45. // the state COMPLETED or ERROR. Will wait no longer than the duration specified by timeout.
  46. func (api *TasksAPI) WaitTimeout(id string, timeout time.Duration) (task *Task, err error) {
  47. start := time.Now()
  48. numErrors := 0
  49. maxErrors := api.client.options.TaskRetryCount
  50. for time.Since(start) < timeout {
  51. task, err = api.Get(id)
  52. if err != nil {
  53. switch err.(type) {
  54. // If an ApiError comes back, something is wrong, return the error to the caller
  55. case ApiError:
  56. return
  57. // For other errors, retry before giving up
  58. default:
  59. numErrors++
  60. if numErrors > maxErrors {
  61. return
  62. }
  63. }
  64. } else {
  65. // Reset the error count any time a successful call is made
  66. numErrors = 0
  67. if task.State == "COMPLETED" {
  68. return
  69. }
  70. if task.State == "ERROR" {
  71. err = TaskError{task.ID, getFailedStep(task)}
  72. return
  73. }
  74. }
  75. time.Sleep(api.client.options.TaskPollDelay)
  76. }
  77. err = TaskTimeoutError{id}
  78. return
  79. }
  80. // Waits for a task to complete by polling the tasks API until a task returns with
  81. // the state COMPLETED or ERROR.
  82. func (api *TasksAPI) Wait(id string) (task *Task, err error) {
  83. return api.WaitTimeout(id, api.client.options.TaskPollTimeout)
  84. }
  85. // Gets the failed step in the task to get error details for failed task.
  86. func getFailedStep(task *Task) (step Step) {
  87. var errorStep Step
  88. for _, s := range task.Steps {
  89. if s.State == "ERROR" {
  90. errorStep = s
  91. break
  92. }
  93. }
  94. return errorStep
  95. }