...

Source file src/github.com/Azure/azure-sdk-for-go/services/classic/management/operations.go

Documentation: github.com/Azure/azure-sdk-for-go/services/classic/management

     1  // +build go1.7
     2  
     3  package management
     4  
     5  // Copyright (c) Microsoft Corporation. All rights reserved.
     6  // Licensed under the MIT License. See License.txt in the project root for license information.
     7  
     8  import (
     9  	"encoding/xml"
    10  	"errors"
    11  	"fmt"
    12  	"time"
    13  )
    14  
    15  var (
    16  	// ErrOperationCancelled from WaitForOperation when the polling loop is
    17  	// cancelled through signaling the channel.
    18  	ErrOperationCancelled = errors.New("Polling for operation status cancelled")
    19  )
    20  
    21  // GetOperationStatusResponse represents an in-flight operation. Use
    22  // client.GetOperationStatus() to get the operation given the operation ID, or
    23  // use WaitForOperation() to poll and wait until the operation has completed.
    24  // See https://msdn.microsoft.com/en-us/library/azure/ee460783.aspx
    25  type GetOperationStatusResponse struct {
    26  	XMLName        xml.Name `xml:"http://schemas.microsoft.com/windowsazure Operation"`
    27  	ID             string
    28  	Status         OperationStatus
    29  	HTTPStatusCode string
    30  	Error          *AzureError
    31  }
    32  
    33  // OperationStatus describes the states an Microsoft Azure Service Management
    34  // operation an be in.
    35  type OperationStatus string
    36  
    37  // List of states an operation can be reported as
    38  const (
    39  	OperationStatusInProgress OperationStatus = "InProgress"
    40  	OperationStatusSucceeded  OperationStatus = "Succeeded"
    41  	OperationStatusFailed     OperationStatus = "Failed"
    42  )
    43  
    44  // OperationID is assigned by Azure API and can be used to look up the status of
    45  // an operation
    46  type OperationID string
    47  
    48  func (c client) GetOperationStatus(operationID OperationID) (GetOperationStatusResponse, error) {
    49  	operation := GetOperationStatusResponse{}
    50  	if operationID == "" {
    51  		return operation, fmt.Errorf(errParamNotSpecified, "operationID")
    52  	}
    53  
    54  	url := fmt.Sprintf("operations/%s", operationID)
    55  	response, azureErr := c.SendAzureGetRequest(url)
    56  	if azureErr != nil {
    57  		return operation, azureErr
    58  	}
    59  
    60  	err := xml.Unmarshal(response, &operation)
    61  	return operation, err
    62  }
    63  
    64  func (c client) WaitForOperation(operationID OperationID, cancel chan struct{}) error {
    65  	for {
    66  		done, err := c.checkOperationStatus(operationID)
    67  		if err != nil || done {
    68  			return err
    69  		}
    70  		select {
    71  		case <-time.After(c.config.OperationPollInterval):
    72  		case <-cancel:
    73  			return ErrOperationCancelled
    74  		}
    75  	}
    76  }
    77  
    78  func (c client) checkOperationStatus(id OperationID) (done bool, err error) {
    79  	op, err := c.GetOperationStatus(id)
    80  	if err != nil {
    81  		return false, fmt.Errorf("Failed to get operation status '%s': %v", id, err)
    82  	}
    83  
    84  	switch op.Status {
    85  	case OperationStatusSucceeded:
    86  		return true, nil
    87  	case OperationStatusFailed:
    88  		if op.Error != nil {
    89  			return true, op.Error
    90  		}
    91  		return true, fmt.Errorf("Azure Operation (x-ms-request-id=%s) has failed", id)
    92  	case OperationStatusInProgress:
    93  		return false, nil
    94  	default:
    95  		return false, fmt.Errorf("Unknown operation status returned from API: %s (x-ms-request-id=%s)", op.Status, id)
    96  	}
    97  }
    98  

View as plain text