github.com/ablease/cli@v6.37.1-0.20180613014814-3adbb7d7fb19+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 int `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  		Result: &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 := time.Now()
    69  	for time.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  			return allWarnings, ccerror.JobFailedError{
    78  				JobGUID: job.GUID,
    79  				Message: job.Errors[0].Detail,
    80  			}
    81  		}
    82  
    83  		if job.IsComplete() {
    84  			return allWarnings, nil
    85  		}
    86  
    87  		time.Sleep(client.jobPollingInterval)
    88  	}
    89  
    90  	return allWarnings, ccerror.JobTimeoutError{
    91  		JobGUID: job.GUID,
    92  		Timeout: client.jobPollingTimeout,
    93  	}
    94  }