github.com/jenspinney/cli@v6.42.1-0.20190207184520-7450c600020e+incompatible/api/cloudcontroller/ccv3/job.go (about) 1 package ccv3 2 3 import ( 4 "time" 5 6 "code.cloudfoundry.org/cli/api/cloudcontroller" 7 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 8 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant" 9 ) 10 11 // ErrorDetails provides information regarding a job's error. 12 type ErrorDetails struct { 13 // Code is a numeric code for this error. 14 Code int64 `json:"code"` 15 // Detail is a verbose description of the error. 16 Detail string `json:"detail"` 17 // Title is a short description of the error. 18 Title string `json:"title"` 19 } 20 21 // Job represents a Cloud Controller Job. 22 type Job struct { 23 // Errors is a list of errors that occurred while processing the job. 24 Errors []ErrorDetails `json:"errors"` 25 // GUID is a unique identifier for the job. 26 GUID string `json:"guid"` 27 // State is the state of the job. 28 State constant.JobState `json:"state"` 29 } 30 31 // HasFailed returns true when the job has completed with an error/failure. 32 func (job Job) HasFailed() bool { 33 return job.State == constant.JobFailed 34 } 35 36 // IsComplete returns true when the job has completed successfully. 37 func (job Job) IsComplete() bool { 38 return job.State == constant.JobComplete 39 } 40 41 // GetJob returns a job for the provided GUID. 42 func (client *Client) GetJob(jobURL JobURL) (Job, Warnings, error) { 43 request, err := client.newHTTPRequest(requestOptions{URL: string(jobURL)}) 44 if err != nil { 45 return Job{}, nil, err 46 } 47 48 var job Job 49 response := cloudcontroller.Response{ 50 DecodeJSONResponseInto: &job, 51 } 52 53 err = client.connection.Make(request, &response) 54 return job, response.Warnings, err 55 } 56 57 // PollJob will keep polling the given job until the job has terminated, an 58 // error is encountered, or config.OverallPollingTimeout is reached. In the 59 // last case, a JobTimeoutError is returned. 60 func (client *Client) PollJob(jobURL JobURL) (Warnings, error) { 61 var ( 62 err error 63 warnings Warnings 64 allWarnings Warnings 65 job Job 66 ) 67 68 startTime := client.clock.Now() 69 for client.clock.Now().Sub(startTime) < client.jobPollingTimeout { 70 job, warnings, err = client.GetJob(jobURL) 71 allWarnings = append(allWarnings, warnings...) 72 if err != nil { 73 return allWarnings, err 74 } 75 76 if job.HasFailed() { 77 firstError := job.Errors[0] 78 return allWarnings, ccerror.V3JobFailedError{ 79 JobGUID: job.GUID, 80 Code: firstError.Code, 81 Detail: firstError.Detail, 82 Title: firstError.Title, 83 } 84 } 85 86 if job.IsComplete() { 87 return allWarnings, nil 88 } 89 90 time.Sleep(client.jobPollingInterval) 91 } 92 93 return allWarnings, ccerror.JobTimeoutError{ 94 JobGUID: job.GUID, 95 Timeout: client.jobPollingTimeout, 96 } 97 }